summaryrefslogtreecommitdiff
path: root/cpan/Unicode-Collate/Collate.xs
diff options
context:
space:
mode:
Diffstat (limited to 'cpan/Unicode-Collate/Collate.xs')
-rw-r--r--cpan/Unicode-Collate/Collate.xs47
1 files changed, 33 insertions, 14 deletions
diff --git a/cpan/Unicode-Collate/Collate.xs b/cpan/Unicode-Collate/Collate.xs
index d96912bf6d..7f00642820 100644
--- a/cpan/Unicode-Collate/Collate.xs
+++ b/cpan/Unicode-Collate/Collate.xs
@@ -416,9 +416,6 @@ mk_SortKey (self, buf)
else
croak("$self is not a HASHREF.");
- svp = hv_fetch(selfHV, "level", 5, FALSE);
- level = svp ? SvIV(*svp) : MaxLevel;
-
if (SvROK(buf) && SvTYPE(SvRV(buf)) == SVt_PVAV)
bufAV = (AV*)SvRV(buf);
else
@@ -433,8 +430,10 @@ mk_SortKey (self, buf)
d = (U8*)SvPVX(dst);
while (dlen--)
*d++ = '\0';
- }
- else {
+ } else {
+ svp = hv_fetch(selfHV, "level", 5, FALSE);
+ level = svp ? SvIV(*svp) : MaxLevel;
+
for (lv = 0; lv < level; lv++) {
New(0, eachlevel[lv], 2 * (1 + buf_len) + 1, U8);
s[lv] = eachlevel[lv];
@@ -551,14 +550,27 @@ OUTPUT:
SV*
-_varCE (vbl, vce)
- SV* vbl
- SV* vce
+varCE (self, vce)
+ SV* self;
+ SV* vce;
PREINIT:
- SV *dst;
+ SV *dst, *vbl, **svp;
+ HV *selfHV;
U8 *a, *v, *d;
STRLEN alen, vlen;
+ bool ig_l2;
+ UV totwt;
CODE:
+ if (SvROK(self) && SvTYPE(SvRV(self)) == SVt_PVHV)
+ selfHV = (HV*)SvRV(self);
+ else
+ croak("$self is not a HASHREF.");
+
+ svp = hv_fetch(selfHV, "ignore_level2", 13, FALSE);
+ ig_l2 = svp ? SvTRUE(*svp) : FALSE;
+
+ svp = hv_fetch(selfHV, "variable", 8, FALSE);
+ vbl = svp ? *svp : &PL_sv_no;
a = (U8*)SvPV(vbl, alen);
v = (U8*)SvPV(vce, vlen);
@@ -569,29 +581,36 @@ _varCE (vbl, vce)
SvCUR_set(dst, vlen);
d[vlen] = '\0';
+ /* primary weight == 0 && secondary weight != 0 */
+ if (ig_l2 && !d[1] && !d[2] && (d[3] || d[4])) {
+ d[3] = d[4] = d[5] = d[6] = '\0';
+ }
+
/* variable: checked only the first char and the length,
trusting checkCollator() and %VariableOK in Perl ... */
if (vlen < VCE_Length /* ignore short VCE (unexpected) */
||
- *a == 'n') /* 'non-ignorable' */
+ *a == 'n') /* non-ignorable */
1;
else if (*v) {
if (*a == 's') { /* shifted or shift-trimmed */
d[7] = d[1]; /* wt level 1 to 4 */
d[8] = d[2];
- }
+ } /* else blanked */
+
d[1] = d[2] = d[3] = d[4] = d[5] = d[6] = '\0';
}
else if (*a == 'b') /* blanked */
1;
else if (*a == 's') { /* shifted or shift-trimmed */
- if (alen == 7 && (d[1] + d[2] + d[3] + d[4] + d[5] + d[6])) {
+ totwt = d[1] + d[2] + d[3] + d[4] + d[5] + d[6];
+ if (alen == 7 && totwt != 0) { /* shifted */
d[7] = (U8)(Shift4Wt >> 8);
d[8] = (U8)(Shift4Wt & 0xFF);
}
- else {
- d[7] = d[8] = 0;
+ else { /* shift-trimmed */
+ d[7] = d[8] = '\0';
}
}
else