diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-09-25 11:55:57 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-09-25 11:55:57 +0000 |
commit | d9391b15f166cfc016f5768c8d6a89858e0d7e41 (patch) | |
tree | 0524b8ff17be49d32a88250a6b899e35b0d000d3 | |
parent | a545726d2baa08b28510336b32d85de91df51d9e (diff) | |
download | busybox-w32-d9391b15f166cfc016f5768c8d6a89858e0d7e41.tar.gz busybox-w32-d9391b15f166cfc016f5768c8d6a89858e0d7e41.tar.bz2 busybox-w32-d9391b15f166cfc016f5768c8d6a89858e0d7e41.zip |
ed: large cleanup
function old new delta
bad_nums - 43 +43
skip_blank - 24 +24
getNum 557 578 +21
insertLine 159 163 +4
setCurNum 31 33 +2
lastNum 4 - -4
fileName 4 - -4
dirty 4 - -4
curNum 4 - -4
curLine 4 - -4
bufUsed 4 - -4
bufSize 4 - -4
bufPtr 4 - -4
bufBase 4 - -4
printLines 357 345 -12
findLine 165 152 -13
lines 16 - -16
deleteLines 203 144 -59
readLines 538 473 -65
addLines 163 87 -76
marks 104 - -104
termEdit 140 - -140
ed_main 3125 2654 -471
------------------------------------------------------------------------------
(add/remove: 2/12 grow/shrink: 3/6 up/down: 94/-992) Total: -898 bytes
text data bss dec hex filename
771142 1034 10564 782740 bf194 busybox_old
770265 1034 10404 781703 bed87 busybox_unstripped
# size */ed.o
text data bss dec hex filename
6370 0 156 6526 197e editors.org/ed.o
5505 0 0 5505 1581 editors/ed.o
-rw-r--r-- | editors/ed.c | 440 |
1 files changed, 135 insertions, 305 deletions
diff --git a/editors/ed.c b/editors/ed.c index e6576b406..f5b9c39bb 100644 --- a/editors/ed.c +++ b/editors/ed.c | |||
@@ -9,6 +9,14 @@ | |||
9 | 9 | ||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | typedef struct LINE { | ||
13 | struct LINE *next; | ||
14 | struct LINE *prev; | ||
15 | int len; | ||
16 | char data[1]; | ||
17 | } LINE; | ||
18 | |||
19 | |||
12 | #define searchString bb_common_bufsiz1 | 20 | #define searchString bb_common_bufsiz1 |
13 | 21 | ||
14 | enum { | 22 | enum { |
@@ -17,64 +25,92 @@ enum { | |||
17 | INITBUF_SIZE = 1024, /* initial buffer size */ | 25 | INITBUF_SIZE = 1024, /* initial buffer size */ |
18 | }; | 26 | }; |
19 | 27 | ||
20 | typedef struct LINE { | 28 | struct globals { |
21 | struct LINE *next; | 29 | int curNum; |
22 | struct LINE *prev; | 30 | int lastNum; |
23 | int len; | 31 | int bufUsed; |
24 | char data[1]; | 32 | int bufSize; |
25 | } LINE; | 33 | LINE *curLine; |
34 | char *bufBase; | ||
35 | char *bufPtr; | ||
36 | char *fileName; | ||
37 | LINE lines; | ||
38 | smallint dirty; | ||
39 | int marks[26]; | ||
40 | }; | ||
41 | #define G (*ptr_to_globals) | ||
42 | #define curLine (G.curLine ) | ||
43 | #define bufBase (G.bufBase ) | ||
44 | #define bufPtr (G.bufPtr ) | ||
45 | #define fileName (G.fileName ) | ||
46 | #define curNum (G.curNum ) | ||
47 | #define lastNum (G.lastNum ) | ||
48 | #define bufUsed (G.bufUsed ) | ||
49 | #define bufSize (G.bufSize ) | ||
50 | #define dirty (G.dirty ) | ||
51 | #define lines (G.lines ) | ||
52 | #define marks (G.marks ) | ||
53 | #define INIT_G() do { \ | ||
54 | PTR_TO_GLOBALS = xzalloc(sizeof(G)); \ | ||
55 | } while (0) | ||
26 | 56 | ||
27 | static LINE lines, *curLine; | ||
28 | static int curNum, lastNum, marks[26], dirty; | ||
29 | static char *bufBase, *bufPtr, *fileName; | ||
30 | static int bufUsed, bufSize; | ||
31 | 57 | ||
32 | static void doCommands(void); | 58 | static void doCommands(void); |
33 | static void subCommand(const char *cmd, int num1, int num2); | 59 | static void subCommand(const char *cmd, int num1, int num2); |
34 | static int getNum(const char **retcp, int *retHaveNum, int *retNum); | 60 | static int getNum(const char **retcp, smallint *retHaveNum, int *retNum); |
35 | static int setCurNum(int num); | 61 | static int setCurNum(int num); |
36 | static int initEdit(void); | ||
37 | static void termEdit(void); | ||
38 | static void addLines(int num); | 62 | static void addLines(int num); |
39 | static int insertLine(int num, const char *data, int len); | 63 | static int insertLine(int num, const char *data, int len); |
40 | static int deleteLines(int num1, int num2); | 64 | static void deleteLines(int num1, int num2); |
41 | static int printLines(int num1, int num2, int expandFlag); | 65 | static int printLines(int num1, int num2, int expandFlag); |
42 | static int writeLines(const char *file, int num1, int num2); | 66 | static int writeLines(const char *file, int num1, int num2); |
43 | static int readLines(const char *file, int num); | 67 | static int readLines(const char *file, int num); |
44 | static int searchLines(const char *str, int num1, int num2); | 68 | static int searchLines(const char *str, int num1, int num2); |
45 | static LINE *findLine(int num); | 69 | static LINE *findLine(int num); |
46 | |||
47 | static int findString(const LINE *lp, const char * str, int len, int offset); | 70 | static int findString(const LINE *lp, const char * str, int len, int offset); |
48 | 71 | ||
72 | |||
73 | static int bad_nums(int num1, int num2, const char *for_what) | ||
74 | { | ||
75 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | ||
76 | bb_error_msg("bad line range for %s", for_what); | ||
77 | return 1; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | |||
83 | static char *skip_blank(const char *cp) | ||
84 | { | ||
85 | // NB: fix comment in skip_whitespace! | ||
86 | while (isblank(*cp)) | ||
87 | cp++; | ||
88 | return (char *)cp; | ||
89 | } | ||
90 | |||
91 | |||
49 | int ed_main(int argc, char **argv); | 92 | int ed_main(int argc, char **argv); |
50 | int ed_main(int argc, char **argv) | 93 | int ed_main(int argc, char **argv) |
51 | { | 94 | { |
52 | if (!initEdit()) | 95 | INIT_G(); |
53 | return EXIT_FAILURE; | ||
54 | |||
55 | if (argc > 1) { | ||
56 | fileName = strdup(argv[1]); | ||
57 | 96 | ||
58 | if (fileName == NULL) { | 97 | bufSize = INITBUF_SIZE; |
59 | bb_error_msg("no memory"); | 98 | bufBase = xmalloc(bufSize); |
60 | termEdit(); | 99 | bufPtr = bufBase; |
61 | return EXIT_SUCCESS; | 100 | lines.next = &lines; |
62 | } | 101 | lines.prev = &lines; |
63 | 102 | ||
103 | if (argc > 1) { | ||
104 | fileName = xstrdup(argv[1]); | ||
64 | if (!readLines(fileName, 1)) { | 105 | if (!readLines(fileName, 1)) { |
65 | termEdit(); | ||
66 | return EXIT_SUCCESS; | 106 | return EXIT_SUCCESS; |
67 | } | 107 | } |
68 | |||
69 | if (lastNum) | 108 | if (lastNum) |
70 | setCurNum(1); | 109 | setCurNum(1); |
71 | |||
72 | dirty = FALSE; | 110 | dirty = FALSE; |
73 | } | 111 | } |
74 | 112 | ||
75 | doCommands(); | 113 | doCommands(); |
76 | |||
77 | termEdit(); | ||
78 | return EXIT_SUCCESS; | 114 | return EXIT_SUCCESS; |
79 | } | 115 | } |
80 | 116 | ||
@@ -85,42 +121,25 @@ static void doCommands(void) | |||
85 | { | 121 | { |
86 | const char *cp; | 122 | const char *cp; |
87 | char *endbuf, *newname, buf[USERSIZE]; | 123 | char *endbuf, *newname, buf[USERSIZE]; |
88 | int len, num1, num2, have1, have2; | 124 | int len, num1, num2; |
125 | smallint have1, have2; | ||
89 | 126 | ||
90 | while (TRUE) { | 127 | while (TRUE) { |
91 | printf(": "); | 128 | // NB: fix comment in lineedit.c! |
92 | fflush(stdout); | 129 | /* Returns: |
93 | 130 | * -1 on read errors or EOF, or on bare Ctrl-D. | |
94 | if (fgets(buf, sizeof(buf), stdin) == NULL) | 131 | * 0 on ctrl-C, |
95 | return; | 132 | * >0 length of input string, including terminating '\n' |
96 | 133 | */ | |
97 | len = strlen(buf); | 134 | len = read_line_input(": ", buf, sizeof(buf), NULL); |
98 | 135 | if (len <= 0) | |
99 | if (len == 0) | ||
100 | return; | 136 | return; |
101 | |||
102 | endbuf = &buf[len - 1]; | 137 | endbuf = &buf[len - 1]; |
103 | |||
104 | if (*endbuf != '\n') { | ||
105 | bb_error_msg("command line too long"); | ||
106 | |||
107 | do { | ||
108 | len = fgetc(stdin); | ||
109 | } while ((len != EOF) && (len != '\n')); | ||
110 | |||
111 | continue; | ||
112 | } | ||
113 | |||
114 | while ((endbuf > buf) && isblank(endbuf[-1])) | 138 | while ((endbuf > buf) && isblank(endbuf[-1])) |
115 | endbuf--; | 139 | endbuf--; |
116 | |||
117 | *endbuf = '\0'; | 140 | *endbuf = '\0'; |
118 | 141 | ||
119 | cp = buf; | 142 | cp = skip_blank(buf); |
120 | |||
121 | while (isblank(*cp)) | ||
122 | cp++; | ||
123 | |||
124 | have1 = FALSE; | 143 | have1 = FALSE; |
125 | have2 = FALSE; | 144 | have2 = FALSE; |
126 | 145 | ||
@@ -132,28 +151,21 @@ static void doCommands(void) | |||
132 | if (!getNum(&cp, &have1, &num1)) | 151 | if (!getNum(&cp, &have1, &num1)) |
133 | continue; | 152 | continue; |
134 | 153 | ||
135 | while (isblank(*cp)) | 154 | cp = skip_blank(cp); |
136 | cp++; | ||
137 | 155 | ||
138 | if (*cp == ',') { | 156 | if (*cp == ',') { |
139 | cp++; | 157 | cp++; |
140 | |||
141 | if (!getNum(&cp, &have2, &num2)) | 158 | if (!getNum(&cp, &have2, &num2)) |
142 | continue; | 159 | continue; |
143 | |||
144 | if (!have1) | 160 | if (!have1) |
145 | num1 = 1; | 161 | num1 = 1; |
146 | |||
147 | if (!have2) | 162 | if (!have2) |
148 | num2 = lastNum; | 163 | num2 = lastNum; |
149 | |||
150 | have1 = TRUE; | 164 | have1 = TRUE; |
151 | have2 = TRUE; | 165 | have2 = TRUE; |
152 | } | 166 | } |
153 | |||
154 | if (!have1) | 167 | if (!have1) |
155 | num1 = curNum; | 168 | num1 = curNum; |
156 | |||
157 | if (!have2) | 169 | if (!have2) |
158 | num2 = num1; | 170 | num2 = num1; |
159 | 171 | ||
@@ -176,10 +188,7 @@ static void doCommands(void) | |||
176 | bb_error_msg("bad file command"); | 188 | bb_error_msg("bad file command"); |
177 | break; | 189 | break; |
178 | } | 190 | } |
179 | 191 | cp = skip_blank(cp); | |
180 | while (isblank(*cp)) | ||
181 | cp++; | ||
182 | |||
183 | if (*cp == '\0') { | 192 | if (*cp == '\0') { |
184 | if (fileName) | 193 | if (fileName) |
185 | printf("\"%s\"\n", fileName); | 194 | printf("\"%s\"\n", fileName); |
@@ -187,17 +196,12 @@ static void doCommands(void) | |||
187 | printf("No file name\n"); | 196 | printf("No file name\n"); |
188 | break; | 197 | break; |
189 | } | 198 | } |
190 | |||
191 | newname = strdup(cp); | 199 | newname = strdup(cp); |
192 | |||
193 | if (newname == NULL) { | 200 | if (newname == NULL) { |
194 | bb_error_msg("no memory for file name"); | 201 | bb_error_msg("no memory for file name"); |
195 | break; | 202 | break; |
196 | } | 203 | } |
197 | 204 | free(fileName); | |
198 | if (fileName) | ||
199 | free(fileName); | ||
200 | |||
201 | fileName = newname; | 205 | fileName = newname; |
202 | break; | 206 | break; |
203 | 207 | ||
@@ -206,14 +210,11 @@ static void doCommands(void) | |||
206 | break; | 210 | break; |
207 | 211 | ||
208 | case 'k': | 212 | case 'k': |
209 | while (isblank(*cp)) | 213 | cp = skip_blank(cp); |
210 | cp++; | 214 | if ((*cp < 'a') || (*cp > 'z') || cp[1]) { |
211 | |||
212 | if ((*cp < 'a') || (*cp > 'a') || cp[1]) { | ||
213 | bb_error_msg("bad mark name"); | 215 | bb_error_msg("bad mark name"); |
214 | break; | 216 | break; |
215 | } | 217 | } |
216 | |||
217 | marks[*cp - 'a'] = num2; | 218 | marks[*cp - 'a'] = num2; |
218 | break; | 219 | break; |
219 | 220 | ||
@@ -226,30 +227,20 @@ static void doCommands(void) | |||
226 | break; | 227 | break; |
227 | 228 | ||
228 | case 'q': | 229 | case 'q': |
229 | while (isblank(*cp)) | 230 | cp = skip_blank(cp); |
230 | cp++; | ||
231 | |||
232 | if (have1 || *cp) { | 231 | if (have1 || *cp) { |
233 | bb_error_msg("bad quit command"); | 232 | bb_error_msg("bad quit command"); |
234 | break; | 233 | break; |
235 | } | 234 | } |
236 | |||
237 | if (!dirty) | 235 | if (!dirty) |
238 | return; | 236 | return; |
239 | 237 | len = read_line_input("Really quit? ", buf, 16, NULL); | |
240 | printf("Really quit? "); | 238 | /* read error/EOF - no way to continue */ |
241 | fflush(stdout); | 239 | if (len < 0) |
242 | 240 | return; | |
243 | buf[0] = '\0'; | 241 | cp = skip_blank(buf); |
244 | fgets(buf, sizeof(buf), stdin); | 242 | if ((*cp | 0x20) == 'y') /* Y or y */ |
245 | cp = buf; | ||
246 | |||
247 | while (isblank(*cp)) | ||
248 | cp++; | ||
249 | |||
250 | if ((*cp == 'y') || (*cp == 'Y')) | ||
251 | return; | 243 | return; |
252 | |||
253 | break; | 244 | break; |
254 | 245 | ||
255 | case 'r': | 246 | case 'r': |
@@ -257,24 +248,17 @@ static void doCommands(void) | |||
257 | bb_error_msg("bad read command"); | 248 | bb_error_msg("bad read command"); |
258 | break; | 249 | break; |
259 | } | 250 | } |
260 | 251 | cp = skip_blank(cp); | |
261 | while (isblank(*cp)) | ||
262 | cp++; | ||
263 | |||
264 | if (*cp == '\0') { | 252 | if (*cp == '\0') { |
265 | bb_error_msg("no file name"); | 253 | bb_error_msg("no file name"); |
266 | break; | 254 | break; |
267 | } | 255 | } |
268 | |||
269 | if (!have1) | 256 | if (!have1) |
270 | num1 = lastNum; | 257 | num1 = lastNum; |
271 | |||
272 | if (readLines(cp, num1 + 1)) | 258 | if (readLines(cp, num1 + 1)) |
273 | break; | 259 | break; |
274 | |||
275 | if (fileName == NULL) | 260 | if (fileName == NULL) |
276 | fileName = strdup(cp); | 261 | fileName = strdup(cp); |
277 | |||
278 | break; | 262 | break; |
279 | 263 | ||
280 | case 's': | 264 | case 's': |
@@ -286,36 +270,30 @@ static void doCommands(void) | |||
286 | bb_error_msg("bad write command"); | 270 | bb_error_msg("bad write command"); |
287 | break; | 271 | break; |
288 | } | 272 | } |
289 | 273 | cp = skip_blank(cp); | |
290 | while (isblank(*cp)) | ||
291 | cp++; | ||
292 | |||
293 | if (!have1) { | 274 | if (!have1) { |
294 | num1 = 1; | 275 | num1 = 1; |
295 | num2 = lastNum; | 276 | num2 = lastNum; |
296 | } | 277 | } |
297 | |||
298 | if (*cp == '\0') | 278 | if (*cp == '\0') |
299 | cp = fileName; | 279 | cp = fileName; |
300 | |||
301 | if (cp == NULL) { | 280 | if (cp == NULL) { |
302 | bb_error_msg("no file name specified"); | 281 | bb_error_msg("no file name specified"); |
303 | break; | 282 | break; |
304 | } | 283 | } |
305 | |||
306 | writeLines(cp, num1, num2); | 284 | writeLines(cp, num1, num2); |
307 | break; | 285 | break; |
308 | 286 | ||
309 | case 'z': | 287 | case 'z': |
310 | switch (*cp) { | 288 | switch (*cp) { |
311 | case '-': | 289 | case '-': |
312 | printLines(curNum-21, curNum, FALSE); | 290 | printLines(curNum - 21, curNum, FALSE); |
313 | break; | 291 | break; |
314 | case '.': | 292 | case '.': |
315 | printLines(curNum-11, curNum+10, FALSE); | 293 | printLines(curNum - 11, curNum + 10, FALSE); |
316 | break; | 294 | break; |
317 | default: | 295 | default: |
318 | printLines(curNum, curNum+21, FALSE); | 296 | printLines(curNum, curNum + 21, FALSE); |
319 | break; | 297 | break; |
320 | } | 298 | } |
321 | break; | 299 | break; |
@@ -325,29 +303,24 @@ static void doCommands(void) | |||
325 | bb_error_msg("no arguments allowed"); | 303 | bb_error_msg("no arguments allowed"); |
326 | break; | 304 | break; |
327 | } | 305 | } |
328 | |||
329 | printLines(curNum, curNum, FALSE); | 306 | printLines(curNum, curNum, FALSE); |
330 | break; | 307 | break; |
331 | 308 | ||
332 | case '-': | 309 | case '-': |
333 | if (setCurNum(curNum - 1)) | 310 | if (setCurNum(curNum - 1)) |
334 | printLines(curNum, curNum, FALSE); | 311 | printLines(curNum, curNum, FALSE); |
335 | |||
336 | break; | 312 | break; |
337 | 313 | ||
338 | case '=': | 314 | case '=': |
339 | printf("%d\n", num1); | 315 | printf("%d\n", num1); |
340 | break; | 316 | break; |
341 | |||
342 | case '\0': | 317 | case '\0': |
343 | if (have1) { | 318 | if (have1) { |
344 | printLines(num2, num2, FALSE); | 319 | printLines(num2, num2, FALSE); |
345 | break; | 320 | break; |
346 | } | 321 | } |
347 | |||
348 | if (setCurNum(curNum + 1)) | 322 | if (setCurNum(curNum + 1)) |
349 | printLines(curNum, curNum, FALSE); | 323 | printLines(curNum, curNum, FALSE); |
350 | |||
351 | break; | 324 | break; |
352 | 325 | ||
353 | default: | 326 | default: |
@@ -362,17 +335,15 @@ static void doCommands(void) | |||
362 | * Do the substitute command. | 335 | * Do the substitute command. |
363 | * The current line is set to the last substitution done. | 336 | * The current line is set to the last substitution done. |
364 | */ | 337 | */ |
365 | static void subCommand(const char * cmd, int num1, int num2) | 338 | static void subCommand(const char *cmd, int num1, int num2) |
366 | { | 339 | { |
367 | char *cp, *oldStr, *newStr, buf[USERSIZE]; | 340 | char *cp, *oldStr, *newStr, buf[USERSIZE]; |
368 | int delim, oldLen, newLen, deltaLen, offset; | 341 | int delim, oldLen, newLen, deltaLen, offset; |
369 | LINE *lp, *nlp; | 342 | LINE *lp, *nlp; |
370 | int globalFlag, printFlag, didSub, needPrint; | 343 | int globalFlag, printFlag, didSub, needPrint; |
371 | 344 | ||
372 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | 345 | if (bad_nums(num1, num2, "substitute")) |
373 | bb_error_msg("bad line range for substitute"); | ||
374 | return; | 346 | return; |
375 | } | ||
376 | 347 | ||
377 | globalFlag = FALSE; | 348 | globalFlag = FALSE; |
378 | printFlag = FALSE; | 349 | printFlag = FALSE; |
@@ -394,7 +365,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
394 | oldStr = cp; | 365 | oldStr = cp; |
395 | 366 | ||
396 | cp = strchr(cp, delim); | 367 | cp = strchr(cp, delim); |
397 | |||
398 | if (cp == NULL) { | 368 | if (cp == NULL) { |
399 | bb_error_msg("missing 2nd delimiter for substitute"); | 369 | bb_error_msg("missing 2nd delimiter for substitute"); |
400 | return; | 370 | return; |
@@ -414,11 +384,9 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
414 | case 'g': | 384 | case 'g': |
415 | globalFlag = TRUE; | 385 | globalFlag = TRUE; |
416 | break; | 386 | break; |
417 | |||
418 | case 'p': | 387 | case 'p': |
419 | printFlag = TRUE; | 388 | printFlag = TRUE; |
420 | break; | 389 | break; |
421 | |||
422 | default: | 390 | default: |
423 | bb_error_msg("unknown option for substitute"); | 391 | bb_error_msg("unknown option for substitute"); |
424 | return; | 392 | return; |
@@ -429,7 +397,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
429 | bb_error_msg("no previous search string"); | 397 | bb_error_msg("no previous search string"); |
430 | return; | 398 | return; |
431 | } | 399 | } |
432 | |||
433 | oldStr = searchString; | 400 | oldStr = searchString; |
434 | } | 401 | } |
435 | 402 | ||
@@ -437,7 +404,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
437 | strcpy(searchString, oldStr); | 404 | strcpy(searchString, oldStr); |
438 | 405 | ||
439 | lp = findLine(num1); | 406 | lp = findLine(num1); |
440 | |||
441 | if (lp == NULL) | 407 | if (lp == NULL) |
442 | return; | 408 | return; |
443 | 409 | ||
@@ -455,11 +421,9 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
455 | printLines(num1, num1, FALSE); | 421 | printLines(num1, num1, FALSE); |
456 | needPrint = FALSE; | 422 | needPrint = FALSE; |
457 | } | 423 | } |
458 | |||
459 | offset = 0; | 424 | offset = 0; |
460 | lp = lp->next; | 425 | lp = lp->next; |
461 | num1++; | 426 | num1++; |
462 | |||
463 | continue; | 427 | continue; |
464 | } | 428 | } |
465 | 429 | ||
@@ -473,7 +437,6 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
473 | */ | 437 | */ |
474 | if (deltaLen <= 0) { | 438 | if (deltaLen <= 0) { |
475 | memcpy(&lp->data[offset], newStr, newLen); | 439 | memcpy(&lp->data[offset], newStr, newLen); |
476 | |||
477 | if (deltaLen) { | 440 | if (deltaLen) { |
478 | memcpy(&lp->data[offset + newLen], | 441 | memcpy(&lp->data[offset + newLen], |
479 | &lp->data[offset + oldLen], | 442 | &lp->data[offset + oldLen], |
@@ -481,20 +444,15 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
481 | 444 | ||
482 | lp->len += deltaLen; | 445 | lp->len += deltaLen; |
483 | } | 446 | } |
484 | |||
485 | offset += newLen; | 447 | offset += newLen; |
486 | |||
487 | if (globalFlag) | 448 | if (globalFlag) |
488 | continue; | 449 | continue; |
489 | |||
490 | if (needPrint) { | 450 | if (needPrint) { |
491 | printLines(num1, num1, FALSE); | 451 | printLines(num1, num1, FALSE); |
492 | needPrint = FALSE; | 452 | needPrint = FALSE; |
493 | } | 453 | } |
494 | |||
495 | lp = lp->next; | 454 | lp = lp->next; |
496 | num1++; | 455 | num1++; |
497 | |||
498 | continue; | 456 | continue; |
499 | } | 457 | } |
500 | 458 | ||
@@ -503,8 +461,7 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
503 | * structure and use that. Link it in in place of | 461 | * structure and use that. Link it in in place of |
504 | * the old line structure. | 462 | * the old line structure. |
505 | */ | 463 | */ |
506 | nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltaLen); | 464 | nlp = malloc(sizeof(LINE) + lp->len + deltaLen); |
507 | |||
508 | if (nlp == NULL) { | 465 | if (nlp == NULL) { |
509 | bb_error_msg("cannot get memory for line"); | 466 | bb_error_msg("cannot get memory for line"); |
510 | return; | 467 | return; |
@@ -513,9 +470,7 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
513 | nlp->len = lp->len + deltaLen; | 470 | nlp->len = lp->len + deltaLen; |
514 | 471 | ||
515 | memcpy(nlp->data, lp->data, offset); | 472 | memcpy(nlp->data, lp->data, offset); |
516 | |||
517 | memcpy(&nlp->data[offset], newStr, newLen); | 473 | memcpy(&nlp->data[offset], newStr, newLen); |
518 | |||
519 | memcpy(&nlp->data[offset + newLen], | 474 | memcpy(&nlp->data[offset + newLen], |
520 | &lp->data[offset + oldLen], | 475 | &lp->data[offset + oldLen], |
521 | lp->len - offset - oldLen); | 476 | lp->len - offset - oldLen); |
@@ -554,7 +509,7 @@ static void subCommand(const char * cmd, int num1, int num2) | |||
554 | * Search a line for the specified string starting at the specified | 509 | * Search a line for the specified string starting at the specified |
555 | * offset in the line. Returns the offset of the found string, or -1. | 510 | * offset in the line. Returns the offset of the found string, or -1. |
556 | */ | 511 | */ |
557 | static int findString( const LINE * lp, const char * str, int len, int offset) | 512 | static int findString(const LINE *lp, const char *str, int len, int offset) |
558 | { | 513 | { |
559 | int left; | 514 | int left; |
560 | const char *cp, *ncp; | 515 | const char *cp, *ncp; |
@@ -564,20 +519,14 @@ static int findString( const LINE * lp, const char * str, int len, int offset) | |||
564 | 519 | ||
565 | while (left >= len) { | 520 | while (left >= len) { |
566 | ncp = memchr(cp, *str, left); | 521 | ncp = memchr(cp, *str, left); |
567 | |||
568 | if (ncp == NULL) | 522 | if (ncp == NULL) |
569 | return -1; | 523 | return -1; |
570 | |||
571 | left -= (ncp - cp); | 524 | left -= (ncp - cp); |
572 | |||
573 | if (left < len) | 525 | if (left < len) |
574 | return -1; | 526 | return -1; |
575 | |||
576 | cp = ncp; | 527 | cp = ncp; |
577 | |||
578 | if (memcmp(cp, str, len) == 0) | 528 | if (memcmp(cp, str, len) == 0) |
579 | return (cp - lp->data); | 529 | return (cp - lp->data); |
580 | |||
581 | cp++; | 530 | cp++; |
582 | left--; | 531 | left--; |
583 | } | 532 | } |
@@ -597,23 +546,20 @@ static void addLines(int num) | |||
597 | int len; | 546 | int len; |
598 | char buf[USERSIZE + 1]; | 547 | char buf[USERSIZE + 1]; |
599 | 548 | ||
600 | while (fgets(buf, sizeof(buf), stdin)) { | 549 | while (1) { |
601 | if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0')) | 550 | /* Returns: |
602 | return; | 551 | * -1 on read errors or EOF, or on bare Ctrl-D. |
603 | 552 | * 0 on ctrl-C, | |
604 | len = strlen(buf); | 553 | * >0 length of input string, including terminating '\n' |
605 | 554 | */ | |
606 | if (len == 0) | 555 | len = read_line_input("", buf, sizeof(buf), NULL); |
607 | return; | 556 | if (len <= 0) { |
608 | 557 | /* Previously, ctrl-C was exiting to shell. | |
609 | if (buf[len - 1] != '\n') { | 558 | * Now we exit to ed prompt. Is in important? */ |
610 | bb_error_msg("line too long"); | ||
611 | do { | ||
612 | len = fgetc(stdin); | ||
613 | } while ((len != EOF) && (len != '\n')); | ||
614 | return; | 559 | return; |
615 | } | 560 | } |
616 | 561 | if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0')) | |
562 | return; | ||
617 | if (!insertLine(num++, buf, len)) | 563 | if (!insertLine(num++, buf, len)) |
618 | return; | 564 | return; |
619 | } | 565 | } |
@@ -628,20 +574,20 @@ static void addLines(int num) | |||
628 | * Whether there was a number is returned indirectly, as is the number. | 574 | * Whether there was a number is returned indirectly, as is the number. |
629 | * The character pointer which stopped the scan is also returned. | 575 | * The character pointer which stopped the scan is also returned. |
630 | */ | 576 | */ |
631 | static int getNum(const char **retcp, int *retHaveNum, int *retNum) | 577 | static int getNum(const char **retcp, smallint *retHaveNum, int *retNum) |
632 | { | 578 | { |
633 | const char *cp; | 579 | const char *cp; |
634 | char *endStr, str[USERSIZE]; | 580 | char *endStr, str[USERSIZE]; |
635 | int haveNum, value, num, sign; | 581 | int value, num; |
582 | smallint haveNum, minus; | ||
636 | 583 | ||
637 | cp = *retcp; | 584 | cp = *retcp; |
638 | haveNum = FALSE; | ||
639 | value = 0; | 585 | value = 0; |
640 | sign = 1; | 586 | haveNum = FALSE; |
587 | minus = 0; | ||
641 | 588 | ||
642 | while (TRUE) { | 589 | while (TRUE) { |
643 | while (isblank(*cp)) | 590 | cp = skip_blank(cp); |
644 | cp++; | ||
645 | 591 | ||
646 | switch (*cp) { | 592 | switch (*cp) { |
647 | case '.': | 593 | case '.': |
@@ -658,12 +604,10 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) | |||
658 | 604 | ||
659 | case '\'': | 605 | case '\'': |
660 | cp++; | 606 | cp++; |
661 | |||
662 | if ((*cp < 'a') || (*cp > 'z')) { | 607 | if ((*cp < 'a') || (*cp > 'z')) { |
663 | bb_error_msg("bad mark name"); | 608 | bb_error_msg("bad mark name"); |
664 | return FALSE; | 609 | return FALSE; |
665 | } | 610 | } |
666 | |||
667 | haveNum = TRUE; | 611 | haveNum = TRUE; |
668 | num = marks[*cp++ - 'a']; | 612 | num = marks[*cp++ - 'a']; |
669 | break; | 613 | break; |
@@ -671,19 +615,14 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) | |||
671 | case '/': | 615 | case '/': |
672 | strcpy(str, ++cp); | 616 | strcpy(str, ++cp); |
673 | endStr = strchr(str, '/'); | 617 | endStr = strchr(str, '/'); |
674 | |||
675 | if (endStr) { | 618 | if (endStr) { |
676 | *endStr++ = '\0'; | 619 | *endStr++ = '\0'; |
677 | cp += (endStr - str); | 620 | cp += (endStr - str); |
678 | } | 621 | } else |
679 | else | ||
680 | cp = ""; | 622 | cp = ""; |
681 | |||
682 | num = searchLines(str, curNum, lastNum); | 623 | num = searchLines(str, curNum, lastNum); |
683 | |||
684 | if (num == 0) | 624 | if (num == 0) |
685 | return FALSE; | 625 | return FALSE; |
686 | |||
687 | haveNum = TRUE; | 626 | haveNum = TRUE; |
688 | break; | 627 | break; |
689 | 628 | ||
@@ -694,29 +633,25 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) | |||
694 | *retNum = value; | 633 | *retNum = value; |
695 | return TRUE; | 634 | return TRUE; |
696 | } | 635 | } |
697 | |||
698 | num = 0; | 636 | num = 0; |
699 | |||
700 | while (isdigit(*cp)) | 637 | while (isdigit(*cp)) |
701 | num = num * 10 + *cp++ - '0'; | 638 | num = num * 10 + *cp++ - '0'; |
702 | |||
703 | haveNum = TRUE; | 639 | haveNum = TRUE; |
704 | break; | 640 | break; |
705 | } | 641 | } |
706 | 642 | ||
707 | value += num * sign; | 643 | value += (minus ? -num : num); |
708 | 644 | ||
709 | while (isblank(*cp)) | 645 | cp = skip_blank(cp); |
710 | cp++; | ||
711 | 646 | ||
712 | switch (*cp) { | 647 | switch (*cp) { |
713 | case '-': | 648 | case '-': |
714 | sign = -1; | 649 | minus = 1; |
715 | cp++; | 650 | cp++; |
716 | break; | 651 | break; |
717 | 652 | ||
718 | case '+': | 653 | case '+': |
719 | sign = 1; | 654 | minus = 0; |
720 | cp++; | 655 | cp++; |
721 | break; | 656 | break; |
722 | 657 | ||
@@ -731,74 +666,10 @@ static int getNum(const char **retcp, int *retHaveNum, int *retNum) | |||
731 | 666 | ||
732 | 667 | ||
733 | /* | 668 | /* |
734 | * Initialize everything for editing. | ||
735 | */ | ||
736 | static int initEdit(void) | ||
737 | { | ||
738 | int i; | ||
739 | |||
740 | bufSize = INITBUF_SIZE; | ||
741 | bufBase = malloc(bufSize); | ||
742 | |||
743 | if (bufBase == NULL) { | ||
744 | bb_error_msg("no memory for buffer"); | ||
745 | return FALSE; | ||
746 | } | ||
747 | |||
748 | bufPtr = bufBase; | ||
749 | bufUsed = 0; | ||
750 | |||
751 | lines.next = &lines; | ||
752 | lines.prev = &lines; | ||
753 | |||
754 | curLine = NULL; | ||
755 | curNum = 0; | ||
756 | lastNum = 0; | ||
757 | dirty = FALSE; | ||
758 | fileName = NULL; | ||
759 | searchString[0] = '\0'; | ||
760 | |||
761 | for (i = 0; i < 26; i++) | ||
762 | marks[i] = 0; | ||
763 | |||
764 | return TRUE; | ||
765 | } | ||
766 | |||
767 | |||
768 | /* | ||
769 | * Finish editing. | ||
770 | */ | ||
771 | static void termEdit(void) | ||
772 | { | ||
773 | if (bufBase) | ||
774 | free(bufBase); | ||
775 | |||
776 | bufBase = NULL; | ||
777 | bufPtr = NULL; | ||
778 | bufSize = 0; | ||
779 | bufUsed = 0; | ||
780 | |||
781 | if (fileName) | ||
782 | free(fileName); | ||
783 | |||
784 | fileName = NULL; | ||
785 | |||
786 | searchString[0] = '\0'; | ||
787 | |||
788 | if (lastNum) | ||
789 | deleteLines(1, lastNum); | ||
790 | |||
791 | lastNum = 0; | ||
792 | curNum = 0; | ||
793 | curLine = NULL; | ||
794 | } | ||
795 | |||
796 | |||
797 | /* | ||
798 | * Read lines from a file at the specified line number. | 669 | * Read lines from a file at the specified line number. |
799 | * Returns TRUE if the file was successfully read. | 670 | * Returns TRUE if the file was successfully read. |
800 | */ | 671 | */ |
801 | static int readLines(const char * file, int num) | 672 | static int readLines(const char *file, int num) |
802 | { | 673 | { |
803 | int fd, cc; | 674 | int fd, cc; |
804 | int len, lineCount, charCount; | 675 | int len, lineCount, charCount; |
@@ -810,7 +681,6 @@ static int readLines(const char * file, int num) | |||
810 | } | 681 | } |
811 | 682 | ||
812 | fd = open(file, 0); | 683 | fd = open(file, 0); |
813 | |||
814 | if (fd < 0) { | 684 | if (fd < 0) { |
815 | perror(file); | 685 | perror(file); |
816 | return FALSE; | 686 | return FALSE; |
@@ -830,18 +700,15 @@ static int readLines(const char * file, int num) | |||
830 | 700 | ||
831 | if (cp) { | 701 | if (cp) { |
832 | len = (cp - bufPtr) + 1; | 702 | len = (cp - bufPtr) + 1; |
833 | |||
834 | if (!insertLine(num, bufPtr, len)) { | 703 | if (!insertLine(num, bufPtr, len)) { |
835 | close(fd); | 704 | close(fd); |
836 | return FALSE; | 705 | return FALSE; |
837 | } | 706 | } |
838 | |||
839 | bufPtr += len; | 707 | bufPtr += len; |
840 | bufUsed -= len; | 708 | bufUsed -= len; |
841 | charCount += len; | 709 | charCount += len; |
842 | lineCount++; | 710 | lineCount++; |
843 | num++; | 711 | num++; |
844 | |||
845 | continue; | 712 | continue; |
846 | } | 713 | } |
847 | 714 | ||
@@ -853,19 +720,17 @@ static int readLines(const char * file, int num) | |||
853 | if (bufUsed >= bufSize) { | 720 | if (bufUsed >= bufSize) { |
854 | len = (bufSize * 3) / 2; | 721 | len = (bufSize * 3) / 2; |
855 | cp = realloc(bufBase, len); | 722 | cp = realloc(bufBase, len); |
856 | |||
857 | if (cp == NULL) { | 723 | if (cp == NULL) { |
858 | bb_error_msg("no memory for buffer"); | 724 | bb_error_msg("no memory for buffer"); |
859 | close(fd); | 725 | close(fd); |
860 | return FALSE; | 726 | return FALSE; |
861 | } | 727 | } |
862 | |||
863 | bufBase = cp; | 728 | bufBase = cp; |
864 | bufPtr = bufBase + bufUsed; | 729 | bufPtr = bufBase + bufUsed; |
865 | bufSize = len; | 730 | bufSize = len; |
866 | } | 731 | } |
867 | 732 | ||
868 | cc = read(fd, bufPtr, bufSize - bufUsed); | 733 | cc = safe_read(fd, bufPtr, bufSize - bufUsed); |
869 | bufUsed += cc; | 734 | bufUsed += cc; |
870 | bufPtr = bufBase; | 735 | bufPtr = bufBase; |
871 | 736 | ||
@@ -882,7 +747,6 @@ static int readLines(const char * file, int num) | |||
882 | close(fd); | 747 | close(fd); |
883 | return -1; | 748 | return -1; |
884 | } | 749 | } |
885 | |||
886 | lineCount++; | 750 | lineCount++; |
887 | charCount += bufUsed; | 751 | charCount += bufUsed; |
888 | } | 752 | } |
@@ -900,21 +764,18 @@ static int readLines(const char * file, int num) | |||
900 | * Write the specified lines out to the specified file. | 764 | * Write the specified lines out to the specified file. |
901 | * Returns TRUE if successful, or FALSE on an error with a message output. | 765 | * Returns TRUE if successful, or FALSE on an error with a message output. |
902 | */ | 766 | */ |
903 | static int writeLines(const char * file, int num1, int num2) | 767 | static int writeLines(const char *file, int num1, int num2) |
904 | { | 768 | { |
905 | LINE *lp; | 769 | LINE *lp; |
906 | int fd, lineCount, charCount; | 770 | int fd, lineCount, charCount; |
907 | 771 | ||
908 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | 772 | if (bad_nums(num1, num2, "write")) |
909 | bb_error_msg("bad line range for write"); | ||
910 | return FALSE; | 773 | return FALSE; |
911 | } | ||
912 | 774 | ||
913 | lineCount = 0; | 775 | lineCount = 0; |
914 | charCount = 0; | 776 | charCount = 0; |
915 | 777 | ||
916 | fd = creat(file, 0666); | 778 | fd = creat(file, 0666); |
917 | |||
918 | if (fd < 0) { | 779 | if (fd < 0) { |
919 | perror(file); | 780 | perror(file); |
920 | return FALSE; | 781 | return FALSE; |
@@ -924,19 +785,17 @@ static int writeLines(const char * file, int num1, int num2) | |||
924 | fflush(stdout); | 785 | fflush(stdout); |
925 | 786 | ||
926 | lp = findLine(num1); | 787 | lp = findLine(num1); |
927 | |||
928 | if (lp == NULL) { | 788 | if (lp == NULL) { |
929 | close(fd); | 789 | close(fd); |
930 | return FALSE; | 790 | return FALSE; |
931 | } | 791 | } |
932 | 792 | ||
933 | while (num1++ <= num2) { | 793 | while (num1++ <= num2) { |
934 | if (write(fd, lp->data, lp->len) != lp->len) { | 794 | if (full_write(fd, lp->data, lp->len) != lp->len) { |
935 | perror(file); | 795 | perror(file); |
936 | close(fd); | 796 | close(fd); |
937 | return FALSE; | 797 | return FALSE; |
938 | } | 798 | } |
939 | |||
940 | charCount += lp->len; | 799 | charCount += lp->len; |
941 | lineCount++; | 800 | lineCount++; |
942 | lp = lp->next; | 801 | lp = lp->next; |
@@ -964,13 +823,10 @@ static int printLines(int num1, int num2, int expandFlag) | |||
964 | const char *cp; | 823 | const char *cp; |
965 | int ch, count; | 824 | int ch, count; |
966 | 825 | ||
967 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | 826 | if (bad_nums(num1, num2, "print")) |
968 | bb_error_msg("bad line range for print"); | ||
969 | return FALSE; | 827 | return FALSE; |
970 | } | ||
971 | 828 | ||
972 | lp = findLine(num1); | 829 | lp = findLine(num1); |
973 | |||
974 | if (lp == NULL) | 830 | if (lp == NULL) |
975 | return FALSE; | 831 | return FALSE; |
976 | 832 | ||
@@ -979,7 +835,6 @@ static int printLines(int num1, int num2, int expandFlag) | |||
979 | write(1, lp->data, lp->len); | 835 | write(1, lp->data, lp->len); |
980 | setCurNum(num1++); | 836 | setCurNum(num1++); |
981 | lp = lp->next; | 837 | lp = lp->next; |
982 | |||
983 | continue; | 838 | continue; |
984 | } | 839 | } |
985 | 840 | ||
@@ -995,22 +850,18 @@ static int printLines(int num1, int num2, int expandFlag) | |||
995 | 850 | ||
996 | while (count-- > 0) { | 851 | while (count-- > 0) { |
997 | ch = *cp++; | 852 | ch = *cp++; |
998 | |||
999 | if (ch & 0x80) { | 853 | if (ch & 0x80) { |
1000 | fputs("M-", stdout); | 854 | fputs("M-", stdout); |
1001 | ch &= 0x7f; | 855 | ch &= 0x7f; |
1002 | } | 856 | } |
1003 | |||
1004 | if (ch < ' ') { | 857 | if (ch < ' ') { |
1005 | fputc('^', stdout); | 858 | fputc('^', stdout); |
1006 | ch += '@'; | 859 | ch += '@'; |
1007 | } | 860 | } |
1008 | |||
1009 | if (ch == 0x7f) { | 861 | if (ch == 0x7f) { |
1010 | fputc('^', stdout); | 862 | fputc('^', stdout); |
1011 | ch = '?'; | 863 | ch = '?'; |
1012 | } | 864 | } |
1013 | |||
1014 | fputc(ch, stdout); | 865 | fputc(ch, stdout); |
1015 | } | 866 | } |
1016 | 867 | ||
@@ -1031,7 +882,7 @@ static int printLines(int num1, int num2, int expandFlag) | |||
1031 | * The inserted line is also set to become the current line. | 882 | * The inserted line is also set to become the current line. |
1032 | * Returns TRUE if successful. | 883 | * Returns TRUE if successful. |
1033 | */ | 884 | */ |
1034 | static int insertLine(int num, const char * data, int len) | 885 | static int insertLine(int num, const char *data, int len) |
1035 | { | 886 | { |
1036 | LINE *newLp, *lp; | 887 | LINE *newLp, *lp; |
1037 | 888 | ||
@@ -1041,7 +892,6 @@ static int insertLine(int num, const char * data, int len) | |||
1041 | } | 892 | } |
1042 | 893 | ||
1043 | newLp = malloc(sizeof(LINE) + len - 1); | 894 | newLp = malloc(sizeof(LINE) + len - 1); |
1044 | |||
1045 | if (newLp == NULL) { | 895 | if (newLp == NULL) { |
1046 | bb_error_msg("failed to allocate memory for line"); | 896 | bb_error_msg("failed to allocate memory for line"); |
1047 | return FALSE; | 897 | return FALSE; |
@@ -1054,7 +904,6 @@ static int insertLine(int num, const char * data, int len) | |||
1054 | lp = &lines; | 904 | lp = &lines; |
1055 | else { | 905 | else { |
1056 | lp = findLine(num); | 906 | lp = findLine(num); |
1057 | |||
1058 | if (lp == NULL) { | 907 | if (lp == NULL) { |
1059 | free((char *) newLp); | 908 | free((char *) newLp); |
1060 | return FALSE; | 909 | return FALSE; |
@@ -1075,20 +924,17 @@ static int insertLine(int num, const char * data, int len) | |||
1075 | /* | 924 | /* |
1076 | * Delete lines from the given range. | 925 | * Delete lines from the given range. |
1077 | */ | 926 | */ |
1078 | static int deleteLines(int num1, int num2) | 927 | static void deleteLines(int num1, int num2) |
1079 | { | 928 | { |
1080 | LINE *lp, *nlp, *plp; | 929 | LINE *lp, *nlp, *plp; |
1081 | int count; | 930 | int count; |
1082 | 931 | ||
1083 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | 932 | if (bad_nums(num1, num2, "delete")) |
1084 | bb_error_msg("bad line numbers for delete"); | 933 | return; |
1085 | return FALSE; | ||
1086 | } | ||
1087 | 934 | ||
1088 | lp = findLine(num1); | 935 | lp = findLine(num1); |
1089 | |||
1090 | if (lp == NULL) | 936 | if (lp == NULL) |
1091 | return FALSE; | 937 | return; |
1092 | 938 | ||
1093 | if ((curNum >= num1) && (curNum <= num2)) { | 939 | if ((curNum >= num1) && (curNum <= num2)) { |
1094 | if (num2 < lastNum) | 940 | if (num2 < lastNum) |
@@ -1100,10 +946,8 @@ static int deleteLines(int num1, int num2) | |||
1100 | } | 946 | } |
1101 | 947 | ||
1102 | count = num2 - num1 + 1; | 948 | count = num2 - num1 + 1; |
1103 | |||
1104 | if (curNum > num2) | 949 | if (curNum > num2) |
1105 | curNum -= count; | 950 | curNum -= count; |
1106 | |||
1107 | lastNum -= count; | 951 | lastNum -= count; |
1108 | 952 | ||
1109 | while (count-- > 0) { | 953 | while (count-- > 0) { |
@@ -1111,22 +955,17 @@ static int deleteLines(int num1, int num2) | |||
1111 | plp = lp->prev; | 955 | plp = lp->prev; |
1112 | plp->next = nlp; | 956 | plp->next = nlp; |
1113 | nlp->prev = plp; | 957 | nlp->prev = plp; |
1114 | lp->next = NULL; | ||
1115 | lp->prev = NULL; | ||
1116 | lp->len = 0; | ||
1117 | free(lp); | 958 | free(lp); |
1118 | lp = nlp; | 959 | lp = nlp; |
1119 | } | 960 | } |
1120 | 961 | ||
1121 | dirty = TRUE; | 962 | dirty = TRUE; |
1122 | |||
1123 | return TRUE; | ||
1124 | } | 963 | } |
1125 | 964 | ||
1126 | 965 | ||
1127 | /* | 966 | /* |
1128 | * Search for a line which contains the specified string. | 967 | * Search for a line which contains the specified string. |
1129 | * If the string is NULL, then the previously searched for string | 968 | * If the string is "", then the previously searched for string |
1130 | * is used. The currently searched for string is saved for future use. | 969 | * is used. The currently searched for string is saved for future use. |
1131 | * Returns the line number which matches, or 0 if there was no match | 970 | * Returns the line number which matches, or 0 if there was no match |
1132 | * with an error printed. | 971 | * with an error printed. |
@@ -1136,17 +975,14 @@ static int searchLines(const char *str, int num1, int num2) | |||
1136 | const LINE *lp; | 975 | const LINE *lp; |
1137 | int len; | 976 | int len; |
1138 | 977 | ||
1139 | if ((num1 < 1) || (num2 > lastNum) || (num1 > num2)) { | 978 | if (bad_nums(num1, num2, "search")) |
1140 | bb_error_msg("bad line numbers for search"); | ||
1141 | return 0; | 979 | return 0; |
1142 | } | ||
1143 | 980 | ||
1144 | if (*str == '\0') { | 981 | if (*str == '\0') { |
1145 | if (searchString[0] == '\0') { | 982 | if (searchString[0] == '\0') { |
1146 | bb_error_msg("no previous search string"); | 983 | bb_error_msg("no previous search string"); |
1147 | return 0; | 984 | return 0; |
1148 | } | 985 | } |
1149 | |||
1150 | str = searchString; | 986 | str = searchString; |
1151 | } | 987 | } |
1152 | 988 | ||
@@ -1156,14 +992,12 @@ static int searchLines(const char *str, int num1, int num2) | |||
1156 | len = strlen(str); | 992 | len = strlen(str); |
1157 | 993 | ||
1158 | lp = findLine(num1); | 994 | lp = findLine(num1); |
1159 | |||
1160 | if (lp == NULL) | 995 | if (lp == NULL) |
1161 | return 0; | 996 | return 0; |
1162 | 997 | ||
1163 | while (num1 <= num2) { | 998 | while (num1 <= num2) { |
1164 | if (findString(lp, str, len, 0) >= 0) | 999 | if (findString(lp, str, len, 0) >= 0) |
1165 | return num1; | 1000 | return num1; |
1166 | |||
1167 | num1++; | 1001 | num1++; |
1168 | lp = lp->next; | 1002 | lp = lp->next; |
1169 | } | 1003 | } |
@@ -1196,12 +1030,10 @@ static LINE *findLine(int num) | |||
1196 | 1030 | ||
1197 | lp = curLine; | 1031 | lp = curLine; |
1198 | lnum = curNum; | 1032 | lnum = curNum; |
1199 | |||
1200 | if (num < (curNum / 2)) { | 1033 | if (num < (curNum / 2)) { |
1201 | lp = lines.next; | 1034 | lp = lines.next; |
1202 | lnum = 1; | 1035 | lnum = 1; |
1203 | } | 1036 | } else if (num > ((curNum + lastNum) / 2)) { |
1204 | else if (num > ((curNum + lastNum) / 2)) { | ||
1205 | lp = lines.prev; | 1037 | lp = lines.prev; |
1206 | lnum = lastNum; | 1038 | lnum = lastNum; |
1207 | } | 1039 | } |
@@ -1228,10 +1060,8 @@ static int setCurNum(int num) | |||
1228 | LINE *lp; | 1060 | LINE *lp; |
1229 | 1061 | ||
1230 | lp = findLine(num); | 1062 | lp = findLine(num); |
1231 | |||
1232 | if (lp == NULL) | 1063 | if (lp == NULL) |
1233 | return FALSE; | 1064 | return FALSE; |
1234 | |||
1235 | curNum = num; | 1065 | curNum = num; |
1236 | curLine = lp; | 1066 | curLine = lp; |
1237 | return TRUE; | 1067 | return TRUE; |