summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embed.h2
-rwxr-xr-xembed.pl2
-rw-r--r--pod/perlapi.pod5
-rw-r--r--pod/perlunicode.pod6
-rw-r--r--proto.h2
-rw-r--r--regexec.c6
-rw-r--r--utf8.c87
7 files changed, 56 insertions, 54 deletions
diff --git a/embed.h b/embed.h
index 9523ef5826..ea261bf17d 100644
--- a/embed.h
+++ b/embed.h
@@ -1782,7 +1782,7 @@
#define hv_undef(a) Perl_hv_undef(aTHX_ a)
#define ibcmp(a,b,c) Perl_ibcmp(aTHX_ a,b,c)
#define ibcmp_locale(a,b,c) Perl_ibcmp_locale(aTHX_ a,b,c)
-#define ibcmp_utf8(a,b,c,d,e) Perl_ibcmp_utf8(aTHX_ a,b,c,d,e)
+#define ibcmp_utf8(a,b,c,d,e,f) Perl_ibcmp_utf8(aTHX_ a,b,c,d,e,f)
#define ingroup(a,b) Perl_ingroup(aTHX_ a,b)
#define init_argv_symbols(a,b) Perl_init_argv_symbols(aTHX_ a,b)
#define init_debugger() Perl_init_debugger(aTHX)
diff --git a/embed.pl b/embed.pl
index 639ba6cf9e..91c2ac0331 100755
--- a/embed.pl
+++ b/embed.pl
@@ -1333,7 +1333,7 @@ Apd |HE* |hv_store_ent |HV* tb|SV* key|SV* val|U32 hash
Apd |void |hv_undef |HV* tb
Ap |I32 |ibcmp |const char* a|const char* b|I32 len
Ap |I32 |ibcmp_locale |const char* a|const char* b|I32 len
-Apd |I32 |ibcmp_utf8 |const char* a|bool ua|const char* b|bool ub|I32 len
+Apd |I32 |ibcmp_utf8 |const char* a|bool ua|I32 len1|const char* b|bool ub|I32 len2
p |bool |ingroup |Gid_t testgid|Uid_t effective
p |void |init_argv_symbols|int|char **
p |void |init_debugger
diff --git a/pod/perlapi.pod b/pod/perlapi.pod
index 6ac32f4014..7bdf75c8c9 100644
--- a/pod/perlapi.pod
+++ b/pod/perlapi.pod
@@ -1113,14 +1113,13 @@ Found in file hv.c
Return true if the strings s1 and s2 differ case-insensitively, false
if not (if they are equal case-insensitively). If u1 is true, the
string s1 is assumed to be in UTF-8-encoded Unicode. If u2 is true,
-the string s2 is assumed to be in UTF-8-encoded Unicode. (If both u1
-and u2 are false, ibcmp() is called.)
+the string s2 is assumed to be in UTF-8-encoded Unicode.
For case-insensitiveness, the "casefolding" of Unicode is used
instead of upper/lowercasing both the characters, see
http://www.unicode.org/unicode/reports/tr21/ (Case Mappings).
- I32 ibcmp_utf8(const char* a, bool ua, const char* b, bool ub, I32 len)
+ I32 ibcmp_utf8(const char* a, bool ua, I32 len1, const char* b, bool ub, I32 len2)
=for hackers
Found in file utf8.c
diff --git a/pod/perlunicode.pod b/pod/perlunicode.pod
index b1ffed534f..e707dc6c87 100644
--- a/pod/perlunicode.pod
+++ b/pod/perlunicode.pod
@@ -885,9 +885,9 @@ code points).
=item *
-ibcmp_utf8(s1, u1, s2, u2, len) can be used to compare two strings
-case-insensitively in Unicode. (For case-sensitive comparisons you
-can just use memEQ() and memNE() as usual.)
+ibcmp_utf8(s1, u1, len1, s2, u2, len2) can be used to compare two
+strings case-insensitively in Unicode. (For case-sensitive
+comparisons you can just use memEQ() and memNE() as usual.)
=back
diff --git a/proto.h b/proto.h
index 5c9a514930..f9161bbaad 100644
--- a/proto.h
+++ b/proto.h
@@ -315,7 +315,7 @@ PERL_CALLCONV HE* Perl_hv_store_ent(pTHX_ HV* tb, SV* key, SV* val, U32 hash);
PERL_CALLCONV void Perl_hv_undef(pTHX_ HV* tb);
PERL_CALLCONV I32 Perl_ibcmp(pTHX_ const char* a, const char* b, I32 len);
PERL_CALLCONV I32 Perl_ibcmp_locale(pTHX_ const char* a, const char* b, I32 len);
-PERL_CALLCONV I32 Perl_ibcmp_utf8(pTHX_ const char* a, bool ua, const char* b, bool ub, I32 len);
+PERL_CALLCONV I32 Perl_ibcmp_utf8(pTHX_ const char* a, bool ua, I32 len1, const char* b, bool ub, I32 len2);
PERL_CALLCONV bool Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective);
PERL_CALLCONV void Perl_init_argv_symbols(pTHX_ int, char **);
PERL_CALLCONV void Perl_init_debugger(pTHX);
diff --git a/regexec.c b/regexec.c
index 0d97be3222..4b073d2da4 100644
--- a/regexec.c
+++ b/regexec.c
@@ -971,7 +971,8 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
while (s <= e) {
if ( utf8_to_uvchr((U8*)s, &len) == c1
&& (ln == 1 ||
- ibcmp_utf8(s, do_utf8, m, UTF, ln)) )
+ ibcmp_utf8(s, do_utf8, strend - s,
+ m, UTF, ln)) )
goto got_it;
s += len;
}
@@ -980,7 +981,8 @@ S_find_byclass(pTHX_ regexp * prog, regnode *c, char *s, char *strend, char *sta
UV c = utf8_to_uvchr((U8*)s, &len);
if ( (c == c1 || c == c2)
&& (ln == 1 ||
- ibcmp_utf8(s, do_utf8, m, UTF, ln)) )
+ ibcmp_utf8(s, do_utf8, strend - s,
+ m, UTF, ln)) )
goto got_it;
s += len;
}
diff --git a/utf8.c b/utf8.c
index 1a024b719c..747b78cfe6 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1579,8 +1579,7 @@ Perl_sv_uni_display(pTHX_ SV *dsv, SV *ssv, STRLEN pvlim, UV flags)
Return true if the strings s1 and s2 differ case-insensitively, false
if not (if they are equal case-insensitively). If u1 is true, the
string s1 is assumed to be in UTF-8-encoded Unicode. If u2 is true,
-the string s2 is assumed to be in UTF-8-encoded Unicode. (If both u1
-and u2 are false, ibcmp() is called.)
+the string s2 is assumed to be in UTF-8-encoded Unicode.
For case-insensitiveness, the "casefolding" of Unicode is used
instead of upper/lowercasing both the characters, see
@@ -1588,50 +1587,52 @@ http://www.unicode.org/unicode/reports/tr21/ (Case Mappings).
=cut */
I32
-Perl_ibcmp_utf8(pTHX_ const char *s1, bool u1, const char *s2, bool u2, register I32 len)
-{
- if (u1 || u2) {
- register U8 *a = (U8*)s1;
- register U8 *b = (U8*)s2;
- STRLEN la, lb;
- UV ca, cb;
- STRLEN ulen1, ulen2;
- U8 tmpbuf1[UTF8_MAXLEN*3+1];
- U8 tmpbuf2[UTF8_MAXLEN*3+1];
-
- while (len) {
+Perl_ibcmp_utf8(pTHX_ const char *s1, bool u1, register I32 len1, const char *s2, bool u2, register I32 len2)
+{
+ register U8 *a = (U8*)s1;
+ register U8 *b = (U8*)s2;
+ register U8 *ae = b + len1;
+ register U8 *be = b + len2;
+ STRLEN la, lb;
+ UV ca, cb;
+ STRLEN ulen1, ulen2;
+ U8 tmpbuf1[UTF8_MAXLEN*3+1];
+ U8 tmpbuf2[UTF8_MAXLEN*3+1];
+
+ while (a < ae && b < be) {
+ if (u1) {
+ if (a + UTF8SKIP(a) > ae)
+ break;
+ ca = utf8_to_uvchr((U8*)a, &la);
+ } else {
+ ca = *a;
+ la = 1;
+ }
+ if (u2) {
+ if (b + UTF8SKIP(b) > be)
+ break;
+ cb = utf8_to_uvchr((U8*)b, &lb);
+ } else {
+ cb = *b;
+ lb = 1;
+ }
+ if (ca != cb) {
if (u1)
- ca = utf8_to_uvchr((U8*)a, &la);
- else {
- ca = *a;
- la = 1;
- }
+ to_uni_fold(NATIVE_TO_UNI(ca), tmpbuf1, &ulen1);
+ else
+ ulen1 = 1;
if (u2)
- cb = utf8_to_uvchr((U8*)b, &lb);
- else {
- cb = *b;
- lb = 1;
- }
- if (ca != cb) {
- if (u1)
- to_uni_fold(NATIVE_TO_UNI(ca), tmpbuf1, &ulen1);
- else
- ulen1 = 1;
- if (u2)
- to_uni_fold(NATIVE_TO_UNI(cb), tmpbuf2, &ulen2);
- else
- ulen2 = 1;
- if (ulen1 != ulen2
- || (ulen1 == 1 && PL_fold[ca] != PL_fold[cb])
- || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
- return 1;
- }
- a += la;
- b += lb;
+ to_uni_fold(NATIVE_TO_UNI(cb), tmpbuf2, &ulen2);
+ else
+ ulen2 = 1;
+ if (ulen1 != ulen2
+ || (ulen1 == 1 && PL_fold[ca] != PL_fold[cb])
+ || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
+ return 1; /* mismatch */
}
- return 0;
+ a += la;
+ b += lb;
}
- else
- return ibcmp(s1, s2, len);
+ return a == ae && b == be ? 0 : 1; /* 0 match, 1 mismatch */
}