widestr.pas 6.8 KB

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