diff options
author | Mark Whitley <markw@lineo.com> | 2000-07-13 19:58:04 +0000 |
---|---|---|
committer | Mark Whitley <markw@lineo.com> | 2000-07-13 19:58:04 +0000 |
commit | 06f3529ada8c564673eb2d551b9979b3d65a7475 (patch) | |
tree | cc2b443fb7532f7ef7c3471f6fbf0d7f3879a9c2 | |
parent | 156959ea938f2db927ed49ec19a4f993a30591bf (diff) | |
download | busybox-w32-06f3529ada8c564673eb2d551b9979b3d65a7475.tar.gz busybox-w32-06f3529ada8c564673eb2d551b9979b3d65a7475.tar.bz2 busybox-w32-06f3529ada8c564673eb2d551b9979b3d65a7475.zip |
Minor code reorg: Changed the interface to index_of_next_unescaped_slash to an
interface that seems a little more sensible to me. Also broke out s///
expression parsing into it's own subroutine.
-rw-r--r-- | editors/sed.c | 106 | ||||
-rw-r--r-- | sed.c | 106 |
2 files changed, 116 insertions, 96 deletions
diff --git a/editors/sed.c b/editors/sed.c index 21f868167..8ae34f8c7 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -162,7 +162,7 @@ static char *trim_str(const char *str) | |||
162 | * index_of_unescaped_slash - walks left to right through a string beginning | 162 | * index_of_unescaped_slash - walks left to right through a string beginning |
163 | * at a specified index and returns the index of the next unescaped slash. | 163 | * at a specified index and returns the index of the next unescaped slash. |
164 | */ | 164 | */ |
165 | static int index_of_next_unescaped_slash(int idx, const char *str) | 165 | static int index_of_next_unescaped_slash(const char *str, int idx) |
166 | { | 166 | { |
167 | do { | 167 | do { |
168 | idx++; | 168 | idx++; |
@@ -196,7 +196,7 @@ static int get_address(const char *str, int *line, regex_t **regex) | |||
196 | idx++; | 196 | idx++; |
197 | } | 197 | } |
198 | else if (my_str[idx] == '/') { | 198 | else if (my_str[idx] == '/') { |
199 | idx = index_of_next_unescaped_slash(idx, my_str); | 199 | idx = index_of_next_unescaped_slash(my_str, idx); |
200 | if (idx == -1) | 200 | if (idx == -1) |
201 | fatalError("unterminated match expression\n"); | 201 | fatalError("unterminated match expression\n"); |
202 | my_str[idx] = '\0'; | 202 | my_str[idx] = '\0'; |
@@ -222,6 +222,59 @@ static char *strdup_substr(const char *str, int start, int end) | |||
222 | return newstr; | 222 | return newstr; |
223 | } | 223 | } |
224 | 224 | ||
225 | static void parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr) | ||
226 | { | ||
227 | int oldidx, cflags = REG_NEWLINE; | ||
228 | char *match; | ||
229 | int idx = 0; | ||
230 | |||
231 | /* | ||
232 | * the string that gets passed to this function should look like this: | ||
233 | * s/match/replace/gI | ||
234 | * || | || | ||
235 | * mandatory optional | ||
236 | * | ||
237 | * (all three of the '/' slashes are mandatory) | ||
238 | */ | ||
239 | |||
240 | /* verify that the 's' is followed by a 'slash' */ | ||
241 | if (substr[++idx] != '/') | ||
242 | fatalError("bad format in substitution expression\n"); | ||
243 | |||
244 | /* save the match string */ | ||
245 | oldidx = idx+1; | ||
246 | idx = index_of_next_unescaped_slash(substr, idx); | ||
247 | if (idx == -1) | ||
248 | fatalError("bad format in substitution expression\n"); | ||
249 | match = strdup_substr(substr, oldidx, idx); | ||
250 | |||
251 | /* save the replacement string */ | ||
252 | oldidx = idx+1; | ||
253 | idx = index_of_next_unescaped_slash(substr, idx); | ||
254 | if (idx == -1) | ||
255 | fatalError("bad format in substitution expression\n"); | ||
256 | sed_cmd->replace = strdup_substr(substr, oldidx, idx); | ||
257 | |||
258 | /* process the flags */ | ||
259 | while (substr[++idx]) { | ||
260 | switch (substr[idx]) { | ||
261 | case 'g': | ||
262 | sed_cmd->sub_g = 1; | ||
263 | break; | ||
264 | case 'I': | ||
265 | cflags |= REG_ICASE; | ||
266 | break; | ||
267 | default: | ||
268 | fatalError("bad option in substitution expression\n"); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /* compile the regex */ | ||
273 | sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); | ||
274 | xregcomp(sed_cmd->sub_match, match, cflags); | ||
275 | free(match); | ||
276 | } | ||
277 | |||
225 | static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | 278 | static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) |
226 | { | 279 | { |
227 | int idx = 0; | 280 | int idx = 0; |
@@ -246,53 +299,10 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | |||
246 | if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ | 299 | if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ |
247 | fatalError("invalid command\n"); | 300 | fatalError("invalid command\n"); |
248 | sed_cmd->cmd = cmdstr[idx]; | 301 | sed_cmd->cmd = cmdstr[idx]; |
249 | /* special-case handling for 's' */ | ||
250 | if (sed_cmd->cmd == 's') { | ||
251 | int oldidx, cflags = REG_NEWLINE; | ||
252 | char *match; | ||
253 | /* format for substitution is: | ||
254 | * s/match/replace/gI | ||
255 | * | || | ||
256 | * mandatory optional | ||
257 | */ | ||
258 | |||
259 | /* verify that we have an 's' followed by a 'slash' */ | ||
260 | if (cmdstr[++idx] != '/') | ||
261 | fatalError("bad format in substitution expression\n"); | ||
262 | |||
263 | /* save the match string */ | ||
264 | oldidx = idx+1; | ||
265 | idx = index_of_next_unescaped_slash(idx, cmdstr); | ||
266 | if (idx == -1) | ||
267 | fatalError("bad format in substitution expression\n"); | ||
268 | match = strdup_substr(cmdstr, oldidx, idx); | ||
269 | 302 | ||
270 | /* save the replacement string */ | 303 | /* special-case handling for (s)ubstitution */ |
271 | oldidx = idx+1; | 304 | if (sed_cmd->cmd == 's') |
272 | idx = index_of_next_unescaped_slash(idx, cmdstr); | 305 | parse_subst_cmd(sed_cmd, &cmdstr[idx]); |
273 | if (idx == -1) | ||
274 | fatalError("bad format in substitution expression\n"); | ||
275 | sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx); | ||
276 | |||
277 | /* process the flags */ | ||
278 | while (cmdstr[++idx]) { | ||
279 | switch (cmdstr[idx]) { | ||
280 | case 'g': | ||
281 | sed_cmd->sub_g = 1; | ||
282 | break; | ||
283 | case 'I': | ||
284 | cflags |= REG_ICASE; | ||
285 | break; | ||
286 | default: | ||
287 | fatalError("bad option in substitution expression\n"); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* compile the regex */ | ||
292 | sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); | ||
293 | xregcomp(sed_cmd->sub_match, match, cflags); | ||
294 | free(match); | ||
295 | } | ||
296 | } | 306 | } |
297 | 307 | ||
298 | static void add_cmd_str(const char *cmdstr) | 308 | static void add_cmd_str(const char *cmdstr) |
@@ -162,7 +162,7 @@ static char *trim_str(const char *str) | |||
162 | * index_of_unescaped_slash - walks left to right through a string beginning | 162 | * index_of_unescaped_slash - walks left to right through a string beginning |
163 | * at a specified index and returns the index of the next unescaped slash. | 163 | * at a specified index and returns the index of the next unescaped slash. |
164 | */ | 164 | */ |
165 | static int index_of_next_unescaped_slash(int idx, const char *str) | 165 | static int index_of_next_unescaped_slash(const char *str, int idx) |
166 | { | 166 | { |
167 | do { | 167 | do { |
168 | idx++; | 168 | idx++; |
@@ -196,7 +196,7 @@ static int get_address(const char *str, int *line, regex_t **regex) | |||
196 | idx++; | 196 | idx++; |
197 | } | 197 | } |
198 | else if (my_str[idx] == '/') { | 198 | else if (my_str[idx] == '/') { |
199 | idx = index_of_next_unescaped_slash(idx, my_str); | 199 | idx = index_of_next_unescaped_slash(my_str, idx); |
200 | if (idx == -1) | 200 | if (idx == -1) |
201 | fatalError("unterminated match expression\n"); | 201 | fatalError("unterminated match expression\n"); |
202 | my_str[idx] = '\0'; | 202 | my_str[idx] = '\0'; |
@@ -222,6 +222,59 @@ static char *strdup_substr(const char *str, int start, int end) | |||
222 | return newstr; | 222 | return newstr; |
223 | } | 223 | } |
224 | 224 | ||
225 | static void parse_subst_cmd(struct sed_cmd *sed_cmd, const char *substr) | ||
226 | { | ||
227 | int oldidx, cflags = REG_NEWLINE; | ||
228 | char *match; | ||
229 | int idx = 0; | ||
230 | |||
231 | /* | ||
232 | * the string that gets passed to this function should look like this: | ||
233 | * s/match/replace/gI | ||
234 | * || | || | ||
235 | * mandatory optional | ||
236 | * | ||
237 | * (all three of the '/' slashes are mandatory) | ||
238 | */ | ||
239 | |||
240 | /* verify that the 's' is followed by a 'slash' */ | ||
241 | if (substr[++idx] != '/') | ||
242 | fatalError("bad format in substitution expression\n"); | ||
243 | |||
244 | /* save the match string */ | ||
245 | oldidx = idx+1; | ||
246 | idx = index_of_next_unescaped_slash(substr, idx); | ||
247 | if (idx == -1) | ||
248 | fatalError("bad format in substitution expression\n"); | ||
249 | match = strdup_substr(substr, oldidx, idx); | ||
250 | |||
251 | /* save the replacement string */ | ||
252 | oldidx = idx+1; | ||
253 | idx = index_of_next_unescaped_slash(substr, idx); | ||
254 | if (idx == -1) | ||
255 | fatalError("bad format in substitution expression\n"); | ||
256 | sed_cmd->replace = strdup_substr(substr, oldidx, idx); | ||
257 | |||
258 | /* process the flags */ | ||
259 | while (substr[++idx]) { | ||
260 | switch (substr[idx]) { | ||
261 | case 'g': | ||
262 | sed_cmd->sub_g = 1; | ||
263 | break; | ||
264 | case 'I': | ||
265 | cflags |= REG_ICASE; | ||
266 | break; | ||
267 | default: | ||
268 | fatalError("bad option in substitution expression\n"); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /* compile the regex */ | ||
273 | sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); | ||
274 | xregcomp(sed_cmd->sub_match, match, cflags); | ||
275 | free(match); | ||
276 | } | ||
277 | |||
225 | static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | 278 | static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) |
226 | { | 279 | { |
227 | int idx = 0; | 280 | int idx = 0; |
@@ -246,53 +299,10 @@ static void parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr) | |||
246 | if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ | 299 | if (!strchr("pds", cmdstr[idx])) /* <-- XXX add new commands here */ |
247 | fatalError("invalid command\n"); | 300 | fatalError("invalid command\n"); |
248 | sed_cmd->cmd = cmdstr[idx]; | 301 | sed_cmd->cmd = cmdstr[idx]; |
249 | /* special-case handling for 's' */ | ||
250 | if (sed_cmd->cmd == 's') { | ||
251 | int oldidx, cflags = REG_NEWLINE; | ||
252 | char *match; | ||
253 | /* format for substitution is: | ||
254 | * s/match/replace/gI | ||
255 | * | || | ||
256 | * mandatory optional | ||
257 | */ | ||
258 | |||
259 | /* verify that we have an 's' followed by a 'slash' */ | ||
260 | if (cmdstr[++idx] != '/') | ||
261 | fatalError("bad format in substitution expression\n"); | ||
262 | |||
263 | /* save the match string */ | ||
264 | oldidx = idx+1; | ||
265 | idx = index_of_next_unescaped_slash(idx, cmdstr); | ||
266 | if (idx == -1) | ||
267 | fatalError("bad format in substitution expression\n"); | ||
268 | match = strdup_substr(cmdstr, oldidx, idx); | ||
269 | 302 | ||
270 | /* save the replacement string */ | 303 | /* special-case handling for (s)ubstitution */ |
271 | oldidx = idx+1; | 304 | if (sed_cmd->cmd == 's') |
272 | idx = index_of_next_unescaped_slash(idx, cmdstr); | 305 | parse_subst_cmd(sed_cmd, &cmdstr[idx]); |
273 | if (idx == -1) | ||
274 | fatalError("bad format in substitution expression\n"); | ||
275 | sed_cmd->replace = strdup_substr(cmdstr, oldidx, idx); | ||
276 | |||
277 | /* process the flags */ | ||
278 | while (cmdstr[++idx]) { | ||
279 | switch (cmdstr[idx]) { | ||
280 | case 'g': | ||
281 | sed_cmd->sub_g = 1; | ||
282 | break; | ||
283 | case 'I': | ||
284 | cflags |= REG_ICASE; | ||
285 | break; | ||
286 | default: | ||
287 | fatalError("bad option in substitution expression\n"); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* compile the regex */ | ||
292 | sed_cmd->sub_match = (regex_t *)xmalloc(sizeof(regex_t)); | ||
293 | xregcomp(sed_cmd->sub_match, match, cflags); | ||
294 | free(match); | ||
295 | } | ||
296 | } | 306 | } |
297 | 307 | ||
298 | static void add_cmd_str(const char *cmdstr) | 308 | static void add_cmd_str(const char *cmdstr) |