123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by Carl-Eric Codere,
- member of the Free Pascal development team.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$ifndef FPC_UNIT_HAS_STREND}
- Function StrEnd(P: PAnsiChar): PAnsiChar;
- begin
- StrEnd := P;
- if Assigned(StrEnd) then
- Inc(StrEnd, IndexByte(StrEnd^, -1, 0));
- end;
- {$endif FPC_UNIT_HAS_STREND}
- {$ifndef FPC_UNIT_HAS_STRCOPY}
- { Beware, the naive implementation (copying bytes forward until zero
- is encountered) will end up in undefined behavior if source and dest
- happen to overlap. So do it in a bit more reliable way.
- Also this implementation should not need per-platform optimization,
- given that IndexByte and Move are optimized. }
- Function StrCopy(Dest, Source:PAnsiChar): PAnsiChar;
- var
- counter : SizeInt;
- Begin
- counter := IndexByte(Source^,-1,0);
- { counter+1 will move zero terminator }
- Move(Source^,Dest^,counter+1);
- StrCopy := Dest;
- end;
- {$endif FPC_UNIT_HAS_STRCOPY}
- {$ifndef FPC_UNIT_HAS_STRUPPER}
- function StrUpper(P: PAnsiChar): PAnsiChar;
- var
- counter: SizeInt;
- begin
- counter := 0;
- while (P[counter] <> #0) do
- begin
- if P[Counter] in [#97..#122,#128..#255] then
- P[counter] := Upcase(P[counter]);
- Inc(counter);
- end;
- StrUpper := P;
- end;
- {$endif FPC_UNIT_HAS_STRUPPER}
- {$ifndef FPC_UNIT_HAS_STRLOWER}
- function StrLower(P: PAnsiChar): PAnsiChar;
- var
- counter: SizeInt;
- begin
- counter := 0;
- while (P[counter] <> #0) do
- begin
- if P[counter] in [#65..#90] then
- P[Counter] := chr(ord(P[Counter]) + 32);
- Inc(counter);
- end;
- StrLower := P;
- end;
- {$endif FPC_UNIT_HAS_STRLOWER}
- {$ifndef FPC_UNIT_HAS_STRSCAN}
- function StrScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
- Begin
- dec(P);
- repeat
- inc(P);
- until (P^ = #0) or (P^ = C);
- if (P^ = #0) and (C <> #0) then
- P := nil;
- StrScan := P;
- end;
- {$endif FPC_UNIT_HAS_STRSCAN}
- {$ifndef FPC_UNIT_HAS_STRISCAN}
- function StrIScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
- Var
- count: SizeInt;
- UC: AnsiChar;
- Begin
- UC := upcase(C);
- count := 0;
- { As in Borland Pascal , if looking for NULL return null }
- if UC = #0 then
- begin
- StrIScan := @(P[StrLen(P)]);
- exit;
- end;
- { Find first matching character of Ch in Str }
- while P[count] <> #0 do
- begin
- if UC = upcase(P[count]) then
- begin
- StrIScan := @(P[count]);
- exit;
- end;
- Inc(count);
- end;
- { nothing found. }
- StrIScan := nil;
- end;
- {$endif FPC_UNIT_HAS_STRSCAN}
- {$ifndef FPC_UNIT_HAS_STRRSCAN}
- function StrRScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
- Begin
- StrRScan := P + IndexByte(P^, -1, 0);
- { As in Borland Pascal , if looking for NULL return null }
- if C = #0 then
- exit;
- while (StrRScan <> P) and (StrRScan[-1] <> C) do
- dec(StrRScan);
- if StrRScan = P then
- StrRScan := nil
- else
- dec(StrRScan);
- end;
- {$endif FPC_UNIT_HAS_STRRSCAN}
- {$ifndef FPC_UNIT_HAS_STRRISCAN}
- function StrRIScan(P: PAnsiChar; C: AnsiChar): PAnsiChar;
- Var
- count: SizeInt;
- index: SizeInt;
- UC: AnsiChar;
- Begin
- UC := upcase(C);
- count := Strlen(P);
- { As in Borland Pascal , if looking for NULL return null }
- if UC = #0 then
- begin
- StrRIScan := @(P[count]);
- exit;
- end;
- Dec(count);
- for index := count downto 0 do
- begin
- if UC = upcase(P[index]) then
- begin
- StrRIScan := @(P[index]);
- exit;
- end;
- end;
- { nothing found. }
- StrRIScan := nil;
- end;
- {$endif FPC_UNIT_HAS_STRRSCAN}
- {$ifndef FPC_UNIT_HAS_STRECOPY}
- Function StrECopy(Dest, Source: PAnsiChar): PAnsiChar;
- { Equivalent to the following: }
- { strcopy(Dest,Source); }
- { StrECopy := StrEnd(Dest); }
- var
- counter : SizeInt;
- Begin
- counter := IndexByte(Source^,-1,0);
- { counter+1 will move zero terminator }
- Move(Source^,Dest^,counter+1);
- StrECopy := Dest+counter;
- end;
- {$endif FPC_UNIT_HAS_STRECOPY}
- {$ifndef FPC_UNIT_HAS_STRLCOPY}
- Function StrLCopy(Dest,Source: PAnsiChar; MaxLen: SizeInt): PAnsiChar;
- var
- nmove: SizeInt;
- Begin
- { To be compatible with BP, on a null string, put two nulls }
- If Source[0] = #0 then
- unaligned(PUint16(Dest)^):=0
- else
- begin
- if MaxLen < 0 then MaxLen := 0; { Paranoia. }
- nmove := IndexByte(Source^,MaxLen,0) + 1;
- if nmove = 0 then
- begin
- nmove := MaxLen;
- Dest[MaxLen] := #0;
- end;
- Move(Source^,Dest^,nmove);
- end;
- StrLCopy := Dest;
- end;
- {$endif FPC_UNIT_HAS_STRLCOPY}
- {$ifndef FPC_UNIT_HAS_STRCOMP}
- function StrComp(Str1, Str2 : PAnsiChar): SizeInt;
- var
- counter: SizeInt;
- sample: char;
- Begin
- counter := -1;
- repeat
- inc(counter);
- sample := str1[counter];
- until (sample = #0) or (sample <> str2[counter]);
- StrComp := ord(sample) - ord(str2[counter]);
- end;
- {$endif FPC_UNIT_HAS_STRCOMP}
- {$ifndef FPC_UNIT_HAS_STRICOMP}
- function StrIComp(Str1, Str2 : PAnsiChar): SizeInt;
- Begin
- dec(Str1);
- dec(Str2);
- repeat
- inc(Str1);
- inc(Str2);
- StrIComp := ord(Str1^) - ord(Str2^);
- if Str1^ = #0 then break;
- if StrIComp = 0 then continue;
- StrIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
- if StrIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
- until false;
- end;
- {$endif FPC_UNIT_HAS_STRICOMP}
- {$ifndef FPC_UNIT_HAS_STRLCOMP}
- function StrLComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
- Begin
- while (L > 0) and (Str1^ <> #0) and (Str1^ = Str2^) do
- begin
- inc(Str1);
- inc(Str2);
- dec(L);
- end;
- if L <= 0 then StrLComp := 0 else StrLComp := ord(Str1^) - ord(Str2^);
- end;
- {$endif FPC_UNIT_HAS_STRLCOMP}
- {$ifndef FPC_UNIT_HAS_STRLICOMP}
- function StrLIComp(Str1, Str2 : PAnsiChar; L: SizeInt): SizeInt;
- Begin
- dec(Str1);
- dec(Str2);
- inc(L);
- StrLIComp := 0;
- Repeat
- dec(L);
- if L <= 0 then break;
- inc(Str1);
- inc(Str2);
- StrLIComp := ord(Str1^) - ord(Str2^);
- if Str1^ = #0 then break;
- if StrLIComp = 0 then continue;
- StrLIComp := ord(UpCase(Str1^)) - ord(UpCase(Str2^));
- if StrLIComp <> 0 then break; { Making it the loop condition might be suboptimal because of “continue”. }
- until false;
- end;
- {$endif FPC_UNIT_HAS_STRLICOMP}
|