genstr.inc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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: PChar): PChar;
  13. var
  14. counter: SizeInt;
  15. begin
  16. counter := 0;
  17. if not Assigned(P) then
  18. StrEnd:=Nil
  19. else
  20. begin
  21. while P[counter] <> #0 do
  22. Inc(counter);
  23. StrEnd := @(P[Counter]);
  24. end;
  25. end;
  26. {$endif FPC_UNIT_HAS_STREND}
  27. {$ifndef FPC_UNIT_HAS_STRCOPY}
  28. { Beware, the naive implementation (copying bytes forward until zero
  29. is encountered) will end up in undefined behavior if source and dest
  30. happen to overlap. So do it in a bit more reliable way.
  31. Also this implementation should not need per-platform optimization,
  32. given that IndexByte and Move are optimized. }
  33. Function StrCopy(Dest, Source:PChar): PChar;
  34. var
  35. counter : SizeInt;
  36. Begin
  37. counter := IndexByte(Source^,-1,0);
  38. { counter+1 will move zero terminator }
  39. Move(Source^,Dest^,counter+1);
  40. StrCopy := Dest;
  41. end;
  42. {$endif FPC_UNIT_HAS_STRCOPY}
  43. {$ifndef FPC_UNIT_HAS_STRUPPER}
  44. function StrUpper(P: PChar): PChar;
  45. var
  46. counter: SizeInt;
  47. begin
  48. counter := 0;
  49. while (P[counter] <> #0) do
  50. begin
  51. if P[Counter] in [#97..#122,#128..#255] then
  52. P[counter] := Upcase(P[counter]);
  53. Inc(counter);
  54. end;
  55. StrUpper := P;
  56. end;
  57. {$endif FPC_UNIT_HAS_STRUPPER}
  58. {$ifndef FPC_UNIT_HAS_STRLOWER}
  59. function StrLower(P: PChar): PChar;
  60. var
  61. counter: SizeInt;
  62. begin
  63. counter := 0;
  64. while (P[counter] <> #0) do
  65. begin
  66. if P[counter] in [#65..#90] then
  67. P[Counter] := chr(ord(P[Counter]) + 32);
  68. Inc(counter);
  69. end;
  70. StrLower := P;
  71. end;
  72. {$endif FPC_UNIT_HAS_STRLOWER}
  73. {$ifndef FPC_UNIT_HAS_STRSCAN}
  74. function StrScan(P: PChar; C: Char): PChar;
  75. Var
  76. count: SizeInt;
  77. Begin
  78. count := 0;
  79. { As in Borland Pascal , if looking for NULL return null }
  80. if C = #0 then
  81. begin
  82. StrScan := @(P[StrLen(P)]);
  83. exit;
  84. end;
  85. { Find first matching character of Ch in Str }
  86. while P[count] <> #0 do
  87. begin
  88. if C = P[count] then
  89. begin
  90. StrScan := @(P[count]);
  91. exit;
  92. end;
  93. Inc(count);
  94. end;
  95. { nothing found. }
  96. StrScan := nil;
  97. end;
  98. {$endif FPC_UNIT_HAS_STRSCAN}
  99. {$ifndef FPC_UNIT_HAS_STRISCAN}
  100. function StrIScan(P: PChar; C: Char): PChar;
  101. Var
  102. count: SizeInt;
  103. UC: Char;
  104. Begin
  105. UC := upcase(C);
  106. count := 0;
  107. { As in Borland Pascal , if looking for NULL return null }
  108. if UC = #0 then
  109. begin
  110. StrIScan := @(P[StrLen(P)]);
  111. exit;
  112. end;
  113. { Find first matching character of Ch in Str }
  114. while P[count] <> #0 do
  115. begin
  116. if UC = upcase(P[count]) then
  117. begin
  118. StrIScan := @(P[count]);
  119. exit;
  120. end;
  121. Inc(count);
  122. end;
  123. { nothing found. }
  124. StrIScan := nil;
  125. end;
  126. {$endif FPC_UNIT_HAS_STRSCAN}
  127. {$ifndef FPC_UNIT_HAS_STRRSCAN}
  128. function StrRScan(P: PChar; C: Char): PChar;
  129. Var
  130. count: SizeInt;
  131. index: SizeInt;
  132. Begin
  133. count := Strlen(P);
  134. { As in Borland Pascal , if looking for NULL return null }
  135. if C = #0 then
  136. begin
  137. StrRScan := @(P[count]);
  138. exit;
  139. end;
  140. Dec(count);
  141. for index := count downto 0 do
  142. begin
  143. if C = P[index] then
  144. begin
  145. StrRScan := @(P[index]);
  146. exit;
  147. end;
  148. end;
  149. { nothing found. }
  150. StrRScan := nil;
  151. end;
  152. {$endif FPC_UNIT_HAS_STRRSCAN}
  153. {$ifndef FPC_UNIT_HAS_STRRISCAN}
  154. function StrRIScan(P: PChar; C: Char): PChar;
  155. Var
  156. count: SizeInt;
  157. index: SizeInt;
  158. UC: Char;
  159. Begin
  160. UC := upcase(C);
  161. count := Strlen(P);
  162. { As in Borland Pascal , if looking for NULL return null }
  163. if UC = #0 then
  164. begin
  165. StrRIScan := @(P[count]);
  166. exit;
  167. end;
  168. Dec(count);
  169. for index := count downto 0 do
  170. begin
  171. if UC = upcase(P[index]) then
  172. begin
  173. StrRIScan := @(P[index]);
  174. exit;
  175. end;
  176. end;
  177. { nothing found. }
  178. StrRIScan := nil;
  179. end;
  180. {$endif FPC_UNIT_HAS_STRRSCAN}
  181. {$ifndef FPC_UNIT_HAS_STRECOPY}
  182. Function StrECopy(Dest, Source: PChar): PChar;
  183. { Equivalent to the following: }
  184. { strcopy(Dest,Source); }
  185. { StrECopy := StrEnd(Dest); }
  186. var
  187. counter : SizeInt;
  188. Begin
  189. counter := IndexByte(Source^,-1,0);
  190. { counter+1 will move zero terminator }
  191. Move(Source^,Dest^,counter+1);
  192. StrECopy := Dest+counter;
  193. end;
  194. {$endif FPC_UNIT_HAS_STRECOPY}
  195. {$ifndef FPC_UNIT_HAS_STRLCOPY}
  196. Function StrLCopy(Dest,Source: PChar; MaxLen: SizeInt): PChar;
  197. var
  198. counter: SizeInt;
  199. Begin
  200. counter := 0;
  201. { To be compatible with BP, on a null string, put two nulls }
  202. If Source[0] = #0 then
  203. Begin
  204. Dest[0]:=Source[0];
  205. Inc(counter);
  206. end;
  207. while (Source[counter] <> #0) and (counter < MaxLen) do
  208. Begin
  209. Dest[counter] := char(Source[counter]);
  210. Inc(counter);
  211. end;
  212. { terminate the string }
  213. Dest[counter] := #0;
  214. StrLCopy := Dest;
  215. end;
  216. {$endif FPC_UNIT_HAS_STRLCOPY}
  217. {$ifndef FPC_UNIT_HAS_STRCOMP}
  218. function StrComp(Str1, Str2 : PChar): SizeInt;
  219. var
  220. counter: SizeInt;
  221. Begin
  222. counter := 0;
  223. While str1[counter] = str2[counter] do
  224. Begin
  225. if (str2[counter] = #0) or (str1[counter] = #0) then
  226. break;
  227. Inc(counter);
  228. end;
  229. StrComp := ord(str1[counter]) - ord(str2[counter]);
  230. end;
  231. {$endif FPC_UNIT_HAS_STRCOMP}
  232. {$ifndef FPC_UNIT_HAS_STRICOMP}
  233. function StrIComp(Str1, Str2 : PChar): SizeInt;
  234. var
  235. counter: SizeInt;
  236. c1, c2: char;
  237. Begin
  238. counter := 0;
  239. c1 := upcase(str1[counter]);
  240. c2 := upcase(str2[counter]);
  241. While c1 = c2 do
  242. Begin
  243. if (c1 = #0) or (c2 = #0) then break;
  244. Inc(counter);
  245. c1 := upcase(str1[counter]);
  246. c2 := upcase(str2[counter]);
  247. end;
  248. StrIComp := ord(c1) - ord(c2);
  249. end;
  250. {$endif FPC_UNIT_HAS_STRICOMP}
  251. {$ifndef FPC_UNIT_HAS_STRLCOMP}
  252. function StrLComp(Str1, Str2 : PChar; L: SizeInt): SizeInt;
  253. var
  254. counter: SizeInt;
  255. c1, c2: char;
  256. Begin
  257. counter := 0;
  258. if L = 0 then
  259. begin
  260. StrLComp := 0;
  261. exit;
  262. end;
  263. Repeat
  264. c1 := str1[counter];
  265. c2 := str2[counter];
  266. if (c1 = #0) or (c2 = #0) then break;
  267. Inc(counter);
  268. Until (c1 <> c2) or (counter >= L);
  269. StrLComp := ord(c1) - ord(c2);
  270. end;
  271. {$endif FPC_UNIT_HAS_STRLCOMP}
  272. {$ifndef FPC_UNIT_HAS_STRLICOMP}
  273. function StrLIComp(Str1, Str2 : PChar; L: SizeInt): SizeInt;
  274. var
  275. counter: SizeInt;
  276. c1, c2: char;
  277. Begin
  278. counter := 0;
  279. if L = 0 then
  280. begin
  281. StrLIComp := 0;
  282. exit;
  283. end;
  284. Repeat
  285. c1 := upcase(str1[counter]);
  286. c2 := upcase(str2[counter]);
  287. if (c1 = #0) or (c2 = #0) then break;
  288. Inc(counter);
  289. Until (c1 <> c2) or (counter >= L);
  290. StrLIComp := ord(c1) - ord(c2);
  291. end;
  292. {$endif FPC_UNIT_HAS_STRLICOMP}