Mercurial > hg > toybox
annotate toys/pending/grep.c @ 1001:8b49ff103af9
grep: -om counts matching lines, not matching parts of lines.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 12 Aug 2013 03:16:29 -0500 |
parents | 99dad9fb5613 |
children | 059e1f30b80b |
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 * | |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html |
948 | 6 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
7 USE_GREP(NEWTOY(grep, "EFHabhinosvwclqe*f*m#x[!wx][!EFw]", TOYFLAG_BIN)) |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
8 USE_GREP(OLDTOY(egrep, grep, OPTSTR_grep, TOYFLAG_BIN)) |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
9 USE_GREP(OLDTOY(fgrep, grep, OPTSTR_grep, TOYFLAG_BIN)) |
948 | 10 |
11 config GREP | |
12 bool "grep" | |
13 default n | |
14 help | |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
15 usage: grep [-EFivwcloqsHbhn] [-m MAX] [-e REGEX]... [-f REGFILE] [FILE]... |
948 | 16 |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
17 Show lines matching regular expressions. If no -e, first argument is |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
18 regular expression to match. With no files (or "-" filename) read stdin. |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
19 Returns 0 if matched, 1 if no match found. |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
20 |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
21 -e Regex to match. (May be repeated.) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
22 -f File containing regular expressions to match. |
948 | 23 |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
24 match type: |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
25 -E extended regex syntax -F fixed (match literal string) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
26 -i case insensitive -v invert match |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
27 -w whole word (implies -E) -m stop after this many lines matched |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
28 -x whole line |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
29 |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
30 display modes: (default: matched line) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
31 -c count of matching lines -l show matching filenames |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
32 -o only matching part -q quiet (errors only) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
33 -s silent (no error msg) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
34 |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
35 prefix modes (default: filename if checking more than 1 file) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
36 -H force filename -b byte offset of match |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
37 -h hide filename -n line number of match |
948 | 38 */ |
39 | |
40 #define FOR_grep | |
41 #include "toys.h" | |
42 #include <regex.h> | |
43 | |
44 GLOBALS( | |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
45 long m; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
46 struct arg_list *f; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
47 struct arg_list *e; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
48 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
49 char *regstr; |
948 | 50 ) |
51 | |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
52 static void do_grep(int fd, char *name) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
53 { |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
54 FILE *file = fdopen(fd, "r"); |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
55 long offset = 0; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
56 int lcount = 0, mcount = 0, which = toys.optflags & FLAG_w ? 2 : 0; |
948 | 57 |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
58 if (!fd) name = "(standard input)"; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
59 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
60 if (!file) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
61 perror_msg("%s", name); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
62 return; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
63 } |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
64 |
948 | 65 for (;;) { |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
66 char *line = 0, *start; |
970 | 67 regmatch_t matches[3]; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
68 size_t unused; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
69 long len; |
1001
8b49ff103af9
grep: -om counts matching lines, not matching parts of lines.
Rob Landley <rob@landley.net>
parents:
1000
diff
changeset
|
70 int mmatch = 0; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
71 |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
72 lcount++; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
73 if (0 > (len = getline(&line, &unused, file))) break; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
74 if (line[len-1] == '\n') line[len-1] = 0; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
75 |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
76 start = line; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
77 |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
78 for (;;) |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
79 { |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
80 int rc = 0, skip = 0; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
81 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
82 if (toys.optflags & FLAG_F) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
83 struct arg_list *seek; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
84 char *s = 0; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
85 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
86 for (seek = TT.e; seek; seek = seek->next) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
87 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
88 if (toys.optflags & FLAG_i) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
89 long ll = strlen(seek->arg);; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
90 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
91 // Alas, posix hasn't got strcasestr() |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
92 for (s = line; *s; s++) if (!strncasecmp(s, seek->arg, ll)) break; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
93 if (!*s) s = 0; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
94 } else s = strstr(line, seek->arg); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
95 if (s) break; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
96 } |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
97 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
98 if (s) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
99 matches[which].rm_so = (s-line); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
100 skip = matches[which].rm_eo = (s-line)+strlen(seek->arg); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
101 } else rc = 1; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
102 } else { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
103 rc = regexec((regex_t *)toybuf, start, 3, matches, |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
104 start==line ? 0 : REG_NOTBOL); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
105 skip = matches[which].rm_eo; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
106 } |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
107 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
108 if (toys.optflags & FLAG_x) |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
109 if (matches[which].rm_so || line[matches[which].rm_eo]) rc = 1; |
948 | 110 |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
111 if (toys.optflags & FLAG_v) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
112 if (toys.optflags & FLAG_o) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
113 if (rc) skip = matches[which].rm_eo = strlen(start); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
114 else if (!matches[which].rm_so) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
115 start += skip; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
116 continue; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
117 } else matches[which].rm_eo = matches[which].rm_so; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
118 } else { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
119 if (!rc) break; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
120 matches[which].rm_eo = strlen(start); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
121 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
122 matches[which].rm_so = 0; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
123 } else if (rc) break; |
948 | 124 |
1001
8b49ff103af9
grep: -om counts matching lines, not matching parts of lines.
Rob Landley <rob@landley.net>
parents:
1000
diff
changeset
|
125 mmatch++; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
126 if (toys.optflags & FLAG_q) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
127 toys.exitval = 0; |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
128 xexit(); |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
129 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
130 if (toys.optflags & FLAG_l) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
131 printf("%s\n", name); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
132 free(line); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
133 fclose(file); |
948 | 134 return; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
135 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
136 if (!(toys.optflags & FLAG_c)) { |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
137 if (!(toys.optflags & FLAG_h)) printf("%s:", name); |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
138 if (toys.optflags & FLAG_n) printf("%d:", lcount); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
139 if (toys.optflags & FLAG_b) |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
140 printf("%ld:", offset + (start-line) + |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
141 ((toys.optflags & FLAG_o) ? matches[which].rm_so : 0)); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
142 if (!(toys.optflags & FLAG_o)) xputs(line); |
948 | 143 else { |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
144 xprintf("%.*s\n", matches[which].rm_eo - matches[which].rm_so, |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
145 start + matches[which].rm_so); |
948 | 146 } |
147 } | |
148 | |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
149 start += skip; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
150 if (!(toys.optflags & FLAG_o) || !*start) break; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
151 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
152 offset += len; |
948 | 153 |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
154 free(line); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
155 |
1001
8b49ff103af9
grep: -om counts matching lines, not matching parts of lines.
Rob Landley <rob@landley.net>
parents:
1000
diff
changeset
|
156 if (mmatch) mcount++; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
157 if ((toys.optflags & FLAG_m) && mcount >= TT.m) break; |
948 | 158 } |
159 | |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
160 if (toys.optflags & FLAG_c) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
161 if (!(toys.optflags & FLAG_h)) printf("%s:", name); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
162 xprintf("%d\n", mcount); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
163 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
164 |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
165 // loopfiles will also close the fd, but this frees an (opaque) struct. |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
166 fclose(file); |
948 | 167 } |
168 | |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
169 static void parse_regex(void) |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
170 { |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
171 struct arg_list *al, *new, *list = NULL; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
172 long len = 0; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
173 char *s, *ss; |
948 | 174 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
175 // Add all -f lines to -e list. (Yes, this is leaking allocation context for |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
176 // exit to free. Not supporting nofork for this command any time soon.) |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
177 al = TT.f ? TT.f : TT.e; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
178 while (al) { |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
179 if (TT.f) s = ss = xreadfile(al->arg); |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
180 else s = ss = al->arg; |
948 | 181 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
182 while (ss && *s) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
183 ss = strchr(s, '\n'); |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
184 if (ss) *(ss++) = 0; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
185 new = xmalloc(sizeof(struct arg_list)); |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
186 new->next = list; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
187 new->arg = s; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
188 list = new; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
189 s = ss; |
948 | 190 } |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
191 al = al->next; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
192 if (!al && TT.f) { |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
193 TT.f = 0; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
194 al = TT.e; |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
195 } |
948 | 196 } |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
197 TT.e = list; |
948 | 198 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
199 if (!(toys.optflags & FLAG_F)) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
200 int w = toys.optflags & FLAG_w; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
201 |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
202 // Convert strings to one big regex |
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
203 if (w) len = 36; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
204 for (al = TT.e; al; al = al->next) len += strlen(al->arg)+1; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
205 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
206 TT.regstr = s = xmalloc(len); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
207 if (w) s = stpcpy(s, "(^|[^_[:alnum:]])("); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
208 for (al = TT.e; al; al = al->next) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
209 s = stpcpy(s, al->arg); |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
210 if (!(toys.optflags & FLAG_E)) *(s++) = '\\'; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
211 *(s++) = '|'; |
959 | 212 } |
1000
99dad9fb5613
More grep work: name "(standard input)" correctly, make multiple -e work, regex with embedded newline, multiple regex without -E.
Rob Landley <rob@landley.net>
parents:
999
diff
changeset
|
213 *(s-=(1+!(toys.optflags & FLAG_E))) = 0; |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
214 if (w) strcpy(s, ")($|[^_[:alnum:]])"); |
948 | 215 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
216 w = regcomp((regex_t *)toybuf, TT.regstr, |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
217 ((toys.optflags & FLAG_E) ? REG_EXTENDED : 0) | |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
218 ((toys.optflags & FLAG_i) ? REG_ICASE : 0)); |
970 | 219 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
220 if (w) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
221 regerror(w, (regex_t *)toybuf, toybuf+sizeof(regex_t), |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
222 sizeof(toybuf)-sizeof(regex_t)); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
223 error_exit("bad REGEX: %s", toybuf); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
224 } |
948 | 225 } |
226 } | |
227 | |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
228 void grep_main(void) |
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
229 { |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
230 // Handle egrep and fgrep |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
231 if (*toys.which->name == 'e' || (toys.optflags & FLAG_w)) |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
232 toys.optflags |= FLAG_E; |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
233 if (*toys.which->name == 'f') toys.optflags |= FLAG_F; |
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
|
234 |
999
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
235 if (!TT.e && !TT.f) { |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
236 if (!*toys.optargs) error_exit("no REGEX"); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
237 TT.e = xzalloc(sizeof(struct arg_list)); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
238 TT.e->arg = *(toys.optargs++); |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
239 toys.optc--; |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
240 } |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
241 |
0af2375a8ef8
More grep cleanup, and make OPTSTR_command macros for use with OLDTOY()
Rob Landley <rob@landley.net>
parents:
987
diff
changeset
|
242 parse_regex(); |
948 | 243 |
959 | 244 if (!(toys.optflags & FLAG_H) && (toys.optc < 2)) toys.optflags |= FLAG_h; |
948 | 245 |
959 | 246 toys.exitval = 1; |
987
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
247 if (toys.optflags & FLAG_s) { |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
248 close(2); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
249 xopen("/dev/null", O_RDWR); |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
250 } |
b570b2bfbf7d
Cleanup grep, make it pass the current test suite.
Rob Landley <rob@landley.net>
parents:
983
diff
changeset
|
251 loopfiles_rw(toys.optargs, O_RDONLY, 0, 1, do_grep); |
983
c38c25282b88
Cleanup grep: help text, whitespace, add parentheses.
Rob Landley <rob@landley.net>
parents:
982
diff
changeset
|
252 xexit(); |
948 | 253 } |