#define PL_utf8_ascii (vTHX->Iutf8_ascii)
#define PL_utf8_cntrl (vTHX->Iutf8_cntrl)
#define PL_utf8_digit (vTHX->Iutf8_digit)
+#define PL_utf8_foldclosures (vTHX->Iutf8_foldclosures)
#define PL_utf8_graph (vTHX->Iutf8_graph)
#define PL_utf8_idcont (vTHX->Iutf8_idcont)
#define PL_utf8_idstart (vTHX->Iutf8_idstart)
#define PL_Iutf8_ascii PL_utf8_ascii
#define PL_Iutf8_cntrl PL_utf8_cntrl
#define PL_Iutf8_digit PL_utf8_digit
+#define PL_Iutf8_foldclosures PL_utf8_foldclosures
#define PL_Iutf8_graph PL_utf8_graph
#define PL_Iutf8_idcont PL_utf8_idcont
#define PL_Iutf8_idstart PL_utf8_idstart
/* Compile-time block start/end hooks */
PERLVAR(Iblockhooks, AV *)
+
+/* Everything that folds to a character, for case insensitivity regex matching */
+PERLVARI(Iutf8_foldclosures, HV *, NULL)
+
/* If you are adding a U8 or U16, check to see if there are 'Space' comments
* above on where there are gaps which currently will be structure padding. */
SvREFCNT_dec(PL_utf8_tofold);
SvREFCNT_dec(PL_utf8_idstart);
SvREFCNT_dec(PL_utf8_idcont);
+ SvREFCNT_dec(PL_utf8_foldclosures);
PL_utf8_alnum = NULL;
PL_utf8_ascii = NULL;
PL_utf8_alpha = NULL;
PL_utf8_tofold = NULL;
PL_utf8_idstart = NULL;
PL_utf8_idcont = NULL;
+ PL_utf8_foldclosures = NULL;
if (!specialWARN(PL_compiling.cop_warnings))
PerlMemShared_free(PL_compiling.cop_warnings);
if (swash_fetch(sw, folded, 1)) { /* 1 => is utf8 */
match = TRUE;
}
+ else {
+ SV** listp;
+
+ /* Consider "k" =~ /[K]/i. The line above would
+ * have just folded the 'k' to itself, and that
+ * isn't going to match 'K'. So we look through
+ * the closure of everything that folds to 'k'.
+ * That will find the 'K'. Initialize the list, if
+ * necessary */
+ if (! PL_utf8_foldclosures) {
+
+ /* If the folds haven't been read in, call a fold
+ * function to force that */
+ if (! PL_utf8_tofold) {
+ U8 dummy[UTF8_MAXBYTES+1];
+ STRLEN dummy_len;
+ to_utf8_fold((U8*) "A", dummy, &dummy_len);
+ }
+ PL_utf8_foldclosures =
+ _swash_inversion_hash(PL_utf8_tofold);
+ }
+
+ /* The data structure is a hash with the keys every
+ * character that is folded to, like 'k', and the
+ * values each an array of everything that folds to
+ * its key. e.g. [ 'k', 'K', KELVIN_SIGN ] */
+ if ((listp = hv_fetch(PL_utf8_foldclosures,
+ (char *) folded, foldlen, FALSE)))
+ {
+ AV* list = (AV*) *listp;
+ IV i;
+ for (i = 0; i <= av_len(list); i++) {
+ SV** try_p = av_fetch(list, i, FALSE);
+ if (try_p == NULL) {
+ Perl_croak(aTHX_ "panic: invalid PL_utf8_foldclosures structure");
+ }
+ /* Don't have to worry about embeded nulls
+ * since NULL isn't folded or foldable */
+ if (swash_fetch(sw, (U8*) SvPVX(*try_p),1)) {
+ match = TRUE;
+ break;
+ }
+ }
+ }
+ }
}
}
PL_registered_mros = hv_dup_inc(proto_perl->Iregistered_mros, param);
PL_blockhooks = av_dup_inc(proto_perl->Iblockhooks, param);
+ PL_utf8_foldclosures = hv_dup_inc(proto_perl->Iutf8_foldclosures, param);
/* Call the ->CLONE method, if it exists, for each of the stashes
identified by sv_dup() above.
}
}
}
+
+push @tests, qq[like chr(0x0430), qr/[=\x{0410}-\x{0411}]/i, 'Bug #71752 Unicode /i char in a range'];
+$count++;
+push @tests, qq[like 'a', qr/\\p{Upper}/i, "'a' =~ /\\\\p{Upper}/i"];
+$count++;
+
eval join ";\n","plan tests=>".($count-1),@tests,"1"
or die $@;
__DATA__