This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: Add invlist_lowest() and use it
authorKarl Williamson <khw@cpan.org>
Sun, 31 Mar 2019 20:00:25 +0000 (14:00 -0600)
committerKarl Williamson <khw@cpan.org>
Wed, 20 Nov 2019 22:26:02 +0000 (15:26 -0700)
This makes it less complicated to find the lowest code point in an
inversion list.  This makes the place where it's used clearer as to what
is going on.  And it may eventually be used in more than one place.

embed.fnc
embed.h
proto.h
regcomp.c

index cb49719..3a75a4c 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1887,6 +1887,7 @@ EiT       |void   |invlist_iterfinish|NN SV* invlist
 EiRT   |bool   |invlist_is_iterating|NN SV* const invlist
 EiR    |SV*    |invlist_contents|NN SV* const invlist              \
                                 |const bool traditional_style
+EixRT  |UV     |invlist_lowest|NN SV* const invlist
 #ifndef PERL_EXT_RE_BUILD
 EiRT   |UV*    |_invlist_array_init    |NN SV* const invlist|const bool will_have_0
 EiRT   |UV     |invlist_max    |NN SV* const invlist
diff --git a/embed.h b/embed.h
index 4e22323..6cd8051 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define handle_user_defined_property(a,b,c,d,e,f,g,h,i,j)      Perl_handle_user_defined_property(aTHX_ a,b,c,d,e,f,g,h,i,j)
 #define invlist_contents(a,b)  S_invlist_contents(aTHX_ a,b)
 #define invlist_is_iterating   S_invlist_is_iterating
+#define invlist_lowest         S_invlist_lowest
 #define is_ssc_worth_it                S_is_ssc_worth_it
 #define join_exact(a,b,c,d,e,f,g)      S_join_exact(aTHX_ a,b,c,d,e,f,g)
 #define make_exactf_invlist(a,b)       S_make_exactf_invlist(aTHX_ a,b)
diff --git a/proto.h b/proto.h
index 4aa32de..587be9a 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -5603,6 +5603,13 @@ PERL_STATIC_INLINE bool  S_invlist_is_iterating(SV* const invlist)
        assert(invlist)
 #endif
 
+#ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE UV  S_invlist_lowest(SV* const invlist)
+                       __attribute__warn_unused_result__;
+#define PERL_ARGS_ASSERT_INVLIST_LOWEST        \
+       assert(invlist)
+#endif
+
 STATIC bool    S_is_ssc_worth_it(const RExC_state_t * pRExC_state, const regnode_ssc * ssc);
 #define PERL_ARGS_ASSERT_IS_SSC_WORTH_IT       \
        assert(pRExC_state); assert(ssc)
index a5273a9..4116dd3 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -10319,6 +10319,28 @@ Perl_invlist_clone(pTHX_ SV* const invlist, SV* new_invlist)
 
 #endif
 
+PERL_STATIC_INLINE UV
+S_invlist_lowest(SV* const invlist)
+{
+    /* Returns the lowest code point that matches an inversion list.  This API
+     * has an ambiguity, as it returns 0 under either the lowest is actually
+     * 0, or if the list is empty.  If this distinction matters to you, check
+     * for emptiness before calling this function */
+
+    UV len = _invlist_len(invlist);
+    UV *array;
+
+    PERL_ARGS_ASSERT_INVLIST_LOWEST;
+
+    if (len == 0) {
+        return 0;
+    }
+
+    array = invlist_array(invlist);
+
+    return array[0];
+}
+
 STATIC SV *
 S_invlist_contents(pTHX_ SV* const invlist, const bool traditional_style)
 {
@@ -18465,14 +18487,11 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
                  |= ANYOFL_FOLD
                  |  ANYOFL_SHARED_UTF8_LOCALE_fold_HAS_MATCHES_nonfold_REQD;
         }
-        else if (cp_list) { /* Look to see if a 0-255 code point is in list */
-            UV start, end;
-            invlist_iterinit(cp_list);
-            if (invlist_iternext(cp_list, &start, &end) && start < 256) {
-                anyof_flags |= ANYOFL_FOLD;
-                has_runtime_dependency |= HAS_L_RUNTIME_DEPENDENCY;
-            }
-            invlist_iterfinish(cp_list);
+        else if (cp_list && invlist_lowest(cp_list) < 256) {
+            /* If nothing is below 256, has no locale dependency; otherwise it
+             * does */
+            anyof_flags |= ANYOFL_FOLD;
+            has_runtime_dependency |= HAS_L_RUNTIME_DEPENDENCY;
         }
     }
     else if (   DEPENDS_SEMANTICS