diff options
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 |
commit | 716bbe96d47f61cf20ac9298d0911be522eefe98 (patch) | |
tree | 8ad641450e5c10c1648f66f291bbd9c3064a9c19 | |
parent | 73804d6f7e6220e220ac167bd77ef210ea6e3d68 (diff) | |
download | busybox-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.c | 78 |
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; | |||
82 | static llist_t *pattern_head; /* growable list of patterns to match */ | 83 | static llist_t *pattern_head; /* growable list of patterns to match */ |
83 | static char *cur_file; /* the current file we are reading */ | 84 | static char *cur_file; /* the current file we are reading */ |
84 | 85 | ||
86 | typedef 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 | ||
86 | static void print_line(const char *line, int linenum, char decoration) | 94 | static 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(®ex, pattern_ptr->data, reflags); | 142 | gl->flg_mem_alocated_compiled |= COMPILED; |
133 | ret |= regexec(®ex, line, 0, NULL, 0) == 0; | 143 | xregcomp(&(gl->preg), gl->pattern, reflags); |
134 | regfree(®ex); | 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) | ||
246 | static 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) | ||
249 | static 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 | |||
233 | static void load_regexes_from_file(llist_t *fopt) | 263 | static 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. */ |