Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/findutils/grep.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 25  Line 25 
25  /* options */  /* options */
26  #define OPTSTR_GREP \  #define OPTSTR_GREP \
27   "lnqvscFiHhe:f:Lorm:" \   "lnqvscFiHhe:f:Lorm:" \
28   USE_FEATURE_GREP_CONTEXT("A:B:C:") \   IF_FEATURE_GREP_CONTEXT("A:B:C:") \
29   USE_FEATURE_GREP_EGREP_ALIAS("E") \   IF_FEATURE_GREP_EGREP_ALIAS("E") \
30   USE_DESKTOP("w") \   IF_DESKTOP("w") \
31     IF_EXTRA_COMPAT("z") \
32   "aI"   "aI"
33    
34  /* ignored: -a "assume all files to be text" */  /* ignored: -a "assume all files to be text" */
35  /* ignored: -I "assume binary files have no matches" */  /* ignored: -I "assume binary files have no matches" */
36    
# Line 49  enum { Line 51  enum {
51   OPTBIT_o, /* show only matching parts of lines */   OPTBIT_o, /* show only matching parts of lines */
52   OPTBIT_r, /* recurse dirs */   OPTBIT_r, /* recurse dirs */
53   OPTBIT_m, /* -m MAX_MATCHES */   OPTBIT_m, /* -m MAX_MATCHES */
54   USE_FEATURE_GREP_CONTEXT(    OPTBIT_A ,) /* -A NUM: after-match context */   IF_FEATURE_GREP_CONTEXT(    OPTBIT_A ,) /* -A NUM: after-match context */
55   USE_FEATURE_GREP_CONTEXT(    OPTBIT_B ,) /* -B NUM: before-match context */   IF_FEATURE_GREP_CONTEXT(    OPTBIT_B ,) /* -B NUM: before-match context */
56   USE_FEATURE_GREP_CONTEXT(    OPTBIT_C ,) /* -C NUM: -A and -B combined */   IF_FEATURE_GREP_CONTEXT(    OPTBIT_C ,) /* -C NUM: -A and -B combined */
57   USE_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */   IF_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */
58   USE_DESKTOP(                 OPTBIT_w ,) /* whole word match */   IF_DESKTOP(                 OPTBIT_w ,) /* whole word match */
59     IF_EXTRA_COMPAT(            OPTBIT_z ,) /* input is NUL terminated */
60   OPT_l = 1 << OPTBIT_l,   OPT_l = 1 << OPTBIT_l,
61   OPT_n = 1 << OPTBIT_n,   OPT_n = 1 << OPTBIT_n,
62   OPT_q = 1 << OPTBIT_q,   OPT_q = 1 << OPTBIT_q,
# Line 70  enum { Line 73  enum {
73   OPT_o = 1 << OPTBIT_o,   OPT_o = 1 << OPTBIT_o,
74   OPT_r = 1 << OPTBIT_r,   OPT_r = 1 << OPTBIT_r,
75   OPT_m = 1 << OPTBIT_m,   OPT_m = 1 << OPTBIT_m,
76   OPT_A = USE_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_A)) + 0,   OPT_A = IF_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_A)) + 0,
77   OPT_B = USE_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_B)) + 0,   OPT_B = IF_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_B)) + 0,
78   OPT_C = USE_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_C)) + 0,   OPT_C = IF_FEATURE_GREP_CONTEXT(    (1 << OPTBIT_C)) + 0,
79   OPT_E = USE_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0,   OPT_E = IF_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0,
80   OPT_w = USE_DESKTOP(                 (1 << OPTBIT_w)) + 0,   OPT_w = IF_DESKTOP(                 (1 << OPTBIT_w)) + 0,
81     OPT_z = IF_EXTRA_COMPAT(            (1 << OPTBIT_z)) + 0,
82  };  };
83    
84  #define PRINT_FILES_WITH_MATCHES    (option_mask32 & OPT_l)  #define PRINT_FILES_WITH_MATCHES    (option_mask32 & OPT_l)
# Line 84  enum { Line 88  enum {
88  #define PRINT_MATCH_COUNTS          (option_mask32 & OPT_c)  #define PRINT_MATCH_COUNTS          (option_mask32 & OPT_c)
89  #define FGREP_FLAG                  (option_mask32 & OPT_F)  #define FGREP_FLAG                  (option_mask32 & OPT_F)
90  #define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L)  #define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L)
91    #define NUL_DELIMITED               (option_mask32 & OPT_z)
92    
93  struct globals {  struct globals {
94   int max_matches;   int max_matches;
# Line 100  struct globals { Line 105  struct globals {
105   int lines_before;   int lines_before;
106   int lines_after;   int lines_after;
107   char **before_buf;   char **before_buf;
108   USE_EXTRA_COMPAT(size_t *before_buf_size;)   IF_EXTRA_COMPAT(size_t *before_buf_size;)
109   int last_line_printed;   int last_line_printed;
110  #endif  #endif
111   /* globals used internally */   /* globals used internally */
# Line 115  struct globals { Line 120  struct globals {
120  } while (0)  } while (0)
121  #define max_matches       (G.max_matches         )  #define max_matches       (G.max_matches         )
122  #if !ENABLE_EXTRA_COMPAT  #if !ENABLE_EXTRA_COMPAT
123  #define reflags           (G.reflags             )  # define reflags          (G.reflags             )
124  #else  #else
125  #define case_fold         (G.case_fold           )  # define case_fold        (G.case_fold           )
126  /* http://www.delorie.com/gnu/docs/regex/regex_46.html */  /* http://www.delorie.com/gnu/docs/regex/regex_46.html */
127  #define reflags           re_syntax_options  # define reflags           re_syntax_options
128  #undef REG_NOSUB  # undef REG_NOSUB
129  #undef REG_EXTENDED  # undef REG_EXTENDED
130  #undef REG_ICASE  # undef REG_ICASE
131  #define REG_NOSUB    bug:is:here /* should not be used */  # define REG_NOSUB    bug:is:here /* should not be used */
132  #define REG_EXTENDED RE_SYNTAX_EGREP  /* Just RE_SYNTAX_EGREP is not enough, need to enable {n[,[m]]} too */
133  #define REG_ICASE    bug:is:here /* should not be used */  # define REG_EXTENDED (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
134    # define REG_ICASE    bug:is:here /* should not be used */
135  #endif  #endif
136  #define invert_search     (G.invert_search       )  #define invert_search     (G.invert_search       )
137  #define print_filename    (G.print_filename      )  #define print_filename    (G.print_filename      )
# Line 186  static void print_line(const char *line, Line 192  static void print_line(const char *line,
192   puts(line);   puts(line);
193  #else  #else
194   fwrite(line, 1, line_len, stdout);   fwrite(line, 1, line_len, stdout);
195   putchar('\n');   putchar(NUL_DELIMITED ? '\0' : '\n');
196  #endif  #endif
197   }   }
198  }  }
# Line 197  static ssize_t FAST_FUNC bb_getline(char Line 203  static ssize_t FAST_FUNC bb_getline(char
203  {  {
204   ssize_t res_sz;   ssize_t res_sz;
205   char *line;   char *line;
206     int delim = (NUL_DELIMITED ? '\0' : '\n');
207    
208   res_sz = getline(line_ptr, line_alloc_len, file);   res_sz = getdelim(line_ptr, line_alloc_len, delim, file);
209   line = *line_ptr;   line = *line_ptr;
210    
211   if (res_sz > 0) {   if (res_sz > 0) {
212   if (line[res_sz - 1] == '\n')   if (line[res_sz - 1] == delim)
213   line[--res_sz] = '\0';   line[--res_sz] = '\0';
214   } else {   } else {
215   free(line); /* uclibc allocates a buffer even on EOF. WTF? */   free(line); /* uclibc allocates a buffer even on EOF. WTF? */
# Line 222  static int grep_file(FILE *file) Line 229  static int grep_file(FILE *file)
229   char *line = NULL;   char *line = NULL;
230   ssize_t line_len;   ssize_t line_len;
231   size_t line_alloc_len;   size_t line_alloc_len;
232  #define rm_so start[0]  # define rm_so start[0]
233  #define rm_eo end[0]  # define rm_eo end[0]
234  #endif  #endif
235  #if ENABLE_FEATURE_GREP_CONTEXT  #if ENABLE_FEATURE_GREP_CONTEXT
236   int print_n_lines_after = 0;   int print_n_lines_after = 0;
# Line 231  static int grep_file(FILE *file) Line 238  static int grep_file(FILE *file)
238   int idx = 0; /* used for iteration through the circular buffer */   int idx = 0; /* used for iteration through the circular buffer */
239  #else  #else
240   enum { print_n_lines_after = 0 };   enum { print_n_lines_after = 0 };
241  #endif /* ENABLE_FEATURE_GREP_CONTEXT */  #endif
242    
243   while (   while (
244  #if !ENABLE_EXTRA_COMPAT  #if !ENABLE_EXTRA_COMPAT
# Line 364  static int grep_file(FILE *file) Line 371  static int grep_file(FILE *file)
371   if (found)   if (found)
372   print_line(gl->pattern, strlen(gl->pattern), linenum, ':');   print_line(gl->pattern, strlen(gl->pattern), linenum, ':');
373   } else while (1) {   } else while (1) {
374   char old = line[gl->matched_range.rm_eo];   unsigned end = gl->matched_range.rm_eo;
375   line[gl->matched_range.rm_eo] = '\0';   char old = line[end];
376     line[end] = '\0';
377   print_line(line + gl->matched_range.rm_so,   print_line(line + gl->matched_range.rm_so,
378   gl->matched_range.rm_eo - gl->matched_range.rm_so,   end - gl->matched_range.rm_so,
379   linenum, ':');   linenum, ':');
380   line[gl->matched_range.rm_eo] = old;   if (old == '\0')
381     break;
382     line[end] = old;
383  #if !ENABLE_EXTRA_COMPAT  #if !ENABLE_EXTRA_COMPAT
384   break;   if (regexec(&gl->compiled_regex, line + end,
385     1, &gl->matched_range, REG_NOTBOL) != 0)
386     break;
387     gl->matched_range.rm_so += end;
388     gl->matched_range.rm_eo += end;
389  #else  #else
390   if (re_search(&gl->compiled_regex, line, line_len,   if (re_search(&gl->compiled_regex, line, line_len,
391   gl->matched_range.rm_eo, line_len - gl->matched_range.rm_eo,   end, line_len - end,
392   &gl->matched_range) < 0)   &gl->matched_range) < 0)
393   break;   break;
394  #endif  #endif
395   }   }
396   } else {   } else {
397   print_line(line, line_len, linenum, ':');   print_line(line, line_len, linenum, ':');
398   }   }
# Line 394  static int grep_file(FILE *file) Line 408  static int grep_file(FILE *file)
408   /* Add the line to the circular 'before' buffer */   /* Add the line to the circular 'before' buffer */
409   free(before_buf[curpos]);   free(before_buf[curpos]);
410   before_buf[curpos] = line;   before_buf[curpos] = line;
411   USE_EXTRA_COMPAT(before_buf_size[curpos] = line_len;)   IF_EXTRA_COMPAT(before_buf_size[curpos] = line_len;)
412   curpos = (curpos + 1) % lines_before;   curpos = (curpos + 1) % lines_before;
413   /* avoid free(line) - we took the line */   /* avoid free(line) - we took the line */
414   line = NULL;   line = NULL;
# Line 407  static int grep_file(FILE *file) Line 421  static int grep_file(FILE *file)
421  #endif  #endif
422   /* Did we print all context after last requested match? */   /* Did we print all context after last requested match? */
423   if ((option_mask32 & OPT_m)   if ((option_mask32 & OPT_m)
424   && !print_n_lines_after && nmatches == max_matches)   && !print_n_lines_after
425     && nmatches == max_matches
426     ) {
427   break;   break;
428     }
429   } /* while (read line) */   } /* while (read line) */
430    
431   /* special-case file post-processing for options where we don't print line   /* special-case file post-processing for options where we don't print line
# Line 502  static int grep_dir(const char *dir) Line 519  static int grep_dir(const char *dir)
519  }  }
520    
521  int grep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int grep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
522  int grep_main(int argc, char **argv)  int grep_main(int argc UNUSED_PARAM, char **argv)
523  {  {
524   FILE *file;   FILE *file;
525   int matched;   int matched;
# Line 535  int grep_main(int argc, char **argv) Line 552  int grep_main(int argc, char **argv)
552   lines_after = 0;   lines_after = 0;
553   } else if (lines_before > 0) {   } else if (lines_before > 0) {
554   before_buf = xzalloc(lines_before * sizeof(before_buf[0]));   before_buf = xzalloc(lines_before * sizeof(before_buf[0]));
555   USE_EXTRA_COMPAT(before_buf_size = xzalloc(lines_before * sizeof(before_buf_size[0]));)   IF_EXTRA_COMPAT(before_buf_size = xzalloc(lines_before * sizeof(before_buf_size[0]));)
556   }   }
557  #else  #else
558   /* with auto sanity checks */   /* with auto sanity checks */
# Line 589  int grep_main(int argc, char **argv) Line 606  int grep_main(int argc, char **argv)
606   }   }
607    
608   argv += optind;   argv += optind;
  argc -= optind;  
