[前][次][番号順一覧][スレッド一覧]

ruby-changes:73939

From: Nobuyoshi <ko1@a...>
Date: Sun, 9 Oct 2022 19:02:21 +0900 (JST)
Subject: [ruby-changes:73939] f178ff3933 (master): Allow abbreviated dump options with additional options

https://git.ruby-lang.org/ruby.git/commit/?id=f178ff3933

From f178ff39334ac2fb33de0d6c3e6ec8fb7714e8da Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Sun, 9 Oct 2022 16:08:09 +0900
Subject: Allow abbreviated dump options with additional options

---
 ruby.c                        | 50 +++++++++++++++++++++++++++++++++++++------
 test/ruby/test_rubyoptions.rb |  5 +++--
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/ruby.c b/ruby.c
index cddd9c0e3d..752498f66c 100644
--- a/ruby.c
+++ b/ruby.c
@@ -156,6 +156,9 @@ enum dump_flag_bits { https://github.com/ruby/ruby/blob/trunk/ruby.c#L156
     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) https://github.com/ruby/ruby/blob/trunk/ruby.c#L903
     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) https://github.com/ruby/ruby/blob/trunk/ruby.c#L1018
     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);
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index cf6829cf88..0198bbd900 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -1001,8 +1001,7 @@ class TestRubyOptions < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rubyoptions.rb#L1001
     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 https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rubyoptions.rb#L1025
   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
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]