home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / paswiz15 / source / strings.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1993-08-02  |  10.0 KB  |  410 lines

  1. {   +----------------------------------------------------------------------+
  2.     |                                                                      |
  3.     |        PasWiz  Copyright (c) 1990-1993  Thomas G. Hanlin III         |
  4.     |             3544 E. Southern Ave. #104,  Mesa, AZ 85204              |
  5.     |                                                                      |
  6.     |                     The Pascal Wizard's Library                      |
  7.     |                                                                      |
  8.     +----------------------------------------------------------------------+
  9.  
  10.  
  11.  
  12. Strings:
  13.  
  14.    This unit provides extensions to Pascal's rather minimal string support.
  15.    This includes string trimming, substring extraction, uppercase/lowercase
  16.    conversions (handles names, too), simple encryption and compression,
  17.    assorted searches, advanced comparisons, and other useful tools.
  18.  
  19. }
  20.  
  21.  
  22.  
  23. UNIT Strings;
  24.  
  25.  
  26.  
  27. INTERFACE
  28.  
  29.  
  30.  
  31. FUNCTION Bickel (St1, St2: String): Integer;
  32. FUNCTION BSq (St: String): String;
  33. FUNCTION BUsq (St: String): String;
  34. FUNCTION Cipher (St, Passwd: String): String;
  35. FUNCTION CipherP (St, Passwd: String): String;
  36. FUNCTION Crunch (SubSt, St: String): String;
  37. FUNCTION Dupe (Count: Integer; SubSt: String): String;
  38. FUNCTION Extract (St, Delimiter: String; Index: Integer): String;
  39. FUNCTION Instr (Start: Integer; SubSt, St: String): Integer;
  40. FUNCTION Left (St: String; Len: Integer): String;
  41. FUNCTION LowerCase (St: String): String;
  42. FUNCTION LTrim (St: String): String;
  43. FUNCTION MatchFile (Pattern, FileName: String): Boolean;
  44. FUNCTION NameCase (St: String): String;
  45. FUNCTION Replace (OldSubSt, NewSubSt, St: String): String;
  46. FUNCTION Reverse (St: String): String;
  47. FUNCTION Right (St: String; Len: Integer): String;
  48. FUNCTION RPos (SubSt, St: String): Integer;
  49. FUNCTION RTrim (St: String): String;
  50. FUNCTION Soundex (St: String): String;
  51. FUNCTION StripCh (ChList, St: String): String;
  52. FUNCTION StripSt (SubSt, St: String): String;
  53. FUNCTION StripType (ChType: Integer; St: String): String;
  54. FUNCTION TypePos (ChType: Integer; St: String): Integer;
  55. FUNCTION UpperCase (St: String): String;
  56.  
  57.  
  58.  
  59. { --------------------------------------------------------------------------- }
  60.  
  61.  
  62.  
  63. IMPLEMENTATION
  64.  
  65.  
  66.  
  67. {$F+}
  68.  
  69. { routines in assembly language }
  70.  
  71. FUNCTION Bickel; external;           { string comparison by Bickel method }
  72. {$L BICKEL}
  73.  
  74. FUNCTION LowerCase; external;        { convert to lowercase }
  75. {$L LOCASE}
  76.  
  77. FUNCTION MatchFile; external;        { see if filename matches wildcard spec }
  78. {$L MATCHFIL}
  79.  
  80. FUNCTION NameCase; external;         { capitalize a name appropriately }
  81. {$L NAMECASE}
  82.  
  83. FUNCTION UpperCase; external;        { convert to uppercase }
  84. {$L UPCASE}
  85.  
  86. FUNCTION Reverse; external;          { reverse a string }
  87. {$L REVERSE}
  88.  
  89. FUNCTION Soundex; external;          { string comparison by Soundex method }
  90. {$L SOUNDEX}
  91.  
  92. FUNCTION TypePos; external;          { seek a given type of character }
  93. {$L TYPEPOS}
  94.  
  95.  
  96.  
  97. { compress spaces in a string }
  98. FUNCTION BSq (St: String): String;
  99. VAR
  100.    SqSt: String;
  101.    Ptr, RepCount: Integer;
  102. BEGIN
  103.    SqSt := '';
  104.    RepCount := 0;
  105.    FOR Ptr := 1 TO Length(St) DO
  106.       IF St[Ptr] = ' ' THEN
  107.          INC(RepCount)
  108.       ELSE BEGIN
  109.          CASE RepCount OF
  110.             0: ;
  111.             1: IF Ptr = 2 THEN
  112.                   SqSt := ' '
  113.                ELSE
  114.                   SqSt[Length(SqSt)] := CHR(ORD(SqSt[Length(SqSt)]) OR $80);
  115.             2: SqSt := SqSt + CHR(ORD(' ') OR $80);
  116.             ELSE SqSt := SqSt + CHR($80) + CHR((RepCount - 3) OR $80);
  117.          END;
  118.          SqSt := SqSt + St[Ptr];
  119.          RepCount := 0;
  120.       END;
  121.    { flush any remaining spaces }
  122.    CASE RepCount OF
  123.       0: ;
  124.       1: IF St = ' ' THEN
  125.             SqSt := ' '
  126.          ELSE
  127.             SqSt[Length(SqSt)] := CHR(ORD(SqSt[Length(SqSt)]) OR $80);
  128.       2: SqSt := SqSt + CHR(ORD(' ') OR $80)
  129.       ELSE SqSt := SqSt + CHR($80) + CHR((RepCount - 3) OR $80);
  130.    END;
  131.    BSq := SqSt;
  132. END;
  133.  
  134.  
  135.  
  136. { uncompress a string processed by BSq }
  137. FUNCTION BUsq (St: String): String;
  138. VAR
  139.    UnsqSt: String;
  140.    Ptr: Integer;
  141. BEGIN
  142.    UnsqSt := '';
  143.    Ptr := 1;
  144.    WHILE Ptr <= Length(St) DO
  145.       CASE ORD(St[Ptr]) OF
  146.          0..$7F:    { ordinary chars }
  147.             BEGIN
  148.                UnsqSt := UnsqSt + St[Ptr];
  149.                INC(Ptr);
  150.             END;
  151.          $80:       { RLE sequence }
  152.             BEGIN
  153.                UnsqSt := UnsqSt + Dupe((ORD(St[Ptr + 1]) AND $7F) + 3, ' ');
  154.                INC(Ptr, 2);
  155.             END;
  156.          $81..$FF:  { character followed by one space }
  157.             BEGIN
  158.                UnsqSt := UnsqSt + CHR(ORD(St[Ptr]) AND $7F) + ' ';
  159.                INC(Ptr);
  160.             END;
  161.       END;
  162.    BUsq := UnsqSt;
  163. END;
  164.  
  165.  
  166.  
  167. { encipher or decipher a string }
  168. FUNCTION Cipher (St, Passwd: String): String;
  169. VAR
  170.    SPtr, PPtr: Integer;
  171. BEGIN
  172.    IF Length(Passwd) > 0 THEN BEGIN
  173.       PPtr := 1;
  174.       FOR SPtr := 1 TO Length(St) DO BEGIN
  175.          St[SPtr] := CHR(Ord(St[SPtr]) XOR Ord(Passwd[PPtr]));
  176.          INC(PPtr);
  177.          IF PPtr > Length(Passwd) THEN
  178.             PPtr := 1;
  179.       END;
  180.    END;
  181.    Cipher := St;
  182. END;
  183.  
  184.  
  185.  
  186. { encipher or decipher a string, with printable results }
  187. FUNCTION CipherP (St, Passwd: String): String;
  188. VAR
  189.    SPtr, PPtr: Integer;
  190. BEGIN
  191.    IF Length(Passwd) > 0 THEN BEGIN
  192.       PPtr := 1;
  193.       FOR SPtr := 1 TO Length(St) DO BEGIN
  194.          St[SPtr] := CHR(Ord(St[SPtr]) XOR Ord(Passwd[PPtr]) XOR $80);
  195.          INC(PPtr);
  196.          IF PPtr > Length(Passwd) THEN
  197.             PPtr := 1;
  198.       END;
  199.    END;
  200.    CipherP := St;
  201. END;
  202.  
  203.  
  204.  
  205. { remove adjacent occurrences of a given substring from a string }
  206. FUNCTION Crunch (SubSt, St: String): String;
  207. VAR
  208.    Two: String;
  209.    Posn: Integer;
  210. BEGIN
  211.    IF Length(SubSt) > 0 THEN BEGIN
  212.       Two := SubSt + SubSt;
  213.       REPEAT
  214.          Posn := Pos(Two, St);
  215.          IF Posn > 0 THEN
  216.             Delete(St, Posn, Length(SubSt));
  217.       UNTIL Posn = 0;
  218.    END;
  219.    Crunch := St;
  220. END;
  221.  
  222.  
  223.  
  224. { form a string of repeated substrings }
  225. FUNCTION Dupe (Count: Integer; SubSt: String): String;
  226. VAR
  227.    St: String;
  228. BEGIN
  229.    St := '';
  230.    WHILE Count > 0 DO BEGIN
  231.       St := St + SubSt;
  232.       DEC(Count);
  233.    END;
  234.    Dupe := St;
  235. END;
  236.  
  237.  
  238.  
  239. { extract a substring from a string partitioned by delimiters }
  240. FUNCTION Extract (St, Delimiter: String; Index: Integer): String;
  241. VAR
  242.    Start, SLen, Posn: Integer;
  243. BEGIN
  244.    Start := 1;
  245.    IF (Index > 0) AND (Length(Delimiter) > 0) THEN BEGIN
  246.       REPEAT
  247.          Posn := Instr(Start, Delimiter, St);
  248.          DEC(Index);
  249.          IF Index = 0 THEN
  250.             IF Posn > 0 THEN
  251.                SLen := Posn - Start
  252.             ELSE
  253.                SLen := Length(St) - Start + 1
  254.          ELSE IF Posn = 0 THEN
  255.             SLen := 0
  256.          ELSE
  257.             Start := Posn + Length(Delimiter);
  258.       UNTIL (Posn = 0) OR (Index = 0);
  259.    END
  260.    ELSE
  261.       SLen := 0;
  262.    Extract := Copy(St, Start, SLen);
  263. END;
  264.  
  265.  
  266.  
  267. { search for a substring within a string (like Pos but with start position) }
  268. FUNCTION Instr (Start: Integer; SubSt, St: String): Integer;
  269. VAR
  270.    Posn: Integer;
  271. BEGIN
  272.    Posn := Pos(SubSt, Copy(St, Start, 255));
  273.    IF Posn > 0 THEN
  274.       Posn := Posn + Start - 1;
  275.    Instr := Posn;
  276. END;
  277.  
  278.  
  279.  
  280. { return part of a string starting from the left side }
  281. FUNCTION Left (St: String; Len: Integer): String;
  282. BEGIN
  283.    Left := Copy(St, 1, Len);
  284. END;
  285.  
  286.  
  287.  
  288. { trim blanks from the left side of a string }
  289. FUNCTION LTrim (St: String): String;
  290. BEGIN
  291.    WHILE Copy(St, 1, 1) = ' ' DO
  292.       Delete(St, 1, 1);
  293.    LTrim := St;
  294. END;
  295.  
  296.  
  297.  
  298. { replace a given substring with another }
  299. FUNCTION Replace (OldSubSt, NewSubSt, St: String): String;
  300. VAR
  301.    Tmp: String;
  302.    Posn: Integer;
  303. BEGIN
  304.    IF Length(OldSubSt) > 0 THEN BEGIN
  305.       Tmp := '';
  306.       REPEAT
  307.          Posn := Pos(OldSubSt, St);
  308.          IF Posn > 0 THEN BEGIN
  309.             Tmp := Tmp + Copy(St, 1, Posn - 1) + NewSubSt;
  310.             Delete(St, 1, Posn + Length(OldSubSt) - 1);
  311.          END
  312.          ELSE
  313.             Tmp := Tmp + St;
  314.       UNTIL Posn = 0;
  315.       Replace := Tmp;
  316.    END
  317.    ELSE
  318.       Replace := St;
  319. END;
  320.  
  321.  
  322.  
  323. { return part of a string starting from the right side }
  324. FUNCTION Right (St: String; Len: Integer): String;
  325. BEGIN
  326.    IF Len >= Length(St) THEN
  327.       Right := St
  328.    ELSE
  329.       Right := Copy(St, Length(St) - Len + 1, 255);
  330. END;
  331.  
  332.  
  333.  
  334. { search for a substring, starting from the right side of a string }
  335. FUNCTION RPos (SubSt, St: String): Integer;
  336. VAR
  337.    Posn: Integer;
  338. BEGIN
  339.    Posn := Pos(Reverse(SubSt), Reverse(St));
  340.    IF Posn > 0 THEN
  341.       Posn := Length(St) - Length(SubSt) - Posn + 2;
  342.    RPos := Posn;
  343. END;
  344.  
  345.  
  346.  
  347. { trim blanks from the right side of a string }
  348. FUNCTION RTrim (St: String): String;
  349. BEGIN
  350.    WHILE Copy(St, Length(St), 1) = ' ' DO
  351.       Delete(St, Length(St), 1);
  352.    RTrim := St;
  353. END;
  354.  
  355.  
  356.  
  357. { strip all occurrences of a list of characters from a string }
  358. FUNCTION StripCh (ChList, St: String): String;
  359. VAR
  360.    Ptr: Integer;
  361.    Tmp: String;
  362. BEGIN
  363.    Tmp := '';
  364.    IF Length(ChList) > 0 THEN
  365.       FOR Ptr := 1 TO Length(St) DO
  366.          IF Pos(St[Ptr], ChList) = 0 THEN
  367.             Tmp := Tmp + St[Ptr];
  368.    StripCh := Tmp;
  369. END;
  370.  
  371.  
  372.  
  373. { strip all occurrences of a substring from a string }
  374. FUNCTION StripSt (SubSt, St: String): String;
  375. VAR
  376.    Posn: Integer;
  377. BEGIN
  378.    IF (Length(St) = 0) OR (Length(SubSt) = 0) THEN
  379.       StripSt := ''
  380.    ELSE BEGIN
  381.       REPEAT
  382.          Posn := Pos(SubSt, St);
  383.          IF Posn > 0 THEN
  384.             Delete(St, Posn, Length(SubSt));
  385.       UNTIL Posn = 0;
  386.       StripSt := St;
  387.    END;
  388. END;
  389.  
  390.  
  391.  
  392. { strip all occurrences of given types of character from a string }
  393. FUNCTION StripType (ChType: Integer; St: String): String;
  394. VAR
  395.    Posn: Integer;
  396. BEGIN
  397.    REPEAT
  398.       Posn := TypePos(ChType, St);
  399.       IF Posn > 0 THEN
  400.          Delete(St, Posn, 1);
  401.    UNTIL Posn = 0;
  402.    StripType := St;
  403. END;
  404.  
  405.  
  406.  
  407. { ----------------------- initialization code --------------------------- }
  408. BEGIN
  409. END.
  410.