aboutsummaryrefslogtreecommitdiff
path: root/sed.c
diff options
context:
space:
mode:
authormarkw <markw@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-07-14 23:24:00 +0000
committermarkw <markw@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-07-14 23:24:00 +0000
commit28611675ac2c9073639562f4e4477f8e81d01845 (patch)
treec770d2ac4df0293c245dc246f93abf500545d865 /sed.c
parent3836d9ff5dbc4daec768cb3f8d8c1142bd198fd1 (diff)
downloadbusybox-w32-28611675ac2c9073639562f4e4477f8e81d01845.tar.gz
busybox-w32-28611675ac2c9073639562f4e4477f8e81d01845.tar.bz2
busybox-w32-28611675ac2c9073639562f4e4477f8e81d01845.zip
Fixed a couple of buglets:
- add_cmd_str: segv's were being generated if there was a '# comment' line (and probably other kinds of lines, too) that was not followed by a semi-colon or whitespace - parse_edit_cmd: was returning a wrong number (too low) for the index; it was not accounting for backslashes eaten, for the fact that we start at the 3rd index in the string, or for the fact that we add an extra newline. - parse_cmd_str: was returning a wrong number (again, too low) for the index in the case of single-letter commands (p,d). There was some over-compensation for this in the 'return' stmt at the end which also needed some help. - load_cmd_file: was not eating trailing newlines off the line read from the command file. This had the deleterious effect of printing an extra newlines after text displayed from edit (i,a,c) commands. git-svn-id: svn://busybox.net/trunk/busybox@862 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'sed.c')
-rw-r--r--sed.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/sed.c b/sed.c
index 40400fe3a..1f1e9069c 100644
--- a/sed.c
+++ b/sed.c
@@ -307,6 +307,7 @@ out:
307static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr) 307static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
308{ 308{
309 int idx = 0; 309 int idx = 0;
310 int slashes_eaten = 0;
310 char *ptr; /* shorthand */ 311 char *ptr; /* shorthand */
311 312
312 /* 313 /*
@@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
346 while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) { 347 while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) {
347 idx++; 348 idx++;
348 if (!ptr[idx]) { 349 if (!ptr[idx]) {
349 ptr[idx] = '\n'; 350 goto out;
350 ptr[idx+1] = 0;
351 return idx;
352 } 351 }
353 } 352 }
354 /* move the newline over the '\' before it (effectively eats the '\') */ 353 /* move the newline over the '\' before it (effectively eats the '\') */
355 memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1])); 354 memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
356 ptr[strlen(ptr)-1] = 0; 355 ptr[strlen(ptr)-1] = 0;
356 slashes_eaten++;
357 /* substitue \r for \n if needed */ 357 /* substitue \r for \n if needed */
358 if (ptr[idx] == '\r') 358 if (ptr[idx] == '\r')
359 ptr[idx] = '\n'; 359 ptr[idx] = '\n';
360 } 360 }
361 361
362out:
363 ptr[idx] = '\n';
364 ptr[idx+1] = 0;
365
366 /* this accounts for discrepancies between the modified string and the
367 * original string passed in to this function */
368 idx += slashes_eaten;
369
370 /* this accounts for the fact that A) we started at index 3, not at index
371 * 0 and B) that we added an extra '\n' at the end (if you think the next
372 * line should read 'idx += 4' remember, arrays are zero-based) */
373
374 idx += 3;
375
362 return idx; 376 return idx;
363} 377}
364 378
@@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
398 fatalError("only a beginning address can be specified for edit commands\n"); 412 fatalError("only a beginning address can be specified for edit commands\n");
399 idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]); 413 idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
400 } 414 }
415 /* if it was a single-letter command (such as 'p' or 'd') we need to
416 * increment the index past that command */
417 else
418 idx++;
401 419
402 /* give back whatever's left over */ 420 /* give back whatever's left over */
403 return (char *)&cmdstr[++idx]; 421 return (char *)&cmdstr[idx];
404} 422}
405 423
406static void add_cmd_str(const char *cmdstr) 424static void add_cmd_str(const char *cmdstr)
@@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr)
412 /* trim leading whitespace and semicolons */ 430 /* trim leading whitespace and semicolons */
413 memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr)); 431 memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
414 /* if we ate the whole thing, that means there was just trailing 432 /* if we ate the whole thing, that means there was just trailing
415 * whitespace or a final semicolon. either way, get out */ 433 * whitespace or a final / no-op semicolon. either way, get out */
416 if (strlen(mystr) == 0) 434 if (strlen(mystr) == 0)
417 return; 435 return;
418 /* if this is a comment, jump past it and keep going */ 436 /* if this is a comment, jump past it and keep going */
@@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr)
427 /* load command string into new array element, get remainder */ 445 /* load command string into new array element, get remainder */
428 mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr); 446 mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
429 447
430 } while (mystr); 448 } while (mystr && strlen(mystr));
431} 449}
432 450
433 451
@@ -447,7 +465,12 @@ static void load_cmd_file(char *filename)
447 (nextline = get_line_from_file(cmdfile)) != NULL) { 465 (nextline = get_line_from_file(cmdfile)) != NULL) {
448 line = realloc(line, strlen(line) + strlen(nextline) + 1); 466 line = realloc(line, strlen(line) + strlen(nextline) + 1);
449 strcat(line, nextline); 467 strcat(line, nextline);
468 free(nextline);
450 } 469 }
470 /* eat trailing newline (if any) --if I don't do this, edit commands
471 * (aic) will print an extra newline */
472 if (line[strlen(line)-1] == '\n')
473 line[strlen(line)-1] = 0;
451 add_cmd_str(line); 474 add_cmd_str(line);
452 free(line); 475 free(line);
453 } 476 }