widestr.pas 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 by Florian Klaempfl
  4. This unit contains basic functions for unicode support in the
  5. compiler, this unit is mainly necessary to bootstrap widestring
  6. support ...
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ****************************************************************************
  19. }
  20. unit widestr;
  21. interface
  22. uses
  23. charset;
  24. type
  25. tcompilerwidechar = word;
  26. tcompilerwidecharptr = ^tcompilerwidechar;
  27. {$ifdef delphi}
  28. { delphi doesn't allow pointer accessing as array }
  29. tcompilerwidechararray = array[0..0] of tcompilerwidechar;
  30. pcompilerwidechar = ^tcompilerwidechararray;
  31. {$else}
  32. pcompilerwidechar = ^tcompilerwidechar;
  33. {$endif}
  34. pcompilerwidestring = ^_tcompilerwidestring;
  35. _tcompilerwidestring = record
  36. data : pcompilerwidechar;
  37. maxlen,len : StrLenInt;
  38. end;
  39. procedure initwidestring(var r : pcompilerwidestring);
  40. procedure donewidestring(var r : pcompilerwidestring);
  41. procedure setlengthwidestring(r : pcompilerwidestring;l : StrLenInt);
  42. function getlengthwidestring(r : pcompilerwidestring) : StrLenInt;
  43. procedure concatwidestringchar(r : pcompilerwidestring;c : tcompilerwidechar);
  44. procedure concatwidestrings(s1,s2 : pcompilerwidestring);
  45. function comparewidestrings(s1,s2 : pcompilerwidestring) : StrLenInt;
  46. procedure copywidestring(s,d : pcompilerwidestring);
  47. function asciichar2unicode(c : char) : tcompilerwidechar;
  48. function unicode2asciichar(c : tcompilerwidechar) : char;
  49. procedure ascii2unicode(p : pchar;l : StrLenInt;r : pcompilerwidestring);
  50. procedure unicode2ascii(r : pcompilerwidestring;p : pchar);
  51. function getcharwidestring(r : pcompilerwidestring;l : StrLenInt) : tcompilerwidechar;
  52. function cpavailable(const s : string) : boolean;
  53. implementation
  54. uses
  55. cp8859_1,cp850,cp437,
  56. globals;
  57. procedure initwidestring(var r : pcompilerwidestring);
  58. begin
  59. new(r);
  60. r^.data:=nil;
  61. r^.len:=0;
  62. r^.maxlen:=0;
  63. end;
  64. procedure donewidestring(var r : pcompilerwidestring);
  65. begin
  66. if assigned(r^.data) then
  67. freemem(r^.data);
  68. dispose(r);
  69. r:=nil;
  70. end;
  71. function getcharwidestring(r : pcompilerwidestring;l : StrLenInt) : tcompilerwidechar;
  72. begin
  73. getcharwidestring:=r^.data[l];
  74. end;
  75. function getlengthwidestring(r : pcompilerwidestring) : StrLenInt;
  76. begin
  77. getlengthwidestring:=r^.len;
  78. end;
  79. procedure setlengthwidestring(r : pcompilerwidestring;l : StrLenInt);
  80. begin
  81. if r^.maxlen>=l then
  82. exit;
  83. if assigned(r^.data) then
  84. reallocmem(r^.data,sizeof(tcompilerwidechar)*l)
  85. else
  86. getmem(r^.data,sizeof(tcompilerwidechar)*l);
  87. end;
  88. procedure concatwidestringchar(r : pcompilerwidestring;c : tcompilerwidechar);
  89. begin
  90. if r^.len>=r^.maxlen then
  91. setlengthwidestring(r,r^.len+16);
  92. r^.data[r^.len]:=c;
  93. inc(r^.len);
  94. end;
  95. procedure concatwidestrings(s1,s2 : pcompilerwidestring);
  96. begin
  97. setlengthwidestring(s1,s1^.len+s2^.len);
  98. inc(s1^.len,s2^.len);
  99. move(s2^.data^,s1^.data[s1^.len],s2^.len*sizeof(tcompilerwidechar));
  100. end;
  101. procedure copywidestring(s,d : pcompilerwidestring);
  102. begin
  103. setlengthwidestring(d,s^.len);
  104. d^.len:=s^.len;
  105. move(s^.data^,d^.data^,s^.len*sizeof(tcompilerwidechar));
  106. end;
  107. function comparewidestrings(s1,s2 : pcompilerwidestring) : StrLenInt;
  108. var
  109. maxi,temp : StrLenInt;
  110. begin
  111. if pointer(s1)=pointer(s2) then
  112. begin
  113. comparewidestrings:=0;
  114. exit;
  115. end;
  116. maxi:=s1^.len;
  117. temp:=s2^.len;
  118. if maxi>temp then
  119. maxi:=Temp;
  120. temp:=compareword(s1^.data^,s2^.data^,maxi);
  121. if temp=0 then
  122. temp:=s1^.len-s2^.len;
  123. comparewidestrings:=temp;
  124. end;
  125. function asciichar2unicode(c : char) : tcompilerwidechar;
  126. var
  127. m : punicodemap;
  128. begin
  129. m:=getmap(aktsourcecodepage);
  130. asciichar2unicode:=getunicode(c,m);
  131. end;
  132. function unicode2asciichar(c : tcompilerwidechar) : char;
  133. begin
  134. {$ifdef fpc}{$warning todo}{$endif}
  135. unicode2asciichar:=#0;
  136. end;
  137. procedure ascii2unicode(p : pchar;l : StrLenInt;r : pcompilerwidestring);
  138. var
  139. source : pchar;
  140. dest : tcompilerwidecharptr;
  141. i : StrLenInt;
  142. m : punicodemap;
  143. begin
  144. m:=getmap(aktsourcecodepage);
  145. setlengthwidestring(r,l);
  146. source:=p;
  147. r^.len:=l;
  148. dest:=tcompilerwidecharptr(r^.data);
  149. for i:=1 to l do
  150. begin
  151. dest^:=getunicode(source^,m);
  152. inc(dest);
  153. inc(source);
  154. end;
  155. end;
  156. procedure unicode2ascii(r : pcompilerwidestring;p:pchar);
  157. (*
  158. var
  159. m : punicodemap;
  160. i : longint;
  161. begin
  162. m:=getmap(aktsourcecodepage);
  163. { should be a very good estimation :) }
  164. setlengthwidestring(r,length(s));
  165. // !!!! MBCS
  166. for i:=1 to length(s) do
  167. begin
  168. end;
  169. end;
  170. *)
  171. var
  172. source : tcompilerwidecharptr;
  173. dest : pchar;
  174. i : longint;
  175. begin
  176. source:=tcompilerwidecharptr(r^.data);
  177. dest:=p;
  178. for i:=1 to r^.len do
  179. begin
  180. if word(source^)<128 then
  181. dest^:=char(word(source^))
  182. else
  183. dest^:=' ';
  184. inc(dest);
  185. inc(source);
  186. end;
  187. end;
  188. function cpavailable(const s : string) : boolean;
  189. begin
  190. cpavailable:=mappingavailable(s);
  191. end;
  192. end.
  193. {
  194. $Log$
  195. Revision 1.11 2002-07-20 17:16:03 florian
  196. + source code page support
  197. Revision 1.10 2002/05/18 13:34:21 peter
  198. * readded missing revisions
  199. Revision 1.9 2002/05/16 19:46:47 carl
  200. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  201. + try to fix temp allocation (still in ifdef)
  202. + generic constructor calls
  203. + start of tassembler / tmodulebase class cleanup
  204. }