-
Notifications
You must be signed in to change notification settings - Fork 1
/
insert.c
200 lines (169 loc) · 4.55 KB
/
insert.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* insert.c
*
* part of dbasic
*
* (C) k theis <theis.kurt@gmail.com> 2022
*
* edit routines for interactive dbasic
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dbasic.h"
/* scan thru buffer, return the highest line number used */
int gethighestlinenumber() {
extern char *buffer;
extern int pos;
int n=0, tmppos=0, linenumber = 0;
char linenum[LNSIZE] = {'\0'};
char line[LINESIZE] = {'\0'}; memset(line,0,LINESIZE);
// read a line, get line number
ghln:
n = 0;
while(1) {
if (buffer[tmppos+n]=='\n' || buffer[tmppos+n]=='\0') break;
line[n] = buffer[tmppos+n];
n++;
}
sscanf(line,"%s ",linenum);
linenumber = atoi(linenum);
tmppos += n+1; // skip final \n
if (tmppos < pos) goto ghln;
return linenumber;
}
/* return the starting address of the line
* where the linenumber is just above the given
* linenumber
*/
int getaddressbeforelinenumber(int lnr) {
extern char *buffer;
extern int pos;
int n=0, tmppos=0, linenumber=0;
char linenum[LNSIZE];
char line[LINESIZE]; memset(line,0,LINESIZE);
// read a line, get line number and address.
// As soon as the line number is greater than
// the given line number, return the address;
gln:
n = 0;
while (1) {
if (buffer[tmppos+n]=='\n' || buffer[tmppos+n]=='\0') break;
line[n] = buffer[tmppos+n];
n++;
}
sscanf(line,"%s ",linenum);
linenumber = atoi(linenum);
if (linenumber > lnr) return tmppos;
tmppos += n+1;
if (tmppos < pos) goto gln;
return -1;
}
/* insert or delete a line */
int insert(char line[LINESIZE]) {
/*
* If a line with a linenumber only is given, delete the line from the buffer
* If a line if given with a linenumber greater than the last line, append
* that line to the buffer.
* If a line with a linenumber somewhere in the middle of the buffer is given,
* insert that line into the buffer.
*
*/
extern int getstartaddress(int);
extern int pos;
extern char *buffer;
char ch;
int i=0, n=0, QFLAG=0;
int linestart=0, lineend=0, linesize=0;
if (strlen(line) > (BUFSIZE-pos)) {
printf("Error - no space left\n");
return -1;
}
// convert all except between "" to lower case
QFLAG=0; n=0;
while (1) {
ch = line[n];
if (ch == '\n' || ch == '\0') break;
if (ch == '"')
QFLAG = abs(QFLAG-1);
if (!QFLAG)
line[n] = tolower(ch);
n++;
continue;
}
// test if line has a line number
char linenum[LNSIZE], keyword[LINESIZE];
sscanf(line,"%s %s",linenum, keyword);
if (atoi(linenum) < 1) {
printf("Error - missing line number\nReady.\n");
return -1;
}
// test if line number is a match
int startaddress = getstartaddress(atoi(linenum));
// line number not in buffer- see where to place it
if (startaddress == -1) {
// first test for an empty line (not allowed)
n=-1;
while (1) {
n++;
if (isdigit(line[n])) continue;
if (line[n] == '\0' || line[n] == '\n') return 0;
if (isblank(line[n])) continue;
break;
}
// test for end-of-buffer insert
if (gethighestlinenumber() < atoi(linenum)) {
for (i=0; i<strlen(line); i++) {
buffer[pos+i] = line[i];
}
pos += i; // and increment the end of the buffer
return 0;
}
// insert somewhere in the buffer
startaddress = getaddressbeforelinenumber(atoi(linenum));
// insert the line at this address
linesize = strlen(line);
n = 0;
while (1) { // shift everything up by line length
buffer[pos+linesize-n] = buffer[pos-n];
n++;
if (pos-n == startaddress-1) break;
}
pos += linesize; // update end of buffer
// insert new line at startaddress
for (n=0; n<linesize; n++)
buffer[startaddress+n] = line[n];
return 0;
}
linestart = startaddress;
// get lineend address
for (i=startaddress; i<startaddress+LINESIZE; i++) {
if (buffer[i] == '\n') break;
}
i++; // skip \n
lineend = i;
// get size of existing line
linesize = i-linestart+1;
// shift down everything, deleting old line
for (n=0; n<pos; n++)
buffer[linestart+n] = buffer[lineend+n];
pos = pos-linesize+1;
if (strlen(line) - strlen(linenum) == 1)
return 0; // user hit line# and return, delete line and done
// insert changed line
if (strlen(line) - strlen(linenum) > 1) {
linesize = strlen(line);
n = 0;
while (1) { // shift everything up by line length
buffer[pos+linesize-n] = buffer[pos-n];
n++;
if (pos-n == linestart-1) break;
}
pos += linesize; // update end of buffer
// insert new line at startaddress
for (n=0; n<linesize; n++)
buffer[startaddress+n] = line[n];
}
return 0;
}