strings.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by 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. unit strings;
  12. { Zero-terminated (ascii-z) string handling }
  13. interface
  14. {$ifndef FPK}
  15. {$E-}
  16. {$endif}
  17. { Returns the length of a string }
  18. function strlen(p : pchar) : longint;
  19. { Converts a Pascal string to a null-terminated string }
  20. function strpcopy(d : pchar;const s : string) : pchar;
  21. { Converts a null-terminated string to a Pascal string }
  22. function strpas(p : pchar) : string;
  23. { Copies source to dest, returns a pointer to dest }
  24. function strcopy(dest,source : pchar) : pchar;
  25. { Copies at most maxlen bytes from source to dest. }
  26. { Returns a pointer to dest }
  27. function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
  28. { Copies source to dest and returns a pointer to the terminating }
  29. { null character. }
  30. function strecopy(dest,source : pchar) : pchar;
  31. { Returns a pointer tro the terminating null character of p }
  32. function strend(p : pchar) : pchar;
  33. { Appends source to dest, returns a pointer do dest}
  34. function strcat(dest,source : pchar) : pchar;
  35. { Compares str1 und str2, returns }
  36. { a value <0 if str1<str2; }
  37. { 0 when str1=str2 }
  38. { and a value >0 if str1>str2 }
  39. function strcomp(str1,str2 : pchar) : longint;
  40. { The same as strcomp, but at most l characters are compared }
  41. function strlcomp(str1,str2 : pchar;l : longint) : longint;
  42. { The same as strcomp but case insensitive }
  43. function stricomp(str1,str2 : pchar) : longint;
  44. { Copies l characters from source to dest, returns dest. }
  45. function strmove(dest,source : pchar;l : longint) : pchar;
  46. { Appends at most l characters from source to dest }
  47. function strlcat(dest,source : pchar;l : longint) : pchar;
  48. { Returns a pointer to the first occurrence of c in p }
  49. { If c doesn't occur, nil is returned }
  50. function strscan(p : pchar;c : char) : pchar;
  51. { Returns a pointer to the last occurrence of c in p }
  52. { If c doesn't occur, nil is returned }
  53. function strrscan(p : pchar;c : char) : pchar;
  54. { converts p to all-lowercase, returns p }
  55. function strlower(p : pchar) : pchar;
  56. { converts p to all-uppercase, returns p }
  57. function strupper(p : pchar) : pchar;
  58. { The same al stricomp, but at most l characters are compared }
  59. function strlicomp(str1,str2 : pchar;l : longint) : longint;
  60. { Returns a pointer to the first occurrence of str2 in }
  61. { str2 Otherwise returns nil }
  62. function strpos(str1,str2 : pchar) : pchar;
  63. { Makes a copy of p on the heap, and returns a pointer to this copy }
  64. function strnew(p : pchar) : pchar;
  65. { Allocates L bytes on the heap, returns a pchar pointer to it }
  66. function stralloc(L : longint) : pchar;
  67. { Releases a null-terminated string from the heap }
  68. procedure strdispose(p : pchar);
  69. implementation
  70. function strcopy(dest,source : pchar) : pchar;
  71. begin
  72. asm
  73. cld
  74. movl 12(%ebp),%edi
  75. movl $0xffffffff,%ecx
  76. xorb %al,%al
  77. repne
  78. scasb
  79. not %ecx
  80. movl 8(%ebp),%edi
  81. movl 12(%ebp),%esi
  82. movl %ecx,%eax
  83. shrl $2,%ecx
  84. rep
  85. movsl
  86. movl %eax,%ecx
  87. andl $3,%ecx
  88. rep
  89. movsb
  90. movl 8(%ebp),%eax
  91. leave
  92. ret $8
  93. end;
  94. end;
  95. function strecopy(dest,source : pchar) : pchar;
  96. begin
  97. asm
  98. cld
  99. movl 12(%ebp),%edi
  100. movl $0xffffffff,%ecx
  101. xorl %eax,%eax
  102. repne
  103. scasb
  104. not %ecx
  105. movl 8(%ebp),%edi
  106. movl 12(%ebp),%esi
  107. movl %ecx,%eax
  108. shrl $2,%ecx
  109. rep
  110. movsl
  111. movl %eax,%ecx
  112. andl $3,%ecx
  113. rep
  114. movsb
  115. movl 8(%ebp),%eax
  116. decl %edi
  117. movl %edi,%eax
  118. leave
  119. ret $8
  120. end ['EAX','ESI','EDI'];
  121. end;
  122. function strlcopy(dest,source : pchar;maxlen : longint) : pchar;
  123. begin
  124. asm
  125. movl 8(%ebp),%edi
  126. movl 12(%ebp),%esi
  127. movl 16(%ebp),%ecx
  128. cld
  129. .LSTRLCOPY1:
  130. lodsb
  131. stosb
  132. decl %ecx // Lower maximum
  133. jz .LSTRLCOPY2 // 0 reached ends
  134. orb %al,%al
  135. jnz .LSTRLCOPY1
  136. movl 8(%ebp),%eax
  137. leave
  138. ret $12
  139. .LSTRLCOPY2:
  140. xorb %al,%al // If cutted
  141. stosb // add a #0
  142. movl 8(%ebp),%eax
  143. leave
  144. ret $12
  145. end ['EAX','ECX','ESI','EDI'];
  146. end;
  147. function strlen(p : pchar) : longint;
  148. begin
  149. asm
  150. cld
  151. movl 8(%ebp),%edi
  152. movl $0xffffffff,%ecx
  153. xorl %eax,%eax
  154. repne
  155. scasb
  156. movl $0xfffffffe,%eax
  157. subl %ecx,%eax
  158. leave
  159. ret $4
  160. end ['EDI','ECX','EAX'];
  161. end;
  162. function strend(p : pchar) : pchar;
  163. begin
  164. asm
  165. cld
  166. movl 8(%ebp),%edi
  167. movl $0xffffffff,%ecx
  168. xorl %eax,%eax
  169. repne
  170. scasb
  171. movl %edi,%eax
  172. decl %eax
  173. leave
  174. ret $4
  175. end ['EDI','ECX','EAX'];
  176. end;
  177. function strpcopy(d : pchar;const s : string) : pchar;
  178. begin
  179. asm
  180. pushl %esi // Save ESI
  181. cld
  182. movl 8(%ebp),%edi // load destination address
  183. movl 12(%ebp),%esi // Load Source adress
  184. movl %edi,%ebx // Set return value
  185. lodsb // load length in ECX
  186. movzbl %al,%ecx
  187. rep
  188. movsb
  189. xorb %al,%al // Set #0
  190. stosb
  191. movl %ebx,%eax // return value to EAX
  192. popl %esi
  193. leave // ... and ready
  194. ret $8
  195. end ['EDI','ESI','EBX','EAX','ECX'];
  196. end;
  197. function strpas(p : pchar) : string;
  198. begin
  199. asm
  200. cld
  201. movl 12(%ebp),%edi
  202. movl $0xff,%ecx
  203. xorl %eax,%eax
  204. movl %edi,%esi
  205. repne
  206. scasb
  207. movl %ecx,%eax
  208. movl 8(%ebp),%edi
  209. notb %al
  210. decl %eax
  211. stosb
  212. cmpl $7,%eax
  213. jl .LStrPas2
  214. movl %edi,%ecx # Align on 32bits
  215. negl %ecx
  216. andl $3,%ecx
  217. subl %ecx,%eax
  218. rep
  219. movsb
  220. movl %eax,%ecx
  221. andl $3,%eax
  222. shrl $2,%ecx
  223. rep
  224. movsl
  225. .LStrPas2:
  226. movl %eax,%ecx
  227. rep
  228. movsb
  229. end ['ECX','EAX','ESI','EDI'];
  230. end;
  231. function strcat(dest,source : pchar) : pchar;
  232. begin
  233. strcat:=strcopy(strend(dest),source);
  234. end;
  235. function strlcat(dest,source : pchar;l : longint) : pchar;
  236. var
  237. destend : pchar;
  238. begin
  239. destend:=strend(dest);
  240. l:=l-(destend-dest);
  241. strlcat:=strlcopy(destend,source,l);
  242. end;
  243. function strcomp(str1,str2 : pchar) : longint;
  244. begin
  245. asm
  246. // Find terminating zero
  247. movl 12(%ebp),%edi
  248. movl $0xffffffff,%ecx
  249. cld
  250. xorl %eax,%eax
  251. repne
  252. scasb
  253. not %ecx
  254. movl 12(%ebp),%edi
  255. movl 8(%ebp),%esi
  256. repe
  257. cmpsb
  258. movb -1(%esi),%al
  259. movzbl -1(%edi),%ecx
  260. subl %ecx,%eax
  261. leave
  262. ret $8
  263. end ['EAX','ECX','ESI','EDI'];
  264. end;
  265. function strlcomp(str1,str2 : pchar;l : longint) : longint;
  266. begin
  267. asm
  268. // Find terminating zero
  269. movl 12(%ebp),%edi
  270. movl $0xffffffff,%ecx
  271. cld
  272. xorl %eax,%eax
  273. repne
  274. scasb
  275. not %ecx
  276. cmpl 16(%ebp),%ecx
  277. jl .LSTRLCOMP1
  278. movl 16(%ebp),%ecx
  279. .LSTRLCOMP1:
  280. movl 12(%ebp),%edi
  281. movl 8(%ebp),%esi
  282. repe
  283. cmpsb
  284. movb -1(%esi),%al
  285. movzbl -1(%edi),%ecx
  286. subl %ecx,%eax
  287. leave
  288. ret $12
  289. end ['EAX','ECX','ESI','EDI'];
  290. end;
  291. function stricomp(str1,str2 : pchar) : longint;
  292. begin
  293. asm
  294. // Find terminating zero
  295. movl 12(%ebp),%edi
  296. movl $0xffffffff,%ecx
  297. cld
  298. xorl %eax,%eax
  299. repne
  300. scasb
  301. not %ecx
  302. movl 12(%ebp),%edi
  303. movl 8(%ebp),%esi
  304. .LSTRICOMP2:
  305. repe
  306. cmpsb
  307. jz .LSTRICOMP3 // If last reached then exit
  308. movb (%esi),%al
  309. movzbl (%edi),%ebx
  310. cmpb $97,%al
  311. jb .LSTRICOMP1
  312. cmpb $122,%al
  313. ja .LSTRICOMP1
  314. subb $0x20,%al
  315. .LSTRICOMP1:
  316. cmpb $97,%bl
  317. jb .LSTRICOMP4
  318. cmpb $122,%bl
  319. ja .LSTRICOMP4
  320. subb $0x20,%bl
  321. .LSTRICOMP4:
  322. subl %ebx,%eax
  323. jz .LSTRICOMP2 // If still equal, compare again
  324. .LSTRICOMP3:
  325. leave
  326. ret $8
  327. end ['EAX','ECX','ESI','EDI'];
  328. end;
  329. function strlicomp(str1,str2 : pchar;l : longint) : longint;
  330. begin
  331. asm
  332. // Search terminating zero
  333. movl 12(%ebp),%edi
  334. movl $0xffffffff,%ecx
  335. cld
  336. xorl %eax,%eax
  337. repne
  338. scasb
  339. not %ecx
  340. cmpl 16(%ebp),%ecx
  341. jl .LSTRLICOMP5
  342. movl 16(%ebp),%ecx
  343. .LSTRLICOMP5:
  344. movl 12(%ebp),%edi
  345. movl 8(%ebp),%esi
  346. .LSTRLICOMP2:
  347. repe
  348. cmpsb
  349. jz .LSTRLICOMP3 // If last reached, exit
  350. movb (%esi),%al
  351. movzbl (%edi),%ebx
  352. cmpb $97,%al
  353. jb .LSTRLICOMP1
  354. cmpb $122,%al
  355. ja .LSTRLICOMP1
  356. subb $0x20,%al
  357. .LSTRLICOMP1:
  358. cmpb $97,%bl
  359. jb .LSTRLICOMP4
  360. cmpb $122,%bl
  361. ja .LSTRLICOMP4
  362. subb $0x20,%bl
  363. .LSTRLICOMP4:
  364. subl %ebx,%eax
  365. jz .LSTRLICOMP2
  366. .LSTRLICOMP3:
  367. leave
  368. ret $12
  369. end ['EAX','ECX','ESI','EDI'];
  370. end;
  371. function strmove(dest,source : pchar;l : longint) : pchar;
  372. begin
  373. move(source^,dest^,l);
  374. strmove:=dest;
  375. end;
  376. function strscan(p : pchar;c : char) : pchar;
  377. begin
  378. asm
  379. movl 8(%ebp),%edi
  380. movl $0xffffffff,%ecx
  381. cld
  382. xorb %al,%al
  383. repne
  384. scasb
  385. not %ecx
  386. movb 12(%ebp),%al
  387. movl 8(%ebp),%edi
  388. repne
  389. scasb
  390. movl $0,%eax
  391. jnz .LSTRSCAN
  392. movl %edi,%eax
  393. decl %eax
  394. .LSTRSCAN:
  395. leave
  396. ret $6
  397. end;
  398. end;
  399. function strrscan(p : pchar;c : char) : pchar;
  400. begin
  401. asm
  402. movl 8(%ebp),%edi
  403. movl $0xffffffff,%ecx
  404. cld
  405. xorb %al,%al
  406. repne
  407. scasb
  408. not %ecx
  409. movb 12(%ebp),%al
  410. movl 8(%ebp),%edi
  411. addl %ecx,%edi
  412. decl %edi
  413. std
  414. repne
  415. scasb
  416. movl $0,%eax
  417. jnz .LSTRRSCAN
  418. movl %edi,%eax
  419. incl %eax
  420. .LSTRRSCAN:
  421. leave
  422. ret $6
  423. end;
  424. end;
  425. function strupper(p : pchar) : pchar;
  426. begin
  427. asm
  428. movl 8(%ebp),%esi
  429. movl %esi,%edi
  430. .LSTRUPPER1:
  431. lodsb
  432. cmpb $97,%al
  433. jb .LSTRUPPER3
  434. cmpb $122,%al
  435. ja .LSTRUPPER3
  436. subb $0x20,%al
  437. .LSTRUPPER3:
  438. stosb
  439. orb %al,%al
  440. jnz .LSTRUPPER1
  441. movl 8(%ebp),%eax
  442. leave
  443. ret $4
  444. end;
  445. end;
  446. function strlower(p : pchar) : pchar;
  447. begin
  448. asm
  449. movl 8(%ebp),%esi
  450. movl %esi,%edi
  451. .LSTRLOWER1:
  452. lodsb
  453. cmpb $65,%al
  454. jb .LSTRLOWER3
  455. cmpb $90,%al
  456. ja .LSTRLOWER3
  457. addb $0x20,%al
  458. .LSTRLOWER3:
  459. stosb
  460. orb %al,%al
  461. jnz .LSTRLOWER1
  462. movl 8(%ebp),%eax
  463. leave
  464. ret $4
  465. end;
  466. end;
  467. function strpos(str1,str2 : pchar) : pchar;
  468. var
  469. p : pchar;
  470. lstr2 : longint;
  471. begin
  472. strpos:=nil;
  473. p:=strscan(str1,str2^);
  474. if p=nil then
  475. exit;
  476. lstr2:=strlen(str2);
  477. while p<>nil do
  478. begin
  479. if strlcomp(p,str2,lstr2)=0 then
  480. begin
  481. strpos:=p;
  482. exit;
  483. end;
  484. inc(longint(p));
  485. p:=strscan(p,str2^);
  486. end;
  487. end;
  488. procedure strdispose(p : pchar);
  489. begin
  490. if p<>nil then
  491. freemem(p,strlen(p)+1);
  492. end;
  493. function strnew(p : pchar) : pchar;
  494. var
  495. len : longint;
  496. begin
  497. strnew:=nil;
  498. if (p=nil) or (p^=#0) then
  499. exit;
  500. len:=strlen(p)+1;
  501. getmem(strnew,len);
  502. if strnew<>nil then
  503. strmove(strnew,p,len);
  504. end;
  505. function stralloc(L : longint) : pchar;
  506. begin
  507. StrAlloc:=Nil;
  508. GetMem (Stralloc,l);
  509. end;
  510. end.
  511. {
  512. $Log$
  513. Revision 1.1 1998-03-25 11:18:42 root
  514. Initial revision
  515. Revision 1.7 1998/02/24 17:50:46 peter
  516. * upto 100% (255's char is different ;) faster STRCMP
  517. * faster StrPas from i386.inc also strings.pp
  518. Revision 1.6 1998/01/26 11:59:12 michael
  519. + Added log at the end
  520. revision 1.5
  521. date: 1998/01/16 16:14:08; author: michael; state: Exp; lines: +11 -1
  522. + Implemented StrAlloc() function.
  523. ----------------------------
  524. revision 1.4
  525. date: 1997/12/01 18:21:39; author: pierre; state: Exp; lines: +2 -2
  526. * small bug without importance fixed
  527. in strrscan a call to a label in strscan was called
  528. ----------------------------
  529. revision 1.3
  530. date: 1997/12/01 12:34:38; author: michael; state: Exp; lines: +11 -4
  531. + added copyright reference in header.
  532. ----------------------------
  533. revision 1.2
  534. date: 1997/11/28 18:59:10; author: pierre; state: Exp; lines: +42 -42
  535. local labels prefixed with .L
  536. ----------------------------
  537. revision 1.1
  538. date: 1997/11/27 08:33:47; author: michael; state: Exp;
  539. Initial revision
  540. ----------------------------
  541. revision 1.1.1.1
  542. date: 1997/11/27 08:33:47; author: michael; state: Exp; lines: +0 -0
  543. FPC RTL CVS start
  544. =============================================================================
  545. 1.5.1994: Version 0.9
  546. Unit ist komplett implementiert (noch nicht getestet)
  547. 20.3.1995: Version 0.91
  548. strmove korriert, f�r system.move m�ssen Pointer
  549. dereferenziert werden
  550. 24.12.1995: Version 0.92
  551. strcomp war fehlerhaft; korrigiert
  552. dito strlcomp
  553. }