Mercurial > hg > toybox
comparison toys/pending/sed.c @ 1561:162c7cc868e5 draft
sed: fix 'q', and { }, and } after s/// with no semicolon.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 17 Nov 2014 21:21:04 -0600 |
parents | 5d140d08cc30 |
children | b5968bffb65c |
comparison
equal
deleted
inserted
replaced
1560:5d140d08cc30 | 1561:162c7cc868e5 |
---|---|
282 int eol = 0, tea = 0; | 282 int eol = 0, tea = 0; |
283 | 283 |
284 // Grab next line for deferred processing (EOF detection: we get a NULL | 284 // Grab next line for deferred processing (EOF detection: we get a NULL |
285 // pline at EOF to flush last line). Note that only end of _last_ input | 285 // pline at EOF to flush last line). Note that only end of _last_ input |
286 // file matches $ (unless we're doing -i). | 286 // file matches $ (unless we're doing -i). |
287 TT.nextline = 0; | |
288 TT.nextlen = 0; | |
287 if (pline) { | 289 if (pline) { |
288 TT.nextline = *pline; | 290 TT.nextline = *pline; |
289 TT.nextlen = plen; | 291 TT.nextlen = plen; |
290 *pline = 0; | 292 *pline = 0; |
291 } | 293 } |
433 goto done; | 435 goto done; |
434 } else if (c=='p' || c=='P') { | 436 } else if (c=='p' || c=='P') { |
435 char *l = (c=='P') ? strchr(line, '\n') : 0; | 437 char *l = (c=='P') ? strchr(line, '\n') : 0; |
436 | 438 |
437 if (emit(line, l ? l-line : len, eol)) break; | 439 if (emit(line, l ? l-line : len, eol)) break; |
438 } else if (c=='q') break; | 440 } else if (c=='q') { |
439 else if (c=='s') { | 441 if (pline) *pline = (void *)1; |
442 free(TT.nextline); | |
443 TT.nextline = 0; | |
444 TT.nextlen = 0; | |
445 | |
446 break; | |
447 } else if (c=='s') { | |
440 char *rline = line, *new = logrus->arg2 + (char *)logrus, *swap, *rswap; | 448 char *rline = line, *new = logrus->arg2 + (char *)logrus, *swap, *rswap; |
441 regmatch_t *match = (void *)toybuf; | 449 regmatch_t *match = (void *)toybuf; |
442 regex_t *reg = get_regex(logrus, logrus->arg1); | 450 regex_t *reg = get_regex(logrus, logrus->arg1); |
443 int mflags = 0, count = 0, zmatch = 1, rlen = len, mlen, off, newlen; | 451 int mflags = 0, count = 0, zmatch = 1, rlen = len, mlen, off, newlen; |
444 | 452 |
564 for (i = 0; i < len; i++) { | 572 for (i = 0; i < len; i++) { |
565 j = stridx(from, line[i]); | 573 j = stridx(from, line[i]); |
566 if (j != -1) line[i] = to[j]; | 574 if (j != -1) line[i] = to[j]; |
567 } | 575 } |
568 } else if (c=='=') xprintf("%ld\n", TT.count); | 576 } else if (c=='=') xprintf("%ld\n", TT.count); |
569 else if (c!=':') error_exit("todo: %c", c); | 577 else if (!strchr(":{}", c)) error_exit("todo: %c", c); |
570 | 578 |
571 logrus = logrus->next; | 579 logrus = logrus->next; |
572 } | 580 } |
573 | 581 |
574 if (line && !(toys.optflags & FLAG_n)) emit(line, len, eol); | 582 if (line && !(toys.optflags & FLAG_n)) emit(line, len, eol); |
592 } | 600 } |
593 } | 601 } |
594 | 602 |
595 // Genericish function, can probably get moved to lib.c | 603 // Genericish function, can probably get moved to lib.c |
596 | 604 |
597 // Iterate over lines in file, calling function. Function can write NULL to | 605 // Iterate over lines in file, calling function. Function can write 0 to |
598 // the line pointer if they want to keep it, otherwise line is freed. | 606 // the line pointer if they want to keep it, or 1 to terminate processing, |
599 // Passed file descriptor is closed at the end of processing. | 607 // otherwise line is freed. Passed file descriptor is closed at the end. |
600 static void do_lines(int fd, char *name, void (*call)(char **pline, long len)) | 608 static void do_lines(int fd, char *name, void (*call)(char **pline, long len)) |
601 { | 609 { |
602 FILE *fp = fd ? xfdopen(fd, "r") : stdin; | 610 FILE *fp = fd ? xfdopen(fd, "r") : stdin; |
603 | 611 |
604 for (;;) { | 612 for (;;) { |
606 ssize_t len; | 614 ssize_t len; |
607 | 615 |
608 len = getline(&line, (void *)&len, fp); | 616 len = getline(&line, (void *)&len, fp); |
609 if (len > 0) { | 617 if (len > 0) { |
610 call(&line, len); | 618 call(&line, len); |
619 if (line == (void *)1) break; | |
611 free(line); | 620 free(line); |
612 } else break; | 621 } else break; |
613 } | 622 } |
614 | 623 |
615 if (fd) fclose(fp); | 624 if (fd) fclose(fp); |
801 | 810 |
802 corwin->arg2 = corwin->arg1 + sizeof(regex_t); | 811 corwin->arg2 = corwin->arg1 + sizeof(regex_t); |
803 reg = extend_string((void *)&corwin, fiona, corwin->arg2, line-fiona)+1; | 812 reg = extend_string((void *)&corwin, fiona, corwin->arg2, line-fiona)+1; |
804 | 813 |
805 // get flags | 814 // get flags |
806 for (line++; *line && *line != ';' && *line != '#'; line++) { | 815 for (line++; *line; line++) { |
807 long l; | 816 long l; |
808 | 817 |
809 if (isspace(*line)) continue; | 818 if (isspace(*line)) continue; |
810 | 819 |
811 if (0 <= (l = stridx("igp", *line))) corwin->sflags |= 1<<l; | 820 if (0 <= (l = stridx("igp", *line))) corwin->sflags |= 1<<l; |
812 else if (!corwin->sflags >> 3 && 0<(l = strtol(line, &line, 10))) { | 821 else if (!corwin->sflags >> 3 && 0<(l = strtol(line, &line, 10))) { |
813 corwin->sflags |= l << 3; | 822 corwin->sflags |= l << 3; |
814 line--; | 823 line--; |
815 } else if (*line == 'w') break; | 824 } else break; |
816 else goto brand; | 825 } |
817 } | 826 |
818 | 827 // We deferred actually parsing the regex until we had the s///i flag |
819 // We deferred actually parsing the rexex until we had the s///i flag | |
820 // allocating the space was done by extend_string() above | 828 // allocating the space was done by extend_string() above |
821 if (!*merlin) corwin->arg1 = 0; | 829 if (!*merlin) corwin->arg1 = 0; |
822 else xregcomp((void *)(corwin->arg1 + (char *)corwin), merlin, | 830 else xregcomp((void *)(corwin->arg1 + (char *)corwin), merlin, |
823 ((toys.optflags & FLAG_r)*REG_EXTENDED)|((corwin->sflags&1)*REG_ICASE)); | 831 ((toys.optflags & FLAG_r)*REG_EXTENDED)|((corwin->sflags&1)*REG_ICASE)); |
824 if (*line == 'w') { | 832 if (*line == 'w') { |