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') {