Prechádzať zdrojové kódy

* when converting a constant char (not widechar) with ord>=128 to a string,
convert it into a widechar at compile time using the current source file's
code page (and in case it was to a non-widestring, then convert it at run
time into the current run time ansi code page) (mantis #12993)

Previously, the characters were either stuffed into the string without
conversion (widestring), or passed to the run time "ansi-character to
stringtype" routine (other string types; which was also wrong, since
that routine expects the character to be in ansi-encoding, which is
not necessarily the same as whatever the source file encoding was)

git-svn-id: trunk@12580 -

Jonas Maebe 16 rokov pred
rodič
commit
bfbfa2eb64
3 zmenil súbory, kde vykonal 55 pridanie a 4 odobranie
  1. 1 0
      .gitattributes
  2. 16 4
      compiler/ncnv.pas
  3. 38 0
      tests/webtbs/tw12933.pp

+ 1 - 0
.gitattributes

@@ -8731,6 +8731,7 @@ tests/webtbs/tw1279.pp svneol=native#text/plain
 tests/webtbs/tw1283.pp svneol=native#text/plain
 tests/webtbs/tw1284.pp svneol=native#text/plain
 tests/webtbs/tw1286.pp svneol=native#text/plain
+tests/webtbs/tw12933.pp svneol=native#text/plain
 tests/webtbs/tw12942.pp svneol=native#text/plain
 tests/webtbs/tw1295.pp svneol=native#text/plain
 tests/webtbs/tw1299.pp svneol=native#text/plain

+ 16 - 4
compiler/ncnv.pas

@@ -916,26 +916,38 @@ implementation
          result:=nil;
          { we can't do widechar to ansichar conversions at compile time, since }
          { this maps all non-ascii chars to '?' -> loses information           }
+         
+         { one thing we have to do in advance: "constant ansichar" -> ansistring }
+         { conversions with ord(ansichar) >= 128, have to be done by converting  }
+         { the ansichar to a widechar at compile time (using the source's code   }
+         { page), and then by converting the widechar to an ansistring at run    }
+         { time (using the run time code page)                        }
+         if (left.nodetype=ordconstn) and
+            not(tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring]) and
+            (torddef(left.resultdef).ordtype=uchar) and
+            not(tordconstnode(left).value.uvalue<128) then
+           inserttypeconv(left,cwidechartype);
+         
          if (left.nodetype=ordconstn) and
             ((tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring]) or
              (torddef(left.resultdef).ordtype=uchar) or
-             { >=128 is destroyed }
+             { widechar >=128 is destroyed }
              (tordconstnode(left).value.uvalue<128)) then
            begin
-              if tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring] then
+              if (tstringdef(resultdef).stringtype in [st_widestring,st_unicodestring]) then
                begin
                  initwidestring(ws);
                  if torddef(left.resultdef).ordtype=uwidechar then
                    concatwidestringchar(ws,tcompilerwidechar(tordconstnode(left).value.uvalue))
                  else
-                   concatwidestringchar(ws,tcompilerwidechar(chr(tordconstnode(left).value.uvalue)));
+                   concatwidestringchar(ws,asciichar2unicode(chr(tordconstnode(left).value.uvalue)));
                  hp:=cstringconstnode.createwstr(ws);
                  hp.changestringtype(resultdef);
                  donewidestring(ws);
                end
               else
                 begin
-                  if torddef(left.resultdef).ordtype=uwidechar then
+                  if (torddef(left.resultdef).ordtype=uwidechar) then
                     hp:=cstringconstnode.createstr(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value.uvalue)))
                   else
                     hp:=cstringconstnode.createstr(chr(tordconstnode(left).value.uvalue));

+ 38 - 0
tests/webtbs/tw12933.pp

@@ -0,0 +1,38 @@
+{$codepage cp866}
+
+{ warning: this test will terminate successfully when run on systems that do
+  not support the character used below in the current code page, even if the
+  used compiler is buggy. On other systems, the test will properly fail if
+  the compiler is buggy.
+}
+
+{$ifdef unix}
+uses
+  cwstring;
+{$endif}
+var
+  s, s2: ansistring;
+  ws, ws2, ws3: widestring;
+begin
+    s := '£';
+    writeln(s);
+
+    ws := s;
+    writeln(ws);
+
+    ws2 := '££';
+    writeln(ws2);
+    s2:=ws2;
+    ws2:=s2;
+
+    ws3 := '£';
+    writeln(ws3);
+    s2:=ws3;
+    ws3:=s2;
+
+    delete(ws2,1,1);
+
+    if (ws<>ws2) or
+       (ws<>ws3) then
+      halt(1);
+end.