mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 21:16:05 +02:00
LazUtils: Add case-insensitive functions PosI(), LazStartsText() and LazEndsText().
git-svn-id: trunk@64503 -
This commit is contained in:
parent
5fe23e9ae8
commit
bd875ab2f5
@ -187,7 +187,7 @@ begin
|
|||||||
inc(p);
|
inc(p);
|
||||||
if p>fHtmlLen then break;
|
if p>fHtmlLen then break;
|
||||||
if fHTML[p]='=' then
|
if fHTML[p]='=' then
|
||||||
AttrName:=UpperCase(copy(fHTML,Start,p-Start));
|
AttrName:=copy(fHTML,Start,p-Start);
|
||||||
end;
|
end;
|
||||||
// Attribute "value"
|
// Attribute "value"
|
||||||
if fHTML[p]='"' then
|
if fHTML[p]='"' then
|
||||||
@ -197,7 +197,7 @@ begin
|
|||||||
while (p<=fHtmlLen) and (fHTML[p]<>'"') do
|
while (p<=fHtmlLen) and (fHTML[p]<>'"') do
|
||||||
inc(p);
|
inc(p);
|
||||||
if p>fHtmlLen then break;
|
if p>fHtmlLen then break;
|
||||||
AttrValue:=UpperCase(copy(fHTML,Start,p-Start));
|
AttrValue:=copy(fHTML,Start,p-Start);
|
||||||
end;
|
end;
|
||||||
inc(p);
|
inc(p);
|
||||||
if (fHTML[p-1]='>') then break; // end of tag
|
if (fHTML[p-1]='>') then break; // end of tag
|
||||||
@ -214,7 +214,8 @@ begin
|
|||||||
AddNewLine;
|
AddNewLine;
|
||||||
'DIV':
|
'DIV':
|
||||||
begin
|
begin
|
||||||
fInDivTitle:=(AttrName='CLASS') and (AttrValue='TITLE');
|
fInDivTitle:=(CompareText(AttrName,'CLASS')=0)
|
||||||
|
and (CompareText(AttrValue,'TITLE')=0);
|
||||||
if fInDivTitle then
|
if fInDivTitle then
|
||||||
begin
|
begin
|
||||||
AddNewLine;
|
AddNewLine;
|
||||||
|
@ -583,12 +583,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TLazLoggerLogGroupList.IndexOf(const AConfigName: String): integer;
|
function TLazLoggerLogGroupList.IndexOf(const AConfigName: String): integer;
|
||||||
var
|
|
||||||
s: String;
|
|
||||||
begin
|
begin
|
||||||
Result := Count - 1;
|
Result := Count - 1;
|
||||||
s := UpperCase(AConfigName);
|
while (Result >= 0) and (CompareText(Item[Result]^.ConfigName, AConfigName) <> 0) do
|
||||||
while (Result >= 0) and (Item[Result]^.ConfigName <> s) do
|
|
||||||
dec(Result);
|
dec(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ type
|
|||||||
const
|
const
|
||||||
EndOfLine: shortstring = LineEnding;
|
EndOfLine: shortstring = LineEnding;
|
||||||
|
|
||||||
|
function PosI(const SubStr, S: string): integer;
|
||||||
|
function LazStartsText(const ASubText, AText: string): Boolean;
|
||||||
|
function LazEndsText(const ASubText, AText: string): Boolean;
|
||||||
function IsNumber(s: String): Boolean;
|
function IsNumber(s: String): Boolean;
|
||||||
|
|
||||||
// Functions for line endings
|
// Functions for line endings
|
||||||
@ -111,6 +114,61 @@ const
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function PosI(const SubStr, S: string): integer;
|
||||||
|
// A case-insensitive version of Pos().
|
||||||
|
// Note: StrUtils has ContainsText but its implementation is VERY slow.
|
||||||
|
var
|
||||||
|
Len1, Len2, Cnt1, Cnt2: integer;
|
||||||
|
SubFirst: Char;
|
||||||
|
begin
|
||||||
|
Len1 := Length(SubStr);
|
||||||
|
Len2 := Length(S);
|
||||||
|
if (Len1 = 0) or (Len1 > Len2) then
|
||||||
|
Exit(0);
|
||||||
|
SubFirst := LowerCase(SubStr[1]);
|
||||||
|
Result := 0;
|
||||||
|
for Cnt1 := 1 to Len2-Len1+1 do
|
||||||
|
begin // Outer loop finds the first matching character.
|
||||||
|
if LowerCase(S[Cnt1]) = SubFirst then
|
||||||
|
begin // Maybe a start of the substring.
|
||||||
|
Result := Cnt1;
|
||||||
|
for Cnt2 := 2 to Len1 do
|
||||||
|
if LowerCase(S[Cnt1+Cnt2-1]) <> LowerCase(SubStr[Cnt2]) then
|
||||||
|
begin
|
||||||
|
Result := 0; // No match
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Result > 0 then
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LazStartsText(const ASubText, AText: string): Boolean;
|
||||||
|
// A fast implementation of StartsText.
|
||||||
|
// The version in RTL calls AnsiCompareText and is VERY slow.
|
||||||
|
begin
|
||||||
|
if (Length(AText) >= Length(ASubText)) and (ASubText <> '') then
|
||||||
|
Result := StrLIComp(PChar(ASubText), PChar(AText), Length(ASubText)) = 0
|
||||||
|
else
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LazEndsText(const ASubText, AText: string): Boolean;
|
||||||
|
// A fast implementation of StartsText.
|
||||||
|
// The version in RTL calls AnsiCompareText and is VERY slow.
|
||||||
|
var
|
||||||
|
LS, LT: SizeInt;
|
||||||
|
begin
|
||||||
|
LS := Length(ASubText);
|
||||||
|
LT := Length(AText);
|
||||||
|
if (LT >= LS) and (ASubText <> '') then
|
||||||
|
Result := StrLIComp(PChar(ASubText), @AText[LT-LS+1], LS) = 0
|
||||||
|
else
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function IsNumber(s: String): Boolean;
|
function IsNumber(s: String): Boolean;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
@ -1096,7 +1154,7 @@ function GetPart(const ASkipTo, AnEnd: array of String; var ASource: String;
|
|||||||
const AnIgnoreCase: Boolean = False; const AnUpdateSource: Boolean = True): String;
|
const AnIgnoreCase: Boolean = False; const AnUpdateSource: Boolean = True): String;
|
||||||
var
|
var
|
||||||
n, i, idx: Integer;
|
n, i, idx: Integer;
|
||||||
S, Source, Match: String;
|
Source, Match: String;
|
||||||
HasEscape: Boolean;
|
HasEscape: Boolean;
|
||||||
begin
|
begin
|
||||||
Source := ASource;
|
Source := ASource;
|
||||||
@ -1106,9 +1164,6 @@ begin
|
|||||||
idx := 0;
|
idx := 0;
|
||||||
Match := '';
|
Match := '';
|
||||||
HasEscape := False;
|
HasEscape := False;
|
||||||
if AnIgnoreCase
|
|
||||||
then S := UpperCase(Source)
|
|
||||||
else S := Source;
|
|
||||||
for n := Low(ASkipTo) to High(ASkipTo) do
|
for n := Low(ASkipTo) to High(ASkipTo) do
|
||||||
begin
|
begin
|
||||||
if ASkipTo[n] = ''
|
if ASkipTo[n] = ''
|
||||||
@ -1117,33 +1172,26 @@ begin
|
|||||||
Continue;
|
Continue;
|
||||||
end;
|
end;
|
||||||
if AnIgnoreCase
|
if AnIgnoreCase
|
||||||
then i := Pos(UpperCase(ASkipTo[n]), S)
|
then i := PosI(ASkipTo[n], Source)
|
||||||
else i := Pos(ASkipTo[n], S);
|
else i := Pos(ASkipTo[n], Source);
|
||||||
if i > idx
|
if i > idx
|
||||||
then begin
|
then begin
|
||||||
idx := i;
|
idx := i;
|
||||||
Match := ASkipTo[n];
|
Match := ASkipTo[n];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if (idx = 0) and not HasEscape
|
if (idx = 0) and not HasEscape then Exit('');
|
||||||
then begin
|
|
||||||
Result := '';
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
if idx > 0
|
if idx > 0
|
||||||
then Delete(Source, 1, idx + Length(Match) - 1);
|
then Delete(Source, 1, idx + Length(Match) - 1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if AnIgnoreCase
|
|
||||||
then S := UpperCase(Source)
|
|
||||||
else S := Source;
|
|
||||||
idx := MaxInt;
|
idx := MaxInt;
|
||||||
for n := Low(AnEnd) to High(AnEnd) do
|
for n := Low(AnEnd) to High(AnEnd) do
|
||||||
begin
|
begin
|
||||||
if AnEnd[n] = '' then Continue;
|
if AnEnd[n] = '' then Continue;
|
||||||
if AnIgnoreCase
|
if AnIgnoreCase
|
||||||
then i := Pos(UpperCase(AnEnd[n]), S)
|
then i := PosI(AnEnd[n], Source)
|
||||||
else i := Pos(AnEnd[n], S);
|
else i := Pos(AnEnd[n], Source);
|
||||||
if (i > 0) and (i < idx) then idx := i;
|
if (i > 0) and (i < idx) then idx := i;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1277,30 +1325,29 @@ end;
|
|||||||
|
|
||||||
function StringCase(const AString: String; const ACase: array of String; const AIgnoreCase, APartial: Boolean): Integer;
|
function StringCase(const AString: String; const ACase: array of String; const AIgnoreCase, APartial: Boolean): Integer;
|
||||||
var
|
var
|
||||||
Search, S: String;
|
S: String;
|
||||||
begin
|
begin
|
||||||
if High(ACase) = -1
|
if High(ACase) = -1 then Exit(-1);
|
||||||
then begin
|
|
||||||
Result := -1;
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if AIgnoreCase
|
|
||||||
then Search := UpperCase(AString)
|
|
||||||
else Search := AString;
|
|
||||||
|
|
||||||
for Result := Low(ACase) to High(ACase) do
|
for Result := Low(ACase) to High(ACase) do
|
||||||
begin
|
begin
|
||||||
if AIgnoreCase
|
S := ACase[Result];
|
||||||
then S := UpperCase(ACase[Result])
|
// Exact match
|
||||||
else S := ACase[Result];
|
if AIgnoreCase then begin
|
||||||
|
if CompareText(AString, S) = 0 then Exit;
|
||||||
if Search = S then Exit;
|
end
|
||||||
|
else begin
|
||||||
|
if AString = S then Exit;
|
||||||
|
end;
|
||||||
if not APartial then Continue;
|
if not APartial then Continue;
|
||||||
if Length(Search) >= Length(S) then Continue;
|
if Length(AString) >= Length(S) then Continue;
|
||||||
if StrLComp(PChar(Search), PChar(S), Length(Search)) = 0 then Exit;
|
// Partial match
|
||||||
|
if AIgnoreCase then begin
|
||||||
|
if StrLIComp(PChar(AString), PChar(S), Length(AString)) = 0 then Exit;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if StrLComp(PChar(AString), PChar(S), Length(AString)) = 0 then Exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := -1;
|
Result := -1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -541,7 +541,7 @@ begin
|
|||||||
inc(I);
|
inc(I);
|
||||||
if not (Path[I] in AllowDirectorySeparators) then
|
if not (Path[I] in AllowDirectorySeparators) then
|
||||||
Exit('');
|
Exit('');
|
||||||
if UpperCase(Copy(Path, I + 1, 3)) = 'UNC' then
|
if CompareText(Copy(Path, I+1, 3), 'UNC') = 0 then
|
||||||
begin
|
begin
|
||||||
inc(I, 4);
|
inc(I, 4);
|
||||||
if I < Len then
|
if I < Len then
|
||||||
|
@ -33,6 +33,8 @@ uses
|
|||||||
Classes, SysUtils, contnrs, Math, dateutils, laz.VirtualTrees,
|
Classes, SysUtils, contnrs, Math, dateutils, laz.VirtualTrees,
|
||||||
// LCL
|
// LCL
|
||||||
Controls, Graphics, Menus, Dialogs, Forms, LCLType, Buttons,
|
Controls, Graphics, Menus, Dialogs, Forms, LCLType, Buttons,
|
||||||
|
// LazUtils
|
||||||
|
LazStringUtils,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
LCLIntf, PackageIntf,
|
LCLIntf, PackageIntf,
|
||||||
// OpkMan
|
// OpkMan
|
||||||
@ -941,7 +943,7 @@ procedure TVisualTree.FilterTree(const AFilterBy: TFilterBy; const AText:
|
|||||||
var
|
var
|
||||||
P: Integer;
|
P: Integer;
|
||||||
begin
|
begin
|
||||||
P := Pos(UpperCase(AText), UpperCase(ADataText));
|
P := PosI(AText, ADataText);
|
||||||
if P > 0 then
|
if P > 0 then
|
||||||
FVST.IsVisible[Node] := True
|
FVST.IsVisible[Node] := True
|
||||||
else
|
else
|
||||||
@ -987,7 +989,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
if Data^.DataType = 12 then
|
if Data^.DataType = 12 then
|
||||||
begin
|
begin
|
||||||
if Pos(UpperCase(CategoriesEng[AExtraParam]), UpperCase(Data^.Category)) > 0 then
|
if PosI(CategoriesEng[AExtraParam], Data^.Category) > 0 then
|
||||||
FilterNode(Node, 'PackageCategory')
|
FilterNode(Node, 'PackageCategory')
|
||||||
else
|
else
|
||||||
FilterNode(Node, '')
|
FilterNode(Node, '')
|
||||||
|
Loading…
Reference in New Issue
Block a user