home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 March / Chip_1998-03_cd.bin / zkuste / delphi / WhiteAnts / CMPNAMES.ZIP / STRUTILS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-02-04  |  17.1 KB  |  600 lines

  1. {
  2. +----------------------------------------------------------------------------+
  3. |                                      ⌐  ⌐                                  |
  4. |                                    ⌐⌐ ⌐ ⌐ ⌐                                |
  5. |                                 ⌐⌐⌐ ⌐   ⌐  ⌐                               |
  6. |                                 ⌐⌐    ⌐ ⌐   ⌐                              |
  7. |                  ⌐             ⌐⌐     ⌐  ⌐                                 |
  8. |                 ⌐ ⌐            ⌐⌐⌐    ⌐⌐  ⌐                                |
  9. |             ⌐⌐  ⌐  ⌐      ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐  ⌐                                    |
  10. |            ⌐  ⌐⌐  ⌐⌐      ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐                                  |
  11. |            ⌐ ⌐⌐⌐ ⌐⌐⌐⌐⌐⌐ ⌐⌐⌐ ⌐   ⌐⌐⌐⌐⌐⌐⌐⌐                                   |
  12. |           ⌐ ⌐⌐ ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐ ⌐   ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐      Copyright ⌐ 1996-1997 by:  |
  13. |           ⌐ ⌐⌐⌐⌐⌐⌐ ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐  ⌐ ⌐⌐⌐⌐⌐ ⌐⌐                                 |
  14. |          ⌐ ⌐⌐⌐⌐⌐⌐⌐   ⌐⌐⌐⌐⌐ ⌐⌐⌐⌐    ⌐⌐ ⌐⌐ ⌐      WHITE ANTS SYSTEMHOUSE BV  |
  15. |         ⌐  ⌐⌐⌐⌐⌐⌐⌐ ⌐⌐⌐ ⌐⌐⌐ ⌐⌐ ⌐       ⌐⌐⌐⌐      Geleen 12                  |
  16. |         ⌐ ⌐⌐⌐⌐⌐⌐⌐    ⌐   ⌐⌐   ⌐⌐⌐       ⌐       8032 GB Zwolle             |
  17. |           ⌐⌐⌐⌐⌐⌐     ⌐            ⌐ ⌐           Netherlands                |
  18. |      ⌐⌐⌐  ⌐⌐⌐⌐⌐      ⌐     ⌐⌐     ⌐  ⌐                                     |
  19. |            ⌐⌐       ⌐              ⌐  ⌐⌐⌐ ⌐     Tel. +31 38 453 86 31      |
  20. |      ⌐              ⌐              ⌐            Fax. +31 38 453 41 22      |
  21. |      ⌐             ⌐               ⌐⌐                                      |
  22. |    ⌐              ⌐                  ⌐⌐         www.whiteants.com          |
  23. |  ⌐⌐              ⌐                     ⌐ ⌐      support@whiteants.com      |
  24. |                 ⌐                                                          |
  25. +----------------------------------------------------------------------------+
  26.   file     : StrUtils
  27.   version  : 1.01
  28.   comment  : Part of this file was taken form S_STRING.PAS by RAY LISCHNER
  29.              Book: Secrets of Delphi 2.0
  30.   author   : G. Beuze, R. Post, L. Laarhoven, R. Lischner
  31.   compiler : Delphi 1.0, partly Delphi 2.0
  32. +----------------------------------------------------------------------------+
  33. | DISCLAIMER:                                                                |
  34. | THIS SOURCE IS FREEWARE. YOU ARE ALLOWED TO USE IT IN YOUR OWN PROJECTS    |
  35. | WITHOUT ANY RESTRICTIONS. YOU ARE NOT ALLOWED TO SELL THE SOURCE CODE.     |
  36. | THERE IS NO WARRANTY AT ALL - YOU USE IT ON YOUR OWN RISC. WHITE ANTS DOES |
  37. | NOT ASSUME ANY RESPONSIBILITY FOR ANY DAMAGE OR ANY LOSS OF TIME OR MONEY  |
  38. | DUE THE USE OF ANY PART OF THIS SOURCE CODE.                               |
  39. +----------------------------------------------------------------------------+
  40. }
  41. unit StrUtils;
  42.  
  43. interface
  44.  
  45. uses
  46.   SysUtils;
  47.  
  48. { Convert a Pascal string to a PChar. }
  49. function StrToPChar(const Str: string): PChar;
  50.  
  51. { Delimiters use by XXXToBinaryStr procedures }
  52. const
  53.   NibbleDelimiter : Char = '.';
  54.   ByteDelimiter : Char = ' ';
  55.  
  56. {$IFNDEF WIN32}
  57. type
  58.   ShortString = string;
  59.   PShortString = ^ShortString;
  60.   AnsiChar = Char;
  61.   PAnsiChar = ^AnsiChar;
  62.  
  63. { Set the length of string, Str, to Length. }
  64. procedure SetLength(var Str: string; Length: Byte);
  65.  
  66. { Set the contents of string Str, to Length bytes, starting at From. }
  67. procedure SetString(var Str: string; From: PChar; Length: Byte);
  68.  
  69. { Copy and return Str, after trimming leading and trailing white space
  70.   characters. Do not modify Str. }
  71. function Trim(const Str: string): string;
  72.  
  73. { Copy and return Str, after trimming leading white space
  74.   characters. Do not modify Str. }
  75. function TrimLeft(const Str: string): string;
  76.  
  77. { Copy and return Str, after trimming trailing white space
  78.   characters. Do not modify Str. }
  79. function TrimRight(const Str: string): string;
  80. {$ENDIF}
  81.  
  82. function DelChars(const Str: string; C: Char): string;
  83.   { Removes any character C from S }
  84.  
  85. function DelWhiteSpace(const Str: string): string;
  86.   { Removes any characters #0..#32 from Str }
  87.  
  88. function DelLeftChars(const Str: string; C: Char): string;
  89.   { Removes any leading character C from S }
  90.  
  91. function DelRightChars(const Str: string; C: Char): string;
  92.   { Removes any trailing character C from S }
  93.  
  94. function DelLeftRightChars(const Str: string; C: Char): string;
  95.   { Removes any leading and trailing character C from S }
  96.  
  97. function CharString(C: Char; Cnt: Byte): string;
  98.   { Returns a string of length (Cnt), filled with C }
  99.  
  100. function BlankString(Cnt: Byte): string;
  101.   { Returns a string a Cnt blanks }
  102.  
  103. function LeadCharsCnt(const S: string; C: Char): Byte;
  104.   { Returns number of leading chars C }
  105.  
  106. function LeadBlanksCnt(const S: string): Byte;
  107.   { Returns number of leading blanks }
  108.  
  109. function LeadTabCnt(const S: string): Byte;
  110.   { Returns number of leading tabs }
  111.  
  112. function AbbrStr(const Source: string; MaxLen: Byte): string;
  113.   { Returns a string with length <= MaxLen. Abbreviating on words }
  114.  
  115. function MixedCase(const Str: string): string;
  116.   { Returns S in lower case except the first char which is upper:
  117.     'example' -> 'Example', 'EXAMPLE' -> 'Example' }
  118.  
  119. function IsPrefix(const SubStr, Str: string): Boolean;
  120.   { Returns True if Str starts with SubStr ignoring case }
  121.  
  122. function StringValue(S: PString): string;
  123.   { Returns S^ or '' if s = nil }
  124.  
  125. function ByteToBCD(a: Byte): Byte;
  126.   { Returns BCD coded representation of a }
  127.  
  128. function BCDtoByte(a : Byte) : Byte;
  129.   { Returns Byte value of BCD coded byte a }
  130.  
  131. function ByteToBinaryStr(B: Byte): string;
  132.   { Returns '0001.1100' style string, with . defined by NibbleDelimiter const }
  133.  
  134. function WordToBinaryStr(W: Word): string;
  135.   { Returns '00011100|00011100' style string,
  136.     with | defined by ByteDelimiter const, See NibbleDelimiter }
  137.  
  138. function LongToBinaryStr(L: LongInt): string;
  139.   { Returns '00011100|00011100|00011100|00011100' style string, see Delimiters }
  140.  
  141. function MatchStrings(const Source, Pattern: string): Boolean;
  142.   { Returns True if Source matches Pattern '*Example?*' etc }
  143.   {  Orignal code by Sean Stanley in C, Rewritten in Delphi by David Stidolph }
  144.  
  145. function StrToFloatDef(const Str: string; DefValue: Extended): Extended;
  146.   { Converts S to extended, on exception returns DefValue }
  147.  
  148. function GetTemplate(const Str: string): string;
  149.   { Returns 'template' as in TEMPLATE0001 }
  150.  
  151. function GetIndex(const Str: string): Integer;
  152.   { Returns Index = 1 as in TEMPLATE0001 }
  153.  
  154. function GetTemplateAndIndex(const Str: string; var Template: string;
  155.                              var Index: Integer): Boolean;
  156.   { Returns True if a number was found to the right of Str
  157.     for example as in 'Button123'. Returns Button in Template and 123 in Index
  158.     Returns False if no number was found }
  159.  
  160. function GetName(const S: string): string;
  161.   { Returns Name as iN: Name=Value , or '' if no = was found }
  162.  
  163. function GetValue(const S: string): string;
  164.   { Returns Value as in: Name=Value , or '' if no = was found }
  165.  
  166. function GetNameAndValue(const S: string; var Name, Value: string): Boolean;
  167.   { Returns True is S could be split in name and value as in Name=Value, else False }
  168.  
  169. implementation
  170.  
  171. { Return whether the character C, is a white space character,
  172.   or a nonprintable control character. }
  173. function IsWhiteSpace(C: Char): Boolean;
  174. begin
  175.   Result := C in [#0..' ']
  176. end;
  177.  
  178. {$IFDEF WIN32}
  179. { Delphi 2.0 knows how to convert string to PChar. }
  180. function StrToPChar(const Str: string): PChar;
  181. begin
  182.   Result := PChar(Str);
  183. end;
  184.  
  185. {$ELSE}
  186.  
  187. { Return a PChar representation of the string, Str. Allocate a dynamic
  188.   copy of the string. Keep a ring of 8 dynamic strings, and free the
  189.   old strings. Thus, you can usually rely on the returned string being
  190.   valid while it is needed. The most common need is to pass an argument
  191.   to a Windows API function, so the need is temporary, but several
  192.   such strings might be required. That's why the ring has 8 items in it:
  193.   more than enough for most uses. }
  194. type
  195.   TRingIndex = 0..7;
  196. var
  197.   Ring: array[TRingIndex] of PChar;
  198.   RingIndex: TRingIndex;
  199.  
  200. function StrToPChar(const Str: string): PChar;
  201. begin
  202.   { Allocate a PChar and copy the original string. }
  203.   Result := StrAlloc(Length(Str)+1);
  204.   StrPCopy(Result, Str);
  205.  
  206.   { Add the string to the ring. }
  207.   StrDispose(Ring[RingIndex]);
  208.   Ring[RingIndex] := Result;
  209.   RingIndex := (RingIndex + 1) mod (High(TRingIndex) + 1);
  210. end;
  211.  
  212. { Set the length of a string. }
  213. procedure SetLength(var Str: string; Length: Byte);
  214. begin
  215.   Str[0] := Chr(Length)
  216. end;
  217.  
  218. { Set the contents of a string. If there are fewer than Length bytes
  219.   in the string, From, then leave the remaining bytes unchanged. }
  220. procedure SetString(var Str: string; From: PChar; Length: Byte);
  221. var
  222.   FromLen: Integer;
  223. begin
  224.   Str[0] := Chr(Length);
  225.   { In Delphi 2.0, a nil pointer represents an empty string. The representation
  226.     should be hidden by the compiler, but some people use an explicit nil
  227.     pointer to mean an empty string. This is sloppy programming, but some
  228.     people do it anyway. }
  229.   if From <> nil then
  230.   begin
  231.     { Only copy as many bytes as are in the From string. }
  232.     FromLen := StrLen(From);
  233.     if FromLen < Length then
  234.       Length := FromLen;
  235.     Move(From^, Str[1], Length);
  236.   end;
  237. end;
  238.  
  239. { Trim all leading and trailing white space characters. }
  240. function Trim(const Str: string): string;
  241. var
  242.   L, R: Integer;
  243. begin
  244.   L := 1;
  245.   R := Length(Str);
  246.   while (L <= R) and IsWhiteSpace(Str[L]) do
  247.     Inc(L);
  248.   while (L <= R) and IsWhiteSpace(Str[R]) do
  249.     Dec(R);
  250.   Result := Copy(Str, L, R-L+1);
  251. end;
  252.  
  253. { Trim leading white space characters. }
  254. function TrimLeft(const Str: string): string;
  255. var
  256.   L, R: Integer;
  257. begin
  258.   L := 1;
  259.   R := Length(Str);
  260.   while (L <= R) and IsWhiteSpace(Str[L]) do
  261.     Inc(L);
  262.   Result := Copy(Str, L, 255);
  263. end;
  264.  
  265. { Trim trailing white space characters. }
  266. function TrimRight(const Str: string): string;
  267. var
  268.   R: Integer;
  269. begin
  270.   R := Length(Str);
  271.   while (R >= 1) and IsWhiteSpace(Str[R]) do
  272.     Dec(R);
  273.   Result := Copy(Str, 1, R);
  274. end;
  275. {$ENDIF}
  276.  
  277. function DelChars(const Str: string; C: Char): string;
  278. var I: Integer;
  279. begin
  280.   Result := '';
  281.   for I := 1 to Length(Str) do
  282.     if Str[I] <> C then
  283.       Result := Result + Str[I];
  284. end;
  285.  
  286. function DelWhiteSpace(const Str: string): string;
  287. var I: Integer;
  288. begin
  289.   Result := '';
  290.   for I := 1 to Length(Str) do
  291.     if not IsWhiteSpace(Str[I]) then
  292.       Result := Result + Str[I];
  293. end;
  294.  
  295. function DelLeftChars(const Str: string; C: Char): string;
  296. var
  297.   L, R: Integer;
  298. begin
  299.   L := 1;
  300.   R := Length(Str);
  301.   while (L <= R) and (Str[L] = C) do
  302.     Inc(L);
  303.   Result := Copy(Str, L, 255);
  304. end;
  305.  
  306. function DelRightChars(const Str: string; C: Char): string;
  307. var
  308.   R: Integer;
  309. begin
  310.   R := Length(Str);
  311.   while (R >= 1) and (Str[R] = C) do
  312.     Dec(R);
  313.   Result := Copy(Str, 1, R);
  314. end;
  315.  
  316. function DelLeftRightChars(const Str: string; C: Char): string;
  317. var
  318.   L, R: Integer;
  319. begin
  320.   L := 1;
  321.   R := Length(Str);
  322.   while (L <= R) and (Str[L] = C) do
  323.     Inc(L);
  324.   while (L <= R) and (Str[R] = C) do
  325.     Dec(R);
  326.   Result := Copy(Str, L, R-L+1);
  327. end;
  328.  
  329. function CharString(C: Char; Cnt: Byte): string;
  330. var
  331.   I: Integer;
  332. begin
  333.   Result := '';
  334.   for I := 0 to Cnt-1 do Result := Result + C;
  335. end;
  336.  
  337. function BlankString(Cnt: Byte): String;
  338. begin
  339.   Result := CharString(#32, Cnt);
  340. end;
  341.  
  342. function LeadCharsCnt(const S: string; C: Char): Byte;
  343. var I : Integer;
  344. begin
  345.   for I := 1 to Length(S) do
  346.     if S[I] <> C then
  347.     begin
  348.       Result := I - 1;
  349.       Exit;
  350.     end;
  351.   Result := Length(S);
  352. end;
  353.  
  354. function LeadBlanksCnt(const S: string): Byte;
  355. begin
  356.   Result := LeadCharsCnt(S, ' ');
  357. end;
  358.  
  359. function LeadTabCnt(const S: string): Byte;
  360. begin
  361.   Result := LeadCharsCnt(S, #9);
  362. end;
  363.  
  364. function AbbrStr(const Source: string; MaxLen: Byte): string;
  365. begin
  366.   if Length(Source) > MaxLen then
  367.   begin
  368.     Result := Copy(Source, 1, MaxLen);
  369.     if (Source[MaxLen] <> ' ') and (Source[MaxLen + 1] <> ' ') then
  370.     if MaxLen > 1 then
  371.     begin
  372.       Result[MaxLen] := '.';
  373.       Result[MaxLen - 1] := '.';
  374.     end;
  375.   end
  376.   else
  377.     Result := Source;
  378. end;
  379.  
  380. function MixedCase(const Str: string): string;
  381. begin
  382.   Result := LowerCase(Str);
  383.   if Length(Result) > 0 then Result[1] := Upcase(Result[1]);
  384. end;
  385.  
  386. function IsPrefix(const SubStr, Str: string): Boolean;
  387. begin
  388.   Result := (Length(SubStr) <= Length(Str)) and
  389.             (CompareText(SubStr, Copy(Str, 1, Length(SubStr))) = 0);
  390. end;
  391.  
  392. function StringValue(S: PString): string;
  393. begin
  394.   if Assigned(S) then
  395.     Result := S^
  396.   else
  397.     Result := '';
  398. end;
  399.  
  400. function ByteToBCD(A: Byte): Byte;
  401. var Decs, Units : Byte;
  402. begin
  403.   if A <= 99  then
  404.   begin
  405.     Decs := A div 10;
  406.     Units := A mod 10;
  407.     Result := (Decs shl 4) or Units;
  408.   end
  409.   else
  410.     Result := A;
  411. end;
  412.  
  413. function BCDtoByte(a : Byte) : Byte;
  414. begin
  415.   if (A >= $A0) or ((A and $0F) > $09) then
  416.     Result := A
  417.   else
  418.     Result := ((A SHR 4) and $0F ) * 10 + (A and $0F);
  419. end;
  420.  
  421. function ByteToBinaryStr(B: Byte): string;
  422. var
  423.   I : Integer;
  424. begin
  425.   Result := '';
  426.   for I := 7 downto 0 do
  427.   begin
  428.     if I = 3 then Result := Result + NibbleDelimiter;
  429.     if ((B SHR i) AND $1) = 0 then
  430.       Result := Result + '0'
  431.     else
  432.       Result := Result + '1';
  433.   end;
  434. end;
  435.  
  436. function WordToBinaryStr(W: Word): string;
  437. begin
  438.   Result := ByteToBinaryStr(WordRec(W).Hi) + ByteDelimiter +
  439.             ByteToBinaryStr(WordRec(W).Lo);
  440. end;
  441.  
  442. function LongToBinaryStr(L: LongInt): string;
  443. begin
  444.   Result := WordToBinaryStr(LongRec(L).Hi) + ByteDelimiter +
  445.             WordToBinaryStr(LongRec(L).Lo);
  446. end;
  447.  
  448.  
  449. {-------------------------------------------------------------------------}
  450. {
  451.   This function takes two strings and compares them.  The first string
  452.   can be anything, but should not contain pattern characters (* or ?).
  453.   The pattern string can have as many of these pattern characters as you want.
  454.   For example: MatchStrings('David Stidolph','*St*') would return True.
  455.  
  456.   Orignal code by Sean Stanley in C
  457.   Rewritten in Delphi by David Stidolph
  458. }
  459. {-------------------------------------------------------------------------}
  460. function MatchStrings(const Source, Pattern: string): Boolean;
  461. var
  462.   pSource: Array [0..255] of Char;
  463.   pPattern: Array [0..255] of Char;
  464.  
  465.   function MatchPattern(Element, Pattern: PChar): Boolean;
  466.  
  467.     function IsPatternWild(Pattern: PChar): Boolean;
  468.     begin
  469.       Result := StrScan(Pattern,'*') <> nil;
  470.       if not Result then Result := StrScan(Pattern,'?') <> nil;
  471.     end;
  472.  
  473.   begin
  474.     if 0 = StrComp(Pattern,'*') then
  475.       Result := True
  476.     else if (Element^ = Chr(0)) and (Pattern^ <> Chr(0)) then
  477.       Result := False
  478.     else if Element^ = Chr(0) then
  479.       Result := True
  480.     else begin
  481.       case Pattern^ of
  482.       '*': if MatchPattern(Element,@Pattern[1]) then
  483.              Result := True
  484.            else
  485.              Result := MatchPattern(@Element[1], Pattern);
  486.       '?': Result := MatchPattern(@Element[1], @Pattern[1]);
  487.       else
  488.         if Element^ = Pattern^ then
  489.           Result := MatchPattern(@Element[1], @Pattern[1])
  490.         else
  491.           Result := False;
  492.       end;
  493.     end;
  494.   end;
  495.  
  496. begin
  497.   StrPCopy(pSource, Source);
  498.   StrPCopy(pPattern, Pattern);
  499.   Result := MatchPattern(pSource,pPattern);
  500. end;
  501.  
  502. function StrToFloatDef(const Str: string; DefValue: Extended): Extended;
  503. begin
  504.   try
  505.     Result := StrToFloat(Str);
  506.   except
  507.     Result := DefValue;
  508.   end;
  509. end;
  510.  
  511. const
  512.   Numbers: set of Char = ['0'..'9'];
  513.  
  514. function GetTemplate(const Str: string): string;
  515. var Index: Integer;
  516. begin
  517.   GetTemplateAndIndex(Str, Result, Index);
  518. end;
  519.  
  520. function GetIndex(const Str: string): Integer;
  521. var Template: string;
  522. begin
  523.   GetTemplateAndIndex(Str, Template, Result);
  524. end;
  525.  
  526. function GetTemplateAndIndex(const Str: string; var Template: string;
  527.                              var Index: Integer): Boolean;
  528. var R: Integer;
  529. begin
  530.   R := Length(Str);
  531.   while (R > 0) and (Str[R] in Numbers) do Dec(R);
  532.   Result := R < Length(Str);
  533.   if Result then
  534.   begin
  535.     Template := Copy(Str, 1, R);
  536.     Index := StrToInt(Copy(Str, R+1, 255));
  537.   end
  538.   else
  539.   begin
  540.     Index := -1;
  541.     Template := Str;
  542.   end;
  543. end;
  544.  
  545. function GetName(const S: string): string;
  546. var P: Integer;
  547. begin
  548.   P := Pos('=', S);
  549.   if P > 0 then
  550.     Result := Copy(S, 1, P - 1)
  551.   else
  552.     Result := '';
  553. end;
  554.  
  555. function GetValue(const S: string): string;
  556. var P: Integer;
  557. begin
  558.   P := Pos('=', S);
  559.   if P > 0 then
  560.     Result := Copy(S, P + 1, 255)
  561.   else
  562.     Result := '';
  563. end;
  564.  
  565. function GetNameAndValue(const S: string; var Name, Value: string): Boolean;
  566. var P: Integer;
  567. begin
  568.   P := Pos('=', S);
  569.   Result := P > 0;
  570.   if Result then
  571.   begin
  572.     Name := Copy(S, 1, P - 1);
  573.     Value := Copy(S, P + 1, 255);
  574.   end
  575.   else
  576.   begin
  577.     Name := '';
  578.     Value := '';
  579.   end;
  580. end;
  581.  
  582. {$IFNDEF WIN32}
  583. { Free all the left over strings in the StrToPChar ring. }
  584. procedure Terminate; far;
  585. var
  586.   I: TRingIndex;
  587. begin
  588.   for I := Low(TRingIndex) to High(TRingIndex) do
  589.   begin
  590.     StrDispose(Ring[I]);
  591.     Ring[I] := nil; { just in case StrToPChar is called again }
  592.   end;
  593. end;
  594.  
  595.  
  596. initialization
  597.   AddExitProc(Terminate);
  598. {$ENDIF}
  599. end.
  600.