diff options
Diffstat (limited to 'cpan/Unicode-Collate/Collate.xs')
-rw-r--r-- | cpan/Unicode-Collate/Collate.xs | 47 |
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 |