aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2024-12-10 02:36:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2024-12-10 02:55:58 +0100
commit470f00955212368cb688832e2e4b1fdd165e9ec6 (patch)
treea237585b23102a44cff5cae5829af7fc0e40e4c9
parent55fc6a18da068a67b1854e4ca6fbb8d92e3af745 (diff)
downloadbusybox-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.c42
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
58typedef 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
77struct cut_list { 75struct 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)
88static void cut_file(FILE *file, const char *delim, const char *odelim, 86static 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(&reg, 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(&reg, 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
230int cut_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 226int 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(&reg, delim, REG_EXTENDED);
333 delim = (void*) &reg;
334 }
335#endif
336
331 { 337 {
332 exitcode_t retval = EXIT_SUCCESS; 338 exitcode_t retval = EXIT_SUCCESS;
333 339