home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1995 December / SOFM_Dec1995.bin / pc / os2 / vpascal / source / rtl / strings.pas < prev    next >
Pascal/Delphi Source File  |  1995-10-31  |  17KB  |  532 lines

  1. {█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
  2. {█                                                       █}
  3. {█      Virtual Pascal Runtime Library.  Version 1.0.    █}
  4. {█      String Handling Unit (ASCIIZ)                    █}
  5. {█      ─────────────────────────────────────────────────█}
  6. {█      Copyright (C) 1995 B&M&T Corporation             █}
  7. {█      ─────────────────────────────────────────────────█}
  8. {█      Written by Vitaly Miryanov                       █}
  9. {█                                                       █}
  10. {▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}
  11. {$S-,R-,Q-,I-,Cdecl-,OrgName-,AlignRec-}
  12.  
  13. unit Strings;
  14.  
  15. interface
  16.  
  17. uses Use32;
  18.  
  19. function StrLen(Str: PChar): Word;
  20. function StrEnd(Str: PChar): PChar;
  21. function StrMove(Dest, Source: PChar; Count: Word): PChar;
  22. function StrCopy(Dest, Source: PChar): PChar;
  23. function StrECopy(Dest, Source: PChar): PChar;
  24. function StrLCopy(Dest, Source: PChar; MaxLen: Word): PChar;
  25. function StrPCopy(Dest: PChar; Source: String): PChar;
  26. function StrCat(Dest, Source: PChar): PChar;
  27. function StrLCat(Dest, Source: PChar; MaxLen: Word): PChar;
  28. function StrComp(Str1, Str2: PChar): Integer;
  29. function StrIComp(Str1, Str2: PChar): Integer;
  30. function StrLComp(Str1, Str2: PChar; MaxLen: Word): Integer;
  31. function StrLIComp(Str1, Str2: PChar; MaxLen: Word): Integer;
  32. function StrScan(Str: PChar; Chr: Char): PChar;
  33. function StrRScan(Str: PChar; Chr: Char): PChar;
  34. function StrPos(Str1, Str2: PChar): PChar;
  35. function StrUpper(Str: PChar): PChar;
  36. function StrLower(Str: PChar): PChar;
  37. function StrPas(Str: PChar): String;
  38. function StrNew(Str: PChar): PChar;
  39. procedure StrDispose(Str: PChar);
  40.  
  41. implementation
  42.  
  43. { Returns the number of characters in Str, not counting the null        }
  44. { terminator.                                                           }
  45.  
  46. function StrLen(Str: PChar): Word; assembler; {$USES edi} {$FRAME-}
  47. asm
  48.                 cld
  49.                 mov     edi,Str
  50.                 or      ecx,-1
  51.                 xor     eax,eax
  52.                 repne   scasb
  53.                 sub     eax,ecx
  54.         sub    eax,2
  55. end;
  56.  
  57. { Returns a pointer to the null character that terminates Str.          }
  58.  
  59. function StrEnd(Str: PChar): PChar; assembler; {$USES edi} {$FRAME-}
  60. asm
  61.                 cld
  62.                 mov     edi,Str
  63.                 or      ecx,-1
  64.                 xor     al,al
  65.                 repne   scasb
  66.                 lea     eax,[edi-1]
  67. end;
  68.  
  69. { Copies exactly Count characters from Source to Dest and returns Dest. }
  70. { Source and Dest may overlap.                                          }
  71.  
  72. function StrMove(Dest, Source: PChar; Count: Word): PChar; assembler; {$USES esi,edi} {$FRAME-}
  73. asm
  74.                 mov     esi,Source
  75.                 mov     edi,Dest
  76.                 mov     edx,edi
  77.                 mov     ecx,Count
  78.                 cmp     esi,edi
  79.                 jae     @@1
  80.                 std
  81.                 add     esi,ecx
  82.                 add     edi,ecx
  83.                 mov     eax,ecx
  84.                 and     ecx,11b
  85.                 shr     eax,2
  86.                 dec     esi
  87.                 dec     edi
  88.                 rep     movsb
  89.                 mov     ecx,eax
  90.                 sub     esi,3
  91.                 sub     edi,3
  92.                 rep     movsd
  93.                 jmp     @@2
  94.               @@1:
  95.                 cld
  96.                 mov     eax,ecx
  97.                 shr     ecx,2
  98.                 and     al,11b
  99.                 rep     movsd
  100.                 mov     cl,al
  101.                 rep     movsb
  102.               @@2:
  103.                 mov     eax,edx
  104. end;
  105.  
  106. { Copies Source to Dest and returns Dest.                               }
  107.  
  108. function StrCopy(Dest, Source: PChar): PChar; assembler; {$USES esi,edi} {$FRAME-}
  109. asm
  110.                 cld
  111.                 mov     edi,Source
  112.                 mov     esi,edi
  113.                 xor     al,al
  114.                 or      ecx,-1
  115.                 repne   scasb
  116.                 not     ecx
  117.                 mov     dl,cl
  118.                 mov     edi,Dest
  119.                 mov     eax,edi
  120.                 shr     ecx,2
  121.                 and     dl,11b
  122.                 rep     movsd
  123.                 mov     cl,dl
  124.                 rep     movsb
  125. end;
  126.  
  127. { Copies Source to Dest and returns StrEnd(Dest).                       }
  128.  
  129. function StrECopy(Dest, Source: PChar): PChar; assembler; {$USES esi,edi} {$FRAME-}
  130. asm
  131.                 cld
  132.                 mov     edi,Source
  133.                 mov     esi,edi
  134.                 xor     al,al
  135.                 or      ecx,-1
  136.                 repne   scasb
  137.                 not     ecx
  138.                 mov     al,cl
  139.                 mov     edi,Dest
  140.                 shr     ecx,2
  141.                 and     al,11b
  142.                 rep     movsd
  143.                 mov     cl,al
  144.                 rep     movsb
  145.                 lea     eax,[edi-1]
  146. end;
  147.  
  148. { Copies at most MaxLen characters from Source to Dest and returns Dest.}
  149.  
  150. function StrLCopy(Dest, Source: PChar; MaxLen: Word): PChar; assembler; {$USES esi,edi} {$FRAME-}
  151. asm
  152.                 cld
  153.                 mov     edi,Source
  154.                 mov     esi,edi
  155.                 mov     ecx,MaxLen
  156.                 mov     edx,ecx
  157.                 xor     al,al
  158.                 repne   scasb
  159.                 sub     edx,ecx
  160.                 mov     ecx,edx
  161.                 mov     edi,Dest
  162.                 mov     eax,edi
  163.                 shr     ecx,2
  164.                 and     dl,11b
  165.                 rep     movsd
  166.                 mov     cl,dl
  167.                 rep     movsb
  168.                 mov     [edi].Byte,0
  169. end;
  170.  
  171. { Copies the Pascal style string Source into Dest and returns Dest.     }
  172.  
  173. function StrPCopy(Dest: PChar; Source: String): PChar; assembler; {$USES esi,edi} {$FRAME-}
  174. asm
  175.                 cld
  176.                 mov     esi,Source
  177.                 mov     edi,Dest
  178.                 mov     eax,edi
  179.                 xor     ecx,ecx
  180.                 mov     cl,[esi]
  181.                 inc     esi
  182.                 mov     dl,cl
  183.                 shr     ecx,2
  184.                 and     dl,11b
  185.                 rep     movsd
  186.                 mov     cl,dl
  187.                 rep     movsb
  188.                 mov     [edi].Byte,0
  189. end;
  190.  
  191. { Appends a copy of Source to the end of Dest and returns Dest.         }
  192.  
  193. function StrCat(Dest, Source: PChar): PChar; assembler; {$USES None} {$FRAME+}
  194. asm
  195.                 push    Dest
  196.                 Call    StrEnd
  197.                 push    eax
  198.                 push    Source
  199.                 Call    StrCopy
  200.                 mov     eax,Dest
  201. end;
  202.  
  203. { Appends at most MaxLen - StrLen(Dest) characters from Source to the   }
  204. { end of Dest, and returns Dest.                                        }
  205.  
  206. function StrLCat(Dest, Source: PChar; MaxLen: Word): PChar; assembler; {$USES None} {$FRAME+}
  207. asm
  208.                 push    Dest
  209.                 Call    StrEnd
  210.                 mov     ecx,Dest
  211.                 add     ecx,MaxLen
  212.                 sub     ecx,eax
  213.                 jbe     @@1
  214.                 push    eax
  215.                 push    Source
  216.                 push    ecx
  217.                 Call    StrLCopy
  218.               @@1:
  219.                 mov     eax,Dest
  220. end;
  221.  
  222. { Compares Str1 to Str2. The return value is less than 0 if Str1 < Str2,}
  223. { 0 if Str1 = Str2, or greater than 0 if Str1 > Str2.                   }
  224.  
  225. function StrComp(Str1, Str2: PChar): Integer; assembler; {$USES esi,edi} {$FRAME-}
  226. asm
  227.                 cld
  228.                 mov     edi,Str2
  229.                 mov     esi,edi
  230.                 or      ecx,-1
  231.                 xor     eax,eax
  232.                 xor     edx,edx
  233.                 repne   scasb
  234.                 not     ecx
  235.                 mov     edi,esi
  236.                 mov     esi,Str1
  237.                 repe    cmpsb
  238.                 mov     al,[esi-1]
  239.                 mov     dl,[edi-1]
  240.                 sub     eax,edx
  241. end;
  242.  
  243. { Compares Str1 to Str2, without case sensitivity. The return value is  }
  244. { the same as StrComp.                                                  }
  245.  
  246. function StrIComp(Str1, Str2: PChar): Integer; assembler; {$USES esi,edi} {$FRAME-}
  247. asm
  248.                 cld
  249.                 mov     edi,Str2
  250.                 mov     esi,edi
  251.                 or      ecx,-1
  252.                 xor     eax,eax
  253.                 xor     edx,edx
  254.                 repne   scasb
  255.                 not     ecx
  256.                 mov     edi,esi
  257.                 mov     esi,Str1
  258.               @@1:
  259.                 repe    cmpsb
  260.                 je      @@4
  261.                 mov     al,[esi-1]
  262.                 cmp     al,'a'
  263.                 jb      @@2
  264.                 cmp     al,'z'
  265.                 ja      @@2
  266.                 sub     al,'a'-'A'
  267.               @@2:
  268.                 mov     dl,[edi-1]
  269.                 cmp     dl,'a'
  270.                 jb      @@3
  271.                 cmp     dl,'z'
  272.                 ja      @@3
  273.                 sub     dl,'a'-'A'
  274.               @@3:
  275.                 sub     eax,edx
  276.                 je      @@1
  277.               @@4:
  278. end;
  279.  
  280. { Compares Str1 to Str2, for a maximum length of MaxLen characters. The }
  281. { return value is the same as StrComp.                                  }
  282.  
  283. function StrLComp(Str1, Str2: PChar; MaxLen: Word): Integer; assembler; {$USES esi,edi} {$FRAME-}
  284. asm
  285.                 cld
  286.                 mov     edi,Str2
  287.                 mov     esi,edi
  288.                 mov     eax,MaxLen
  289.                 mov     ecx,eax
  290.                 jecxz   @@1
  291.                 mov     edx,eax
  292.                 xor     eax,eax
  293.                 repne   scasb
  294.                 sub     edx,ecx
  295.                 mov     ecx,edx
  296.                 mov     edi,esi
  297.                 mov     esi,Str1
  298.                 repe    cmpsb
  299.                 xor     edx,edx
  300.                 mov     al,[esi-1]
  301.                 mov     dl,[edi-1]
  302.                 sub     eax,edx
  303.               @@1:
  304. end;
  305.  
  306. { Compares Str1 to Str2, for a maximum length of MaxLen characters,     }
  307. { without case sensitivity. The return value is the same as StrComp.    }
  308.  
  309. function StrLIComp(Str1, Str2: PChar; MaxLen: Word): Integer; assembler; {$USES esi,edi} {$FRAME-}
  310. asm
  311.                 mov     edi,Str2
  312.                 mov     esi,edi
  313.                 mov     eax,MaxLen
  314.                 mov     ecx,eax
  315.                 jecxz   @@4
  316.                 cld
  317.                 mov     edx,eax
  318.                 xor     eax,eax
  319.                 repne   scasb
  320.                 sub     edx,ecx
  321.                 mov     ecx,edx
  322.                 mov     edi,esi
  323.                 mov     esi,Str1
  324.                 xor     edx,edx
  325.               @@1:
  326.                 repe    cmpsb
  327.                 je      @@4
  328.                 mov     al,[esi-1]
  329.                 cmp     al,'a'
  330.                 jb      @@2
  331.                 cmp     al,'z'
  332.                 ja      @@2
  333.                 sub     al,'a'-'A'
  334.               @@2:
  335.                 mov     dl,[edi-1]
  336.                 cmp     dl,'a'
  337.                 jb      @@3
  338.                 cmp     dl,'z'
  339.                 ja      @@3
  340.                 sub     dl,'a'-'A'
  341.               @@3:
  342.                 sub     eax,edx
  343.                 je      @@1
  344.               @@4:
  345. end;
  346.  
  347. { Returns a pointer to the first occurrence of Chr in Str. If Chr does  }
  348. { not occur in Str, StrScan returns NIL. The null terminator is         }
  349. { considered to be part of the string.                                  }
  350.  
  351. function StrScan(Str: PChar; Chr: Char): PChar; assembler; {$USES edi} {$FRAME-}
  352. asm
  353.                 cld
  354.                 mov     edi,Str
  355.                 mov     edx,edi
  356.                 or      ecx,-1
  357.                 xor     eax,eax
  358.                 repne   scasb
  359.                 not     ecx
  360.                 mov     edi,edx
  361.                 mov     al,Chr
  362.                 repne   scasb
  363.                 mov     al,0
  364.                 jne     @@1
  365.                 lea     eax,[edi-1]
  366.               @@1:
  367. end;
  368.  
  369. { Returns a pointer to the last occurrence of Chr in Str. If Chr does   }
  370. { not occur in Str, StrRScan returns NIL. The null terminator is        }
  371. { considered to be part of the string.                                  }
  372.  
  373. function StrRScan(Str: PChar; Chr: Char): PChar; assembler; {$USES edi} {$FRAME-}
  374. asm
  375.                 cld
  376.                 mov     edi,Str
  377.                 or      ecx,-1
  378.                 xor     eax,eax
  379.                 repne   scasb
  380.                 not     ecx
  381.                 std
  382.                 dec     edi
  383.                 mov     al,Chr
  384.                 repne   scasb
  385.                 mov     al,0
  386.                 jne     @@1
  387.                 lea     eax,[edi+1]
  388.               @@1:
  389. end;
  390.  
  391. { Returns a pointer to the first occurrence of Str2 in Str1. If Str2    }
  392. { does not occur in Str1, StrPos returns NIL.                           }
  393.  
  394. function StrPos(Str1, Str2: PChar): PChar; assembler; {$USES ebx,esi,edi} {$FRAME-}
  395. asm
  396.                 cld
  397.                 xor     al,al
  398.                 mov     edi,Str2
  399.                 or      ecx,-1
  400.                 repne   scasb
  401.                 not     ecx
  402.                 dec     ecx
  403.                 je      @@2
  404.                 mov     edx,ecx
  405.                 mov     edi,Str1
  406.                 mov     ebx,edi
  407.                 or      ecx,-1
  408.                 repne   scasb
  409.                 not     ecx
  410.                 sub     ecx,edx
  411.                 jbe     @@2
  412.                 mov     edi,ebx
  413.               @@1:
  414.                 mov     esi,Str2
  415.                 lodsb
  416.                 repne   scasb
  417.                 jne     @@2
  418.                 mov     eax,ecx
  419.                 mov     ebx,edi
  420.                 mov     ecx,edx
  421.                 dec     ecx
  422.                 repe    cmpsb
  423.                 mov     ecx,eax
  424.                 mov     edi,ebx
  425.                 jne     @@1
  426.                 lea     eax,[edi-1]
  427.                 jmp     @@3
  428.               @@2:
  429.                 xor     eax,eax
  430.               @@3:
  431. end;
  432.  
  433. { Converts Str to upper case and returns Str.                           }
  434.  
  435. function StrUpper(Str: PChar): PChar; assembler; {$USES esi} {$FRAME-}
  436. asm
  437.                 cld
  438.                 mov     esi,Str
  439.                 mov     eax,esi
  440.               @@1:
  441.                 mov     dl,[esi]
  442.                 test    dl,dl
  443.                 jz      @@2
  444.                 inc     esi
  445.                 cmp     dl,'a'
  446.                 jb      @@1
  447.                 cmp     dl,'z'
  448.                 ja      @@1
  449.                 sub     dl,'a'-'A'
  450.                 mov     [esi-1],dl
  451.                 jmp     @@1
  452.               @@2:
  453. end;
  454.  
  455. { Converts Str to lower case and returns Str.                           }
  456.  
  457. function StrLower(Str: PChar): PChar; assembler; {$USES esi} {$FRAME-}
  458. asm
  459.                 cld
  460.                 mov     esi,Str
  461.                 mov     eax,esi
  462.               @@1:
  463.                 mov     dl,[esi]
  464.                 test    dl,dl
  465.                 jz      @@2
  466.                 inc     esi
  467.                 cmp     dl,'A'
  468.                 jb      @@1
  469.                 cmp     dl,'Z'
  470.                 ja      @@1
  471.                 add     dl,'a'-'A'
  472.                 mov     [esi-1],dl
  473.                 jmp     @@1
  474.               @@2:
  475. end;
  476.  
  477. { StrPas converts Str to a Pascal style string.                         }
  478.  
  479. function StrPas(Str: PChar): String; assembler; {$USES esi,edi} {$FRAME-}
  480. asm
  481.                 cld
  482.                 mov     edi,Str
  483.                 or      ecx,-1
  484.                 xor     al,al
  485.                 repne   scasb
  486.                 not     ecx
  487.                 dec     ecx
  488.                 cmp     ecx,255
  489.                 jbe     @@1
  490.                 mov     ecx,255
  491.               @@1:
  492.                 mov     esi,Str
  493.                 mov     edi,@Result
  494.                 mov     al,cl
  495.                 stosb
  496.                 shr     ecx,2
  497.                 and     al,11b
  498.                 rep     movsd
  499.                 mov     cl,al
  500.                 rep     movsb
  501. end;
  502.  
  503. { Allocates a copy of Str on the heap. If Str is NIL or points to an    }
  504. { empty string, StrNew returns NIL and doesn't allocate any heap space. }
  505. { Otherwise, StrNew makes a duplicate of Str, obtaining space with a    }
  506. { call to the GetMem standard procedure, and returns a pointer to the   }
  507. { duplicated string. The allocated space is StrLen(Str) + 1 bytes long. }
  508.  
  509. function StrNew(Str: PChar): PChar;
  510. var
  511.   L: Word;
  512.   P: PChar;
  513. begin
  514.   StrNew := nil;
  515.   if (Str <> nil) and (Str^ <> #0) then
  516.   begin
  517.     L := StrLen(Str) + 1;
  518.     GetMem(P, L);
  519.     if P <> nil then StrNew := StrMove(P, Str, L);
  520.   end;
  521. end;
  522.  
  523. { Disposes a string that was previously allocated with StrNew. If Str   }
  524. { is NIL, StrDispose does nothing.                                      }
  525.  
  526. procedure StrDispose(Str: PChar);
  527. begin
  528.   if Str <> nil then FreeMem(Str, StrLen(Str) + 1);
  529. end;
  530.  
  531. end.
  532.