aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/grep.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/pending/grep.c')
-rw-r--r--toys/pending/grep.c62
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 ();
}