widestr.pas 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. {$ifdef delphi}
  25. ,sysutils
  26. {$endif}
  27. ;
  28. type
  29. tcompilerwidechar = word;
  30. tcompilerwidecharptr = ^tcompilerwidechar;
  31. {$ifdef delphi}
  32. strlenint = integer;
  33. { delphi doesn't allow pointer accessing as array }
  34. tcompilerwidechararray = array[0..0] of tcompilerwidechar;
  35. pcompilerwidechar = ^tcompilerwidechararray;
  36. {$else}
  37. pcompilerwidechar = ^tcompilerwidechar;
  38. {$endif}
  39. pcompilerwidestring = ^_tcompilerwidestring;
  40. _tcompilerwidestring = record
  41. data : pcompilerwidechar;
  42. maxlen,len : StrLenInt;
  43. end;
  44. procedure initwidestring(var r : pcompilerwidestring);
  45. procedure donewidestring(var r : pcompilerwidestring);
  46. procedure setlengthwidestring(r : pcompilerwidestring;l : StrLenInt);
  47. function getlengthwidestring(r : pcompilerwidestring) : StrLenInt;
  48. procedure concatwidestringchar(r : pcompilerwidestring;c : tcompilerwidechar);
  49. procedure concatwidestrings(s1,s2 : pcompilerwidestring);
  50. function comparewidestrings(s1,s2 : pcompilerwidestring) : StrLenInt;
  51. procedure copywidestring(s,d : pcompilerwidestring);
  52. function asciichar2unicode(c : char) : tcompilerwidechar;
  53. function unicode2asciichar(c : tcompilerwidechar) : char;
  54. procedure ascii2unicode(p : pchar;l : StrLenInt;r : pcompilerwidestring);
  55. procedure unicode2ascii(r : pcompilerwidestring;p : pchar);
  56. function getcharwidestring(r : pcompilerwidestring;l : StrLenInt) : tcompilerwidechar;
  57. function cpavailable(const s : string) : boolean;
  58. implementation
  59. uses
  60. cp8859_1,cp850,cp437,
  61. globals;
  62. procedure initwidestring(var r : pcompilerwidestring);
  63. begin
  64. new(r);
  65. r^.data:=nil;
  66. r^.len:=0;
  67. r^.maxlen:=0;
  68. end;
  69. procedure donewidestring(var r : pcompilerwidestring);
  70. begin
  71. if assigned(r^.data) then
  72. freemem(r^.data);
  73. dispose(r);
  74. r:=nil;
  75. end;
  76. function getcharwidestring(r : pcompilerwidestring;l : StrLenInt) : tcompilerwidechar;
  77. begin
  78. getcharwidestring:=r^.data[l];
  79. end;
  80. function getlengthwidestring(r : pcompilerwidestring) : StrLenInt;
  81. begin
  82. getlengthwidestring:=r^.len;
  83. end;
  84. procedure setlengthwidestring(r : pcompilerwidestring;l : StrLenInt);
  85. begin
  86. if r^.maxlen>=l then
  87. exit;
  88. if assigned(r^.data) then
  89. reallocmem(r^.data,sizeof(tcompilerwidechar)*l)
  90. else
  91. getmem(r^.data,sizeof(tcompilerwidechar)*l);
  92. end;
  93. procedure concatwidestringchar(r : pcompilerwidestring;c : tcompilerwidechar);
  94. begin
  95. if r^.len>=r^.maxlen then
  96. setlengthwidestring(r,r^.len+16);
  97. r^.data[r^.len]:=c;
  98. inc(r^.len);
  99. end;
  100. procedure concatwidestrings(s1,s2 : pcompilerwidestring);
  101. begin
  102. setlengthwidestring(s1,s1^.len+s2^.len);
  103. inc(s1^.len,s2^.len);
  104. move(s2^.data^,s1^.data[s1^.len],s2^.len*sizeof(tcompilerwidechar));
  105. end;
  106. procedure copywidestring(s,d : pcompilerwidestring);
  107. begin
  108. setlengthwidestring(d,s^.len);
  109. d^.len:=s^.len;
  110. move(s^.data^,d^.data^,s^.len*sizeof(tcompilerwidechar));
  111. end;
  112. function comparewidestrings(s1,s2 : pcompilerwidestring) : StrLenInt;
  113. var
  114. maxi,temp : StrLenInt;
  115. begin
  116. if pointer(s1)=pointer(s2) then
  117. begin
  118. comparewidestrings:=0;
  119. exit;
  120. end;
  121. maxi:=s1^.len;
  122. temp:=s2^.len;
  123. if maxi>temp then
  124. maxi:=Temp;
  125. {$ifdef Delphi}
  126. temp:=strlenint(comparemem(@s1^.data,@s2^.data,maxi));
  127. {$else}
  128. temp:=compareword(s1^.data^,s2^.data^,maxi);
  129. {$endif}
  130. if temp=0 then
  131. temp:=s1^.len-s2^.len;
  132. comparewidestrings:=temp;
  133. end;
  134. function asciichar2unicode(c : char) : tcompilerwidechar;
  135. var
  136. m : punicodemap;
  137. begin
  138. m:=getmap(aktsourcecodepage);
  139. asciichar2unicode:=getunicode(c,m);
  140. end;
  141. function unicode2asciichar(c : tcompilerwidechar) : char;
  142. begin
  143. {$ifdef fpc}{$warning todo}{$endif}
  144. unicode2asciichar:=#0;
  145. end;
  146. procedure ascii2unicode(p : pchar;l : StrLenInt;r : pcompilerwidestring);
  147. var
  148. source : pchar;
  149. dest : tcompilerwidecharptr;
  150. i : StrLenInt;
  151. m : punicodemap;
  152. begin
  153. m:=getmap(aktsourcecodepage);
  154. setlengthwidestring(r,l);
  155. source:=p;
  156. r^.len:=l;
  157. dest:=tcompilerwidecharptr(r^.data);
  158. for i:=1 to l do
  159. begin
  160. dest^:=getunicode(source^,m);
  161. inc(dest);
  162. inc(source);
  163. end;
  164. end;
  165. procedure unicode2ascii(r : pcompilerwidestring;p:pchar);
  166. (*
  167. var
  168. m : punicodemap;
  169. i : longint;
  170. begin
  171. m:=getmap(aktsourcecodepage);
  172. { should be a very good estimation :) }
  173. setlengthwidestring(r,length(s));
  174. // !!!! MBCS
  175. for i:=1 to length(s) do
  176. begin
  177. end;
  178. end;
  179. *)
  180. var
  181. source : tcompilerwidecharptr;
  182. dest : pchar;
  183. i : longint;
  184. begin
  185. source:=tcompilerwidecharptr(r^.data);
  186. dest:=p;
  187. for i:=1 to r^.len do
  188. begin
  189. if word(source^)<128 then
  190. dest^:=char(word(source^))
  191. else
  192. dest^:=' ';
  193. inc(dest);
  194. inc(source);
  195. end;
  196. end;
  197. function cpavailable(const s : string) : boolean;
  198. begin
  199. cpavailable:=mappingavailable(s);
  200. end;
  201. end.
  202. {
  203. $Log$
  204. Revision 1.12 2002-10-05 12:43:29 carl
  205. * fixes for Delphi 6 compilation
  206. (warning : Some features do not work under Delphi)
  207. Revision 1.11 2002/07/20 17:16:03 florian
  208. + source code page support
  209. Revision 1.10 2002/05/18 13:34:21 peter
  210. * readded missing revisions
  211. Revision 1.9 2002/05/16 19:46:47 carl
  212. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  213. + try to fix temp allocation (still in ifdef)
  214. + generic constructor calls
  215. + start of tassembler / tmodulebase class cleanup
  216. }