genstr.inc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Carl-Eric Codere,
  4. member of the Free Pascal development team.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$ifndef FPC_UNIT_HAS_STREND}
  12. Function StrEnd(P: PAnsiChar): PAnsiChar;
  13. begin
  14. StrEnd := P;
  15. if Assigned(StrEnd) then
  16. Inc(StrEnd, IndexByte(StrEnd^, -1, 0));
  17. end;
  18. {$endif FPC_UNIT_HAS_STREND}
  19. {$ifndef FPC_UNIT_HAS_STRCOPY}
  20. { Beware, the naive implementation (copying bytes forward until zero
  21. is encountered) will end up in undefined behavior if source and dest
  22. happen to overlap. So do it in a bit more reliable way.
  23. Also this implementation should not need per-platform optimization,
  24. given that IndexByte and Move are optimized. }
  25. Function StrCopy(Dest, Source:PAnsiChar): PAnsiChar;
  26. var
  27. counter : SizeInt;
  28. Begin
  29. counter := IndexByte(Source^,-1,0);
  30. { counter+1 will move zero terminator }
  31. Move(Source^,Dest^,counter+1);
  32. StrCopy := Dest;
  33. end;
  34. {$endif FPC_UNIT_HAS_STRCOPY}
  35. {$ifndef FPC_UNIT_HAS_STRUPPER}
  36. function StrUpper(P: PAnsiChar): PAnsiChar;
  37. var
  38. counter: SizeInt;
  39. begin
  40. counter := 0;
  41. while (P[counter] <> #0) do
  42. begin
  43. if P[Counter] in [#97..#122,#128..#255] then
  44. P[counter] := Upcase(P[counter]);
  45. Inc(counter);
  46. end;
  47. StrUpper := P;
  48. end;
  49. {$endif FPC_UNIT_HAS_STRUPPER}
  50. {$ifndef FPC_UNIT_HAS_STRLOWER}
  51. function StrLower(P: PAnsiChar): PAnsiChar;
  52. var
  53. counter: SizeInt;
  54. begin
  55. counter := 0;
  56. while (P[counter] <> #0) do
  57. begin
  58. if P[counter] in [#65..#90] then
  59. P[Counter] := chr(ord(P[Counter]) + 32);
  60. Inc(counter);
  61. end;
  62. StrLower := P;
  63. end;
  64. {$endif FPC_UNIT_HAS_STRLOWER}
  65. {$ifndef FPC_UNIT_HAS_STRSCAN}
  66. function StrScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
  67. Begin
  68. dec(P);
  69. repeat
  70. inc(P);
  71. until (P^ = #0) or (P^ = C);
  72. if (P^ = #0) and (C <> #0) then
  73. P := nil;
  74. StrScan := P;
  75. end;
  76. {$endif FPC_UNIT_HAS_STRSCAN}
  77. {$ifndef FPC_UNIT_HAS_STRISCAN}
  78. function StrIScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
  79. Var
  80. count: SizeInt;
  81. UC: AnsiChar;
  82. Begin
  83. UC := upcase(C);
  84. count := 0;
  85. { As in Borland Pascal , if looking for NULL return null }
  86. if UC = #0 then
  87. begin
  88. StrIScan := @(P[StrLen(P)]);
  89. exit;
  90. end;
  91. { Find first matching character of Ch in Str }
  92. while P[count] <> #0 do
  93. begin
  94. if UC = upcase(P[count]) then
  95. begin
  96. StrIScan := @(P[count]);
  97. exit;
  98. end;
  99. Inc(count);
  100. end;
  101. { nothing found. }
  102. StrIScan := nil;
  103. end;
  104. {$endif FPC_UNIT_HAS_STRSCAN}
  105. {$ifndef FPC_UNIT_HAS_STRRSCAN}
  106. function StrRScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
  107. Begin
  108. StrRScan := P + IndexByte(P^, -1, 0);
  109. { As in Borland Pascal , if looking for NULL return null }
  110. if C = #0 then
  111. exit;
  112. while (StrRScan <> P) and (StrRScan[-1] <> C) do
  113. dec(StrRScan);
  114. if StrRScan = P then
  115. StrRScan := nil
  116. else
  117. dec(StrRScan);
  118. end;
  119. {$endif FPC_UNIT_HAS_STRRSCAN}
  120. {$ifndef FPC_UNIT_HAS_STRRISCAN}
  121. function StrRIScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
  122. Var
  123. count: SizeInt;
  124. index: SizeInt;
  125. UC: AnsiChar;
  126. Begin
  127. UC := upcase(C);
  128. count := Strlen(P);
  129. { As in Borland Pascal , if looking for NULL return null }
  130. if UC = #0 then
  131. begin
  132. StrRIScan := @(P[count]);
  133. exit;
  134. end;
  135. Dec(count);
  136. for index := count downto 0 do
  137. begin
  138. if UC = upcase(P[index]) then
  139. begin
  140. StrRIScan := @(P[index]);
  141. exit;
  142. end;
  143. end;
  144. { nothing found. }
  145. StrRIScan := nil;
  146. end;
  147. {$endif FPC_UNIT_HAS_STRRSCAN}
  148. {$ifndef FPC_UNIT_HAS_STRECOPY}
  149. Function StrECopy(Dest, Source: PAnsiChar): PAnsiChar;
  150. { Equivalent to the following: }
  151. { strcopy(Dest,Source); }
  152. { StrECopy := StrEnd(Dest); }
  153. var
  154. counter : SizeInt;
  155. Begin
  156. counter := IndexByte(Source^,-1,0);
  157. { counter+1 will move zero terminator }
  158. Move(Source^,Dest^,counter+1);
  159. StrECopy := Dest+counter;
  160. end;
  161. {$endif FPC_UNIT_HAS_STRECOPY}
  162. {$ifndef FPC_UNIT_HAS_STRLCOPY}
  163. Function StrLCopy(Dest,Source: PAnsiChar; MaxLen: SizeInt): PAnsiChar;
  164. var
  165. nmove: SizeInt;
  166. Begin
  167. { To be compatible with BP, on a null string, put two nulls }
  168. If Source[0] = #0 then
  169. unaligned(PUint16(Dest)^):=0
  170. else
  171. begin
  172. if MaxLen < 0 then MaxLen := 0; { Paranoia. }
  173. nmove := IndexByte(Source^,MaxLen,0) + 1;
  174. if nmove = 0 then
  175. begin
  176. nmove := MaxLen;
  177. Dest[MaxLen] := #0;
  178. end;
  179. Move(Source^,Dest^,nmove);
  180. end;
  181. StrLCopy := Dest;
  182. end;
  183. {$endif FPC_UNIT_HAS_STRLCOPY}
  184. {$ifndef FPC_UNIT_HAS_STRCOMP}
  185. function StrComp(Str1, Str2 : PAnsiChar): SizeInt;
  186. var
  187. counter: SizeInt;
  188. sample: char;
  189. Begin
  190. counter := -1;
  191. repeat
  192. inc(counter);
  193. sample := str1[counter];
  194. until (sample = #0) or (sample <> str2[counter]);
  195. StrComp := ord(sample) - ord(str2[counter]);
  196. end;
  197. {$endif FPC_UNIT_HAS_STRCOMP}
  198. {$ifndef FPC_UNIT_HAS_STRICOMP}
  199. function StrIComp(Str1, Str2 : PAnsiChar): SizeInt;
  200. Begin
  201. dec(Str1);
  202. dec(Str2);
  203. repeat
  204. inc(Str1);
  205. inc(Str2);
  206. StrIComp := ord(Str1^) - ord(Str2^);
  207. if Str1^ = #0 then break;
  208. if StrIComp = 0 then continue;
  209. StrIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
  210. if StrIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
  211. until false;
  212. end;
  213. {$endif FPC_UNIT_HAS_STRICOMP}
  214. {$ifndef FPC_UNIT_HAS_STRLCOMP}
  215. function StrLComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
  216. Begin
  217. while (L > 0) and (Str1^ <> #0) and (Str1^ = Str2^) do
  218. begin
  219. inc(Str1);
  220. inc(Str2);
  221. dec(L);
  222. end;
  223. if L <= 0 then StrLComp := 0 else StrLComp := ord(Str1^) - ord(Str2^);
  224. end;
  225. {$endif FPC_UNIT_HAS_STRLCOMP}
  226. {$ifndef FPC_UNIT_HAS_STRLICOMP}
  227. function StrLIComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
  228. Begin
  229. dec(Str1);
  230. dec(Str2);
  231. inc(L);
  232. StrLIComp := 0;
  233. Repeat
  234. dec(L);
  235. if L <= 0 then break;
  236. inc(Str1);
  237. inc(Str2);
  238. StrLIComp := ord(Str1^) - ord(Str2^);
  239. if Str1^ = #0 then break;
  240. if StrLIComp = 0 then continue;
  241. StrLIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
  242. if StrLIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
  243. until false;
  244. end;
  245. {$endif FPC_UNIT_HAS_STRLICOMP}