aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2005-09-23 15:38:49 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2005-09-23 15:38:49 +0000
commitaaf0e233302a3c139c395eacb1acd236ee2548fb (patch)
tree50411e77209eb7eedcdfa5bca23d3dc75ac6155c
parentbf4497406f4eb67e57e3bfaa3ef98c8811104847 (diff)
downloadbusybox-w32-aaf0e233302a3c139c395eacb1acd236ee2548fb.tar.gz
busybox-w32-aaf0e233302a3c139c395eacb1acd236ee2548fb.tar.bz2
busybox-w32-aaf0e233302a3c139c395eacb1acd236ee2548fb.zip
- replace variables by defines to save space
- rename string denoting stdin from "-" to "(standard input)" to match GNU grep.
-rw-r--r--findutils/grep.c128
1 files changed, 57 insertions, 71 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index e41f1a3be..323e4afc6 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -1,24 +1,15 @@
1/* vi: set sw=4 ts=4: */
1/* 2/*
2 * Mini grep implementation for busybox using libc regex. 3 * Mini grep implementation for busybox using libc regex.
3 * 4 *
4 * Copyright (C) 1999,2000,2001 by Lineo, inc. and Mark Whitley 5 * Copyright (C) 1999,2000,2001 by Lineo, inc. and Mark Whitley
5 * Copyright (C) 1999,2000,2001 by Mark Whitley <markw@codepoet.org> 6 * Copyright (C) 1999,2000,2001 by Mark Whitley <markw@codepoet.org>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * Licensed under the GPL v2, see the file LICENSE in this tarball.
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */ 9 */
10/* BB_AUDIT SUSv3 defects - unsupported option -x. */
11/* BB_AUDIT GNU defects - always acts as -a. */
12/* http://www.opengroup.org/onlinepubs/007904975/utilities/grep.html */
22/* 13/*
23 * Apr 2004 by Vladimir Oleynik <dzo@simtreas.ru> - 14 * Apr 2004 by Vladimir Oleynik <dzo@simtreas.ru> -
24 * correction "-e pattern1 -e pattern2" logic and more optimizations. 15 * correction "-e pattern1 -e pattern2" logic and more optimizations.
@@ -34,30 +25,31 @@
34 25
35 26
36/* options */ 27/* options */
28static unsigned long opt;
37#define GREP_OPTS "lnqvscFiHhe:f:L" 29#define GREP_OPTS "lnqvscFiHhe:f:L"
38#define GREP_OPT_l (1<<0) 30#define GREP_OPT_l (1<<0)
39static char print_files_with_matches; 31#define PRINT_FILES_WITH_MATCHES (opt & GREP_OPT_l)
40#define GREP_OPT_n (1<<1) 32#define GREP_OPT_n (1<<1)
41static char print_line_num; 33#define PRINT_LINE_NUM (opt & GREP_OPT_n)
42#define GREP_OPT_q (1<<2) 34#define GREP_OPT_q (1<<2)
43static char be_quiet; 35#define BE_QUIET (opt & GREP_OPT_q)
44#define GREP_OPT_v (1<<3) 36#define GREP_OPT_v (1<<3)
45typedef char invert_search_t; 37typedef char invert_search_t;
46static invert_search_t invert_search; 38static invert_search_t invert_search;
47#define GREP_OPT_s (1<<4) 39#define GREP_OPT_s (1<<4)
48static char suppress_err_msgs; 40#define SUPPRESS_ERR_MSGS (opt & GREP_OPT_s)
49#define GREP_OPT_c (1<<5) 41#define GREP_OPT_c (1<<5)
50static char print_match_counts; 42#define PRINT_MATCH_COUNTS (opt & GREP_OPT_c)
51#define GREP_OPT_F (1<<6) 43#define GREP_OPT_F (1<<6)
52static char fgrep_flag; 44#define FGREP_FLAG (opt & GREP_OPT_F)
53#define GREP_OPT_i (1<<7) 45#define GREP_OPT_i (1<<7)
54#define GREP_OPT_H (1<<8) 46#define GREP_OPT_H (1<<8)
55#define GREP_OPT_h (1<<9) 47#define GREP_OPT_h (1<<9)
56#define GREP_OPT_e (1<<10) 48#define GREP_OPT_e (1<<10)
57#define GREP_OPT_f (1<<11) 49#define GREP_OPT_f (1<<11)
58#define GREP_OPT_L (1<<12) 50#define GREP_OPT_L (1<<12)
59static char print_files_without_matches; 51#define PRINT_FILES_WITHOUT_MATCHES ((opt & GREP_OPT_L) != 0)
60#ifdef CONFIG_FEATURE_GREP_CONTEXT 52#if ENABLE_FEATURE_GREP_CONTEXT
61#define GREP_OPT_CONTEXT "A:B:C" 53#define GREP_OPT_CONTEXT "A:B:C"
62#define GREP_OPT_A (1<<13) 54#define GREP_OPT_A (1<<13)
63#define GREP_OPT_B (1<<14) 55#define GREP_OPT_B (1<<14)
@@ -65,9 +57,12 @@ static char print_files_without_matches;
65#define GREP_OPT_E (1<<16) 57#define GREP_OPT_E (1<<16)
66#else 58#else
67#define GREP_OPT_CONTEXT "" 59#define GREP_OPT_CONTEXT ""
60#define GREP_OPT_A (0)
61#define GREP_OPT_B (0)
62#define GREP_OPT_C (0)
68#define GREP_OPT_E (1<<13) 63#define GREP_OPT_E (1<<13)
69#endif 64#endif
70#ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS 65#if ENABLE_FEATURE_GREP_EGREP_ALIAS
71# define OPT_EGREP "E" 66# define OPT_EGREP "E"
72#else 67#else
73# define OPT_EGREP "" 68# define OPT_EGREP ""
@@ -76,12 +71,12 @@ static char print_files_without_matches;
76static int reflags; 71static int reflags;
77static int print_filename; 72static int print_filename;
78 73
79#ifdef CONFIG_FEATURE_GREP_CONTEXT 74#if ENABLE_FEATURE_GREP_CONTEXT
80static int lines_before; 75static int lines_before;
81static int lines_after; 76static int lines_after;
82static char **before_buf; 77static char **before_buf;
83static int last_line_printed; 78static int last_line_printed;
84#endif /* CONFIG_FEATURE_GREP_CONTEXT */ 79#endif /* ENABLE_FEATURE_GREP_CONTEXT */
85 80
86/* globals used internally */ 81/* globals used internally */
87static llist_t *pattern_head; /* growable list of patterns to match */ 82static llist_t *pattern_head; /* growable list of patterns to match */
@@ -90,7 +85,7 @@ static char *cur_file; /* the current file we are reading */
90 85
91static void print_line(const char *line, int linenum, char decoration) 86static void print_line(const char *line, int linenum, char decoration)
92{ 87{
93#ifdef CONFIG_FEATURE_GREP_CONTEXT 88#if ENABLE_FEATURE_GREP_CONTEXT
94 /* possibly print the little '--' separator */ 89 /* possibly print the little '--' separator */
95 if ((lines_before || lines_after) && last_line_printed && 90 if ((lines_before || lines_after) && last_line_printed &&
96 last_line_printed < linenum - 1) { 91 last_line_printed < linenum - 1) {
@@ -100,7 +95,7 @@ static void print_line(const char *line, int linenum, char decoration)
100#endif 95#endif
101 if (print_filename > 0) 96 if (print_filename > 0)
102 printf("%s%c", cur_file, decoration); 97 printf("%s%c", cur_file, decoration);
103 if (print_line_num) 98 if (PRINT_LINE_NUM)
104 printf("%i%c", linenum, decoration); 99 printf("%i%c", linenum, decoration);
105 puts(line); 100 puts(line);
106} 101}
@@ -112,11 +107,11 @@ static int grep_file(FILE *file)
112 invert_search_t ret; 107 invert_search_t ret;
113 int linenum = 0; 108 int linenum = 0;
114 int nmatches = 0; 109 int nmatches = 0;
115#ifdef CONFIG_FEATURE_GREP_CONTEXT 110#if ENABLE_FEATURE_GREP_CONTEXT
116 int print_n_lines_after = 0; 111 int print_n_lines_after = 0;
117 int curpos = 0; /* track where we are in the circular 'before' buffer */ 112 int curpos = 0; /* track where we are in the circular 'before' buffer */
118 int idx = 0; /* used for iteration through the circular buffer */ 113 int idx = 0; /* used for iteration through the circular buffer */
119#endif /* CONFIG_FEATURE_GREP_CONTEXT */ 114#endif /* ENABLE_FEATURE_GREP_CONTEXT */
120 115
121 while ((line = bb_get_chomped_line_from_file(file)) != NULL) { 116 while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
122 llist_t *pattern_ptr = pattern_head; 117 llist_t *pattern_ptr = pattern_head;
@@ -124,7 +119,7 @@ static int grep_file(FILE *file)
124 linenum++; 119 linenum++;
125 ret = 0; 120 ret = 0;
126 while (pattern_ptr) { 121 while (pattern_ptr) {
127 if (fgrep_flag) { 122 if (FGREP_FLAG) {
128 ret = strstr(line, pattern_ptr->data) != NULL; 123 ret = strstr(line, pattern_ptr->data) != NULL;
129 } else { 124 } else {
130 /* 125 /*
@@ -143,23 +138,23 @@ static int grep_file(FILE *file)
143 138
144 if ((ret ^ invert_search)) { 139 if ((ret ^ invert_search)) {
145 140
146 if (print_files_with_matches || be_quiet) 141 if (PRINT_FILES_WITH_MATCHES || BE_QUIET)
147 free(line); 142 free(line);
148 143
149 /* if we found a match but were told to be quiet, stop here */ 144 /* if we found a match but were told to be quiet, stop here */
150 if (be_quiet || print_files_without_matches) 145 if (BE_QUIET || PRINT_FILES_WITHOUT_MATCHES)
151 return -1; 146 return -1;
152 147
153 /* keep track of matches */ 148 /* keep track of matches */
154 nmatches++; 149 nmatches++;
155 150
156 /* if we're just printing filenames, we stop after the first match */ 151 /* if we're just printing filenames, we stop after the first match */
157 if (print_files_with_matches) 152 if (PRINT_FILES_WITH_MATCHES)
158 break; 153 break;
159 154
160 /* print the matched line */ 155 /* print the matched line */
161 if (print_match_counts == 0) { 156 if (PRINT_MATCH_COUNTS == 0) {
162#ifdef CONFIG_FEATURE_GREP_CONTEXT 157#if ENABLE_FEATURE_GREP_CONTEXT
163 int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1; 158 int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1;
164 159
165 /* if we were told to print 'before' lines and there is at least 160 /* if we were told to print 'before' lines and there is at least
@@ -188,11 +183,11 @@ static int grep_file(FILE *file)
188 183
189 /* make a note that we need to print 'after' lines */ 184 /* make a note that we need to print 'after' lines */
190 print_n_lines_after = lines_after; 185 print_n_lines_after = lines_after;
191#endif /* CONFIG_FEATURE_GREP_CONTEXT */ 186#endif
192 print_line(line, linenum, ':'); 187 print_line(line, linenum, ':');
193 } 188 }
194 } 189 }
195#ifdef CONFIG_FEATURE_GREP_CONTEXT 190#if ENABLE_FEATURE_GREP_CONTEXT
196 else { /* no match */ 191 else { /* no match */
197 /* Add the line to the circular 'before' buffer */ 192 /* Add the line to the circular 'before' buffer */
198 if(lines_before) { 193 if(lines_before) {
@@ -207,7 +202,7 @@ static int grep_file(FILE *file)
207 print_line(line, linenum, '-'); 202 print_line(line, linenum, '-');
208 print_n_lines_after--; 203 print_n_lines_after--;
209 } 204 }
210#endif /* CONFIG_FEATURE_GREP_CONTEXT */ 205#endif /* ENABLE_FEATURE_GREP_CONTEXT */
211 free(line); 206 free(line);
212 } 207 }
213 208
@@ -216,19 +211,19 @@ static int grep_file(FILE *file)
216 * matches, just filenames and possibly match counts */ 211 * matches, just filenames and possibly match counts */
217 212
218 /* grep -c: print [filename:]count, even if count is zero */ 213 /* grep -c: print [filename:]count, even if count is zero */
219 if (print_match_counts) { 214 if (PRINT_MATCH_COUNTS) {
220 if (print_filename > 0) 215 if (print_filename > 0)
221 printf("%s:", cur_file); 216 printf("%s:", cur_file);
222 printf("%d\n", nmatches); 217 printf("%d\n", nmatches);
223 } 218 }
224 219
225 /* grep -l: print just the filename, but only if we grepped the line in the file */ 220 /* grep -l: print just the filename, but only if we grepped the line in the file */
226 if (print_files_with_matches && nmatches > 0) { 221 if (PRINT_FILES_WITH_MATCHES && nmatches > 0) {
227 puts(cur_file); 222 puts(cur_file);
228 } 223 }
229 224
230 /* grep -L: print just the filename, but only if we didn't grep the line in the file */ 225 /* grep -L: print just the filename, but only if we didn't grep the line in the file */
231 if (print_files_without_matches && nmatches == 0) { 226 if (PRINT_FILES_WITHOUT_MATCHES && nmatches == 0) {
232 puts(cur_file); 227 puts(cur_file);
233 } 228 }
234 229
@@ -258,12 +253,11 @@ extern int grep_main(int argc, char **argv)
258{ 253{
259 FILE *file; 254 FILE *file;
260 int matched; 255 int matched;
261 unsigned long opt;
262 llist_t *fopt = NULL; 256 llist_t *fopt = NULL;
263 int error_open_count = 0; 257 int error_open_count = 0;
264 258
265 /* do normal option parsing */ 259 /* do normal option parsing */
266#ifdef CONFIG_FEATURE_GREP_CONTEXT 260#if ENABLE_FEATURE_GREP_CONTEXT
267 { 261 {
268 char *junk; 262 char *junk;
269 char *slines_after; 263 char *slines_after;
@@ -287,14 +281,14 @@ extern int grep_main(int argc, char **argv)
287 } 281 }
288 if(opt & GREP_OPT_A) { 282 if(opt & GREP_OPT_A) {
289 lines_after = strtoul(slines_after, &junk, 10); 283 lines_after = strtoul(slines_after, &junk, 10);
290 if(*junk != '\0') 284 if(*junk != '\0')
291 bb_error_msg_and_die("invalid context length argument"); 285 bb_error_msg_and_die("invalid context length argument");
292 } 286 }
293 if(opt & GREP_OPT_B) { 287 if(opt & GREP_OPT_B) {
294 lines_before = strtoul(slines_before, &junk, 10); 288 lines_before = strtoul(slines_before, &junk, 10);
295 if(*junk != '\0') 289 if(*junk != '\0')
296 bb_error_msg_and_die("invalid context length argument"); 290 bb_error_msg_and_die("invalid context length argument");
297 } 291 }
298 /* sanity checks after parse may be invalid numbers ;-) */ 292 /* sanity checks after parse may be invalid numbers ;-) */
299 if ((opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L))) { 293 if ((opt & (GREP_OPT_c|GREP_OPT_q|GREP_OPT_l|GREP_OPT_L))) {
300 opt &= ~GREP_OPT_n; 294 opt &= ~GREP_OPT_n;
@@ -308,16 +302,9 @@ extern int grep_main(int argc, char **argv)
308 bb_opt_complementally = "H-h:e*:f*:c-n:q-n:l-n"; 302 bb_opt_complementally = "H-h:e*:f*:c-n:q-n:l-n";
309 opt = bb_getopt_ulflags(argc, argv, GREP_OPTS OPT_EGREP, 303 opt = bb_getopt_ulflags(argc, argv, GREP_OPTS OPT_EGREP,
310 &pattern_head, &fopt); 304 &pattern_head, &fopt);
311
312#endif 305#endif
313 print_files_with_matches = opt & GREP_OPT_l;
314 print_files_without_matches = (opt & GREP_OPT_L) != 0;
315 print_line_num = opt & GREP_OPT_n;
316 be_quiet = opt & GREP_OPT_q;
317 invert_search = (opt & GREP_OPT_v) != 0; /* 0 | 1 */ 306 invert_search = (opt & GREP_OPT_v) != 0; /* 0 | 1 */
318 suppress_err_msgs = opt & GREP_OPT_s; 307
319 print_match_counts = opt & GREP_OPT_c;
320 fgrep_flag = opt & GREP_OPT_F;
321 if(opt & GREP_OPT_H) 308 if(opt & GREP_OPT_H)
322 print_filename++; 309 print_filename++;
323 if(opt & GREP_OPT_h) 310 if(opt & GREP_OPT_h)
@@ -325,16 +312,13 @@ extern int grep_main(int argc, char **argv)
325 if(opt & GREP_OPT_f) 312 if(opt & GREP_OPT_f)
326 load_regexes_from_file(fopt); 313 load_regexes_from_file(fopt);
327 314
328#ifdef CONFIG_FEATURE_GREP_FGREP_ALIAS 315 if(ENABLE_FEATURE_GREP_FGREP_ALIAS && bb_applet_name[0] == 'f')
329 if(bb_applet_name[0] == 'f') 316 opt |= GREP_OPT_F;
330 fgrep_flag = 1;
331#endif
332 317
333#ifdef CONFIG_FEATURE_GREP_EGREP_ALIAS 318 if(ENABLE_FEATURE_GREP_EGREP_ALIAS &&
334 if(bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)) 319 (bb_applet_name[0] == 'e' || (opt & GREP_OPT_E)))
335 reflags = REG_EXTENDED | REG_NOSUB; 320 reflags = REG_EXTENDED | REG_NOSUB;
336 else 321 else
337#endif
338 reflags = REG_NOSUB; 322 reflags = REG_NOSUB;
339 323
340 if(opt & GREP_OPT_i) 324 if(opt & GREP_OPT_i)
@@ -368,15 +352,15 @@ extern int grep_main(int argc, char **argv)
368 while (argc--) { 352 while (argc--) {
369 cur_file = *argv++; 353 cur_file = *argv++;
370 if(!cur_file || (*cur_file == '-' && !cur_file[1])) { 354 if(!cur_file || (*cur_file == '-' && !cur_file[1])) {
371 cur_file = "-"; 355 cur_file = "(standard input)";
372 file = stdin; 356 file = stdin;
373 } else { 357 } else {
374 file = fopen(cur_file, "r"); 358 file = fopen(cur_file, "r");
375 } 359 }
376 if (file == NULL) { 360 if (file == NULL) {
377 if (!suppress_err_msgs) 361 if (!SUPPRESS_ERR_MSGS)
378 bb_perror_msg("%s", cur_file); 362 bb_perror_msg("%s", cur_file);
379 error_open_count++; 363 error_open_count++;
380 } else { 364 } else {
381 matched += grep_file(file); 365 matched += grep_file(file);
382 if(matched < 0) { 366 if(matched < 0) {
@@ -388,17 +372,19 @@ extern int grep_main(int argc, char **argv)
388 } 372 }
389 } 373 }
390 374
391#ifdef CONFIG_FEATURE_CLEAN_UP
392 /* destroy all the elments in the pattern list */ 375 /* destroy all the elments in the pattern list */
376 if (ENABLE_FEATURE_CLEAN_UP)
393 while (pattern_head) { 377 while (pattern_head) {
394 llist_t *pattern_head_ptr = pattern_head; 378 llist_t *pattern_head_ptr = pattern_head;
395 379
396 pattern_head = pattern_head->link; 380 pattern_head = pattern_head->link;
397 free(pattern_head_ptr); 381 free(pattern_head_ptr);
398 } 382 }
399#endif
400 383
401 if(be_quiet && matched) 384 /* 0 = success, 1 = failed, 2 = error */
385 /* If the -q option is specified, the exit status shall be zero
386 * if an input line is selected, even if an error was detected. */
387 if(BE_QUIET && matched)
402 return 0; 388 return 0;
403 if(error_open_count) 389 if(error_open_count)
404 return 2; 390 return 2;