aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Whitley <markw@lineo.com>2000-07-11 16:53:56 +0000
committerMark Whitley <markw@lineo.com>2000-07-11 16:53:56 +0000
commitdf5f6ba1159f8c1af500fa1b8eb9c9646e4de2a6 (patch)
tree90005f171e95b4fc0eefca5171593ba0b105b3f7
parentda9841efc1e924ab3f645d931ae17c6d4aaf766f (diff)
downloadbusybox-w32-df5f6ba1159f8c1af500fa1b8eb9c9646e4de2a6.tar.gz
busybox-w32-df5f6ba1159f8c1af500fa1b8eb9c9646e4de2a6.tar.bz2
busybox-w32-df5f6ba1159f8c1af500fa1b8eb9c9646e4de2a6.zip
Applied patch from Matt Kraai which does the following:
- adds case-insensitive matching in sed s/// epxressions - consolodates common regcomp code in grep & sed into bb_regcomp and put in utility.c - cleans up a bunch of cruft
-rw-r--r--editors/sed.c133
-rw-r--r--findutils/grep.c15
-rw-r--r--grep.c15
-rw-r--r--internal.h3
-rw-r--r--sed.c133
-rw-r--r--utility.c16
6 files changed, 120 insertions, 195 deletions
diff --git a/editors/sed.c b/editors/sed.c
index 329f5ae8d..2fb243fb9 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -97,50 +97,6 @@ static const char sed_usage[] =
97#endif 97#endif
98 ; 98 ;
99 99
100#if 0
101/* Nuke from here { */
102
103
104/* get_line_from_file() - This function reads an entire line from a text file
105 * * up to a newline. It returns a malloc'ed char * which must be stored and
106 * * free'ed by the caller. */
107extern char *get_line_from_file(FILE *file)
108{
109 static const int GROWBY = 80; /* how large we will grow strings by */
110
111 int ch;
112 int idx = 0;
113 char *linebuf = NULL;
114 int linebufsz = 0;
115
116 while (1) {
117 ch = fgetc(file);
118 if (ch == EOF)
119 break;
120 /* grow the line buffer as necessary */
121 if (idx > linebufsz-2)
122 linebuf = realloc(linebuf, linebufsz += GROWBY);
123 linebuf[idx++] = (char)ch;
124 if ((char)ch == '\n')
125 break;
126 }
127
128 if (idx == 0)
129 return NULL;
130
131 linebuf[idx] = 0;
132 return linebuf;
133}
134
135static void usage(const char *string)
136{
137 printf("usage: %s\n", string);
138 exit(0);
139}
140
141/* } to here when we integrate this into busybox */
142#endif
143
144static void destroy_cmd_strs() 100static void destroy_cmd_strs()
145{ 101{
146 if (sed_cmds == NULL) 102 if (sed_cmds == NULL)
@@ -246,29 +202,15 @@ static int get_address(const char *str, int *line, regex_t **regex)
246 idx++; 202 idx++;
247 } 203 }
248 else if (my_str[idx] == '/') { 204 else if (my_str[idx] == '/') {
249 int ret;
250 idx = index_of_next_unescaped_slash(idx, my_str); 205 idx = index_of_next_unescaped_slash(idx, my_str);
251 if (idx == -1) { 206 if (idx == -1)
252 free(my_str);
253 exit_sed(1, "sed: unterminated match expression\n"); 207 exit_sed(1, "sed: unterminated match expression\n");
254 } 208 my_str[idx] = '\0';
255 my_str[idx] = 0; /* shave off the trailing '/' */ 209 *regex = (regex_t *)xmalloc(sizeof(regex_t));
256 my_str++; /* shave off the leading '/' */ 210 if (bb_regcomp(*regex, my_str+1, REG_NEWLINE) != 0) {
257 *regex = (regex_t *)malloc(sizeof(regex_t)); 211 free(my_str);
258 if ((ret = regcomp(*regex, my_str, 0)) != 0) {
259 /* error handling if regular expression couldn't be compiled */
260 int errmsgsz = regerror(ret, *regex, NULL, 0);
261 char *errmsg = malloc(errmsgsz);
262 if (errmsg == NULL) {
263 exit_sed(1, "sed: memory error\n");
264 }
265 regerror(ret, *regex, errmsg, errmsgsz);
266 fprintf(stderr, "sed: %s\n", errmsg);
267 free(errmsg);
268 exit_sed(1, NULL); 212 exit_sed(1, NULL);
269 } 213 }
270 my_str--; /* move my_str back so free() (below) won't barf */
271 idx++; /* advance idx one past the end of the /match/ */
272 } 214 }
273 else { 215 else {
274 fprintf(stderr, "sed.c:get_address: no address found in string\n"); 216 fprintf(stderr, "sed.c:get_address: no address found in string\n");
@@ -280,6 +222,15 @@ static int get_address(const char *str, int *line, regex_t **regex)
280 return idx; 222 return idx;
281} 223}
282 224
225static char *strdup_substr(const char *str, int start, int end)
226{
227 int size = end - start + 1;
228 char *newstr = xmalloc(size);
229 memcpy(newstr, str+start, size-1);
230 newstr[size-1] = '\0';
231 return newstr;
232}
233
283static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) 234static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
284{ 235{
285 int idx = 0; 236 int idx = 0;
@@ -306,10 +257,11 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
306 sed_cmd->cmd = cmdstr[idx]; 257 sed_cmd->cmd = cmdstr[idx];
307 /* special-case handling for 's' */ 258 /* special-case handling for 's' */
308 if (sed_cmd->cmd == 's') { 259 if (sed_cmd->cmd == 's') {
309 int oldidx; 260 int oldidx, cflags = REG_NEWLINE;
261 char *match;
310 /* format for substitution is: 262 /* format for substitution is:
311 * s/match/replace/g 263 * s/match/replace/gI
312 * | | 264 * | ||
313 * mandatory optional 265 * mandatory optional
314 */ 266 */
315 267
@@ -317,19 +269,41 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
317 if (cmdstr[++idx] != '/') 269 if (cmdstr[++idx] != '/')
318 exit_sed(1, "sed: bad format in substitution expression\n"); 270 exit_sed(1, "sed: bad format in substitution expression\n");
319 271
320 /* get the substitution part */ 272 /* save the match string */
321 idx += get_address(&cmdstr[idx], NULL, &sed_cmd->sub_match); 273 oldidx = idx+1;
274 idx = index_of_next_unescaped_slash(idx, cmdstr);
275 if (idx == -1)
276 exit_sed(1, "sed: bad format in substitution expression\n");
277 match = strdup_substr(cmdstr, oldidx, idx);
322 278
323 /* get the replacement part */ 279 /* save the replacement string */
324 oldidx = idx; 280 oldidx = idx+1;
325 idx = index_of_next_unescaped_slash(idx, cmdstr); 281 idx = index_of_next_unescaped_slash(idx, cmdstr);
326 sed_cmd->replace = (char *)malloc(idx - oldidx + 1); 282 if (idx == -1)
327 strncpy(sed_cmd->replace, &cmdstr[oldidx], idx - oldidx); 283 exit_sed(1, "sed: bad format in substitution expression\n");
328 sed_cmd->replace[idx - oldidx] = 0; 284 sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx);
329 285
330 /* store the 'g' if present */ 286 /* process the flags */
331 if (cmdstr[++idx] == 'g') 287 while (cmdstr[++idx]) {
332 sed_cmd->sub_g = 1; 288 switch (cmdstr[idx]) {
289 case 'g':
290 sed_cmd->sub_g = 1;
291 break;
292 case 'I':
293 cflags |= REG_ICASE;
294 break;
295 default:
296 exit_sed(1, "sed: bad option in substitution expression\n");
297 }
298 }
299
300 /* compile the regex */
301 sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
302 if (bb_regcomp(sed_cmd->sub_match, match, cflags) != 0) {
303 free(match);
304 exit_sed(1, NULL);
305 }
306 free(match);
333 } 307 }
334} 308}
335 309
@@ -553,10 +527,3 @@ extern int sed_main(int argc, char **argv)
553 /* not reached */ 527 /* not reached */
554 return 0; 528 return 0;
555} 529}
556
557#ifdef TEST_SED
558int main(int argc, char **argv)
559{
560 return sed_main(argc, argv);
561}
562#endif
diff --git a/findutils/grep.c b/findutils/grep.c
index 8d2c915be..dec365f05 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -104,7 +104,6 @@ extern int grep_main(int argc, char **argv)
104{ 104{
105 int opt; 105 int opt;
106 int reflags; 106 int reflags;
107 int ret;
108 107
109 /* do special-case option parsing */ 108 /* do special-case option parsing */
110 if (argv[1] && (strcmp(argv[1], "--help") == 0)) 109 if (argv[1] && (strcmp(argv[1], "--help") == 0))
@@ -147,20 +146,8 @@ extern int grep_main(int argc, char **argv)
147 reflags = REG_NOSUB | REG_NEWLINE; 146 reflags = REG_NOSUB | REG_NEWLINE;
148 if (ignore_case) 147 if (ignore_case)
149 reflags |= REG_ICASE; 148 reflags |= REG_ICASE;
150 if ((ret = regcomp(&regex, argv[optind], reflags)) != 0) { 149 if (bb_regcomp(&regex, argv[optind], reflags) != 0)
151 int errmsgsz = regerror(ret, &regex, NULL, 0);
152 char *errmsg = malloc(errmsgsz);
153 if (errmsg == NULL) {
154 fprintf(stderr, "grep: memory error\n");
155 regfree(&regex);
156 exit(1);
157 }
158 regerror(ret, &regex, errmsg, errmsgsz);
159 fprintf(stderr, "grep: %s\n", errmsg);
160 free(errmsg);
161 regfree(&regex);
162 exit(1); 150 exit(1);
163 }
164 151
165 /* argv[(optind+1)..(argc-1)] should be names of file to grep through. If 152 /* argv[(optind+1)..(argc-1)] should be names of file to grep through. If
166 * there is more than one file to grep, we will print the filenames */ 153 * there is more than one file to grep, we will print the filenames */
diff --git a/grep.c b/grep.c
index 8d2c915be..dec365f05 100644
--- a/grep.c
+++ b/grep.c
@@ -104,7 +104,6 @@ extern int grep_main(int argc, char **argv)
104{ 104{
105 int opt; 105 int opt;
106 int reflags; 106 int reflags;
107 int ret;
108 107
109 /* do special-case option parsing */ 108 /* do special-case option parsing */
110 if (argv[1] && (strcmp(argv[1], "--help") == 0)) 109 if (argv[1] && (strcmp(argv[1], "--help") == 0))
@@ -147,20 +146,8 @@ extern int grep_main(int argc, char **argv)
147 reflags = REG_NOSUB | REG_NEWLINE; 146 reflags = REG_NOSUB | REG_NEWLINE;
148 if (ignore_case) 147 if (ignore_case)
149 reflags |= REG_ICASE; 148 reflags |= REG_ICASE;
150 if ((ret = regcomp(&regex, argv[optind], reflags)) != 0) { 149 if (bb_regcomp(&regex, argv[optind], reflags) != 0)
151 int errmsgsz = regerror(ret, &regex, NULL, 0);
152 char *errmsg = malloc(errmsgsz);
153 if (errmsg == NULL) {
154 fprintf(stderr, "grep: memory error\n");
155 regfree(&regex);
156 exit(1);
157 }
158 regerror(ret, &regex, errmsg, errmsgsz);
159 fprintf(stderr, "grep: %s\n", errmsg);
160 free(errmsg);
161 regfree(&regex);
162 exit(1); 150 exit(1);
163 }
164 151
165 /* argv[(optind+1)..(argc-1)] should be names of file to grep through. If 152 /* argv[(optind+1)..(argc-1)] should be names of file to grep through. If
166 * there is more than one file to grep, we will print the filenames */ 153 * there is more than one file to grep, we will print the filenames */
diff --git a/internal.h b/internal.h
index 5864c47ac..4ef15325e 100644
--- a/internal.h
+++ b/internal.h
@@ -34,7 +34,7 @@
34#include <sys/stat.h> 34#include <sys/stat.h>
35#include <sys/param.h> 35#include <sys/param.h>
36#include <mntent.h> 36#include <mntent.h>
37 37#include <regex.h>
38 38
39/* Some useful definitions */ 39/* Some useful definitions */
40#define FALSE ((int) 1) 40#define FALSE ((int) 1)
@@ -259,6 +259,7 @@ extern int find_real_root_device_name(char* name);
259extern char *get_line_from_file(FILE *file); 259extern char *get_line_from_file(FILE *file);
260extern char process_escape_sequence(char **ptr); 260extern char process_escape_sequence(char **ptr);
261extern char *get_last_path_component(char *path); 261extern char *get_last_path_component(char *path);
262extern int bb_regcomp(regex_t *preg, const char *regex, int cflags);
262 263
263extern void *xmalloc (size_t size); 264extern void *xmalloc (size_t size);
264extern char *xstrdup (const char *s); 265extern char *xstrdup (const char *s);
diff --git a/sed.c b/sed.c
index 329f5ae8d..2fb243fb9 100644
--- a/sed.c
+++ b/sed.c
@@ -97,50 +97,6 @@ static const char sed_usage[] =
97#endif 97#endif
98 ; 98 ;
99 99
100#if 0
101/* Nuke from here { */
102
103
104/* get_line_from_file() - This function reads an entire line from a text file
105 * * up to a newline. It returns a malloc'ed char * which must be stored and
106 * * free'ed by the caller. */
107extern char *get_line_from_file(FILE *file)
108{
109 static const int GROWBY = 80; /* how large we will grow strings by */
110
111 int ch;
112 int idx = 0;
113 char *linebuf = NULL;
114 int linebufsz = 0;
115
116 while (1) {
117 ch = fgetc(file);
118 if (ch == EOF)
119 break;
120 /* grow the line buffer as necessary */
121 if (idx > linebufsz-2)
122 linebuf = realloc(linebuf, linebufsz += GROWBY);
123 linebuf[idx++] = (char)ch;
124 if ((char)ch == '\n')
125 break;
126 }
127
128 if (idx == 0)
129 return NULL;
130
131 linebuf[idx] = 0;
132 return linebuf;
133}
134
135static void usage(const char *string)
136{
137 printf("usage: %s\n", string);
138 exit(0);
139}
140
141/* } to here when we integrate this into busybox */
142#endif
143
144static void destroy_cmd_strs() 100static void destroy_cmd_strs()
145{ 101{
146 if (sed_cmds == NULL) 102 if (sed_cmds == NULL)
@@ -246,29 +202,15 @@ static int get_address(const char *str, int *line, regex_t **regex)
246 idx++; 202 idx++;
247 } 203 }
248 else if (my_str[idx] == '/') { 204 else if (my_str[idx] == '/') {
249 int ret;
250 idx = index_of_next_unescaped_slash(idx, my_str); 205 idx = index_of_next_unescaped_slash(idx, my_str);
251 if (idx == -1) { 206 if (idx == -1)
252 free(my_str);
253 exit_sed(1, "sed: unterminated match expression\n"); 207 exit_sed(1, "sed: unterminated match expression\n");
254 } 208 my_str[idx] = '\0';
255 my_str[idx] = 0; /* shave off the trailing '/' */ 209 *regex = (regex_t *)xmalloc(sizeof(regex_t));
256 my_str++; /* shave off the leading '/' */ 210 if (bb_regcomp(*regex, my_str+1, REG_NEWLINE) != 0) {
257 *regex = (regex_t *)malloc(sizeof(regex_t)); 211 free(my_str);
258 if ((ret = regcomp(*regex, my_str, 0)) != 0) {
259 /* error handling if regular expression couldn't be compiled */
260 int errmsgsz = regerror(ret, *regex, NULL, 0);
261 char *errmsg = malloc(errmsgsz);
262 if (errmsg == NULL) {
263 exit_sed(1, "sed: memory error\n");
264 }
265 regerror(ret, *regex, errmsg, errmsgsz);
266 fprintf(stderr, "sed: %s\n", errmsg);
267 free(errmsg);
268 exit_sed(1, NULL); 212 exit_sed(1, NULL);
269 } 213 }
270 my_str--; /* move my_str back so free() (below) won't barf */
271 idx++; /* advance idx one past the end of the /match/ */
272 } 214 }
273 else { 215 else {
274 fprintf(stderr, "sed.c:get_address: no address found in string\n"); 216 fprintf(stderr, "sed.c:get_address: no address found in string\n");
@@ -280,6 +222,15 @@ static int get_address(const char *str, int *line, regex_t **regex)
280 return idx; 222 return idx;
281} 223}
282 224
225static char *strdup_substr(const char *str, int start, int end)
226{
227 int size = end - start + 1;
228 char *newstr = xmalloc(size);
229 memcpy(newstr, str+start, size-1);
230 newstr[size-1] = '\0';
231 return newstr;
232}
233
283static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) 234static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
284{ 235{
285 int idx = 0; 236 int idx = 0;
@@ -306,10 +257,11 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
306 sed_cmd->cmd = cmdstr[idx]; 257 sed_cmd->cmd = cmdstr[idx];
307 /* special-case handling for 's' */ 258 /* special-case handling for 's' */
308 if (sed_cmd->cmd == 's') { 259 if (sed_cmd->cmd == 's') {
309 int oldidx; 260 int oldidx, cflags = REG_NEWLINE;
261 char *match;
310 /* format for substitution is: 262 /* format for substitution is:
311 * s/match/replace/g 263 * s/match/replace/gI
312 * | | 264 * | ||
313 * mandatory optional 265 * mandatory optional
314 */ 266 */
315 267
@@ -317,19 +269,41 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
317 if (cmdstr[++idx] != '/') 269 if (cmdstr[++idx] != '/')
318 exit_sed(1, "sed: bad format in substitution expression\n"); 270 exit_sed(1, "sed: bad format in substitution expression\n");
319 271
320 /* get the substitution part */ 272 /* save the match string */
321 idx += get_address(&cmdstr[idx], NULL, &sed_cmd->sub_match); 273 oldidx = idx+1;
274 idx = index_of_next_unescaped_slash(idx, cmdstr);
275 if (idx == -1)
276 exit_sed(1, "sed: bad format in substitution expression\n");
277 match = strdup_substr(cmdstr, oldidx, idx);
322 278
323 /* get the replacement part */ 279 /* save the replacement string */
324 oldidx = idx; 280 oldidx = idx+1;
325 idx = index_of_next_unescaped_slash(idx, cmdstr); 281 idx = index_of_next_unescaped_slash(idx, cmdstr);
326 sed_cmd->replace = (char *)malloc(idx - oldidx + 1); 282 if (idx == -1)
327 strncpy(sed_cmd->replace, &cmdstr[oldidx], idx - oldidx); 283 exit_sed(1, "sed: bad format in substitution expression\n");
328 sed_cmd->replace[idx - oldidx] = 0; 284 sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx);
329 285
330 /* store the 'g' if present */ 286 /* process the flags */
331 if (cmdstr[++idx] == 'g') 287 while (cmdstr[++idx]) {
332 sed_cmd->sub_g = 1; 288 switch (cmdstr[idx]) {
289 case 'g':
290 sed_cmd->sub_g = 1;
291 break;
292 case 'I':
293 cflags |= REG_ICASE;
294 break;
295 default:
296 exit_sed(1, "sed: bad option in substitution expression\n");
297 }
298 }
299
300 /* compile the regex */
301 sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t));
302 if (bb_regcomp(sed_cmd->sub_match, match, cflags) != 0) {
303 free(match);
304 exit_sed(1, NULL);
305 }
306 free(match);
333 } 307 }
334} 308}
335 309
@@ -553,10 +527,3 @@ extern int sed_main(int argc, char **argv)
553 /* not reached */ 527 /* not reached */
554 return 0; 528 return 0;
555} 529}
556
557#ifdef TEST_SED
558int main(int argc, char **argv)
559{
560 return sed_main(argc, argv);
561}
562#endif
diff --git a/utility.c b/utility.c
index 46907e46a..cbbc02f98 100644
--- a/utility.c
+++ b/utility.c
@@ -1721,6 +1721,22 @@ char *get_last_path_component(char *path)
1721} 1721}
1722#endif 1722#endif
1723 1723
1724#if defined BB_GREP || defined BB_SED
1725int bb_regcomp(regex_t *preg, const char *regex, int cflags)
1726{
1727 int ret;
1728 if ((ret = regcomp(preg, regex, cflags)) != 0) {
1729 int errmsgsz = regerror(ret, preg, NULL, 0);
1730 char *errmsg = xmalloc(errmsgsz);
1731 regerror(ret, preg, errmsg, errmsgsz);
1732 errorMsg("bb_regcomp: %s\n", errmsg);
1733 free(errmsg);
1734 regfree(preg);
1735 }
1736 return ret;
1737}
1738#endif
1739
1724/* END CODE */ 1740/* END CODE */
1725/* 1741/*
1726Local Variables: 1742Local Variables: