+ /* If the bitmap didn't (or couldn't) match, and something outside the
+ * bitmap could match, try that */
+ if (!match) {
+ if (utf8_target && (flags & ANYOF_UNICODE_ALL) && c >= 256) {
+ match = TRUE;
+ }
+ else if ((flags & ANYOF_NONBITMAP_NON_UTF8)
+ || (utf8_target && flags & ANYOF_UTF8))
+ {
+ AV *av;
+ SV * const sw = regclass_swash(prog, n, TRUE, 0, (SV**)&av);
+
+ if (sw) {
+ U8 * utf8_p;
+ if (utf8_target) {
+ utf8_p = (U8 *) p;
+ } else {
+ STRLEN len = 1;
+ utf8_p = bytes_to_utf8(p, &len);
+ }
+ if (swash_fetch(sw, utf8_p, 1))
+ match = TRUE;
+ else if (flags & ANYOF_FOLD) {
+ if (!match && lenp && av) {
+ I32 i;
+ for (i = 0; i <= av_len(av); i++) {
+ SV* const sv = *av_fetch(av, i, FALSE);
+ STRLEN len;
+ const char * const s = SvPV_const(sv, len);
+ if (len <= maxlen && memEQ(s, (char*)utf8_p, len)) {
+ *lenp = len;
+ match = TRUE;
+ break;
+ }
+ }
+ }
+ if (!match) {
+ U8 folded[UTF8_MAXBYTES_CASE+1];
+
+ /* See if the folded version matches */
+ STRLEN foldlen;
+ to_utf8_fold(utf8_p, folded, &foldlen);
+ if (swash_fetch(sw, folded, 1)) { /* 1 => is utf8 */
+ match = TRUE;
+ }
+ else {
+ /* The fold in a few cases of an above Latin1 char
+ * is in the Latin1 range, and hence may be in the
+ * bitmap */
+ if (UTF8_IS_INVARIANT(*folded)
+ && ANYOF_BITMAP_TEST(n, UNI_TO_NATIVE(*folded)))
+ {
+ match = TRUE;
+ }
+ else if (UTF8_IS_DOWNGRADEABLE_START(*folded)
+ && ANYOF_BITMAP_TEST(n,
+ UNI_TO_NATIVE(
+ TWO_BYTE_UTF8_TO_UNI(folded[0],
+ folded[1]))))
+ { /* Since the fold comes from internally
+ * generated data, we can safely assume it is
+ * valid utf8 in the test above */
+
+ match = TRUE;
+ }
+ if (! match) {
+ 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);
+ char* try_c;
+ 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 */
+ try_c = SvPVX(*try_p);
+ if (UTF8_IS_INVARIANT(*try_c)
+ && ANYOF_BITMAP_TEST(n,
+ UNI_TO_NATIVE(*try_c)))
+ {
+ match = TRUE;
+ break;
+ }
+ else if
+ (UTF8_IS_DOWNGRADEABLE_START(*try_c)
+ && ANYOF_BITMAP_TEST(n,
+ UNI_TO_NATIVE(
+ TWO_BYTE_UTF8_TO_UNI(try_c[0],
+ try_c[1]))))
+ {
+ match = TRUE;
+ break;
+ } else if (swash_fetch(sw,
+ (U8*) try_c, 1))
+ {
+ match = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* If we allocated a string above, free it */
+ if (! utf8_target) Safefree(utf8_p);
+ }
+ }
+ }
+