609    
610   /* if we didn't get a pattern from -e and no command file was specified,   /* if we didn't get a pattern from -e and no command file was specified,
611   * first parameter should be the pattern. no pattern, no worky */   * first parameter should be the pattern. no pattern, no worky */
# Line 599  int grep_main(int argc, char **argv) Line 615  int grep_main(int argc, char **argv)
615   bb_show_usage();   bb_show_usage();
616   pattern = new_grep_list_data(*argv++, 0);   pattern = new_grep_list_data(*argv++, 0);
617   llist_add_to(&pattern_head, pattern);   llist_add_to(&pattern_head, pattern);
  argc--;  
618   }   }
619    
620   /* argv[0..(argc-1)] should be names of file to grep through. If   /* argv[0..(argc-1)] should be names of file to grep through. If
621   * there is more than one file to grep, we will print the filenames. */   * there is more than one file to grep, we will print the filenames. */
622   if (argc > 1)   if (argv[0] && argv[1])
623   print_filename = 1;   print_filename = 1;
624   /* -H / -h of course override */   /* -H / -h of course override */
625   if (option_mask32 & OPT_H)   if (option_mask32 & OPT_H)
# Line 616  int grep_main(int argc, char **argv) Line 631  int grep_main(int argc, char **argv)
631   * stdin. Otherwise, we grep through all the files specified. */   * stdin. Otherwise, we grep through all the files specified. */
632   matched = 0;   matched = 0;
633   do {   do {
634   cur_file = *argv++;   cur_file = *argv;
635   file = stdin;   file = stdin;
636   if (!cur_file || LONE_DASH(cur_file)) {   if (!cur_file || LONE_DASH(cur_file)) {
637   cur_file = "(standard input)";   cur_file = "(standard input)";
# Line 642  int grep_main(int argc, char **argv) Line 657  int grep_main(int argc, char **argv)
657   matched += grep_file(file);   matched += grep_file(file);
658   fclose_if_not_stdin(file);   fclose_if_not_stdin(file);
659   grep_done: ;   grep_done: ;
660   } while (--argc > 0);   } while (*argv && *++argv);
661    
662   /* destroy all the elments in the pattern list */   /* destroy all the elments in the pattern list */
663   if (ENABLE_FEATURE_CLEAN_UP) {   if (ENABLE_FEATURE_CLEAN_UP) {

Legend:
Removed from v.983  
changed lines
  Added in v.984