diff options
| author | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-02-28 10:10:19 +0000 |
|---|---|---|
| committer | vodz <vodz@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2006-02-28 10:10:19 +0000 |
| commit | 9357cdbf8a9302daa64997f33407fc57b5f14f53 (patch) | |
| tree | 8ad641450e5c10c1648f66f291bbd9c3064a9c19 | |
| parent | f3482c5cf3e5aed33d262bcb5f7d522f217bbc57 (diff) | |
| download | busybox-w32-9357cdbf8a9302daa64997f33407fc57b5f14f53.tar.gz busybox-w32-9357cdbf8a9302daa64997f33407fc57b5f14f53.tar.bz2 busybox-w32-9357cdbf8a9302daa64997f33407fc57b5f14f53.zip | |
make grep faster (close bug 758), reduce small memory leak in CONFIG_FEATURE_CLEANUP mode
git-svn-id: svn://busybox.net/trunk/busybox@14361 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -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. */ |
