diff options
-rw-r--r-- | toys/pending/grep.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/toys/pending/grep.c b/toys/pending/grep.c index 52f30678..5b614829 100644 --- a/toys/pending/grep.c +++ b/toys/pending/grep.c @@ -5,13 +5,13 @@ * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html -USE_GREP(NEWTOY(grep, "EFhinovclqe*f*m#", TOYFLAG_BIN)) +USE_GREP(NEWTOY(grep, "EFHahinosvclqe*f*m#", TOYFLAG_BIN)) config GREP bool "grep" default n help - usage: grep [-clq] [-EFhinov] (-e RE | -f REfile | RE) [file...] + usage: grep [-clq] [-EFHhinosv] (-e RE | -f REfile | RE) [file...] modes: default: print lines from each file what match regular expression RE. @@ -22,27 +22,25 @@ config GREP flags: -E: extended RE syntax -F: fixed RE syntax, i.e. all characters literal + -H: print file name -h: not print file name -i: case insensitive -n: print line numbers -o: print only matching part + -s: keep silent on error -v: invert match */ #define FOR_grep #include "toys.h" #include <regex.h> -#include <err.h> - -/* could be in GLOBALS but so need initialization code */ -static int c = 1; static regex_t re; /* fails in GLOBALS */ GLOBALS( long mArgu; struct arg_list *fArgu, *eArgu; - char mode; + char mode, *re_xs; ) static void do_grep (int fd, char *name) { @@ -60,10 +58,11 @@ static void do_grep (int fd, char *name) { while (regexec (&re, y, 1, &match, atBOL ? 0 : REG_NOTBOL) == 0) { if (atBOL) nMatch++; - c = 0; atBOL = 0; + toys.exitval = 0; + atBOL = 0; switch (TT.mode) { case 'q': - exit (0); + xexit (); case 'l': if (!(toys.optflags & FLAG_h)) printf ("%s\n", name); free (x); @@ -102,15 +101,15 @@ char *regfix (char *re_xs) { return re_ys; } -void buildRE (void) { - char *re_xs; +void addRE (char *x) { + if (toys.optflags & FLAG_F) x = regfix (x); + if (TT.re_xs) TT.re_xs = astrcat (TT.re_xs, "|"); + TT.re_xs = astrcat (TT.re_xs, x); + if (toys.optflags & FLAG_F) free (x); +} - re_xs = 0; - for (; TT.eArgu; TT.eArgu = TT.eArgu -> next) { - if (toys.optflags & FLAG_F) TT.eArgu -> arg = regfix (TT.eArgu -> arg); - if (re_xs) re_xs = xastrcat (re_xs, "|"); - re_xs = xastrcat (re_xs, TT.eArgu -> arg); - } +void buildRE (void) { + for (; TT.eArgu; TT.eArgu = TT.eArgu -> next) addRE (TT.eArgu -> arg); for (; TT.fArgu; TT.fArgu = TT.fArgu -> next) { FILE *f; char *x, *y; @@ -121,30 +120,32 @@ void buildRE (void) { for (;;) { if (getline (&x, &l, f) < 0) { if (feof (f)) break; - err (2, "failed to read"); + toys.exitval = 2; + perror_exit ("failed to read"); } y = x + strlen (x) - 1; if (y[0] == '\n') y[0] = 0; - y = toys.optflags & FLAG_F ? regfix (x) : x; - if (re_xs) re_xs = xastrcat (re_xs, "|"); - re_xs = xastrcat (re_xs, y); - free (y); + addRE (x); } free (x); fclose (f); } - if (!re_xs) { - if (toys.optc < 1) errx (2, "no RE"); - re_xs = toys.optflags & FLAG_F ? regfix (toys.optargs[0]) : toys.optargs[0]; + if (!TT.re_xs) { + if (toys.optc < 1) { + toys.exitval = 2; + error_exit ("no RE"); + } + TT.re_xs = toys.optflags & FLAG_F ? regfix (toys.optargs[0]) : toys.optargs[0]; toys.optc--; toys.optargs++; } - if (regcomp (&re, re_xs, + if (regcomp (&re, TT.re_xs, (toys.optflags & (FLAG_E | FLAG_F) ? REG_EXTENDED : 0) | (toys.optflags & FLAG_i ? REG_ICASE : 0)) != 0) { - errx (2, "bad RE"); + toys.exitval = 2; + error_exit ("bad RE"); } } @@ -155,8 +156,9 @@ void grep_main (void) { if (toys.optflags & FLAG_l) TT.mode = 'l'; if (toys.optflags & FLAG_q) TT.mode = 'q'; - if (toys.optc > 0) loopfiles (toys.optargs, do_grep); - else do_grep (0, "-"); + if (!(toys.optflags & FLAG_H) && (toys.optc < 2)) toys.optflags |= FLAG_h; - exit (c); + toys.exitval = 1; + loopfiles_rw (toys.optargs, O_RDONLY, 0, toys.optflags & FLAG_s, do_grep); + xexit (); } |