Mercurial > hg > toybox
annotate toys/pending/grep.c @ 982:0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
Kernel build never uses -w sans -E anyhow.
author | M. Farkas-Dyck <strake888@gmail.com> |
---|---|
date | Thu, 01 Aug 2013 15:46:45 -0500 |
parents | e33f0312de6e |
children | c38c25282b88 |
rev | line source |
---|---|
948 | 1 /* grep.c - print lines what match given regular expression |
2 * | |
3 * Copyright 2013 CE Strake <strake888 at gmail.com> | |
4 * | |
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ | |
6 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html | |
7 | |
971 | 8 USE_GREP(NEWTOY(grep, "EFHabhinosvwclqe*f*m#", TOYFLAG_BIN)) |
948 | 9 |
10 config GREP | |
11 bool "grep" | |
12 default n | |
13 help | |
971 | 14 usage: grep [-clq] [-EFHbhinosvw] (-e RE | -f REfile | RE) [file...] |
948 | 15 |
16 modes: | |
17 default: print lines from each file what match regular expression RE. | |
18 -c: print the number of matching lines in each file. | |
19 -l: print all matching file names. | |
20 -q: print nil; quit with code 0 when match found. | |
21 | |
22 flags: | |
23 -E: extended RE syntax | |
24 -F: fixed RE syntax, i.e. all characters literal | |
959 | 25 -H: print file name |
971 | 26 -b: print byte offset of match |
948 | 27 -h: not print file name |
28 -i: case insensitive | |
29 -n: print line numbers | |
30 -o: print only matching part | |
959 | 31 -s: keep silent on error |
948 | 32 -v: invert match |
970 | 33 -w: match full word only |
948 | 34 */ |
35 | |
36 #define FOR_grep | |
37 #include "toys.h" | |
38 #include <regex.h> | |
39 | |
40 static regex_t re; /* fails in GLOBALS */ | |
41 | |
42 GLOBALS( | |
43 long mArgu; | |
44 struct arg_list *fArgu, *eArgu; | |
959 | 45 char mode, *re_xs; |
948 | 46 ) |
47 | |
48 static void do_grep (int fd, char *name) { | |
982
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
49 int n = 0, nMatch = 0, which = toys.optflags & FLAG_w ? 2 : 0; |
948 | 50 |
51 for (;;) { | |
52 char *x, *y; | |
970 | 53 regmatch_t matches[3]; |
948 | 54 int atBOL = 1; |
55 | |
56 x = get_rawline (fd, 0, '\n'); | |
57 if (!x) break; | |
58 y = x; | |
59 n++; /* start at 1 */ | |
60 | |
970 | 61 while (regexec (&re, y, 3, matches, atBOL ? 0 : REG_NOTBOL) == 0) { |
948 | 62 if (atBOL) nMatch++; |
959 | 63 toys.exitval = 0; |
64 atBOL = 0; | |
948 | 65 switch (TT.mode) { |
66 case 'q': | |
959 | 67 xexit (); |
948 | 68 case 'l': |
69 if (!(toys.optflags & FLAG_h)) printf ("%s\n", name); | |
70 free (x); | |
71 return; | |
72 case 'c': | |
73 break; | |
74 default: | |
75 if (!(toys.optflags & FLAG_h)) printf ("%s:", name); | |
76 if ( (toys.optflags & FLAG_n)) printf ("%d:", n); | |
971 | 77 if ( (toys.optflags & FLAG_b)) printf ("%ld:", lseek (0, 0, SEEK_CUR) - strlen (y) + |
982
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
78 (toys.optflags & FLAG_o ? matches[which].rm_so : 0)); |
948 | 79 if (!(toys.optflags & FLAG_o)) fputs (x, stdout); |
80 else { | |
982
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
81 y += matches[which].rm_so; |
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
82 printf ("%.*s\n", matches[which].rm_eo - matches[which].rm_so, y++); |
948 | 83 } |
84 } | |
85 if (!(toys.optflags & FLAG_o)) break; | |
86 } | |
87 | |
88 free (x); | |
89 | |
90 if ((toys.optflags & FLAG_m) && nMatch >= TT.mArgu) break; | |
91 } | |
92 | |
93 if (TT.mode == 'c') printf ("%s:%d\n", name, nMatch); | |
94 } | |
95 | |
96 char *regfix (char *re_xs) { | |
97 char *re_ys; | |
98 int ii, jj = 0; | |
99 re_ys = xmalloc (2*strlen (re_xs) + 1); | |
100 for (ii = 0; re_xs[ii]; ii++) { | |
101 if (strchr ("^.[]$()|*+?{}\\", re_xs[ii])) re_ys[jj++] = '\\'; | |
102 re_ys[jj++] = re_xs[ii]; | |
103 } | |
104 re_ys[jj] = 0; | |
105 return re_ys; | |
106 } | |
107 | |
959 | 108 void addRE (char *x) { |
109 if (toys.optflags & FLAG_F) x = regfix (x); | |
972 | 110 if (TT.re_xs) TT.re_xs = xastrcat (TT.re_xs, "|"); |
111 TT.re_xs = xastrcat (TT.re_xs, x); | |
959 | 112 if (toys.optflags & FLAG_F) free (x); |
113 } | |
948 | 114 |
959 | 115 void buildRE (void) { |
116 for (; TT.eArgu; TT.eArgu = TT.eArgu -> next) addRE (TT.eArgu -> arg); | |
948 | 117 for (; TT.fArgu; TT.fArgu = TT.fArgu -> next) { |
118 FILE *f; | |
119 char *x, *y; | |
120 size_t l; | |
121 | |
122 f = xfopen (TT.fArgu -> arg, "r"); | |
123 x = 0; | |
124 for (;;) { | |
125 if (getline (&x, &l, f) < 0) { | |
126 if (feof (f)) break; | |
959 | 127 toys.exitval = 2; |
128 perror_exit ("failed to read"); | |
948 | 129 } |
130 y = x + strlen (x) - 1; | |
131 if (y[0] == '\n') y[0] = 0; | |
132 | |
959 | 133 addRE (x); |
948 | 134 } |
135 free (x); | |
136 fclose (f); | |
137 } | |
138 | |
959 | 139 if (!TT.re_xs) { |
140 if (toys.optc < 1) { | |
141 toys.exitval = 2; | |
142 error_exit ("no RE"); | |
143 } | |
144 TT.re_xs = toys.optflags & FLAG_F ? regfix (toys.optargs[0]) : toys.optargs[0]; | |
948 | 145 toys.optc--; toys.optargs++; |
146 } | |
147 | |
982
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
148 TT.re_xs = xmsprintf (toys.optflags & FLAG_w ? "(^|[^_[:alnum:]])(%s)($|[^_[:alnum:]])" : "%s", TT.re_xs); |
970 | 149 |
959 | 150 if (regcomp (&re, TT.re_xs, |
948 | 151 (toys.optflags & (FLAG_E | FLAG_F) ? REG_EXTENDED : 0) | |
152 (toys.optflags & FLAG_i ? REG_ICASE : 0)) != 0) { | |
959 | 153 toys.exitval = 2; |
154 error_exit ("bad RE"); | |
948 | 155 } |
156 } | |
157 | |
158 void grep_main (void) { | |
982
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
159 if (toys.optflags & FLAG_w && !(toys.optflags & FLAG_E || toys.optflags & FLAG_F)) error_exit ("must not use -w sans -E"); |
0666d42df954
Found the fault. My method of -w fails sans -E, so I just disallow it.
M. Farkas-Dyck <strake888@gmail.com>
parents:
972
diff
changeset
|
160 |
948 | 161 buildRE (); |
162 | |
163 if (toys.optflags & FLAG_c) TT.mode = 'c'; | |
164 if (toys.optflags & FLAG_l) TT.mode = 'l'; | |
165 if (toys.optflags & FLAG_q) TT.mode = 'q'; | |
166 | |
959 | 167 if (!(toys.optflags & FLAG_H) && (toys.optc < 2)) toys.optflags |= FLAG_h; |
948 | 168 |
959 | 169 toys.exitval = 1; |
170 loopfiles_rw (toys.optargs, O_RDONLY, 0, toys.optflags & FLAG_s, do_grep); | |
171 xexit (); | |
948 | 172 } |