aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author"Vladimir N. Oleynik" <dzo@simtreas.ru>2006-02-28 10:10:19 +0000
committer"Vladimir N. Oleynik" <dzo@simtreas.ru>2006-02-28 10:10:19 +0000
commit716bbe96d47f61cf20ac9298d0911be522eefe98 (patch)
tree8ad641450e5c10c1648f66f291bbd9c3064a9c19
parent73804d6f7e6220e220ac167bd77ef210ea6e3d68 (diff)
downloadbusybox-w32-716bbe96d47f61cf20ac9298d0911be522eefe98.tar.gz
busybox-w32-716bbe96d47f61cf20ac9298d0911be522eefe98.tar.bz2
busybox-w32-716bbe96d47f61cf20ac9298d0911be522eefe98.zip
make grep faster (close bug 758), reduce small memory leak in CONFIG_FEATURE_CLEANUP mode
-rw-r--r--findutils/grep.c78
1 files changed, 62 insertions, 16 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index 3c5167e28..e1ce8e5fa 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -11,8 +11,9 @@
11/* BB_AUDIT GNU defects - always acts as -a. */ 11/* BB_AUDIT GNU defects - always acts as -a. */
12/* http://www.opengroup.org/onlinepubs/007904975/utilities/grep.html */ 12/* http://www.opengroup.org/onlinepubs/007904975/utilities/grep.html */
13/* 13/*
14 * Apr 2004 by Vladimir Oleynik <dzo@simtreas.ru> - 14 * 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
15 * correction "-e pattern1 -e pattern2" logic and more optimizations. 15 * correction "-e pattern1 -e pattern2" logic and more optimizations.
16 * precompiled regex
16*/ 17*/
17 18
18#include <stdio.h> 19#include <stdio.h>
@@ -82,6 +83,13 @@ static int last_line_printed;
82static llist_t *pattern_head; /* growable list of patterns to match */ 83static llist_t *pattern_head; /* growable list of patterns to match */
83static char *cur_file; /* the current file we are reading */ 84static char *cur_file; /* the current file we are reading */
84 85
86typedef struct GREP_LIST_DATA {
87 char *pattern;
88 regex_t preg;
89#define PATTERN_MEM_A 1
90#define COMPILED 2
91 int flg_mem_alocated_compiled;
92} grep_list_data_t;
85 93
86static void print_line(const char *line, int linenum, char decoration) 94static void print_line(const char *line, int linenum, char decoration)
87{ 95{
@@ -115,12 +123,14 @@ static int grep_file(FILE *file)
115 123
116 while ((line = bb_get_chomped_line_from_file(file)) != NULL) { 124 while ((line = bb_get_chomped_line_from_file(file)) != NULL) {
117 llist_t *pattern_ptr = pattern_head; 125 llist_t *pattern_ptr = pattern_head;
126 grep_list_data_t * gl;
118 127
119 linenum++; 128 linenum++;
120 ret = 0; 129 ret = 0;
121 while (pattern_ptr) { 130 while (pattern_ptr) {
131 gl = (grep_list_data_t *)pattern_ptr->data;
122 if (FGREP_FLAG) { 132 if (FGREP_FLAG) {
123 ret = strstr(line, pattern_ptr->data) != NULL; 133 ret = strstr(line, gl->pattern) != NULL;
124 } else { 134 } else {
125 /* 135 /*
126 * test for a postitive-assertion match (regexec returns success (0) 136 * test for a postitive-assertion match (regexec returns success (0)
@@ -128,10 +138,11 @@ static int grep_file(FILE *file)
128 * match (regexec returns failure (REG_NOMATCH) and the user specified 138 * match (regexec returns failure (REG_NOMATCH) and the user specified
129 * invert search) 139 * invert search)
130 */ 140 */
131 regex_t regex; 141 if(!(gl->flg_mem_alocated_compiled & COMPILED)) {
132 xregcomp(&regex, pattern_ptr->data, reflags); 142 gl->flg_mem_alocated_compiled |= COMPILED;
133 ret |= regexec(&regex, line, 0, NULL, 0) == 0; 143 xregcomp(&(gl->preg), gl->pattern, reflags);
134 regfree(&regex); 144 }
145 ret |= regexec(&(gl->preg), line, 0, NULL, 0) == 0;
135 } 146 }
136 pattern_ptr = pattern_ptr->link; 147 pattern_ptr = pattern_ptr->link;
137 } /* while (pattern_ptr) */ 148 } /* while (pattern_ptr) */
@@ -230,6 +241,25 @@ static int grep_file(FILE *file)
230 return nmatches; 241 return nmatches;
231} 242}
232 243
244#if ENABLE_FEATURE_CLEAN_UP
245#define new_grep_list_data(p, m) add_grep_list_data(p, m)
246static char * add_grep_list_data(char *pattern, int flg_used_mem)
247#else
248#define new_grep_list_data(p, m) add_grep_list_data(p)
249static char * add_grep_list_data(char *pattern)
250#endif
251{
252 grep_list_data_t *gl = xmalloc(sizeof(grep_list_data_t));
253 gl->pattern = pattern;
254#if ENABLE_FEATURE_CLEAN_UP
255 gl->flg_mem_alocated_compiled = flg_used_mem;
256#else
257 gl->flg_mem_alocated_compiled = 0;
258#endif
259 return (char *)gl;
260}
261
262
233static void load_regexes_from_file(llist_t *fopt) 263static void load_regexes_from_file(llist_t *fopt)
234{ 264{
235 char *line; 265 char *line;
@@ -243,7 +273,8 @@ static void load_regexes_from_file(llist_t *fopt)
243 free(cur); 273 free(cur);
244 f = bb_xfopen(ffile, "r"); 274 f = bb_xfopen(ffile, "r");
245 while ((line = bb_get_chomped_line_from_file(f)) != NULL) { 275 while ((line = bb_get_chomped_line_from_file(f)) != NULL) {
246 pattern_head = llist_add_to(pattern_head, line); 276 pattern_head = llist_add_to(pattern_head,
277 new_grep_list_data(line, PATTERN_MEM_A));
247 } 278 }
248 } 279 }
249} 280}
@@ -296,7 +327,7 @@ extern int grep_main(int argc, char **argv)
296 lines_after = 0; 327 lines_after = 0;
297 } else if(lines_before > 0) 328 } else if(lines_before > 0)
298 before_buf = (char **)xcalloc(lines_before, sizeof(char *)); 329 before_buf = (char **)xcalloc(lines_before, sizeof(char *));
299 } 330 }
300#else 331#else
301 /* with auto sanity checks */ 332 /* with auto sanity checks */
302 bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n"; 333 bb_opt_complementally = "H-h:e::f::c-n:q-n:l-n";
@@ -309,6 +340,13 @@ extern int grep_main(int argc, char **argv)
309 print_filename++; 340 print_filename++;
310 if(opt & GREP_OPT_h) 341 if(opt & GREP_OPT_h)
311 print_filename--; 342 print_filename--;
343 if (pattern_head != NULL) {
344 /* convert char *argv[] to grep_list_data_t */
345 llist_t *cur;
346
347 for(cur = pattern_head; cur; cur = cur->link)
348 cur->data = new_grep_list_data(cur->data, 0);
349 }
312 if(opt & GREP_OPT_f) 350 if(opt & GREP_OPT_f)
313 load_regexes_from_file(fopt); 351 load_regexes_from_file(fopt);
314 352
@@ -333,7 +371,9 @@ extern int grep_main(int argc, char **argv)
333 if (*argv == NULL) 371 if (*argv == NULL)
334 bb_show_usage(); 372 bb_show_usage();
335 else { 373 else {
336 pattern_head = llist_add_to(pattern_head, *argv++); 374 char *pattern = new_grep_list_data(*argv++, 0);
375
376 pattern_head = llist_add_to(pattern_head, pattern);
337 argc--; 377 argc--;
338 } 378 }
339 } 379 }
@@ -373,14 +413,20 @@ extern int grep_main(int argc, char **argv)
373 } 413 }
374 414
375 /* destroy all the elments in the pattern list */ 415 /* destroy all the elments in the pattern list */
376 if (ENABLE_FEATURE_CLEAN_UP) 416 if (ENABLE_FEATURE_CLEAN_UP) {
377 while (pattern_head) { 417 while (pattern_head) {
378 llist_t *pattern_head_ptr = pattern_head; 418 llist_t *pattern_head_ptr = pattern_head;
379 419 grep_list_data_t *gl =
380 pattern_head = pattern_head->link; 420 (grep_list_data_t *)pattern_head_ptr->data;
381 free(pattern_head_ptr); 421
422 pattern_head = pattern_head->link;
423 if((gl->flg_mem_alocated_compiled & PATTERN_MEM_A))
424 free(gl->pattern);
425 if((gl->flg_mem_alocated_compiled & COMPILED))
426 regfree(&(gl->preg));
427 free(pattern_head_ptr);
428 }
382 } 429 }
383
384 /* 0 = success, 1 = failed, 2 = error */ 430 /* 0 = success, 1 = failed, 2 = error */
385 /* If the -q option is specified, the exit status shall be zero 431 /* 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. */ 432 * if an input line is selected, even if an error was detected. */