diff options
author | Rob Landley <rob@landley.net> | 2005-05-09 21:42:42 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2005-05-09 21:42:42 +0000 |
commit | 540d3f60f378ed26962501c33b335623fe5fb0fa (patch) | |
tree | d1d847dde8db22ab7af9a24fb018250bb51060fb /coreutils/expr.c | |
parent | b9dfb8c03febea78ab1924b4924c381ca983891c (diff) | |
download | busybox-w32-540d3f60f378ed26962501c33b335623fe5fb0fa.tar.gz busybox-w32-540d3f60f378ed26962501c33b335623fe5fb0fa.tar.bz2 busybox-w32-540d3f60f378ed26962501c33b335623fe5fb0fa.zip |
Patch from Shaun Jackman:
> This patch modfies expr to use portable POSIX regex rather than BSD
> regex.
...
> This updated patch implements an anchored regex by checking that the
> match starts at offset 0.
More to the point, this patch uses the same regex that sed.c is already using
(opportunity to suck in less library code), and even building a dynamically
linked busybox with just expr the result is a slightly smaller binary (by 94
bytes, I dunno what nm --size-sort has to say about it because I didn't build
with debug info, since that changes the binary size a lot by disabling
optimization...)
Your mileage may vary. Handle with caution. Do not taunt happy fun ball.
Diffstat (limited to 'coreutils/expr.c')
-rw-r--r-- | coreutils/expr.c | 37 |
1 files changed, 15 insertions, 22 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c index cbbd4cd03..3f052d92a 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -245,10 +245,9 @@ static int arithmetic_common (VALUE *l, VALUE *r, int op) | |||
245 | static VALUE *docolon (VALUE *sv, VALUE *pv) | 245 | static VALUE *docolon (VALUE *sv, VALUE *pv) |
246 | { | 246 | { |
247 | VALUE *v; | 247 | VALUE *v; |
248 | const char *errmsg; | 248 | regex_t re_buffer; |
249 | struct re_pattern_buffer re_buffer; | 249 | const int NMATCH = 2; |
250 | struct re_registers re_regs; | 250 | regmatch_t re_regs[NMATCH]; |
251 | int len; | ||
252 | 251 | ||
253 | tostring (sv); | 252 | tostring (sv); |
254 | tostring (pv); | 253 | tostring (pv); |
@@ -260,27 +259,22 @@ of a basic regular expression is not portable; it is being ignored", | |||
260 | pv->u.s); | 259 | pv->u.s); |
261 | } | 260 | } |
262 | 261 | ||
263 | len = strlen (pv->u.s); | ||
264 | memset (&re_buffer, 0, sizeof (re_buffer)); | 262 | memset (&re_buffer, 0, sizeof (re_buffer)); |
265 | memset (&re_regs, 0, sizeof (re_regs)); | 263 | memset (re_regs, 0, sizeof (*re_regs)); |
266 | re_buffer.allocated = 2 * len; | 264 | if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) |
267 | re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated); | 265 | bb_error_msg_and_die("Invalid regular expression"); |
268 | re_buffer.translate = 0; | 266 | |
269 | re_syntax_options = RE_SYNTAX_POSIX_BASIC; | 267 | /* expr uses an anchored pattern match, so check that there was a |
270 | errmsg = re_compile_pattern (pv->u.s, len, &re_buffer); | 268 | * match and that the match starts at offset 0. */ |
271 | if (errmsg) { | 269 | if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && |
272 | bb_error_msg_and_die("%s", errmsg); | 270 | re_regs[0].rm_so == 0) { |
273 | } | ||
274 | |||
275 | len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs); | ||
276 | if (len >= 0) { | ||
277 | /* Were \(...\) used? */ | 271 | /* Were \(...\) used? */ |
278 | if (re_buffer.re_nsub > 0) { /* was (re_regs.start[1] >= 0) */ | 272 | if (re_buffer.re_nsub > 0) { |
279 | sv->u.s[re_regs.end[1]] = '\0'; | 273 | sv->u.s[re_regs[1].rm_eo] = '\0'; |
280 | v = str_value (sv->u.s + re_regs.start[1]); | 274 | v = str_value (sv->u.s + re_regs[1].rm_so); |
281 | } | 275 | } |
282 | else | 276 | else |
283 | v = int_value (len); | 277 | v = int_value (re_regs[0].rm_eo); |
284 | } | 278 | } |
285 | else { | 279 | else { |
286 | /* Match failed -- return the right kind of null. */ | 280 | /* Match failed -- return the right kind of null. */ |
@@ -289,7 +283,6 @@ of a basic regular expression is not portable; it is being ignored", | |||
289 | else | 283 | else |
290 | v = int_value (0); | 284 | v = int_value (0); |
291 | } | 285 | } |
292 | free (re_buffer.buffer); | ||
293 | return v; | 286 | return v; |
294 | } | 287 | } |
295 | 288 | ||