summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorSimon Cozens <simon@netthink.co.uk>2000-10-14 21:52:13 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2000-10-15 16:24:44 +0000
commit1d68d6cd5ca16f48de9798b0758052a6de564551 (patch)
treecec6cf88c7c24c5ae0d5f41e34d4cc88133d4df8 /pp.c
parent93f04dac2ed878fbeae5ba64df628ed3ab0b6e21 (diff)
downloadperl-1d68d6cd5ca16f48de9798b0758052a6de564551.tar.gz
Make ~(chr(a).chr(b)) eq chr(~a).chr(~b) on utf8.
Subject: [PATCH] Re: [ID 20000918.005] ~ on wide chars Message-ID: <20001014205213.A9645@pembro4.pmb.ox.ac.uk> p4raw-id: //depot/perl@7235
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/pp.c b/pp.c
index 03609e8333..72d9dee238 100644
--- a/pp.c
+++ b/pp.c
@@ -1476,6 +1476,38 @@ PP(pp_complement)
SvSetSV(TARG, sv);
tmps = SvPV_force(TARG, len);
anum = len;
+ if (SvUTF8(TARG)) {
+ /* Calculate exact length, let's not estimate */
+ STRLEN targlen = 0;
+ U8 *result;
+ char *send;
+
+ send = tmps + len;
+ while (tmps < send) {
+ I32 l;
+ UV c = utf8_to_uv(tmps, &l);
+ c = (UV)~c;
+ tmps += UTF8SKIP(tmps);
+ targlen += UTF8LEN(c);
+ }
+
+ /* Now rewind strings and write them. */
+ tmps -= len;
+ Newz(0, result, targlen + 1, U8);
+ while (tmps < send) {
+ I32 l;
+ UV c = utf8_to_uv(tmps, &l);
+ tmps += UTF8SKIP(tmps);
+ result = uv_to_utf8(result,(UV)~c);
+ }
+ *result = '\0';
+ result -= targlen;
+ sv_setpvn(TARG, result, targlen);
+ SvUTF8_on(TARG);
+ Safefree(result);
+ SETs(TARG);
+ RETURN;
+ }
#ifdef LIBERAL
for ( ; anum && (unsigned long)tmps % sizeof(long); anum--, tmps++)
*tmps = ~*tmps;