mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 16:29:38 +02:00
undo
git-svn-id: trunk@38292 -
This commit is contained in:
parent
8700716f40
commit
ac5fdad655
@ -29,7 +29,7 @@
|
|||||||
<PackageName Value="CodeTools"/>
|
<PackageName Value="CodeTools"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="5">
|
<Units Count="4">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="finddeclaration.lpr"/>
|
<Filename Value="finddeclaration.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
@ -49,11 +49,6 @@
|
|||||||
<Filename Value="../../../../../amat/test/test.inc"/>
|
<Filename Value="../../../../../amat/test/test.inc"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit3>
|
</Unit3>
|
||||||
<Unit4>
|
|
||||||
<Filename Value="scanexamples/commentsidentifiers.pas"/>
|
|
||||||
<IsPartOfProject Value="True"/>
|
|
||||||
<UnitName Value="commentsidentifiers"/>
|
|
||||||
</Unit4>
|
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
@ -48,7 +48,6 @@ begin
|
|||||||
writeln('Usage:');
|
writeln('Usage:');
|
||||||
writeln(' ',ParamStr(0));
|
writeln(' ',ParamStr(0));
|
||||||
writeln(' ',ParamStr(0),' <filename> <X> <Y>');
|
writeln(' ',ParamStr(0),' <filename> <X> <Y>');
|
||||||
Halt(1);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// setup the Options
|
// setup the Options
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
unit commentsidentifiers;
|
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
uses
|
|
||||||
Classes, SysUtils;
|
|
||||||
|
|
||||||
type
|
|
||||||
TMyRange = 1..10;
|
|
||||||
|
|
||||||
{$IFDEF doesnotexist}
|
|
||||||
var
|
|
||||||
i: TMyRange;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
end.
|
|
||||||
|
|
@ -43,7 +43,7 @@ uses
|
|||||||
MemCheck,
|
MemCheck,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, SysUtils, LazUTF8, LazDbgLog, LazFileCache, LazFileUtils,
|
Classes, SysUtils, LazUTF8, LazDbgLog, LazFileCache, LazFileUtils,
|
||||||
lazutf8classes, LazLogger, AVL_Tree, CodeToolsStrConsts;
|
lazutf8classes, AVL_Tree, CodeToolsStrConsts;
|
||||||
|
|
||||||
type
|
type
|
||||||
TFPCStreamSeekType = int64;
|
TFPCStreamSeekType = int64;
|
||||||
@ -289,7 +289,6 @@ function dbgMemRange(P: PByte; Count: integer; Width: integer = 0): string; over
|
|||||||
function DbgS(const i1,i2,i3,i4: integer): string; overload;
|
function DbgS(const i1,i2,i3,i4: integer): string; overload;
|
||||||
function DbgStr(const StringWithSpecialChars: string): string; overload;
|
function DbgStr(const StringWithSpecialChars: string): string; overload;
|
||||||
function DbgStr(const StringWithSpecialChars: string; StartPos, Len: PtrInt): string; overload;
|
function DbgStr(const StringWithSpecialChars: string; StartPos, Len: PtrInt): string; overload;
|
||||||
function DbgText(const StringWithSpecialChars: string; KeepLines: boolean = true): string; overload;
|
|
||||||
|
|
||||||
function MemSizeString(const s: string): PtrUInt; inline;
|
function MemSizeString(const s: string): PtrUInt; inline;
|
||||||
function MemSizeFPList(const List: TFPList): PtrUInt; inline;
|
function MemSizeFPList(const List: TFPList): PtrUInt; inline;
|
||||||
@ -2062,15 +2061,15 @@ var
|
|||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
Result:=StringWithSpecialChars;
|
Result:=StringWithSpecialChars;
|
||||||
i:=length(Result);
|
i:=1;
|
||||||
while (i>0) do begin
|
while (i<=length(Result)) do begin
|
||||||
case Result[i] of
|
case Result[i] of
|
||||||
' '..#126: ;
|
' '..#126: inc(i);
|
||||||
else
|
else
|
||||||
s:='#'+IntToStr(ord(Result[i]));
|
s:='#'+IntToStr(ord(Result[i]));
|
||||||
ReplaceSubstring(Result,i,1,s);
|
Result:=copy(Result,1,i-1)+s+copy(Result,i+1,length(Result)-i);
|
||||||
|
inc(i,length(s));
|
||||||
end;
|
end;
|
||||||
dec(i);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2080,31 +2079,6 @@ begin
|
|||||||
Result:=dbgstr(copy(StringWithSpecialChars,StartPos,Len));
|
Result:=dbgstr(copy(StringWithSpecialChars,StartPos,Len));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function DbgText(const StringWithSpecialChars: string; KeepLines: boolean
|
|
||||||
): string;
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
s: String;
|
|
||||||
begin
|
|
||||||
Result:=StringWithSpecialChars;
|
|
||||||
i:=length(Result);
|
|
||||||
while (i>0) do begin
|
|
||||||
case Result[i] of
|
|
||||||
#10,#13:
|
|
||||||
begin
|
|
||||||
p:=i;
|
|
||||||
inc(i);
|
|
||||||
if (i<=length(Result))
|
|
||||||
end;
|
|
||||||
' '..#126: dec(i);
|
|
||||||
else
|
|
||||||
s:='#'+IntToStr(ord(Result[i]));
|
|
||||||
ReplaceSubstring(Result,i,1,s);
|
|
||||||
dec(i);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function MemSizeString(const s: string): PtrUInt;
|
function MemSizeString(const s: string): PtrUInt;
|
||||||
begin
|
begin
|
||||||
Result:=LazDbgLog.MemSizeString(s);
|
Result:=LazDbgLog.MemSizeString(s);
|
||||||
|
@ -1412,12 +1412,10 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if DirtySrc<>nil then DirtySrc.Clear;
|
if DirtySrc<>nil then DirtySrc.Clear;
|
||||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||||
[btSetIgnoreErrorPos,btCursorPosOutAllowed]);
|
[btSetIgnoreErrorPos,btLoadDirtySource,btCursorPosOutAllowed]);
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TFindDeclarationTool.FindDeclaration C CleanCursorPos=',dbgs(CleanCursorPos));
|
DebugLn('TFindDeclarationTool.FindDeclaration C CleanCursorPos=',dbgs(CleanCursorPos));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
debugln(['TFindDeclarationTool.FindDeclaration ',dbgstr]);
|
|
||||||
|
|
||||||
// find CodeTreeNode at cursor
|
// find CodeTreeNode at cursor
|
||||||
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then begin
|
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then begin
|
||||||
CursorNode:=BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
|
CursorNode:=BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
|
||||||
@ -5167,7 +5165,7 @@ begin
|
|||||||
// build code tree
|
// build code tree
|
||||||
if DirtySrc<>nil then DirtySrc.Clear;
|
if DirtySrc<>nil then DirtySrc.Clear;
|
||||||
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
|
||||||
[btSetIgnoreErrorPos,btCursorPosOutAllowed]);
|
[btSetIgnoreErrorPos,btLoadDirtySource,btCursorPosOutAllowed]);
|
||||||
// find CodeTreeNode at cursor
|
// find CodeTreeNode at cursor
|
||||||
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then
|
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then
|
||||||
CursorNode := BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos, True)
|
CursorNode := BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos, True)
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
resulting source is called the cleaned source. A link points from a position
|
resulting source is called the cleaned source. A link points from a position
|
||||||
of the cleaned source to its position in the real source.
|
of the cleaned source to its position in the real source.
|
||||||
The link list makes it possible to change scanned code in the source files.
|
The link list makes it possible to change scanned code in the source files.
|
||||||
|
|
||||||
|
ToDo:
|
||||||
|
- macros
|
||||||
}
|
}
|
||||||
unit LinkScanner;
|
unit LinkScanner;
|
||||||
|
|
||||||
@ -41,6 +44,7 @@ unit LinkScanner;
|
|||||||
{$I codetools.inc}
|
{$I codetools.inc}
|
||||||
|
|
||||||
{ $DEFINE ShowIgnoreErrorAfter}
|
{ $DEFINE ShowIgnoreErrorAfter}
|
||||||
|
{ $DEFINE EnableIncludeSkippedCode}
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
{ $DEFINE ShowUpdateCleanedSrc}
|
{ $DEFINE ShowUpdateCleanedSrc}
|
||||||
@ -91,10 +95,7 @@ type
|
|||||||
{ TSourceLink is used to map between the codefiles and the cleaned source }
|
{ TSourceLink is used to map between the codefiles and the cleaned source }
|
||||||
TSourceLinkKind = (
|
TSourceLinkKind = (
|
||||||
slkCode,
|
slkCode,
|
||||||
slkMissingIncludeFile,
|
slkMissingIncludeFile
|
||||||
slkSkipStart, // start of skipped code due to IFDEFs {#3
|
|
||||||
slkSkipEnd, // end of skipped code due to IFDEFs #3}
|
|
||||||
slkCompilerString // e.g. {$I %FPCVERSION%}
|
|
||||||
);
|
);
|
||||||
TSourceLinkKinds = set of TSourceLinkKind;
|
TSourceLinkKinds = set of TSourceLinkKind;
|
||||||
PSourceLink = ^TSourceLink;
|
PSourceLink = ^TSourceLink;
|
||||||
@ -348,15 +349,15 @@ type
|
|||||||
function ReturnFromIncludeFileAndIsEnd: boolean;
|
function ReturnFromIncludeFileAndIsEnd: boolean;
|
||||||
function ReadIdentifier: string;
|
function ReadIdentifier: string;
|
||||||
function ReadUpperIdentifier: string;
|
function ReadUpperIdentifier: string;
|
||||||
procedure ReadSpace; {$IFDEF UseInline}inline;{$ENDIF}
|
procedure SkipSpace; {$IFDEF UseInline}inline;{$ENDIF}
|
||||||
procedure ReadCurlyComment;
|
procedure SkipCurlyComment;
|
||||||
procedure ReadLineComment;
|
procedure SkipLineComment;
|
||||||
procedure ReadRoundComment;
|
procedure SkipRoundComment;
|
||||||
procedure CommentEndNotFound;
|
procedure CommentEndNotFound;
|
||||||
procedure EndComment; {$IFDEF UseInline}inline;{$ENDIF}
|
procedure EndComment; {$IFDEF UseInline}inline;{$ENDIF}
|
||||||
procedure IncCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
procedure IncCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
||||||
procedure DecCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
procedure DecCommentLevel; {$IFDEF UseInline}inline;{$ENDIF}
|
||||||
procedure HandleDirective;
|
procedure HandleDirectives;
|
||||||
procedure UpdateCleanedSource(NewCopiedSrcPos: integer);
|
procedure UpdateCleanedSource(NewCopiedSrcPos: integer);
|
||||||
function ReturnFromIncludeFile: boolean;
|
function ReturnFromIncludeFile: boolean;
|
||||||
function ParseKeyWord(StartPos, WordLen: integer; LastTokenType: TLSTokenType
|
function ParseKeyWord(StartPos, WordLen: integer; LastTokenType: TLSTokenType
|
||||||
@ -386,9 +387,7 @@ type
|
|||||||
procedure SetCompilerMode(const AValue: TCompilerMode);
|
procedure SetCompilerMode(const AValue: TCompilerMode);
|
||||||
procedure SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
|
procedure SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
|
||||||
function InternalIfDirective: boolean;
|
function InternalIfDirective: boolean;
|
||||||
procedure EndSkipping;
|
|
||||||
procedure AddSkipComment(IsStart: boolean);
|
|
||||||
|
|
||||||
function IfdefDirective: boolean;
|
function IfdefDirective: boolean;
|
||||||
function IfCDirective: boolean;
|
function IfCDirective: boolean;
|
||||||
function IfndefDirective: boolean;
|
function IfndefDirective: boolean;
|
||||||
@ -426,7 +425,6 @@ type
|
|||||||
function MissingIncludeFilesNeedsUpdate: boolean;
|
function MissingIncludeFilesNeedsUpdate: boolean;
|
||||||
procedure ClearMissingIncludeFiles;
|
procedure ClearMissingIncludeFiles;
|
||||||
|
|
||||||
// code macros
|
|
||||||
procedure AddMacroValue(MacroName: PChar;
|
procedure AddMacroValue(MacroName: PChar;
|
||||||
ValueStart, ValueEnd: integer);
|
ValueStart, ValueEnd: integer);
|
||||||
procedure ClearMacros;
|
procedure ClearMacros;
|
||||||
@ -625,7 +623,6 @@ function IndexOfCodeInUniqueList(ACode: Pointer;
|
|||||||
UniqueSortedCodeList: TFPList): integer;
|
UniqueSortedCodeList: TFPList): integer;
|
||||||
function dbgs(r: TLinkScannerRange): string; overload;
|
function dbgs(r: TLinkScannerRange): string; overload;
|
||||||
function dbgs(const ModeSwitches: TCompilerModeSwitches): string; overload;
|
function dbgs(const ModeSwitches: TCompilerModeSwitches): string; overload;
|
||||||
function dbgs(k: TSourceLinkKind): string; overload;
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -692,17 +689,6 @@ begin
|
|||||||
Result:='['+Result+']';
|
Result:='['+Result+']';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function dbgs(k: TSourceLinkKind): string;
|
|
||||||
begin
|
|
||||||
case k of
|
|
||||||
slkCode: Result:='Code';
|
|
||||||
slkMissingIncludeFile: Result:='MissingInc';
|
|
||||||
slkSkipStart: Result:='SkipStart';
|
|
||||||
slkSkipEnd: Result:='SkipEnd';
|
|
||||||
else Result:='?';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure AddCodeToUniqueList(ACode: Pointer; UniqueSortedCodeList: TFPList);
|
procedure AddCodeToUniqueList(ACode: Pointer; UniqueSortedCodeList: TFPList);
|
||||||
var l,m,r: integer;
|
var l,m,r: integer;
|
||||||
begin
|
begin
|
||||||
@ -765,14 +751,7 @@ var
|
|||||||
NewCapacity: Integer;
|
NewCapacity: Integer;
|
||||||
Link: PSourceLink;
|
Link: PSourceLink;
|
||||||
begin
|
begin
|
||||||
if (LinkCount>0) and (FLinks[FLinkCount-1].CleanedPos=CleanedLen+1) then begin
|
if FLinkCount=FLinkCapacity then begin
|
||||||
// last link is empty => remove
|
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
|
||||||
Link:=@FLinks[FLinkCount-1];
|
|
||||||
debugln(['TLinkScanner.AddLink removing empty link: ',dbgs(Link^.Kind)]);
|
|
||||||
{$ENDIF}
|
|
||||||
dec(FLinkCount);
|
|
||||||
end else if FLinkCount=FLinkCapacity then begin
|
|
||||||
NewCapacity:=FLinkCapacity*2;
|
NewCapacity:=FLinkCapacity*2;
|
||||||
if NewCapacity<16 then NewCapacity:=16;
|
if NewCapacity<16 then NewCapacity:=16;
|
||||||
ReAllocMem(FLinks,NewCapacity*SizeOf(TSourceLink));
|
ReAllocMem(FLinks,NewCapacity*SizeOf(TSourceLink));
|
||||||
@ -899,6 +878,8 @@ function TLinkScanner.FindFirstSiblingLink(LinkIndex: integer): integer;
|
|||||||
if LinkIndex is in an include file, the result will be the first link of
|
if LinkIndex is in an include file, the result will be the first link of
|
||||||
the include file. If the include file is included multiple times, it is
|
the include file. If the include file is included multiple times, it is
|
||||||
treated as if they are different files.
|
treated as if they are different files.
|
||||||
|
|
||||||
|
ToDo: if include file includes itself, directly or indirectly
|
||||||
}
|
}
|
||||||
var
|
var
|
||||||
LastIndex: integer;
|
LastIndex: integer;
|
||||||
@ -1062,7 +1043,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.HandleDirective;
|
procedure TLinkScanner.HandleDirectives;
|
||||||
var DirStart, DirLen: integer;
|
var DirStart, DirLen: integer;
|
||||||
begin
|
begin
|
||||||
SrcPos:=CommentInnerStartPos+1;
|
SrcPos:=CommentInnerStartPos+1;
|
||||||
@ -1071,7 +1052,7 @@ begin
|
|||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
DirLen:=SrcPos-DirStart;
|
DirLen:=SrcPos-DirStart;
|
||||||
if DirLen>255 then DirLen:=255;
|
if DirLen>255 then DirLen:=255;
|
||||||
FDirectiveName:=copy(Src,DirStart,DirLen);
|
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||||
DoDirective(DirStart,DirLen);
|
DoDirective(DirStart,DirLen);
|
||||||
SrcPos:=CommentEndPos;
|
SrcPos:=CommentEndPos;
|
||||||
end;
|
end;
|
||||||
@ -1127,20 +1108,20 @@ begin
|
|||||||
'{' :
|
'{' :
|
||||||
begin
|
begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadCurlyComment;
|
SkipCurlyComment;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end;
|
end;
|
||||||
'/':
|
'/':
|
||||||
if p[1]='/' then begin
|
if p[1]='/' then begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadLineComment;
|
SkipLineComment;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end else
|
end else
|
||||||
break;
|
break;
|
||||||
'(':
|
'(':
|
||||||
if p[1]='*' then begin
|
if p[1]='*' then begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadRoundComment;
|
SkipRoundComment;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end else
|
end else
|
||||||
break;
|
break;
|
||||||
@ -1416,12 +1397,13 @@ begin
|
|||||||
LastTokenType:=TokenType;
|
LastTokenType:=TokenType;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
if FSkippingDirectives=lssdNone then begin
|
||||||
DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1));
|
{$IFDEF ShowUpdateCleanedSrc}
|
||||||
{$ENDIF}
|
DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1));
|
||||||
if (SrcPos>CopiedSrcPos) then
|
{$ENDIF}
|
||||||
UpdateCleanedSource(SrcPos-1);
|
if SrcPos>CopiedSrcPos then
|
||||||
if FSkippingDirectives<>lssdNone then begin
|
UpdateCleanedSource(SrcPos-1);
|
||||||
|
end else begin
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
{$IFDEF ShowUpdateCleanedSrc}
|
||||||
DebugLn(['TLinkScanner.Scan missing $ENDIF']);
|
DebugLn(['TLinkScanner.Scan missing $ENDIF']);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -1449,7 +1431,7 @@ begin
|
|||||||
FLinks[Index]:=Value;
|
FLinks[Index]:=Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.ReadCurlyComment;
|
procedure TLinkScanner.SkipCurlyComment;
|
||||||
// a normal pascal {} comment
|
// a normal pascal {} comment
|
||||||
var
|
var
|
||||||
p: PChar;
|
p: PChar;
|
||||||
@ -1487,12 +1469,11 @@ begin
|
|||||||
CommentInnerEndPos:=SrcPos-1;
|
CommentInnerEndPos:=SrcPos-1;
|
||||||
if (CommentLevel>0) then CommentEndNotFound;
|
if (CommentLevel>0) then CommentEndNotFound;
|
||||||
// handle compiler switches
|
// handle compiler switches
|
||||||
if Src[CommentInnerStartPos]='$' then
|
if Src[CommentInnerStartPos]='$' then HandleDirectives;
|
||||||
HandleDirective;
|
|
||||||
EndComment;
|
EndComment;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.ReadLineComment;
|
procedure TLinkScanner.SkipLineComment;
|
||||||
// a // newline comment
|
// a // newline comment
|
||||||
var
|
var
|
||||||
p: PChar;
|
p: PChar;
|
||||||
@ -1513,7 +1494,7 @@ begin
|
|||||||
EndComment;
|
EndComment;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.ReadRoundComment;
|
procedure TLinkScanner.SkipRoundComment;
|
||||||
// a delphi comment (* *)
|
// a delphi comment (* *)
|
||||||
var
|
var
|
||||||
p: PChar;
|
p: PChar;
|
||||||
@ -1558,8 +1539,7 @@ begin
|
|||||||
CommentInnerEndPos:=SrcPos-2;
|
CommentInnerEndPos:=SrcPos-2;
|
||||||
if (CommentLevel>0) then CommentEndNotFound;
|
if (CommentLevel>0) then CommentEndNotFound;
|
||||||
// handle compiler switches
|
// handle compiler switches
|
||||||
if Src[CommentInnerStartPos]='$' then
|
if Src[CommentInnerStartPos]='$' then HandleDirectives;
|
||||||
HandleDirective;
|
|
||||||
EndComment;
|
EndComment;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2372,6 +2352,7 @@ begin
|
|||||||
else if InitialValues.IsDefined('WIN32') then
|
else if InitialValues.IsDefined('WIN32') then
|
||||||
FHiddenUsedUnits:='SYSWIN32';
|
FHiddenUsedUnits:='SYSWIN32';
|
||||||
end;
|
end;
|
||||||
|
// ToDo: heaptrc
|
||||||
if InitialValues.IsDefined(MacroUseLineInfo) then
|
if InitialValues.IsDefined(MacroUseLineInfo) then
|
||||||
FHiddenUsedUnits:=FHiddenUsedUnits+',lineinfo'
|
FHiddenUsedUnits:=FHiddenUsedUnits+',lineinfo'
|
||||||
else if InitialValues.IsDefined(MacroUselnfodwrf) then
|
else if InitialValues.IsDefined(MacroUselnfodwrf) then
|
||||||
@ -2452,24 +2433,20 @@ end;
|
|||||||
|
|
||||||
function TLinkScanner.ShortSwitchDirective: boolean;
|
function TLinkScanner.ShortSwitchDirective: boolean;
|
||||||
// example: {$H+} or {$H+, R- comment}
|
// example: {$H+} or {$H+, R- comment}
|
||||||
var
|
|
||||||
c: Char;
|
|
||||||
begin
|
begin
|
||||||
c:=UpChars[FDirectiveName[1]];
|
FDirectiveName:=CompilerSwitchesNames[FDirectiveName[1]];
|
||||||
FDirectiveName:=CompilerSwitchesNames[c];
|
|
||||||
if FDirectiveName<>'' then begin
|
if FDirectiveName<>'' then begin
|
||||||
if (SrcPos<=SrcLen) and (Src[SrcPos] in ['-','+']) then begin
|
if (SrcPos<=SrcLen) and (Src[SrcPos] in ['-','+']) then begin
|
||||||
if Src[SrcPos]='-' then
|
if Src[SrcPos]='-' then
|
||||||
Values.Variables[FDirectiveName]:='0'
|
Values.Variables[FDirectiveName]:='0'
|
||||||
else
|
else
|
||||||
Values.Variables[FDirectiveName]:='1';
|
Values.Variables[FDirectiveName]:='1';
|
||||||
inc(SrcPos);
|
|
||||||
Result:=ReadNextSwitchDirective;
|
Result:=ReadNextSwitchDirective;
|
||||||
end else begin
|
end else begin
|
||||||
if c='I' then
|
if FDirectiveName<>CompilerSwitchesNames['I'] then
|
||||||
Result:=IncludeDirective
|
Result:=LongSwitchDirective
|
||||||
else
|
else
|
||||||
Result:=LongSwitchDirective;
|
Result:=IncludeDirective;
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -2491,17 +2468,17 @@ begin
|
|||||||
case UpChars[p^] of
|
case UpChars[p^] of
|
||||||
'A':
|
'A':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'L': if CompareIdentifiers(p,'ALIGN')=0 then Result:=LongSwitchDirective;
|
'L': if CompareIdentifiers(p,'ALIGN')=0 then Result:=true;
|
||||||
'S': if CompareIdentifiers(p,'ASSERTIONS')=0 then Result:=LongSwitchDirective;
|
'S': if CompareIdentifiers(p,'ASSERTIONS')=0 then Result:=true;
|
||||||
end;
|
end;
|
||||||
'B':
|
'B':
|
||||||
if CompareIdentifiers(p,'BOOLEVAL')=0 then Result:=LongSwitchDirective;
|
if CompareIdentifiers(p,'BOOLEVAL')=0 then Result:=true;
|
||||||
'D':
|
'D':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
'E':
|
'E':
|
||||||
case UpChars[p[2]] of
|
case UpChars[p[2]] of
|
||||||
'F': if CompareIdentifiers(p,'DEFINE')=0 then Result:=DefineDirective;
|
'F': if CompareIdentifiers(p,'DEFINE')=0 then Result:=DefineDirective;
|
||||||
'B': if CompareIdentifiers(p,'DEBUGINFO')=0 then Result:=LongSwitchDirective;
|
'B': if CompareIdentifiers(p,'DEBUGINFO')=0 then Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
'E':
|
'E':
|
||||||
@ -2521,7 +2498,7 @@ begin
|
|||||||
if CompareIdentifiers(p,'ENDC')=0 then Result:=EndCDirective
|
if CompareIdentifiers(p,'ENDC')=0 then Result:=EndCDirective
|
||||||
else if CompareIdentifiers(p,'ENDIF')=0 then Result:=EndIfDirective;
|
else if CompareIdentifiers(p,'ENDIF')=0 then Result:=EndIfDirective;
|
||||||
'X':
|
'X':
|
||||||
if CompareIdentifiers(p,'EXTENDEDSYNTAX')=0 then Result:=LongSwitchDirective;
|
if CompareIdentifiers(p,'EXTENDEDSYNTAX')=0 then Result:=true;
|
||||||
end;
|
end;
|
||||||
'I':
|
'I':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
@ -2537,36 +2514,36 @@ begin
|
|||||||
'N':
|
'N':
|
||||||
if CompareIdentifiers(p,'INCLUDE')=0 then Result:=IncludeDirective
|
if CompareIdentifiers(p,'INCLUDE')=0 then Result:=IncludeDirective
|
||||||
else if CompareIdentifiers(p,'INCLUDEPATH')=0 then Result:=IncludePathDirective;
|
else if CompareIdentifiers(p,'INCLUDEPATH')=0 then Result:=IncludePathDirective;
|
||||||
'O': if CompareIdentifiers(p,'IOCHECKS')=0 then Result:=LongSwitchDirective;
|
'O': if CompareIdentifiers(p,'IOCHECKS')=0 then Result:=true;
|
||||||
end;
|
end;
|
||||||
'L':
|
'L':
|
||||||
if CompareIdentifiers(p,'LOCALSYMBOLS')=0 then Result:=LongSwitchDirective
|
if CompareIdentifiers(p,'LOCALSYMBOLS')=0 then Result:=true
|
||||||
else if CompareIdentifiers(p,'LONGSTRINGS')=0 then Result:=LongSwitchDirective;
|
else if CompareIdentifiers(p,'LONGSTRINGS')=0 then Result:=true;
|
||||||
'M':
|
'M':
|
||||||
if CompareIdentifiers(p,'MODE')=0 then Result:=ModeDirective
|
if CompareIdentifiers(p,'MODE')=0 then Result:=ModeDirective
|
||||||
else if CompareIdentifiers(p,'MODESWITCH')=0 then Result:=ModeSwitchDirective
|
else if CompareIdentifiers(p,'MODESWITCH')=0 then Result:=ModeSwitchDirective
|
||||||
else if CompareIdentifiers(p,'MACRO')=0 then Result:=MacroDirective;
|
else if CompareIdentifiers(p,'MACRO')=0 then Result:=MacroDirective;
|
||||||
'O':
|
'O':
|
||||||
if CompareIdentifiers(p,'OPENSTRINGS')=0 then Result:=LongSwitchDirective
|
if CompareIdentifiers(p,'OPENSTRINGS')=0 then Result:=true
|
||||||
else if CompareIdentifiers(p,'OVERFLOWCHECKS')=0 then Result:=LongSwitchDirective;
|
else if CompareIdentifiers(p,'OVERFLOWCHECKS')=0 then Result:=true;
|
||||||
'R':
|
'R':
|
||||||
if CompareIdentifiers(p,'RANGECHECKS')=0 then Result:=LongSwitchDirective
|
if CompareIdentifiers(p,'RANGECHECKS')=0 then Result:=true
|
||||||
else if CompareIdentifiers(p,'REFERENCEINFO')=0 then Result:=LongSwitchDirective;
|
else if CompareIdentifiers(p,'REFERENCEINFO')=0 then Result:=true;
|
||||||
'S':
|
'S':
|
||||||
if CompareIdentifiers(p,'SETC')=0 then Result:=SetCDirective
|
if CompareIdentifiers(p,'SETC')=0 then Result:=SetCDirective
|
||||||
else if CompareIdentifiers(p,'STACKFRAMES')=0 then Result:=LongSwitchDirective;
|
else if CompareIdentifiers(p,'STACKFRAMES')=0 then Result:=true;
|
||||||
'T':
|
'T':
|
||||||
if CompareIdentifiers(p,'THREADING')=0 then Result:=ThreadingDirective
|
if CompareIdentifiers(p,'THREADING')=0 then Result:=ThreadingDirective
|
||||||
else if CompareIdentifiers(p,'TYPEADDRESS')=0 then Result:=LongSwitchDirective
|
else if CompareIdentifiers(p,'TYPEADDRESS')=0 then Result:=true
|
||||||
else if CompareIdentifiers(p,'TYPEINFO')=0 then Result:=LongSwitchDirective;
|
else if CompareIdentifiers(p,'TYPEINFO')=0 then Result:=true;
|
||||||
'U':
|
'U':
|
||||||
if CompareIdentifiers(p,'UNDEF')=0 then Result:=UndefDirective;
|
if CompareIdentifiers(p,'UNDEF')=0 then Result:=UndefDirective;
|
||||||
'V':
|
'V':
|
||||||
if CompareIdentifiers(p,'VARSTRINGCHECKS')=0 then Result:=LongSwitchDirective;
|
if CompareIdentifiers(p,'VARSTRINGCHECKS')=0 then Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
// skipping code => read only IF directives
|
// skipping code, but still have to read if directives
|
||||||
case UpChars[p^] of
|
case UpChars[p^] of
|
||||||
'E':
|
'E':
|
||||||
case UpChars[p[1]] of
|
case UpChars[p[1]] of
|
||||||
@ -2605,7 +2582,7 @@ function TLinkScanner.LongSwitchDirective: boolean;
|
|||||||
// example: {$ASSERTIONS ON comment}
|
// example: {$ASSERTIONS ON comment}
|
||||||
var ValStart: integer;
|
var ValStart: integer;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
ValStart:=SrcPos;
|
ValStart:=SrcPos;
|
||||||
while (SrcPos<=SrcLen) and IsWordChar[Src[SrcPos]] do
|
while (SrcPos<=SrcLen) and IsWordChar[Src[SrcPos]] do
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
@ -2617,9 +2594,9 @@ begin
|
|||||||
and (FDirectiveName='ASSERTIONS') then
|
and (FDirectiveName='ASSERTIONS') then
|
||||||
Values.Variables[FDirectiveName]:='PRELOAD'
|
Values.Variables[FDirectiveName]:='PRELOAD'
|
||||||
else if (FDirectiveName='LOCALSYMBOLS') then
|
else if (FDirectiveName='LOCALSYMBOLS') then
|
||||||
// ignore "localsymbols <something>"
|
// ignore link object directive
|
||||||
else if (FDirectiveName='RANGECHECKS') then
|
else if (FDirectiveName='RANGECHECKS') then
|
||||||
// ignore "rangechecks <something>"
|
// ignore link object directive
|
||||||
else if (FDirectiveName='ALIGN') then
|
else if (FDirectiveName='ALIGN') then
|
||||||
// set record align size
|
// set record align size
|
||||||
else begin
|
else begin
|
||||||
@ -2633,7 +2610,7 @@ function TLinkScanner.MacroDirective: boolean;
|
|||||||
var
|
var
|
||||||
ValStart: LongInt;
|
ValStart: LongInt;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
ValStart:=SrcPos;
|
ValStart:=SrcPos;
|
||||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
@ -2653,7 +2630,7 @@ var ValStart: integer;
|
|||||||
AMode: TCompilerMode;
|
AMode: TCompilerMode;
|
||||||
ModeValid: boolean;
|
ModeValid: boolean;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
ValStart:=SrcPos;
|
ValStart:=SrcPos;
|
||||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
@ -2692,7 +2669,7 @@ var
|
|||||||
ModeSwitch: TCompilerModeSwitch;
|
ModeSwitch: TCompilerModeSwitch;
|
||||||
s: TCompilerModeSwitches;
|
s: TCompilerModeSwitches;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
ValStart:=SrcPos;
|
ValStart:=SrcPos;
|
||||||
while (SrcPos<=SrcLen) and (IsIdentChar[Src[SrcPos]]) do
|
while (SrcPos<=SrcLen) and (IsIdentChar[Src[SrcPos]]) do
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
@ -2719,7 +2696,7 @@ function TLinkScanner.ThreadingDirective: boolean;
|
|||||||
var
|
var
|
||||||
ValStart: integer;
|
ValStart: integer;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
ValStart:=SrcPos;
|
ValStart:=SrcPos;
|
||||||
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
while (SrcPos<=SrcLen) and (IsWordChar[Src[SrcPos]]) do
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
@ -2736,7 +2713,7 @@ end;
|
|||||||
function TLinkScanner.ReadNextSwitchDirective: boolean;
|
function TLinkScanner.ReadNextSwitchDirective: boolean;
|
||||||
var DirStart, DirLen: integer;
|
var DirStart, DirLen: integer;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
if (SrcPos<=SrcLen) and (Src[SrcPos]=',') then begin
|
if (SrcPos<=SrcLen) and (Src[SrcPos]=',') then begin
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
DirStart:=SrcPos;
|
DirStart:=SrcPos;
|
||||||
@ -2744,7 +2721,7 @@ begin
|
|||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
DirLen:=SrcPos-DirStart;
|
DirLen:=SrcPos-DirStart;
|
||||||
if DirLen>255 then DirLen:=255;
|
if DirLen>255 then DirLen:=255;
|
||||||
FDirectiveName:=copy(Src,DirStart,DirLen);
|
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||||
Result:=DoDirective(DirStart,DirLen);
|
Result:=DoDirective(DirStart,DirLen);
|
||||||
end else
|
end else
|
||||||
Result:=true;
|
Result:=true;
|
||||||
@ -2756,7 +2733,7 @@ var VariableName: string;
|
|||||||
begin
|
begin
|
||||||
inc(IfLevel);
|
inc(IfLevel);
|
||||||
if FSkippingDirectives<>lssdNone then exit(true);
|
if FSkippingDirectives<>lssdNone then exit(true);
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
VariableName:=ReadUpperIdentifier;
|
VariableName:=ReadUpperIdentifier;
|
||||||
if (VariableName<>'') and (not Values.IsDefined(VariableName)) then
|
if (VariableName<>'') and (not Values.IsDefined(VariableName)) then
|
||||||
SkipTillEndifElse(lssdTillElse);
|
SkipTillEndifElse(lssdTillElse);
|
||||||
@ -2772,7 +2749,7 @@ begin
|
|||||||
Result:=InternalIfDirective;
|
Result:=InternalIfDirective;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.ReadSpace;
|
procedure TLinkScanner.SkipSpace;
|
||||||
begin
|
begin
|
||||||
while (SrcPos<=SrcLen) and (IsSpaceChar[Src[SrcPos]]) do inc(SrcPos);
|
while (SrcPos<=SrcLen) and (IsSpaceChar[Src[SrcPos]]) do inc(SrcPos);
|
||||||
end;
|
end;
|
||||||
@ -2814,7 +2791,7 @@ var VariableName: string;
|
|||||||
begin
|
begin
|
||||||
inc(IfLevel);
|
inc(IfLevel);
|
||||||
if FSkippingDirectives<>lssdNone then exit(true);
|
if FSkippingDirectives<>lssdNone then exit(true);
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
VariableName:=ReadUpperIdentifier;
|
VariableName:=ReadUpperIdentifier;
|
||||||
if (VariableName<>'') and (Values.IsDefined(VariableName)) then
|
if (VariableName<>'') and (Values.IsDefined(VariableName)) then
|
||||||
SkipTillEndifElse(lssdTillElse);
|
SkipTillEndifElse(lssdTillElse);
|
||||||
@ -2833,11 +2810,8 @@ begin
|
|||||||
if IfLevel<=0 then
|
if IfLevel<=0 then
|
||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
dec(IfLevel);
|
dec(IfLevel);
|
||||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
if IfLevel<FSkipIfLevel then begin
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
FSkippingDirectives:=lssdNone;
|
||||||
debugln(['TLinkScanner.EndifDirective end skip']);
|
|
||||||
{$ENDIF}
|
|
||||||
EndSkipping;
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
@ -2855,11 +2829,8 @@ begin
|
|||||||
if IfLevel<=0 then
|
if IfLevel<=0 then
|
||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
dec(IfLevel);
|
dec(IfLevel);
|
||||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
if IfLevel<FSkipIfLevel then begin
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
FSkippingDirectives:=lssdNone;
|
||||||
debugln(['TLinkScanner.EndCDirective end skip']);
|
|
||||||
{$ENDIF}
|
|
||||||
EndSkipping;
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
@ -2876,11 +2847,8 @@ begin
|
|||||||
if IfLevel<=0 then
|
if IfLevel<=0 then
|
||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
dec(IfLevel);
|
dec(IfLevel);
|
||||||
if (IfLevel<FSkipIfLevel) and (FSkippingDirectives<>lssdNone) then begin
|
if IfLevel<FSkipIfLevel then begin
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
FSkippingDirectives:=lssdNone;
|
||||||
debugln(['TLinkScanner.IfEndDirective end skip']);
|
|
||||||
{$ENDIF}
|
|
||||||
EndSkipping;
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
@ -2898,15 +2866,12 @@ begin
|
|||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
case FSkippingDirectives of
|
case FSkippingDirectives of
|
||||||
lssdNone:
|
lssdNone:
|
||||||
// last block was executed, skip all other
|
|
||||||
SkipTillEndifElse(lssdTillEndIf);
|
SkipTillEndifElse(lssdTillEndIf);
|
||||||
lssdTillElse:
|
lssdTillElse:
|
||||||
if IfLevel=FSkipIfLevel then begin
|
if IfLevel=FSkipIfLevel then
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
FSkippingDirectives:=lssdNone;
|
||||||
debugln(['TLinkScanner.ElseDirective skipped front, using ELSE part']);
|
// else: continue skip;
|
||||||
{$ENDIF}
|
lssdTillEndIf: ; // continue skip
|
||||||
EndSkipping;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
@ -2925,15 +2890,12 @@ begin
|
|||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
case FSkippingDirectives of
|
case FSkippingDirectives of
|
||||||
lssdNone:
|
lssdNone:
|
||||||
// last block was executed, skip all other
|
|
||||||
SkipTillEndifElse(lssdTillEndIf);
|
SkipTillEndifElse(lssdTillEndIf);
|
||||||
lssdTillElse:
|
lssdTillElse:
|
||||||
if IfLevel=FSkipIfLevel then begin
|
if IfLevel=FSkipIfLevel then
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
FSkippingDirectives:=lssdNone;
|
||||||
debugln(['TLinkScanner.ElseCDirective skipped front, using ELSEC part']);
|
// else: continue skip;
|
||||||
{$ENDIF}
|
lssdTillEndIf: ; // continue skip
|
||||||
EndSkipping;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
@ -2949,15 +2911,13 @@ function TLinkScanner.ElseIfDirective: boolean;
|
|||||||
begin
|
begin
|
||||||
if IfLevel=0 then
|
if IfLevel=0 then
|
||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
case FSkippingDirectives of
|
if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
|
||||||
lssdNone:
|
Result:=InternalIfDirective;
|
||||||
// last block was executed, skip all other
|
end else begin
|
||||||
SkipTillEndifElse(lssdTillEndIf);
|
if (FSkippingDirectives=lssdNone) then
|
||||||
lssdTillElse:
|
SkipTillEndifElse(lssdTillEndIf);
|
||||||
if IfLevel=FSkipIfLevel then
|
Result:=true;
|
||||||
exit(InternalIfDirective);
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLinkScanner.ElIfCDirective: boolean;
|
function TLinkScanner.ElIfCDirective: boolean;
|
||||||
@ -2972,15 +2932,13 @@ begin
|
|||||||
//DebugLn(['TLinkScanner.ElIfCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
//DebugLn(['TLinkScanner.ElIfCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
||||||
if IfLevel=0 then
|
if IfLevel=0 then
|
||||||
RaiseAWithoutB;
|
RaiseAWithoutB;
|
||||||
case FSkippingDirectives of
|
if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
|
||||||
lssdNone:
|
Result:=InternalIfDirective;
|
||||||
// last block was executed, skip all other
|
end else begin
|
||||||
SkipTillEndifElse(lssdTillEndIf);
|
if (FSkippingDirectives=lssdNone) then
|
||||||
lssdTillElse:
|
SkipTillEndifElse(lssdTillEndIf);
|
||||||
if IfLevel=FSkipIfLevel then
|
Result:=true;
|
||||||
exit(InternalIfDirective);
|
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLinkScanner.DefineDirective: boolean;
|
function TLinkScanner.DefineDirective: boolean;
|
||||||
@ -2988,17 +2946,17 @@ function TLinkScanner.DefineDirective: boolean;
|
|||||||
var VariableName, NewValue: string;
|
var VariableName, NewValue: string;
|
||||||
NamePos: LongInt;
|
NamePos: LongInt;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
NamePos:=SrcPos;
|
NamePos:=SrcPos;
|
||||||
VariableName:=ReadUpperIdentifier;
|
VariableName:=ReadUpperIdentifier;
|
||||||
if (VariableName<>'') then begin
|
if (VariableName<>'') then begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
if FMacrosOn and (SrcPos<SrcLen)
|
if FMacrosOn and (SrcPos<SrcLen)
|
||||||
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
||||||
then begin
|
then begin
|
||||||
// makro => store the value
|
// makro => store the value
|
||||||
inc(SrcPos,2);
|
inc(SrcPos,2);
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
||||||
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
||||||
NewValue:='0'
|
NewValue:='0'
|
||||||
@ -3018,7 +2976,7 @@ function TLinkScanner.UndefDirective: boolean;
|
|||||||
// {$undefine name}
|
// {$undefine name}
|
||||||
var VariableName: string;
|
var VariableName: string;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
VariableName:=ReadUpperIdentifier;
|
VariableName:=ReadUpperIdentifier;
|
||||||
if (VariableName<>'') then
|
if (VariableName<>'') then
|
||||||
Values.Undefine(VariableName);
|
Values.Undefine(VariableName);
|
||||||
@ -3029,15 +2987,15 @@ function TLinkScanner.SetCDirective: boolean;
|
|||||||
// {$setc name} or {$setc name:=value}
|
// {$setc name} or {$setc name:=value}
|
||||||
var VariableName, NewValue: string;
|
var VariableName, NewValue: string;
|
||||||
begin
|
begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
VariableName:=ReadUpperIdentifier;
|
VariableName:=ReadUpperIdentifier;
|
||||||
if (VariableName<>'') then begin
|
if (VariableName<>'') then begin
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
if FMacrosOn and (SrcPos<SrcLen)
|
if FMacrosOn and (SrcPos<SrcLen)
|
||||||
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
and (Src[SrcPos]=':') and (Src[SrcPos+1]='=')
|
||||||
then begin
|
then begin
|
||||||
inc(SrcPos,2);
|
inc(SrcPos,2);
|
||||||
ReadSpace;
|
SkipSpace;
|
||||||
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
NewValue:=copy(Src,SrcPos,CommentInnerEndPos-SrcPos);
|
||||||
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
if CompareIdentifiers(PChar(NewValue),'false')=0 then
|
||||||
NewValue:='0'
|
NewValue:='0'
|
||||||
@ -3058,23 +3016,7 @@ var IncFilename: string;
|
|||||||
DynamicExtension: Boolean;
|
DynamicExtension: Boolean;
|
||||||
begin
|
begin
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
if (Src[SrcPos]='%') then begin
|
if (Src[SrcPos]<>'%') then begin
|
||||||
// ToDo: insert string constant: %date%, %fpcversion%
|
|
||||||
UpdateCleanedSource(CommentStartPos-1);
|
|
||||||
// insert ''
|
|
||||||
if 2>length(FCleanedSrc)-CleanedLen then begin
|
|
||||||
// expand cleaned source string by at least 1024
|
|
||||||
SetLength(FCleanedSrc,length(FCleanedSrc)+1024);
|
|
||||||
end;
|
|
||||||
AddLink(1,nil,slkCompilerString);
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:='''';
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:='''';
|
|
||||||
// continue after directive
|
|
||||||
CopiedSrcPos:=CommentEndPos-1;
|
|
||||||
AddLink(CommentEndPos,Code);
|
|
||||||
end else begin
|
|
||||||
IncFilename:=Trim(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
|
IncFilename:=Trim(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
|
||||||
if (IncFilename<>'') and (IncFilename[1]='''')
|
if (IncFilename<>'') and (IncFilename[1]='''')
|
||||||
and (IncFilename[length(IncFilename)]='''') then
|
and (IncFilename[length(IncFilename)]='''') then
|
||||||
@ -3539,35 +3481,10 @@ begin
|
|||||||
//DebugLn(['TLinkScanner.AddMacroSource END Token=',copy(Src,TokenStart,SrcPos-TokenStart)]);
|
//DebugLn(['TLinkScanner.AddMacroSource END Token=',copy(Src,TokenStart,SrcPos-TokenStart)]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.AddSkipComment(IsStart: boolean);
|
|
||||||
begin
|
|
||||||
//DebugLn(['TLinkScanner.AddSkipComment InFront="',dbgstr(CleanedSrc,CleanedLen-12,13),'" isstart=',IsStart]);
|
|
||||||
// insert {#3 or #3}
|
|
||||||
if 2>length(FCleanedSrc)-CleanedLen then begin
|
|
||||||
// expand cleaned source string by at least 1024
|
|
||||||
SetLength(FCleanedSrc,length(FCleanedSrc)+1024);
|
|
||||||
end;
|
|
||||||
if IsStart then begin
|
|
||||||
AddLink(1,nil,slkSkipStart);
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:='{';
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:=#3;
|
|
||||||
end else begin
|
|
||||||
AddLink(1,nil,slkSkipEnd);
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:=#3;
|
|
||||||
inc(CleanedLen);
|
|
||||||
FCleanedSrc[CleanedLen]:='}';
|
|
||||||
end;
|
|
||||||
// SrcPos was not touched and still stands at the same position
|
|
||||||
//DebugLn(['TLinkScanner.AddSkipComment END']);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLinkScanner.ReturnFromIncludeFile: boolean;
|
function TLinkScanner.ReturnFromIncludeFile: boolean;
|
||||||
var OldPos: TSourceLink;
|
var OldPos: TSourceLink;
|
||||||
begin
|
begin
|
||||||
if (SrcPos-1>CopiedSrcPos) then begin
|
if FSkippingDirectives=lssdNone then begin
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
{$IFDEF ShowUpdateCleanedSrc}
|
||||||
DebugLn('TLinkScanner.ReturnFromIncludeFile A UpdatePos=',DbgS(SrcPos-1));
|
DebugLn('TLinkScanner.ReturnFromIncludeFile A UpdatePos=',DbgS(SrcPos-1));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -3630,7 +3547,7 @@ end;
|
|||||||
function TLinkScanner.DoSourceTypeToken: boolean;
|
function TLinkScanner.DoSourceTypeToken: boolean;
|
||||||
// program, unit, library, package
|
// program, unit, library, package
|
||||||
// unit unit1;
|
// unit unit1;
|
||||||
// unit a.b.unit1 platform;
|
// unit unit1 platform;
|
||||||
// unit unit1 unimplemented;
|
// unit unit1 unimplemented;
|
||||||
begin
|
begin
|
||||||
if ScannedRange<>lsrInit then exit(false);
|
if ScannedRange<>lsrInit then exit(false);
|
||||||
@ -3736,11 +3653,10 @@ begin
|
|||||||
|
|
||||||
SrcPos:=CommentEndPos;
|
SrcPos:=CommentEndPos;
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
{$IFDEF ShowUpdateCleanedSrc}
|
||||||
DebugLn('TLinkScanner.SkipTillEndifElse A UpdatePos=',DbgS(SrcPos-1),' Src=',DbgStr(Src,SrcPos-15,15)+'|'+DbgStr(Src,SrcPos,15));
|
DebugLn('TLinkScanner.SkipTillEndifElse A UpdatePos=',DbgS(SrcPos-1),' Src=',DbgStr(copy(Src,SrcPos-15,15))+'|'+DbgStr(copy(Src,SrcPos,15)));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
UpdateCleanedSource(SrcPos-1);
|
UpdateCleanedSource(SrcPos-1);
|
||||||
AddSkipComment(true);
|
|
||||||
|
|
||||||
// parse till $else, $elseif or $endif
|
// parse till $else, $elseif or $endif
|
||||||
FSkipIfLevel:=IfLevel;
|
FSkipIfLevel:=IfLevel;
|
||||||
if (SrcPos<=SrcLen) then begin
|
if (SrcPos<=SrcLen) then begin
|
||||||
@ -3750,14 +3666,14 @@ begin
|
|||||||
'{':
|
'{':
|
||||||
begin
|
begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadCurlyComment;
|
SkipCurlyComment;
|
||||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end;
|
end;
|
||||||
'/':
|
'/':
|
||||||
if p[1]='/' then begin
|
if p[1]='/' then begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadLineComment;
|
SkipLineComment;
|
||||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end else
|
end else
|
||||||
@ -3765,7 +3681,7 @@ begin
|
|||||||
'(':
|
'(':
|
||||||
if p[1]='*' then begin
|
if p[1]='*' then begin
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
ReadRoundComment;
|
SkipRoundComment;
|
||||||
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
if (FSkippingDirectives=lssdNone) or (SrcPos>SrcLen) then break;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
end else
|
end else
|
||||||
@ -3780,11 +3696,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
#0:
|
#0:
|
||||||
begin
|
begin
|
||||||
// FPC allows that corresponding IFDEF and ENDIF are in different files
|
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
if (SrcPos>SrcLen) then begin
|
if (SrcPos>SrcLen) then begin
|
||||||
if not ReturnFromIncludeFile then begin
|
if not ReturnFromIncludeFile then begin
|
||||||
CopiedSrcPos:=SrcLen+1;
|
CommentStartPos:=0;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
p:=@Src[SrcPos];
|
p:=@Src[SrcPos];
|
||||||
@ -3796,6 +3711,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
SrcPos:=p-PChar(Src)+1;
|
SrcPos:=p-PChar(Src)+1;
|
||||||
|
end;
|
||||||
|
if CommentStartPos>0 then begin
|
||||||
|
CopiedSrcPos:=CommentStartPos-1;
|
||||||
|
AddLink(CommentStartPos,Code);
|
||||||
end else begin
|
end else begin
|
||||||
CopiedSrcPos:=SrcLen+1;
|
CopiedSrcPos:=SrcLen+1;
|
||||||
end;
|
end;
|
||||||
@ -3821,60 +3740,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TLinkScanner.InternalIfDirective: boolean;
|
function TLinkScanner.InternalIfDirective: boolean;
|
||||||
// {$if expression} or {$ifc expression}
|
// {$if expression} or {$ifc expression} or indirectly called by {$elifc expression}
|
||||||
// or indirectly called by {$elifc expression} or {$elseif expression}
|
|
||||||
|
|
||||||
procedure RaiseMissingExpr;
|
|
||||||
begin
|
|
||||||
RaiseException('missing expression');
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
ExprResult: Boolean;
|
ExprResult: Boolean;
|
||||||
begin
|
begin
|
||||||
//DebugLn(['TLinkScanner.InternalIfDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
//DebugLn(['TLinkScanner.InternalIfDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
|
||||||
inc(SrcPos);
|
inc(SrcPos);
|
||||||
if SrcPos>SrcLen then
|
|
||||||
RaiseMissingExpr;
|
|
||||||
ExprResult:=Values.EvalBoolean(@Src[SrcPos],CommentInnerEndPos-SrcPos);
|
ExprResult:=Values.EvalBoolean(@Src[SrcPos],CommentInnerEndPos-SrcPos);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
//DebugLn(['TLinkScanner.InternalIfDirective ExprResult=',ExprResult]);
|
//DebugLn(['TLinkScanner.InternalIfDirective ExprResult=',ExprResult]);
|
||||||
if Values.ErrorPosition>=0 then begin
|
if Values.ErrorPosition>=0 then begin
|
||||||
inc(SrcPos,Values.ErrorPosition);
|
inc(SrcPos,Values.ErrorPosition);
|
||||||
RaiseException(Values.ErrorMsg)
|
RaiseException(Values.ErrorMsg)
|
||||||
end else if ExprResult then begin
|
end else if ExprResult then
|
||||||
// expression evaluates to true => stop skipping and parse block
|
FSkippingDirectives:=lssdNone
|
||||||
if FSkippingDirectives<>lssdNone then begin
|
else
|
||||||
{$IFDEF ShowUpdateCleanedSrc}
|
|
||||||
debugln(['TLinkScanner.InternalIfDirective skipped front, using ELIFC part']);
|
|
||||||
{$ENDIF}
|
|
||||||
EndSkipping;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
// expression evaluates to false => skip this block
|
|
||||||
SkipTillEndifElse(lssdTillElse);
|
SkipTillEndifElse(lssdTillElse);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLinkScanner.EndSkipping;
|
|
||||||
|
|
||||||
procedure ErrorNotSkipping;
|
|
||||||
begin
|
|
||||||
debugln(['ErrorNotSkipping internal error, please report this bug']);
|
|
||||||
CTDumpStack;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if FSkippingDirectives=lssdNone then begin
|
|
||||||
ErrorNotSkipping;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
FSkippingDirectives:=lssdNone;
|
|
||||||
UpdateCleanedSource(CommentStartPos-1);
|
|
||||||
AddSkipComment(false);
|
|
||||||
AddLink(CommentStartPos,Code);
|
|
||||||
FSkipIfLevel:=-1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TLinkScanner.CursorToCleanPos(ACursorPos: integer; ACode: pointer;
|
function TLinkScanner.CursorToCleanPos(ACursorPos: integer; ACode: pointer;
|
||||||
out ACleanPos: integer): integer;
|
out ACleanPos: integer): integer;
|
||||||
// 0=valid CleanPos
|
// 0=valid CleanPos
|
||||||
|
@ -106,6 +106,7 @@ type
|
|||||||
TBuildTreeFlag = (
|
TBuildTreeFlag = (
|
||||||
btSetIgnoreErrorPos,
|
btSetIgnoreErrorPos,
|
||||||
btKeepIgnoreErrorPos,
|
btKeepIgnoreErrorPos,
|
||||||
|
btLoadDirtySource,
|
||||||
btCursorPosOutAllowed
|
btCursorPosOutAllowed
|
||||||
);
|
);
|
||||||
TBuildTreeFlags = set of TBuildTreeFlag;
|
TBuildTreeFlags = set of TBuildTreeFlag;
|
||||||
@ -5133,6 +5134,10 @@ begin
|
|||||||
CaretType:=CaretToCleanPos(CursorPos, CleanCursorPos);
|
CaretType:=CaretToCleanPos(CursorPos, CleanCursorPos);
|
||||||
if (CaretType=0) or (CaretType=-1) then begin
|
if (CaretType=0) or (CaretType=-1) then begin
|
||||||
BuildSubTree(CleanCursorPos);
|
BuildSubTree(CleanCursorPos);
|
||||||
|
if (CaretType=-1) and (btLoadDirtySource in BuildTreeFlags) then begin
|
||||||
|
// cursor position lies in dead code (skipped code between IFDEF/ENDIF)
|
||||||
|
LoadDirtySource(CursorPos);
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
end
|
end
|
||||||
else if (CaretType=-2) or (not (btCursorPosOutAllowed in BuildTreeFlags)) then
|
else if (CaretType=-2) or (not (btCursorPosOutAllowed in BuildTreeFlags)) then
|
||||||
|
Loading…
Reference in New Issue
Block a user