1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Allow abbreviated dump options with additional options

This commit is contained in:
Nobuyoshi Nakada 2022-10-09 16:08:09 +09:00
parent 43f692248e
commit f178ff3933
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6
Notes: git 2022-10-09 19:02:21 +09:00
2 changed files with 47 additions and 8 deletions

50
ruby.c
View file

@ -156,6 +156,9 @@ enum dump_flag_bits {
dump_version_v,
dump_error_tolerant,
EACH_DUMPS(DEFINE_DUMP, COMMA),
dump_error_tolerant_bits = (DUMP_BIT(yydebug) |
DUMP_BIT(parsetree) |
DUMP_BIT(parsetree_with_comment)),
dump_exit_bits = (DUMP_BIT(yydebug) | DUMP_BIT(syntax) |
DUMP_BIT(parsetree) | DUMP_BIT(parsetree_with_comment) |
DUMP_BIT(insns) | DUMP_BIT(insns_without_opt))
@ -900,14 +903,16 @@ name_match_p(const char *name, const char *str, size_t len)
if (len == 0) return 0;
while (1) {
while (TOLOWER(*str) == *name) {
if (!--len || !*++str) return 1;
if (!--len) return 1;
++name;
++str;
}
if (*str != '-' && *str != '_') return 0;
while (ISALNUM(*name)) name++;
if (*name != '-' && *name != '_') return 0;
++name;
++str;
if (--len == 0) return 1;
}
}
@ -1013,16 +1018,49 @@ debug_option(const char *str, int len, void *arg)
rb_warn("debug features are [%.*s].", (int)strlen(list), list);
}
static int
memtermspn(const char *str, char term, int len)
{
RUBY_ASSERT(len >= 0);
if (len <= 0) return 0;
const char *next = memchr(str, term, len);
return next ? (int)(next - str) : len;
}
static const char additional_opt_sep = '+';
static unsigned int
dump_additional_option(const char *str, int len, unsigned int bits, const char *name)
{
int w;
for (; len-- > 0 && *str++ == additional_opt_sep; len -= w, str += w) {
w = memtermspn(str, additional_opt_sep, len);
#define SET_ADDITIONAL(bit) if (NAME_MATCH_P(#bit, str, w)) { \
if (bits & DUMP_BIT(bit)) \
rb_warn("duplicate option to dump %s: `%.*s'", name, w, str); \
bits |= DUMP_BIT(bit); \
continue; \
}
if (dump_error_tolerant_bits & bits) {
SET_ADDITIONAL(error_tolerant);
}
rb_warn("don't know how to dump %s with `%.*s'", name, w, str);
}
return bits;
}
static void
dump_option(const char *str, int len, void *arg)
{
static const char list[] = EACH_DUMPS(LITERAL_NAME_ELEMENT, ", ");
#define NAME_MATCH_TOLERANT_P(name) (len >= 15 && NAME_MATCH_P(#name "+error-tolerant", str, len))
if (NAME_MATCH_TOLERANT_P(yydebug) || NAME_MATCH_TOLERANT_P(parsetree) || NAME_MATCH_TOLERANT_P(parsetree_with_comment)) {
*(unsigned int *)arg |= DUMP_BIT(error_tolerant);
len -= 15;
int w = memtermspn(str, additional_opt_sep, len);
#define SET_WHEN_DUMP(bit) \
if (NAME_MATCH_P(#bit, (str), (w))) { \
*(unsigned int *)arg |= \
dump_additional_option(str + w, len - w, DUMP_BIT(bit), #bit); \
return; \
}
#define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
EACH_DUMPS(SET_WHEN_DUMP, ;);
rb_warn("don't know how to dump `%.*s',", len, str);
rb_warn("but only [%.*s].", (int)strlen(list), list);

View file

@ -1001,8 +1001,7 @@ class TestRubyOptions < Test::Unit::TestCase
stderr = []
Tempfile.create(%w"bug10435- .rb") do |script|
dir, base = File.split(script.path)
script.puts "abort ':run'"
script.close
File.write(script, "abort ':run'\n")
opts = ['-C', dir, '-r', "./#{base}", *opt]
_, e = assert_in_out_err([*opts, '-ep'], "", //)
stderr.concat(e) if e
@ -1026,6 +1025,8 @@ class TestRubyOptions < Test::Unit::TestCase
def test_dump_parsetree_with_rflag
assert_norun_with_rflag('--dump=parsetree')
assert_norun_with_rflag('--dump=parsetree', '-e', '#frozen-string-literal: true')
assert_norun_with_rflag('--dump=parsetree+error_tolerant')
assert_norun_with_rflag('--dump=parse+error_tolerant')
end
def test_dump_insns_with_rflag