aboutsummaryrefslogtreecommitdiff
path: root/findutils/grep.c
diff options
context:
space:
mode:
authorMark Whitley <markw@lineo.com>2001-02-09 00:41:10 +0000
committerMark Whitley <markw@lineo.com>2001-02-09 00:41:10 +0000
commit2fd52989f734c0e85e4a4733351cf3ce4b8c47c7 (patch)
treee91560b567b11c09e4c49ee9dc1ae2acc8681972 /findutils/grep.c
parentd238a7bcc8412bb1ccc008d1e005007ed500e35b (diff)
downloadbusybox-w32-2fd52989f734c0e85e4a4733351cf3ce4b8c47c7.tar.gz
busybox-w32-2fd52989f734c0e85e4a4733351cf3ce4b8c47c7.tar.bz2
busybox-w32-2fd52989f734c0e85e4a4733351cf3ce4b8c47c7.zip
Implemented -A, -B, and -C flags with BB_FEATURE_GREP_CONTEXT option set.
Diffstat (limited to 'findutils/grep.c')
-rw-r--r--findutils/grep.c139
1 files changed, 125 insertions, 14 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index ce2990f64..3eea7792f 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -28,10 +28,10 @@
28#include <errno.h> 28#include <errno.h>
29#include "busybox.h" 29#include "busybox.h"
30 30
31extern void xregcomp(regex_t *preg, const char *regex, int cflags);
32 31
33extern int optind; /* in unistd.h */ 32extern int optind; /* in unistd.h */
34extern int errno; /* for use with strerror() */ 33extern int errno; /* for use with strerror() */
34extern void xregcomp(regex_t *preg, const char *regex, int cflags); /* in busybox.h */
35 35
36/* options */ 36/* options */
37static int ignore_case = 0; 37static int ignore_case = 0;
@@ -42,11 +42,34 @@ static int be_quiet = 0;
42static int invert_search = 0; 42static int invert_search = 0;
43static int suppress_err_msgs = 0; 43static int suppress_err_msgs = 0;
44 44
45/* globals */ 45#ifdef BB_FEATURE_GREP_CONTEXT
46extern char *optarg; /* in getopt.h */
47static int lines_before = 0;
48static int lines_after = 0;
49static char **before_buf = NULL;
50static int last_line_printed = 0;
51#endif /* BB_FEATURE_GREP_CONTEXT */
52
53/* globals used internally */
46static regex_t regex; /* storage space for compiled regular expression */ 54static regex_t regex; /* storage space for compiled regular expression */
47static int matched; /* keeps track of whether we ever matched */ 55static int matched; /* keeps track of whether we ever matched */
48static char *cur_file = NULL; /* the current file we are reading */ 56static char *cur_file = NULL; /* the current file we are reading */
49 57
58static void print_line(const char *line, int linenum, char decoration)
59{
60#ifdef BB_FEATURE_GREP_CONTEXT
61 /* possibly print the little '--' seperator */
62 if (last_line_printed && last_line_printed < linenum - 1) {
63 puts("--");
64 }
65 last_line_printed = linenum;
66#endif
67 if (print_filename)
68 printf("%s%c", cur_file, decoration);
69 if (print_line_num)
70 printf("%i%c", linenum, decoration);
71 puts(line);
72}
50 73
51static void grep_file(FILE *file) 74static void grep_file(FILE *file)
52{ 75{
@@ -54,15 +77,23 @@ static void grep_file(FILE *file)
54 int ret; 77 int ret;
55 int linenum = 0; 78 int linenum = 0;
56 int nmatches = 0; 79 int nmatches = 0;
80#ifdef BB_FEATURE_GREP_CONTEXT
81 int print_n_lines_after = 0;
82 int curpos = 0; /* track where we are in the circular 'before' buffer */
83 int idx = 0; /* used for iteration through the circular buffer */
84#endif /* BB_FEATURE_GREP_CONTEXT */
57 85
58 while ((line = get_line_from_file(file)) != NULL) { 86 while ((line = get_line_from_file(file)) != NULL) {
59 chomp(line); 87 chomp(line);
60 linenum++; 88 linenum++;
61 ret = regexec(&regex, line, 0, NULL, 0);
62 89
63 /* test for a postitive-assertion match (regexec returned success (0) 90 /*
91 * test for a postitive-assertion match (regexec returns success (0)
64 * and the user did not specify invert search), or a negative-assertion 92 * and the user did not specify invert search), or a negative-assertion
65 * match (vice versa) */ 93 * match (regexec returns failure (REG_NOMATCH) and the user specified
94 * invert search)
95 */
96 ret = regexec(&regex, line, 0, NULL, 0);
66 if ((ret == 0 && !invert_search) || (ret == REG_NOMATCH && invert_search)) { 97 if ((ret == 0 && !invert_search) || (ret == REG_NOMATCH && invert_search)) {
67 98
68 /* if we found a match but were told to be quiet, stop here and 99 /* if we found a match but were told to be quiet, stop here and
@@ -72,17 +103,62 @@ static void grep_file(FILE *file)
72 exit(0); 103 exit(0);
73 } 104 }
74 105
75 /* otherwise, keep track of matches, print the matched line, and 106 /* otherwise, keep track of matches and print the matched line */
76 * whatever else the user wanted */
77 nmatches++; 107 nmatches++;
78 if (!print_count_only) { 108 if (!print_count_only) {
79 if (print_filename) 109#ifdef BB_FEATURE_GREP_CONTEXT
80 printf("%s:", cur_file); 110 int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1;
81 if (print_line_num) 111
82 printf("%i:", linenum); 112 /* if we were told to print 'before' lines and there is at least
83 puts(line); 113 * one line in the circular buffer, print them */
114 if (lines_before && before_buf[prevpos] != NULL)
115 {
116 int first_buf_entry_line_num = linenum - lines_before;
117
118 /* advance to the first entry in the circular buffer, and
119 * figure out the line number is of the first line in the
120 * buffer */
121 idx = curpos;
122 while (before_buf[idx] == NULL) {
123 idx = (idx + 1) % lines_before;
124 first_buf_entry_line_num++;
125 }
126
127 /* now print each line in the buffer, clearing them as we go */
128 while (before_buf[idx] != NULL) {
129 print_line(before_buf[idx], first_buf_entry_line_num, '-');
130 free(before_buf[idx]);
131 before_buf[idx] = NULL;
132 idx = (idx + 1) % lines_before;
133 first_buf_entry_line_num++;
134 }
135
136 }
137
138 /* make a note that we need to print 'after' lines */
139 print_n_lines_after = lines_after;
140#endif /* BB_FEATURE_GREP_CONTEXT */
141 print_line(line, linenum, ':');
142 }
143 }
144#ifdef BB_FEATURE_GREP_CONTEXT
145 else { /* no match */
146 /* Add the line to the circular 'before' buffer */
147 if(lines_before)
148 {
149 if(before_buf[curpos])
150 free(before_buf[curpos]);
151 before_buf[curpos] = strdup(line);
152 curpos = (curpos + 1) % lines_before;
84 } 153 }
85 } 154 }
155
156 /* if we need to print some context lines after the last match, do so */
157 if (print_n_lines_after && (last_line_printed != linenum)) {
158 print_line(line, linenum, '-');
159 print_n_lines_after--;
160 }
161#endif /* BB_FEATURE_GREP_CONTEXT */
86 free(line); 162 free(line);
87 } 163 }
88 164
@@ -93,7 +169,7 @@ static void grep_file(FILE *file)
93 printf("%i\n", nmatches); 169 printf("%i\n", nmatches);
94 } 170 }
95 171
96 /* record if we matched */ 172 /* remember if we matched */
97 if (nmatches != 0) 173 if (nmatches != 0)
98 matched = 1; 174 matched = 1;
99} 175}
@@ -102,9 +178,16 @@ extern int grep_main(int argc, char **argv)
102{ 178{
103 int opt; 179 int opt;
104 int reflags; 180 int reflags;
181#ifdef BB_FEATURE_GREP_CONTEXT
182 char *junk;
183#endif
105 184
106 /* do normal option parsing */ 185 /* do normal option parsing */
107 while ((opt = getopt(argc, argv, "iHhnqvsc")) > 0) { 186 while ((opt = getopt(argc, argv, "iHhnqvsc"
187#ifdef BB_FEATURE_GREP_CONTEXT
188"A:B:C:"
189#endif
190)) > 0) {
108 switch (opt) { 191 switch (opt) {
109 case 'i': 192 case 'i':
110 ignore_case++; 193 ignore_case++;
@@ -130,6 +213,25 @@ extern int grep_main(int argc, char **argv)
130 case 'c': 213 case 'c':
131 print_count_only++; 214 print_count_only++;
132 break; 215 break;
216#ifdef BB_FEATURE_GREP_CONTEXT
217 case 'A':
218 lines_after = strtoul(optarg, &junk, 10);
219 if(*junk != '\0')
220 error_msg_and_die("invalid context length argument");
221 break;
222 case 'B':
223 lines_before = strtoul(optarg, &junk, 10);
224 if(*junk != '\0')
225 error_msg_and_die("invalid context length argument");
226 before_buf = (char **)calloc(lines_before, sizeof(char *));
227 break;
228 case 'C':
229 lines_after = lines_before = strtoul(optarg, &junk, 10);
230 if(*junk != '\0')
231 error_msg_and_die("invalid context length argument");
232 before_buf = (char **)calloc(lines_before, sizeof(char *));
233 break;
234#endif /* BB_FEATURE_GREP_CONTEXT */
133 } 235 }
134 } 236 }
135 237
@@ -137,6 +239,15 @@ extern int grep_main(int argc, char **argv)
137 if (argv[optind] == NULL) 239 if (argv[optind] == NULL)
138 usage(grep_usage); 240 usage(grep_usage);
139 241
242 /* sanity check */
243 if (print_count_only || be_quiet) {
244 print_line_num = 0;
245#ifdef BB_FEATURE_GREP_CONTEXT
246 lines_before = 0;
247 lines_after = 0;
248#endif
249 }
250
140 /* compile the regular expression 251 /* compile the regular expression
141 * we're not going to mess with sub-expressions, and we need to 252 * we're not going to mess with sub-expressions, and we need to
142 * treat newlines right. */ 253 * treat newlines right. */