214 |
|
|
215 |
static VALUE *docolon(VALUE *sv, VALUE *pv) |
static VALUE *docolon(VALUE *sv, VALUE *pv) |
216 |
{ |
{ |
217 |
|
enum { NMATCH = 2 }; |
218 |
VALUE *v; |
VALUE *v; |
219 |
regex_t re_buffer; |
regex_t re_buffer; |
|
const int NMATCH = 2; |
|
220 |
regmatch_t re_regs[NMATCH]; |
regmatch_t re_regs[NMATCH]; |
221 |
|
|
222 |
tostring(sv); |
tostring(sv); |
223 |
tostring(pv); |
tostring(pv); |
224 |
|
|
225 |
if (pv->u.s[0] == '^') { |
if (pv->u.s[0] == '^') { |
226 |
bb_error_msg("\ |
bb_error_msg( |
227 |
warning: unportable BRE: `%s': using `^' as the first character\n\ |
"warning: '%s': using '^' as the first character\n" |
228 |
of a basic regular expression is not portable; it is being ignored", pv->u.s); |
"of a basic regular expression is not portable; it is ignored", pv->u.s); |
229 |
} |
} |
230 |
|
|
231 |
memset(&re_buffer, 0, sizeof(re_buffer)); |
memset(&re_buffer, 0, sizeof(re_buffer)); |
232 |
memset(re_regs, 0, sizeof(*re_regs)); |
memset(re_regs, 0, sizeof(re_regs)); |
233 |
xregcomp(&re_buffer, pv->u.s, 0); |
xregcomp(&re_buffer, pv->u.s, 0); |
234 |
|
|
235 |
/* expr uses an anchored pattern match, so check that there was a |
/* expr uses an anchored pattern match, so check that there was a |
238 |
&& re_regs[0].rm_so == 0 |
&& re_regs[0].rm_so == 0 |
239 |
) { |
) { |
240 |
/* Were \(...\) used? */ |
/* Were \(...\) used? */ |
241 |
if (re_buffer.re_nsub > 0) { |
if (re_buffer.re_nsub > 0 && re_regs[1].rm_so >= 0) { |
242 |
sv->u.s[re_regs[1].rm_eo] = '\0'; |
sv->u.s[re_regs[1].rm_eo] = '\0'; |
243 |
v = str_value(sv->u.s + re_regs[1].rm_so); |
v = str_value(sv->u.s + re_regs[1].rm_so); |
244 |
} else { |
} else { |
251 |
else |
else |
252 |
v = int_value(0); |
v = int_value(0); |
253 |
} |
} |
254 |
//FIXME: sounds like here is a bit missing: regfree(&re_buffer); |
regfree(&re_buffer); |
255 |
return v; |
return v; |
256 |
} |
} |
257 |
|
|
481 |
} |
} |
482 |
|
|
483 |
int expr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
int expr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
484 |
int expr_main(int argc, char **argv) |
int expr_main(int argc UNUSED_PARAM, char **argv) |
485 |
{ |
{ |
486 |
VALUE *v; |
VALUE *v; |
487 |
|
|
488 |
if (argc == 1) { |
xfunc_error_retval = 2; /* coreutils compat */ |
489 |
|
G.args = argv + 1; |
490 |
|
if (*G.args == NULL) { |
491 |
bb_error_msg_and_die("too few arguments"); |
bb_error_msg_and_die("too few arguments"); |
492 |
} |
} |
|
|
|
|
G.args = argv + 1; |
|
|
|
|
493 |
v = eval(); |
v = eval(); |
494 |
if (*G.args) |
if (*G.args) |
495 |
bb_error_msg_and_die("syntax error"); |
bb_error_msg_and_die("syntax error"); |
|
|
|
496 |
if (v->type == INTEGER) |
if (v->type == INTEGER) |
497 |
printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); |
printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); |
498 |
else |
else |
499 |
puts(v->u.s); |
puts(v->u.s); |
|
|
|
500 |
fflush_stdout_and_exit(null(v)); |
fflush_stdout_and_exit(null(v)); |
501 |
} |
} |