mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-01 22:20:19 +02:00
codetools: CompareDottedIdentifiersCase: check ampersands
This commit is contained in:
parent
8557bc7d46
commit
d1740179af
@ -193,7 +193,7 @@ function DottedIdentifierLength(Identifier: PChar): integer;
|
||||
function GetDottedIdentifier(Identifier: PChar): string;
|
||||
function IsDottedIdentifier(const Identifier: string): boolean;
|
||||
function CompareDottedIdentifiers(Identifier1, Identifier2: PChar): integer; // compares both to maximum dotted identifier
|
||||
function CompareDottedIdentifiersCaseSens(Identifier1, Identifier2: PChar): integer;
|
||||
function CompareDottedIdentifiersCase(Identifier1, Identifier2: PChar): integer; // case sensitive CompareDottedIdentifiers
|
||||
function ChompDottedIdentifier(const Identifier: string): string;
|
||||
function SkipDottedIdentifierPart(var Identifier: PChar): boolean;
|
||||
|
||||
@ -5341,22 +5341,66 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function CompareDottedIdentifiersCaseSens(Identifier1, Identifier2: PChar): integer;
|
||||
function CompareDottedIdentifiersCase(Identifier1, Identifier2: PChar): integer;
|
||||
var
|
||||
c: Char;
|
||||
begin
|
||||
if (Identifier1<>nil) then begin
|
||||
if (Identifier2<>nil) then begin
|
||||
while (Identifier1[0]=Identifier2[0]) do begin
|
||||
if (IsDottedIdentChar[Identifier1[0]]) then begin
|
||||
if (Identifier1<>nil)
|
||||
and (IsIdentStartChar[Identifier1^]
|
||||
or ((Identifier1^='&') and IsIdentStartChar[Identifier1[1]])) then
|
||||
begin
|
||||
if Identifier1^='&' then inc(Identifier1);
|
||||
if (Identifier2<>nil)
|
||||
and (IsIdentStartChar[Identifier2^]
|
||||
or ((Identifier2^='&') and IsIdentStartChar[Identifier2[1]])) then
|
||||
begin
|
||||
if Identifier2^='&' then inc(Identifier2);
|
||||
while Identifier1^=Identifier2^ do begin
|
||||
c:=Identifier1^;
|
||||
if (IsDottedIdentChar[c]) then begin
|
||||
inc(Identifier1);
|
||||
inc(Identifier2);
|
||||
if c='.' then begin
|
||||
if Identifier1^='&' then begin
|
||||
if IsIdentStartChar[Identifier1[1]] then
|
||||
inc(Identifier1)
|
||||
else begin
|
||||
if Identifier2^='&' then
|
||||
inc(Identifier2);
|
||||
if IsIdentStartChar[Identifier2^] then
|
||||
exit(1) // for example 'a.&' 'a.&b'
|
||||
else
|
||||
exit(0); // for example 'a.&' 'a.&'
|
||||
end;
|
||||
end;
|
||||
if Identifier2^='&' then begin
|
||||
if IsIdentStartChar[Identifier2[1]] then
|
||||
inc(Identifier2)
|
||||
else
|
||||
exit(-1); // for example 'a.&b' 'a.&'
|
||||
end;
|
||||
if Identifier1^='.' then begin
|
||||
// '..'
|
||||
if IsIdentStartChar[Identifier2^] then
|
||||
exit(1) // for example 'a..' 'a.b'
|
||||
else
|
||||
exit(0); // for example 'a..' 'a.1'
|
||||
end;
|
||||
if Identifier2^='.' then begin
|
||||
// '..'
|
||||
if IsIdentStartChar[Identifier1^] then
|
||||
exit(-1) // for example 'a.b' 'a..'
|
||||
else
|
||||
exit(0); // for example 'a.1' 'a..'
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
Result:=0; // for example 'aaA;' 'aAa;'
|
||||
exit;
|
||||
exit(0); // for example 'aa;' 'aa;'
|
||||
end;
|
||||
end;
|
||||
if (IsDottedIdentChar[Identifier1[0]]) then begin
|
||||
if (IsDottedIdentChar[Identifier2[0]]) then begin
|
||||
if Identifier1[0]>Identifier2[0] then
|
||||
if (IsDottedIdentChar[Identifier1^]) then begin
|
||||
if (IsDottedIdentChar[Identifier2^]) then begin
|
||||
if Identifier1^>Identifier2^ then
|
||||
Result:=-1 // for example 'aab' 'aaa'
|
||||
else
|
||||
Result:=1; // for example 'aaa' 'aab'
|
||||
@ -5364,7 +5408,7 @@ begin
|
||||
Result:=-1; // for example 'aaa' 'aa;'
|
||||
end;
|
||||
end else begin
|
||||
if (IsDottedIdentChar[Identifier2[0]]) then
|
||||
if (IsDottedIdentChar[Identifier2^]) then
|
||||
Result:=1 // for example 'aa;' 'aaa'
|
||||
else
|
||||
Result:=0; // for example 'aa;' 'aa,'
|
||||
@ -5373,7 +5417,10 @@ begin
|
||||
Result:=-1; // for example 'aaa' nil
|
||||
end;
|
||||
end else begin
|
||||
if (Identifier2<>nil) then begin
|
||||
if (Identifier2<>nil)
|
||||
and (IsIdentStartChar[Identifier2^]
|
||||
or ((Identifier2^='&') and IsIdentStartChar[Identifier2[1]])) then
|
||||
begin
|
||||
Result:=1; // for example nil 'bbb'
|
||||
end else begin
|
||||
Result:=0; // for example nil nil
|
||||
|
@ -3045,7 +3045,7 @@ begin
|
||||
end;
|
||||
// change if needed
|
||||
if DottedIdents then
|
||||
i:=CompareDottedIdentifiersCaseSens(@Code.Source[IdentStartPos],PChar(Pointer(NewIdentifier)))
|
||||
i:=CompareDottedIdentifiersCase(@Code.Source[IdentStartPos],PChar(Pointer(NewIdentifier)))
|
||||
else
|
||||
i:=CompareIdentifiersCaseSensitive(@Code.Source[IdentStartPos],PChar(Pointer(NewIdentifier)));
|
||||
if i<>0 then begin
|
||||
|
@ -52,6 +52,7 @@ type
|
||||
procedure TestReadNextPascalAtom;
|
||||
procedure TestCompareIdentifiers;
|
||||
procedure TestCompareDottedIdentifiers;
|
||||
procedure TestCompareDottedIdentifiersCase;
|
||||
// FileProcs
|
||||
procedure TestDateToCfgStr;
|
||||
procedure TestFilenameIsMatching;
|
||||
@ -496,6 +497,8 @@ begin
|
||||
t('&a','&;',-1);
|
||||
|
||||
// dotted
|
||||
t('a','a.',1); // compares 'a' and 'a.'
|
||||
t('a','a&',0); // compares 'a' and 'a'
|
||||
t('a','a.b',1);
|
||||
t('a.b','a.b',0);
|
||||
t('a.b','a.b.c',1);
|
||||
@ -513,6 +516,94 @@ begin
|
||||
t('a.&','a.&1',0); // compares 'a.' and 'a.'
|
||||
end;
|
||||
|
||||
procedure TTestBasicCodeTools.TestCompareDottedIdentifiersCase;
|
||||
|
||||
function GetStr(A: PChar): string;
|
||||
begin
|
||||
if A=nil then
|
||||
Result:='nil'
|
||||
else if A^=#0 then
|
||||
Result:='#0'
|
||||
else
|
||||
Result:='"'+A+'"';
|
||||
end;
|
||||
|
||||
procedure Test(A, B: PChar; Expected: integer);
|
||||
var
|
||||
Actual: Integer;
|
||||
AmpA, AmpB: string;
|
||||
begin
|
||||
Actual:=CompareDottedIdentifiersCase(A,B);
|
||||
if Actual<>Expected then
|
||||
Fail('A='+GetStr(A)+' B='+GetStr(B)+', expected '+dbgs(Expected)+', but got '+dbgs(Actual));
|
||||
|
||||
if (A<>nil) and (IsIdentStartChar[A^]) then begin
|
||||
AmpA:='&'+A;
|
||||
Test(PChar(AmpA),B,Expected);
|
||||
if (B<>nil) and (IsIdentStartChar[B^]) then begin
|
||||
AmpB:='&'+B;
|
||||
Test(PChar(AmpA),PChar(AmpB),Expected);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure t(A, B: PChar; Expected: integer);
|
||||
begin
|
||||
Test(A,B,Expected);
|
||||
Test(B,A,-Expected);
|
||||
end;
|
||||
|
||||
begin
|
||||
t(nil,nil,0);
|
||||
t(nil,#0,0);
|
||||
t(nil,#1,0);
|
||||
t(#0,#0,0);
|
||||
t(#0,#1,0);
|
||||
t(#1,#2,0);
|
||||
t('a',nil,-1);
|
||||
t('a',#0,-1);
|
||||
t('a','a',0);
|
||||
t('a','A',-1);
|
||||
t('aa','aa',0);
|
||||
t('aa','a',-1);
|
||||
t('ab','a',-1);
|
||||
t('ab','a;',-1);
|
||||
t('ab','aa',-1);
|
||||
t('ab','aaa',-1);
|
||||
t('ab;','ab',0);
|
||||
t('ab;','ab,',0);
|
||||
t('aaa;','aaa',0);
|
||||
t('i','i',0);
|
||||
t('a',';',-1);
|
||||
t('1','2',0);
|
||||
t(',',',',0);
|
||||
t(',',';',0);
|
||||
t('&',nil,0);
|
||||
t('&',#0,0);
|
||||
t('&','&',0);
|
||||
t('&a','&',-1);
|
||||
t('&a','&;',-1);
|
||||
|
||||
// dotted
|
||||
t('a','a.',1); // compares 'a' and 'a.'
|
||||
t('a','a&',0); // compares 'a' and 'a'
|
||||
t('a','a.b',1);
|
||||
t('a.b','a.b',0);
|
||||
t('a.b','a.b.c',1);
|
||||
t('a.b','a.b',0);
|
||||
t('a.&b','a.b',0);
|
||||
t('a..b','a..b',0); // compares only A.
|
||||
t('a..&b','a..b',0); // compares only A.
|
||||
t('a..b','a..c',0); // compares only A.
|
||||
t('a..&b','a..c',0); // compares only A.
|
||||
t('a.&b','a.c',1);
|
||||
t('a.&b','a.&c',1);
|
||||
t('a.&b','a.&b',0);
|
||||
t('a.&','a.c',1); // compares 'a.' and 'a.c'
|
||||
t('a.&','a.&c',1); // compares 'a.' and 'a.&c'
|
||||
t('a.&','a.&1',0); // compares 'a.' and 'a.'
|
||||
end;
|
||||
|
||||
procedure TTestBasicCodeTools.TestDateToCfgStr;
|
||||
|
||||
procedure t(const Date: TDateTime; const aFormat, Expected: string);
|
||||
|
Loading…
Reference in New Issue
Block a user