diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2024-12-10 02:36:59 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2024-12-10 02:55:58 +0100 |
commit | 470f00955212368cb688832e2e4b1fdd165e9ec6 (patch) | |
tree | a237585b23102a44cff5cae5829af7fc0e40e4c9 | |
parent | 55fc6a18da068a67b1854e4ca6fbb8d92e3af745 (diff) | |
download | busybox-w32-470f00955212368cb688832e2e4b1fdd165e9ec6.tar.gz busybox-w32-470f00955212368cb688832e2e4b1fdd165e9ec6.tar.bz2 busybox-w32-470f00955212368cb688832e2e4b1fdd165e9ec6.zip |
cut: with -F, do not regcomp() pattern for every file
function old new delta
cut_main 1218 1228 +10
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/cut.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/coreutils/cut.c b/coreutils/cut.c index 33aeff6ea..1eb4968d9 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -34,6 +34,7 @@ | |||
34 | //usage: "\n -c LIST Output only characters from LIST" | 34 | //usage: "\n -c LIST Output only characters from LIST" |
35 | //usage: "\n -d SEP Field delimiter for input (default -f TAB, -F run of whitespace)" | 35 | //usage: "\n -d SEP Field delimiter for input (default -f TAB, -F run of whitespace)" |
36 | //usage: "\n -O SEP Field delimeter for output (default = -d for -f, one space for -F)" | 36 | //usage: "\n -O SEP Field delimeter for output (default = -d for -f, one space for -F)" |
37 | //TODO: --output-delimiter=SEP | ||
37 | //usage: "\n -D Don't sort/collate sections or match -fF lines without delimeter" | 38 | //usage: "\n -D Don't sort/collate sections or match -fF lines without delimeter" |
38 | //usage: "\n -f LIST Print only these fields (-d is single char)" | 39 | //usage: "\n -f LIST Print only these fields (-d is single char)" |
39 | //usage: IF_FEATURE_CUT_REGEX( | 40 | //usage: IF_FEATURE_CUT_REGEX( |
@@ -53,11 +54,6 @@ | |||
53 | 54 | ||
54 | #if ENABLE_FEATURE_CUT_REGEX | 55 | #if ENABLE_FEATURE_CUT_REGEX |
55 | #include "xregex.h" | 56 | #include "xregex.h" |
56 | #else | ||
57 | #define regex_t int | ||
58 | typedef struct { int rm_eo, rm_so; } regmatch_t; | ||
59 | #define xregcomp(x, ...) *(x) = 0 | ||
60 | #define regexec(...) 0 | ||
61 | #endif | 57 | #endif |
62 | 58 | ||
63 | /* This is a NOEXEC applet. Be very careful! */ | 59 | /* This is a NOEXEC applet. Be very careful! */ |
@@ -74,6 +70,8 @@ typedef struct { int rm_eo, rm_so; } regmatch_t; | |||
74 | #define OPT_NOSORT (1 << 6) | 70 | #define OPT_NOSORT (1 << 6) |
75 | #define OPT_REGEX ((1 << 7) * ENABLE_FEATURE_CUT_REGEX) | 71 | #define OPT_REGEX ((1 << 7) * ENABLE_FEATURE_CUT_REGEX) |
76 | 72 | ||
73 | #define opt_REGEX (option_mask32 & OPT_REGEX) | ||
74 | |||
77 | struct cut_list { | 75 | struct cut_list { |
78 | int startpos; | 76 | int startpos; |
79 | int endpos; | 77 | int endpos; |
@@ -88,13 +86,8 @@ static int cmpfunc(const void *a, const void *b) | |||
88 | static void cut_file(FILE *file, const char *delim, const char *odelim, | 86 | static void cut_file(FILE *file, const char *delim, const char *odelim, |
89 | const struct cut_list *cut_list, unsigned nlists) | 87 | const struct cut_list *cut_list, unsigned nlists) |
90 | { | 88 | { |
91 | #define opt_REGEX (option_mask32 & OPT_REGEX) | ||
92 | char *line; | 89 | char *line; |
93 | unsigned linenum = 0; /* keep these zero-based to be consistent */ | 90 | unsigned linenum = 0; /* keep these zero-based to be consistent */ |
94 | regex_t reg; | ||
95 | |||
96 | if (opt_REGEX) | ||
97 | xregcomp(®, delim, REG_EXTENDED); | ||
98 | 91 | ||
99 | /* go through every line in the file */ | 92 | /* go through every line in the file */ |
100 | while ((line = xmalloc_fgetline(file)) != NULL) { | 93 | while ((line = xmalloc_fgetline(file)) != NULL) { |
@@ -121,7 +114,7 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
121 | } | 114 | } |
122 | } | 115 | } |
123 | free(printed); | 116 | free(printed); |
124 | } else if (*delim == '\n') { /* cut by lines */ | 117 | } else if (!opt_REGEX && *delim == '\n') { /* cut by lines */ |
125 | int spos = cut_list[cl_pos].startpos; | 118 | int spos = cut_list[cl_pos].startpos; |
126 | 119 | ||
127 | /* get out if we have no more lists to process or if the lines | 120 | /* get out if we have no more lists to process or if the lines |
@@ -181,20 +174,24 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
181 | /* else: will print entire line */ | 174 | /* else: will print entire line */ |
182 | } else if (dcount < cut_list[cl_pos].startpos) | 175 | } else if (dcount < cut_list[cl_pos].startpos) |
183 | start = linelen; /* do not print */ | 176 | start = linelen; /* do not print */ |
184 | end = linelen; | 177 | end = linelen; /* print up to end */ |
185 | } else { | 178 | } else { |
186 | /* Find next delimiter */ | 179 | /* Find next delimiter */ |
180 | #if ENABLE_FEATURE_CUT_REGEX | ||
187 | if (opt_REGEX) { | 181 | if (opt_REGEX) { |
188 | regmatch_t rr = {-1, -1}; | 182 | regmatch_t rr = {-1, -1}; |
183 | regex_t *reg = (void*) delim; | ||
189 | 184 | ||
190 | if (!regexec(®, line + next, 1, &rr, REG_NOTBOL|REG_NOTEOL)) { | 185 | if (regexec(reg, line + next, 1, &rr, REG_NOTBOL|REG_NOTEOL) != 0) { |
191 | end = next + rr.rm_so; | 186 | /* not found, go to "end of line" logic */ |
192 | next += rr.rm_eo; | ||
193 | } else { | ||
194 | next = linelen; | 187 | next = linelen; |
195 | continue; | 188 | continue; |
196 | } | 189 | } |
197 | } else { | 190 | end = next + rr.rm_so; |
191 | next += rr.rm_eo; | ||
192 | } else | ||
193 | #endif | ||
194 | { | ||
198 | end = next++; | 195 | end = next++; |
199 | if (line[end] != *delim) | 196 | if (line[end] != *delim) |
200 | continue; | 197 | continue; |
@@ -224,7 +221,6 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
224 | linenum++; | 221 | linenum++; |
225 | free(line); | 222 | free(line); |
226 | } /* while (got line) */ | 223 | } /* while (got line) */ |
227 | #undef opt_REGEX | ||
228 | } | 224 | } |
229 | 225 | ||
230 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 226 | int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -237,6 +233,9 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
237 | const char *delim = NULL; | 233 | const char *delim = NULL; |
238 | const char *odelim = NULL; | 234 | const char *odelim = NULL; |
239 | unsigned opt; | 235 | unsigned opt; |
236 | #if ENABLE_FEATURE_CUT_REGEX | ||
237 | regex_t reg; | ||
238 | #endif | ||
240 | 239 | ||
241 | #define ARG "bcf"IF_FEATURE_CUT_REGEX("F") | 240 | #define ARG "bcf"IF_FEATURE_CUT_REGEX("F") |
242 | opt = getopt32(argv, "^" | 241 | opt = getopt32(argv, "^" |
@@ -328,6 +327,13 @@ int cut_main(int argc UNUSED_PARAM, char **argv) | |||
328 | qsort(cut_list, nlists, sizeof(cut_list[0]), cmpfunc); | 327 | qsort(cut_list, nlists, sizeof(cut_list[0]), cmpfunc); |
329 | } | 328 | } |
330 | 329 | ||
330 | #if ENABLE_FEATURE_CUT_REGEX | ||
331 | if (opt & OPT_REGEX) { | ||
332 | xregcomp(®, delim, REG_EXTENDED); | ||
333 | delim = (void*) ® | ||
334 | } | ||
335 | #endif | ||
336 | |||
331 | { | 337 | { |
332 | exitcode_t retval = EXIT_SUCCESS; | 338 | exitcode_t retval = EXIT_SUCCESS; |
333 | 339 | ||