Share argument parsing in Regexp#initialize
and Regexp.linear_time?
This commit is contained in:
parent
bb4cbd0803
commit
454c00723a
Notes:
git
2022-12-22 06:51:19 +00:00
63
re.c
63
re.c
@ -3750,6 +3750,15 @@ set_timeout(rb_hrtime_t *hrt, VALUE timeout)
|
|||||||
double2hrtime(hrt, timeout_d);
|
double2hrtime(hrt, timeout_d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct reg_init_args {
|
||||||
|
VALUE src, str, timeout;
|
||||||
|
rb_encoding *enc;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args);
|
||||||
|
static VALUE reg_init_args(VALUE self, VALUE str, rb_encoding *enc, int flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Regexp.new(string, options = 0, n_flag = nil, timeout: nil) -> regexp
|
* Regexp.new(string, options = 0, n_flag = nil, timeout: nil) -> regexp
|
||||||
@ -3813,26 +3822,38 @@ set_timeout(rb_hrtime_t *hrt, VALUE timeout)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
|
rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
struct reg_init_args args;
|
||||||
VALUE str;
|
|
||||||
rb_encoding *enc = 0;
|
|
||||||
|
|
||||||
VALUE src, opts = Qundef, n_flag = Qundef, kwargs, timeout = Qnil;
|
reg_extract_args(argc, argv, &args);
|
||||||
|
reg_init_args(self, args.str, args.enc, args.flags);
|
||||||
|
|
||||||
|
set_timeout(&RREGEXP_PTR(self)->timelimit, args.timeout);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reg_extract_args(int argc, VALUE *argv, struct reg_init_args *args)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
rb_encoding *enc = 0;
|
||||||
|
VALUE str, src, opts = Qundef, n_flag = Qundef, kwargs;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "12:", &src, &opts, &n_flag, &kwargs);
|
rb_scan_args(argc, argv, "12:", &src, &opts, &n_flag, &kwargs);
|
||||||
|
|
||||||
|
args->timeout = Qnil;
|
||||||
if (!NIL_P(kwargs)) {
|
if (!NIL_P(kwargs)) {
|
||||||
static ID keywords[1];
|
static ID keywords[1];
|
||||||
if (!keywords[0]) {
|
if (!keywords[0]) {
|
||||||
keywords[0] = rb_intern_const("timeout");
|
keywords[0] = rb_intern_const("timeout");
|
||||||
}
|
}
|
||||||
rb_get_kwargs(kwargs, keywords, 0, 1, &timeout);
|
rb_get_kwargs(kwargs, keywords, 0, 1, &args->timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RB_TYPE_P(src, T_REGEXP)) {
|
if (RB_TYPE_P(src, T_REGEXP)) {
|
||||||
VALUE re = src;
|
VALUE re = src;
|
||||||
|
|
||||||
if (opts != Qnil) {
|
if (!NIL_P(opts)) {
|
||||||
rb_warn("flags ignored");
|
rb_warn("flags ignored");
|
||||||
}
|
}
|
||||||
rb_reg_check(re);
|
rb_reg_check(re);
|
||||||
@ -3847,7 +3868,7 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
|
|||||||
else if (!NIL_P(opts) && rb_bool_expected(opts, "ignorecase", FALSE))
|
else if (!NIL_P(opts) && rb_bool_expected(opts, "ignorecase", FALSE))
|
||||||
flags = ONIG_OPTION_IGNORECASE;
|
flags = ONIG_OPTION_IGNORECASE;
|
||||||
}
|
}
|
||||||
if (!UNDEF_P(n_flag) && !NIL_P(n_flag)) {
|
if (!NIL_OR_UNDEF_P(n_flag)) {
|
||||||
char *kcode = StringValuePtr(n_flag);
|
char *kcode = StringValuePtr(n_flag);
|
||||||
if (kcode[0] == 'n' || kcode[0] == 'N') {
|
if (kcode[0] == 'n' || kcode[0] == 'N') {
|
||||||
enc = rb_ascii8bit_encoding();
|
enc = rb_ascii8bit_encoding();
|
||||||
@ -3859,15 +3880,19 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self)
|
|||||||
}
|
}
|
||||||
str = StringValue(src);
|
str = StringValue(src);
|
||||||
}
|
}
|
||||||
|
args->src = src;
|
||||||
|
args->str = str;
|
||||||
|
args->enc = enc;
|
||||||
|
args->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
reg_init_args(VALUE self, VALUE str, rb_encoding *enc, int flags)
|
||||||
|
{
|
||||||
if (enc && rb_enc_get(str) != enc)
|
if (enc && rb_enc_get(str) != enc)
|
||||||
rb_reg_init_str_enc(self, str, enc, flags);
|
rb_reg_init_str_enc(self, str, enc, flags);
|
||||||
else
|
else
|
||||||
rb_reg_init_str(self, str, flags);
|
rb_reg_init_str(self, str, flags);
|
||||||
|
|
||||||
regex_t *reg = RREGEXP_PTR(self);
|
|
||||||
|
|
||||||
set_timeout(®->timelimit, timeout);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4219,21 +4244,17 @@ static VALUE
|
|||||||
rb_reg_s_linear_time_p(int argc, VALUE *argv, VALUE self)
|
rb_reg_s_linear_time_p(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
VALUE re;
|
VALUE re;
|
||||||
VALUE src, opts = Qundef, n_flag = Qundef, kwargs;
|
struct reg_init_args args;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "12:", &src, &opts, &n_flag, &kwargs);
|
reg_extract_args(argc, argv, &args);
|
||||||
|
|
||||||
if (RB_TYPE_P(src, T_REGEXP)) {
|
if (RB_TYPE_P(args.src, T_REGEXP)) {
|
||||||
re = src;
|
re = args.src;
|
||||||
if (opts != Qnil) {
|
|
||||||
rb_warn("flags ignored");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
re = rb_class_new_instance(argc, argv, rb_cRegexp);
|
re = reg_init_args(rb_reg_alloc(), args.str, args.enc, args.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_reg_check(re);
|
|
||||||
return RBOOL(onig_check_linear_time(RREGEXP_PTR(re)));
|
return RBOOL(onig_check_linear_time(RREGEXP_PTR(re)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1703,5 +1703,8 @@ class TestRegexp < Test::Unit::TestCase
|
|||||||
assert_send [Regexp, :linear_time?, 'a', Regexp::IGNORECASE]
|
assert_send [Regexp, :linear_time?, 'a', Regexp::IGNORECASE]
|
||||||
assert_not_send [Regexp, :linear_time?, /(a)\1/]
|
assert_not_send [Regexp, :linear_time?, /(a)\1/]
|
||||||
assert_not_send [Regexp, :linear_time?, "(a)\\1"]
|
assert_not_send [Regexp, :linear_time?, "(a)\\1"]
|
||||||
|
|
||||||
|
assert_raise(TypeError) {Regexp.linear_time?(nil)}
|
||||||
|
assert_raise(TypeError) {Regexp.linear_time?(Regexp.allocate)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user