diff options
author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-03-09 08:44:49 +0000 |
---|---|---|
committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-03-09 08:44:49 +0000 |
commit | 98fc9f4df886aaf086fd07b54b637dd8fa9c8a16 (patch) | |
tree | bfb09cc9259cee13eb88f7f7fc67f0f3b3112e26 | |
parent | eebcaa61ea3d02db3e43ae7c97644858451f4d9a (diff) | |
download | busybox-w32-98fc9f4df886aaf086fd07b54b637dd8fa9c8a16.tar.gz busybox-w32-98fc9f4df886aaf086fd07b54b637dd8fa9c8a16.tar.bz2 busybox-w32-98fc9f4df886aaf086fd07b54b637dd8fa9c8a16.zip |
redo get_addres(). save some space. possible fix a bug where the command might be set to 0 if no second address is given. dont parse sed_cmd struct to get_address, we only need the delim field.
git-svn-id: svn://busybox.net/trunk/busybox@6722 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | editors/sed.c | 56 |
1 files changed, 25 insertions, 31 deletions
diff --git a/editors/sed.c b/editors/sed.c index e412cf919..5ae7993c7 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -148,7 +148,7 @@ static void destroy_cmd_strs(void) | |||
148 | * expression delimiter (typically a forward * slash ('/')) not preceeded by | 148 | * expression delimiter (typically a forward * slash ('/')) not preceeded by |
149 | * a backslash ('\'). | 149 | * a backslash ('\'). |
150 | */ | 150 | */ |
151 | static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed_cmd, const char *str, int idx) | 151 | static int index_of_next_unescaped_regexp_delim(const char delimiter, const char *str, int idx) |
152 | { | 152 | { |
153 | int bracket = -1; | 153 | int bracket = -1; |
154 | int escaped = 0; | 154 | int escaped = 0; |
@@ -165,7 +165,7 @@ static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed | |||
165 | escaped = 1; | 165 | escaped = 1; |
166 | else if (ch == '[') | 166 | else if (ch == '[') |
167 | bracket = idx; | 167 | bracket = idx; |
168 | else if (ch == sed_cmd->delimiter) | 168 | else if (ch == delimiter) |
169 | return idx; | 169 | return idx; |
170 | } | 170 | } |
171 | 171 | ||
@@ -176,46 +176,35 @@ static int index_of_next_unescaped_regexp_delim(const struct sed_cmd * const sed | |||
176 | /* | 176 | /* |
177 | * returns the index in the string just past where the address ends. | 177 | * returns the index in the string just past where the address ends. |
178 | */ | 178 | */ |
179 | static int get_address(struct sed_cmd *sed_cmd, const char *str, int *linenum, regex_t **regex) | 179 | static int get_address(char *delimiter, char *my_str, int *linenum, regex_t **regex) |
180 | { | 180 | { |
181 | char *my_str = xstrdup(str); | 181 | int idx = 0; |
182 | int idx = 0, idx_start = 1; | ||
183 | char olddelimiter; | ||
184 | olddelimiter = sed_cmd->delimiter; | ||
185 | sed_cmd->delimiter = '/'; | ||
186 | |||
187 | if (isdigit(my_str[idx])) { | 182 | if (isdigit(my_str[idx])) { |
188 | do { | 183 | char *endstr; |
189 | idx++; | 184 | *linenum = strtol(my_str, &endstr, 10); |
190 | } while (isdigit(my_str[idx])); | 185 | /* endstr shouldnt ever equal NULL */ |
191 | my_str[idx] = 0; | 186 | idx = endstr - my_str; |
192 | *linenum = atoi(my_str); | ||
193 | } | 187 | } |
194 | else if (my_str[idx] == '$') { | 188 | else if (my_str[idx] == '$') { |
195 | *linenum = -1; | 189 | *linenum = -1; |
196 | idx++; | 190 | idx++; |
197 | } | 191 | } |
198 | else if (my_str[idx] == '/' || my_str[idx] == '\\') { | 192 | else if (my_str[idx] == '/' || my_str[idx] == '\\') { |
193 | int idx_start = 1; | ||
194 | |||
199 | if (my_str[idx] == '\\') { | 195 | if (my_str[idx] == '\\') { |
200 | idx_start++; | 196 | idx_start++; |
201 | sed_cmd-> delimiter = my_str[++idx]; | 197 | *delimiter = my_str[++idx]; |
202 | } | 198 | } |
203 | idx = index_of_next_unescaped_regexp_delim(sed_cmd, my_str, ++idx); | 199 | idx = index_of_next_unescaped_regexp_delim(*delimiter, my_str, ++idx); |
204 | if (idx == -1) | 200 | if (idx == -1) { |
205 | error_msg_and_die("unterminated match expression"); | 201 | error_msg_and_die("unterminated match expression"); |
202 | } | ||
206 | my_str[idx] = '\0'; | 203 | my_str[idx] = '\0'; |
207 | *regex = (regex_t *)xmalloc(sizeof(regex_t)); | 204 | *regex = (regex_t *)xmalloc(sizeof(regex_t)); |
208 | xregcomp(*regex, my_str+idx_start, REG_NEWLINE); | 205 | xregcomp(*regex, my_str+idx_start, REG_NEWLINE); |
209 | idx++; /* so it points to the next character after the last '/' */ | 206 | idx++; /* so it points to the next character after the last '/' */ |
210 | } | 207 | } |
211 | else { | ||
212 | error_msg("get_address: no address found in string\n" | ||
213 | "\t(you probably didn't check the string you passed me)"); | ||
214 | idx = -1; | ||
215 | } | ||
216 | |||
217 | free(my_str); | ||
218 | sed_cmd->delimiter = olddelimiter; | ||
219 | return idx; | 208 | return idx; |
220 | } | 209 | } |
221 | 210 | ||
@@ -244,7 +233,7 @@ static int parse_subst_cmd(struct sed_cmd * const sed_cmd, const char *substr) | |||
244 | 233 | ||
245 | /* save the match string */ | 234 | /* save the match string */ |
246 | oldidx = idx+1; | 235 | oldidx = idx+1; |
247 | idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx); | 236 | idx = index_of_next_unescaped_regexp_delim(sed_cmd->delimiter, substr, ++idx); |
248 | if (idx == -1) | 237 | if (idx == -1) |
249 | error_msg_and_die("bad format in substitution expression"); | 238 | error_msg_and_die("bad format in substitution expression"); |
250 | match = xstrndup(substr + oldidx, idx - oldidx); | 239 | match = xstrndup(substr + oldidx, idx - oldidx); |
@@ -263,7 +252,7 @@ static int parse_subst_cmd(struct sed_cmd * const sed_cmd, const char *substr) | |||
263 | 252 | ||
264 | /* save the replacement string */ | 253 | /* save the replacement string */ |
265 | oldidx = idx+1; | 254 | oldidx = idx+1; |
266 | idx = index_of_next_unescaped_regexp_delim(sed_cmd, substr, ++idx); | 255 | idx = index_of_next_unescaped_regexp_delim(sed_cmd->delimiter, substr, ++idx); |
267 | if (idx == -1) | 256 | if (idx == -1) |
268 | error_msg_and_die("bad format in substitution expression"); | 257 | error_msg_and_die("bad format in substitution expression"); |
269 | sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx); | 258 | sed_cmd->replace = xstrndup(substr + oldidx, idx - oldidx); |
@@ -391,7 +380,7 @@ static int parse_file_cmd(struct sed_cmd *sed_cmd, const char *filecmdstr) | |||
391 | } | 380 | } |
392 | 381 | ||
393 | 382 | ||
394 | static char *parse_cmd_str(struct sed_cmd * const sed_cmd, const char *const cmdstr) | 383 | static char *parse_cmd_str(struct sed_cmd * const sed_cmd, char *cmdstr) |
395 | { | 384 | { |
396 | int idx = 0; | 385 | int idx = 0; |
397 | 386 | ||
@@ -402,13 +391,18 @@ static char *parse_cmd_str(struct sed_cmd * const sed_cmd, const char *const cmd | |||
402 | */ | 391 | */ |
403 | 392 | ||
404 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ | 393 | /* first part (if present) is an address: either a '$', a number or a /regex/ */ |
405 | if ((cmdstr[idx] == '$') || (isdigit(cmdstr[idx])) || (cmdstr[idx] == '/') || ((cmdstr[idx] == '\\') && (cmdstr[idx+1] != '\\'))) | 394 | idx = get_address(&sed_cmd->delimiter, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); |
406 | idx = get_address(sed_cmd, cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); | ||
407 | 395 | ||
408 | /* second part (if present) will begin with a comma */ | 396 | /* second part (if present) will begin with a comma */ |
409 | if (cmdstr[idx] == ',') { | 397 | if (cmdstr[idx] == ',') { |
398 | int tmp_idx; | ||
410 | idx++; | 399 | idx++; |
411 | idx += get_address(sed_cmd, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match); | 400 | tmp_idx = get_address(&sed_cmd->delimiter, &cmdstr[idx], &sed_cmd->end_line, &sed_cmd->end_match); |
401 | if (tmp_idx == 0) { | ||
402 | error_msg_and_die("get_address: no address found in string\n" | ||
403 | "\t(you probably didn't check the string you passed me)"); | ||
404 | } | ||
405 | idx += tmp_idx; | ||
412 | } | 406 | } |
413 | 407 | ||
414 | /* skip whitespace before the command */ | 408 | /* skip whitespace before the command */ |