codetools: fixed $ELIFC and $ELSEIF

git-svn-id: trunk@11222 -
This commit is contained in:
mattias 2007-05-29 23:49:11 +00:00
parent 11ec1c7a2e
commit 34c3ed4df7
4 changed files with 197 additions and 203 deletions

View File

@ -47,8 +47,8 @@ begin
// Example: find declaration of 'TObject' // Example: find declaration of 'TObject'
// load the file // load the file
Filename:=AppendPathDelim(GetCurrentDir) Filename:=AppendPathDelim(GetCurrentDir)+'scanexamples'+PathDelim
+'scanexamples'+PathDelim+'simpleunit1.pas'; +'simpleunit1.pas';
Code:=CodeToolBoss.LoadFile(Filename,false,false); Code:=CodeToolBoss.LoadFile(Filename,false,false);
if Code=nil then if Code=nil then
raise Exception.Create('loading failed '+Filename); raise Exception.Create('loading failed '+Filename);

View File

@ -51,18 +51,18 @@ begin
{ Linux } { Linux }
Options.FPCPath:='/usr/bin/ppc386'; Options.FPCPath:='/usr/bin/ppc386';
Options.FPCSrcDir:=ExpandFileName('~/freepascal/fpc'); Options.FPCSrcDir:=ExpandFileName('~/freepascal/fpc');
Options.FPCSrcDir:=ExpandFileName('/home/mattias/pascal/fpc_sources/22/fpc');
Options.LazarusSrcDir:=ExpandFileName('~/pascal/lazarus'); Options.LazarusSrcDir:=ExpandFileName('~/pascal/lazarus');
{ Windows { Windows
Options.FPCPath:='C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe'; //'/usr/bin/ppc386'; Options.FPCPath:='C:\lazarus\fpc\2.0.4\bin\i386-win32\ppc386.exe';
Options.FPCSrcDir:='C:\lazarus\fpc\2.0.4\source'; // ExpandFileName('~/freepascal/fpc'); Options.FPCSrcDir:='C:\lazarus\fpc\2.0.4\source';
Options.LazarusSrcDir:='C:\lazarus\'; // ExpandFileName('~/pascal/lazarus');} Options.LazarusSrcDir:='C:\lazarus\';}
// optional: ProjectDir and TestPascalFile exists only to easily test some // optional: ProjectDir and TestPascalFile exists only to easily test some
// things. // things.
Options.ProjectDir:=SetDirSeparators(GetCurrentDir+'/scanexamples/'); Options.ProjectDir:=SetDirSeparators(GetCurrentDir+'/scanexamples/');
//Options.TestPascalFile:=Options.ProjectDir+'simpleunit1.pas'; Options.TestPascalFile:=Options.ProjectDir+'simpleunit1.pas';
Options.TestPascalFile:=Options.ProjectDir+'modemacpas.pas';
// init the codetools // init the codetools
if not Options.UnitLinkListValid then if not Options.UnitLinkListValid then

View File

@ -7,19 +7,29 @@ interface
uses uses
Classes, SysUtils; Classes, SysUtils;
{$ifc defined FPC_BIG_ENDIAN} {$DEFINE test3}
aaa1 {$DEFINE bogus4}
{$setc TARGET_RT_BIG_ENDIAN := TRUE}
{$setc TARGET_RT_LITTLE_ENDIAN := FALSE} {$ifc defined test1}
{$elifc defined FPC_LITTLE_ENDIAN} type aaa1 = integer;
aaa2 {$elifc defined test2}
{$setc TARGET_RT_BIG_ENDIAN := FALSE} type aaa2 = integer;
{$setc TARGET_RT_LITTLE_ENDIAN := TRUE} {$elifc defined test3}
type aaa3 = integer;
{$ifc defined bogus1}
type bogus1 = integer;
{$elifc defined bogus2}
type bogus2 = integer;
{$elifc defined bogus3}
type bogus3 = integer;
{$elsec}
type bogusELSE = integer;
{$error Neither bogus1 nor bogus2 nor bogus3 are defined.}
{$endc}
{$elsec} {$elsec}
aaa3 type aaaELSE = integer;
{$error Neither FPC_BIG_ENDIAN nor FPC_LITTLE_ENDIAN are defined.} {$error Neither test1 nor test2 nor test3 are defined.}
{$endc} {$endc}
aaa
implementation implementation

View File

@ -108,6 +108,12 @@ type
TCompilerMode = (cmFPC, cmDELPHI, cmGPC, cmTP, cmOBJFPC, cmMacPas); TCompilerMode = (cmFPC, cmDELPHI, cmGPC, cmTP, cmOBJFPC, cmMacPas);
TPascalCompiler = (pcFPC, pcDelphi); TPascalCompiler = (pcFPC, pcDelphi);
TLSSkippingDirective = (
lssdNone,
lssdTillElse,
lssdTillEndIf
);
{ TMissingIncludeFile is a missing include file together with all { TMissingIncludeFile is a missing include file together with all
params involved in the search } params involved in the search }
TMissingIncludeFile = class TMissingIncludeFile = class
@ -233,18 +239,19 @@ type
// directives // directives
FDirectiveName: shortstring; FDirectiveName: shortstring;
FDirectiveFuncList: TKeyWordFunctionList; FDirectiveFuncList: TKeyWordFunctionList;
FDefaultDirectiveFuncList: TKeyWordFunctionList;
FSkipDirectiveFuncList: TKeyWordFunctionList; FSkipDirectiveFuncList: TKeyWordFunctionList;
FMacrosOn: boolean; FMacrosOn: boolean;
FMissingIncludeFiles: TMissingIncludeFiles; FMissingIncludeFiles: TMissingIncludeFiles;
FIncludeStack: TFPList; // list of TSourceLink FIncludeStack: TFPList; // list of TSourceLink
FSkippingTillEndif: boolean; FSkippingDirectives: TLSSkippingDirective;
FSkipIfLevel: integer; FSkipIfLevel: integer;
FCompilerMode: TCompilerMode; FCompilerMode: TCompilerMode;
FPascalCompiler: TPascalCompiler; FPascalCompiler: TPascalCompiler;
procedure SetCompilerMode(const AValue: TCompilerMode); procedure SetCompilerMode(const AValue: TCompilerMode);
procedure SkipTillEndifElse; procedure SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
procedure SkipTillEndCifElse;
function SkipIfDirective: boolean; function SkipIfDirective: boolean;
function InternalIfDirective: boolean;
function IfdefDirective: boolean; function IfdefDirective: boolean;
function IfCDirective: boolean; function IfCDirective: boolean;
function IfndefDirective: boolean; function IfndefDirective: boolean;
@ -252,11 +259,11 @@ type
function IfOptDirective: boolean; function IfOptDirective: boolean;
function EndifDirective: boolean; function EndifDirective: boolean;
function EndCDirective: boolean; function EndCDirective: boolean;
function IfEndDirective: boolean;
function ElseDirective: boolean; function ElseDirective: boolean;
function ElseCDirective: boolean; function ElseCDirective: boolean;
function ElseIfDirective: boolean; function ElseIfDirective: boolean;
function ElIfCDirective: boolean; function ElIfCDirective: boolean;
function IfEndDirective: boolean;
function DefineDirective: boolean; function DefineDirective: boolean;
function UndefDirective: boolean; function UndefDirective: boolean;
function SetCDirective: boolean; function SetCDirective: boolean;
@ -659,7 +666,7 @@ begin
Values.Free; Values.Free;
FInitValues.Free; FInitValues.Free;
ReAllocMem(FLinks,0); ReAllocMem(FLinks,0);
FDirectiveFuncList.Free; FDefaultDirectiveFuncList.Free;
FSkipDirectiveFuncList.Free; FSkipDirectiveFuncList.Free;
inherited Destroy; inherited Destroy;
end; end;
@ -1086,7 +1093,8 @@ begin
CompilerMode:=cmFPC; CompilerMode:=cmFPC;
PascalCompiler:=pcFPC; PascalCompiler:=pcFPC;
IfLevel:=0; IfLevel:=0;
FSkippingTillEndif:=false; FSkippingDirectives:=lssdNone;
FDirectiveFuncList:=FDefaultDirectiveFuncList;
//DebugLn('TLinkScanner.Scan D --------'); //DebugLn('TLinkScanner.Scan D --------');
// initialize Defines // initialize Defines
@ -1149,11 +1157,15 @@ begin
LastTokenType:=TokenType; LastTokenType:=TokenType;
until false; until false;
finally finally
if not FSkippingTillEndif then begin if FSkippingDirectives=lssdNone then begin
{$IFDEF ShowUpdateCleanedSrc} {$IFDEF ShowUpdateCleanedSrc}
DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1)); DebugLn('TLinkScanner.Scan UpdatePos=',DbgS(SrcPos-1));
{$ENDIF} {$ENDIF}
UpdateCleanedSource(SrcPos-1); UpdateCleanedSource(SrcPos-1);
end else begin
{$IFDEF ShowUpdateCleanedSrc}
DebugLn(['TLinkScanner.Scan missing $ENDIF']);
{$ENDIF}
end; end;
end; end;
IncreaseChangeStep; IncreaseChangeStep;
@ -2003,8 +2015,8 @@ end;
procedure TLinkScanner.BuildDirectiveFuncList; procedure TLinkScanner.BuildDirectiveFuncList;
var c: char; var c: char;
begin begin
FDirectiveFuncList:=TKeyWordFunctionList.Create; FDefaultDirectiveFuncList:=TKeyWordFunctionList.Create;
with FDirectiveFuncList do begin with FDefaultDirectiveFuncList do begin
for c:='A' to 'Z' do begin for c:='A' to 'Z' do begin
if CompilerSwitchesNames[c]<>'' then begin if CompilerSwitchesNames[c]<>'' then begin
Add(c,{$ifdef FPC}@{$endif}ShortSwitchDirective); Add(c,{$ifdef FPC}@{$endif}ShortSwitchDirective);
@ -2155,26 +2167,16 @@ begin
SkipSpace; SkipSpace;
VariableName:=ReadUpperIdentifier; VariableName:=ReadUpperIdentifier;
if (VariableName<>'') and (not Values.IsDefined(VariableName)) then if (VariableName<>'') and (not Values.IsDefined(VariableName)) then
SkipTillEndifElse; SkipTillEndifElse(lssdTillElse);
Result:=true; Result:=true;
end; end;
function TLinkScanner.IfCDirective: boolean; function TLinkScanner.IfCDirective: boolean;
// {$ifc expression} or indirectly called by {$elifc expression} // {$ifc expression} or indirectly called by {$elifc expression}
var Expr, ResultStr: string;
begin begin
//DebugLn(['TLinkScanner.IfCDirective FSkippingTillEndif=',FSkippingTillEndif]); //DebugLn(['TLinkScanner.IfCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
inc(IfLevel); inc(IfLevel);
inc(SrcPos); Result:=InternalIfDirective;
Expr:=UpperCaseStr(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
ResultStr:=Values.Eval(Expr);
Result:=true;
//DebugLn(['TLinkScanner.IfCDirective ResultStr=',ResultStr]);
if Values.ErrorPosition>=0 then begin
inc(SrcPos,Values.ErrorPosition);
RaiseException(ctsErrorInDirectiveExpression)
end else if ResultStr='0' then
SkipTillEndCifElse
end; end;
procedure TLinkScanner.SkipSpace; procedure TLinkScanner.SkipSpace;
@ -2221,7 +2223,7 @@ begin
SkipSpace; SkipSpace;
VariableName:=ReadUpperIdentifier; VariableName:=ReadUpperIdentifier;
if (VariableName<>'') and (Values.IsDefined(VariableName)) then if (VariableName<>'') and (Values.IsDefined(VariableName)) then
SkipTillEndifElse; SkipTillEndifElse(lssdTillElse);
Result:=true; Result:=true;
end; end;
@ -2234,11 +2236,11 @@ function TLinkScanner.EndifDirective: boolean;
end; end;
begin begin
if IfLevel<=0 then
RaiseAWithoutB;
dec(IfLevel); dec(IfLevel);
if IfLevel<0 then if IfLevel<FSkipIfLevel then begin
RaiseAWithoutB FSkippingDirectives:=lssdNone;
else if IfLevel<FSkipIfLevel then begin
FSkippingTillEndif:=false;
end; end;
Result:=true; Result:=true;
end; end;
@ -2252,12 +2254,30 @@ function TLinkScanner.EndCDirective: boolean;
end; end;
begin begin
//DebugLn(['TLinkScanner.EndCDirective FSkippingTillEndif=',FSkippingTillEndif]); //DebugLn(['TLinkScanner.EndCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
if IfLevel<=0 then
RaiseAWithoutB;
dec(IfLevel); dec(IfLevel);
if IfLevel<0 then if IfLevel<FSkipIfLevel then begin
RaiseAWithoutB FSkippingDirectives:=lssdNone;
else if IfLevel<FSkipIfLevel then begin end;
FSkippingTillEndif:=false; Result:=true;
end;
function TLinkScanner.IfEndDirective: boolean;
// {$IfEnd comment}
procedure RaiseAWithoutB;
begin
RaiseExceptionFmt(ctsAwithoutB,['$IfEnd','$ElseIf'])
end;
begin
if IfLevel<=0 then
RaiseAWithoutB;
dec(IfLevel);
if IfLevel<FSkipIfLevel then begin
FSkippingDirectives:=lssdNone;
end; end;
Result:=true; Result:=true;
end; end;
@ -2273,10 +2293,15 @@ function TLinkScanner.ElseDirective: boolean;
begin begin
if IfLevel=0 then if IfLevel=0 then
RaiseAWithoutB; RaiseAWithoutB;
if not FSkippingTillEndif then case FSkippingDirectives of
SkipTillEndifElse lssdNone:
else if IfLevel=FSkipIfLevel then SkipTillEndifElse(lssdTillEndIf);
FSkippingTillEndif:=false; lssdTillElse:
if IfLevel=FSkipIfLevel then
FSkippingDirectives:=lssdNone;
// else: continue skip;
lssdTillEndIf: ; // continue skip
end;
Result:=true; Result:=true;
end; end;
@ -2289,13 +2314,18 @@ function TLinkScanner.ElseCDirective: boolean;
end; end;
begin begin
//DebugLn(['TLinkScanner.ElseCDirective FSkippingTillEndif=',FSkippingTillEndif]); //DebugLn(['TLinkScanner.ElseCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
if IfLevel=0 then if IfLevel=0 then
RaiseAWithoutB; RaiseAWithoutB;
if not FSkippingTillEndif then case FSkippingDirectives of
SkipTillEndCifElse lssdNone:
else if IfLevel=FSkipIfLevel then SkipTillEndifElse(lssdTillEndIf);
FSkippingTillEndif:=false; lssdTillElse:
if IfLevel=FSkipIfLevel then
FSkippingDirectives:=lssdNone;
// else: continue skip;
lssdTillEndIf: ; // continue skip
end;
Result:=true; Result:=true;
end; end;
@ -2310,11 +2340,13 @@ function TLinkScanner.ElseIfDirective: boolean;
begin begin
if IfLevel=0 then if IfLevel=0 then
RaiseAWithoutB; RaiseAWithoutB;
if not FSkippingTillEndif then begin if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
SkipTillEndifElse; Result:=InternalIfDirective;
end else begin
if (FSkippingDirectives=lssdNone) then
SkipTillEndifElse(lssdTillEndIf);
Result:=true; Result:=true;
end else if IfLevel=FSkipIfLevel then end;
Result:=IfDirective;
end; end;
function TLinkScanner.ElIfCDirective: boolean; function TLinkScanner.ElIfCDirective: boolean;
@ -2326,32 +2358,16 @@ function TLinkScanner.ElIfCDirective: boolean;
end; end;
begin begin
//DebugLn(['TLinkScanner.ElIfCDirective FSkippingTillEndif=',FSkippingTillEndif]); //DebugLn(['TLinkScanner.ElIfCDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
if IfLevel=0 then if IfLevel=0 then
RaiseAWithoutB; RaiseAWithoutB;
if not FSkippingTillEndif then begin if (FSkippingDirectives=lssdTillElse) and (IfLevel=FSkipIfLevel) then begin
SkipTillEndCifElse; Result:=InternalIfDirective;
end else begin
if (FSkippingDirectives=lssdNone) then
SkipTillEndifElse(lssdTillEndIf);
Result:=true; Result:=true;
end else if IfLevel=FSkipIfLevel then
Result:=IfCDirective;
end;
function TLinkScanner.IfEndDirective: boolean;
// {$IfEnd comment}
procedure RaiseAWithoutB;
begin
RaiseExceptionFmt(ctsAwithoutB,['$IfEnd','$ElseIf'])
end; end;
begin
dec(IfLevel);
if IfLevel<0 then
RaiseAWithoutB
else if IfLevel<FSkipIfLevel then begin
FSkippingTillEndif:=false;
end;
Result:=true;
end; end;
function TLinkScanner.DefineDirective: boolean; function TLinkScanner.DefineDirective: boolean;
@ -2650,18 +2666,9 @@ end;
function TLinkScanner.IfDirective: boolean; function TLinkScanner.IfDirective: boolean;
// {$if expression} or indirectly called by {$elseif expression} // {$if expression} or indirectly called by {$elseif expression}
var Expr, ResultStr: string;
begin begin
inc(IfLevel); inc(IfLevel);
inc(SrcPos); Result:=InternalIfDirective;
Expr:=UpperCaseStr(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
ResultStr:=Values.Eval(Expr);
Result:=true;
if Values.ErrorPosition>=0 then begin
inc(SrcPos,Values.ErrorPosition);
RaiseException(ctsErrorInDirectiveExpression)
end else if ResultStr='0' then
SkipTillEndifElse
end; end;
function TLinkScanner.IfOptDirective: boolean; function TLinkScanner.IfOptDirective: boolean;
@ -2669,6 +2676,7 @@ function TLinkScanner.IfOptDirective: boolean;
var Option, c: char; var Option, c: char;
begin begin
inc(IfLevel); inc(IfLevel);
Result:=true;
inc(SrcPos); inc(SrcPos);
Option:=UpChars[Src[SrcPos]]; Option:=UpChars[Src[SrcPos]];
if (IsWordChar[Option]) and (CompilerSwitchesNames[Option]<>'') if (IsWordChar[Option]) and (CompilerSwitchesNames[Option]<>'')
@ -2678,11 +2686,13 @@ begin
c:=Src[SrcPos]; c:=Src[SrcPos];
if c in ['+','-'] then begin if c in ['+','-'] then begin
if (c='-')<>(Values.Variables[CompilerSwitchesNames[Option]]='0') then if (c='-')<>(Values.Variables[CompilerSwitchesNames[Option]]='0') then
SkipTillEndifElse; begin
SkipTillEndifElse(lssdTillElse);
exit;
end;
end; end;
end; end;
end; end;
Result:=true;
end; end;
procedure TLinkScanner.SetIgnoreMissingIncludeFiles(const Value: boolean); procedure TLinkScanner.SetIgnoreMissingIncludeFiles(const Value: boolean);
@ -2755,7 +2765,7 @@ end;
function TLinkScanner.ReturnFromIncludeFile: boolean; function TLinkScanner.ReturnFromIncludeFile: boolean;
var OldPos: TSourceLink; var OldPos: TSourceLink;
begin begin
if not FSkippingTillEndif 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}
@ -2804,79 +2814,35 @@ begin
Result:=true; Result:=true;
end; end;
procedure TLinkScanner.SkipTillEndifElse; procedure TLinkScanner.SkipTillEndifElse(SkippingUntil: TLSSkippingDirective);
var OldDirectiveFuncList: TKeyWordFunctionList;
c1: Char;
begin
SrcPos:=CommentEndPos;
{$IFDEF ShowUpdateCleanedSrc}
DebugLn('TLinkScanner.SkipTillEndifElse A UpdatePos=',DbgS(SrcPos-1));
{$ENDIF}
UpdateCleanedSource(SrcPos-1);
OldDirectiveFuncList:=FDirectiveFuncList;
FDirectiveFuncList:=FSkipDirectiveFuncList;
try
// parse till $else, $elseif or $endif without adding the code to FCleanedSrc
FSkippingTillEndif:=true;
FSkipIfLevel:=IfLevel;
if (SrcPos<=SrcLen) then begin
while true do begin
c1:=Src[SrcPos];
if IsCommentStartChar[c1] then begin
case c1 of
'{': begin
SkipComment;
if not FSkippingTillEndif then break;
end;
'/': if (Src[SrcPos+1]='/') then begin
SkipDelphiComment;
if not FSkippingTillEndif then break;
end else
inc(SrcPos);
'(': if (Src[SrcPos+1]='*') then begin
SkipOldTPComment;
if not FSkippingTillEndif then break;
end else
inc(SrcPos);
end;
end else if c1='''' then begin
// skip string constant
inc(SrcPos);
while (SrcPos<=SrcLen) and (Src[SrcPos]<>'''') do inc(SrcPos);
inc(SrcPos);
end else begin
inc(SrcPos);
if (SrcPos>SrcLen) and not ReturnFromIncludeFile then
break;
end;
end;
end;
LastCleanSrcPos:=CommentStartPos-1;
AddLink(CleanedLen+1,CommentStartPos,Code);
{$IFDEF ShowUpdateCleanedSrc}
DebugLn('TLinkScanner.SkipTillEndifElse B Continuing after: ',
'"',StringToPascalConst(copy(Src,LastCleanSrcPos+1,20)),'"');
{$ENDIF}
finally
FDirectiveFuncList:=OldDirectiveFuncList;
FSkippingTillEndif:=false;
end;
end;
procedure TLinkScanner.SkipTillEndCifElse; procedure RaiseAlreadySkipping;
var OldDirectiveFuncList: TKeyWordFunctionList; begin
raise Exception.Create('TLinkScanner.SkipTillEndifElse inconsistency: already skipping '
+' Old='+dbgs(ord(FSkippingDirectives))
+' New='+dbgs(ord(SkippingUntil)));
end;
var
OldDirectiveFuncList: TKeyWordFunctionList;
c1: Char; c1: Char;
begin begin
if FSkippingDirectives<>lssdNone then begin
FSkippingDirectives:=SkippingUntil;
exit;
end;
FSkippingDirectives:=SkippingUntil;
SrcPos:=CommentEndPos; SrcPos:=CommentEndPos;
{$IFDEF ShowUpdateCleanedSrc} {$IFDEF ShowUpdateCleanedSrc}
DebugLn('TLinkScanner.SkipTillEndCifElse A UpdatePos=',DbgS(SrcPos-1)); 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);
OldDirectiveFuncList:=FDirectiveFuncList; OldDirectiveFuncList:=FDirectiveFuncList;
FDirectiveFuncList:=FSkipDirectiveFuncList; FDirectiveFuncList:=FSkipDirectiveFuncList;
try
// parse till $elsec, $elifc or $endc without adding the code to FCleanedSrc // parse till $else, $elseif or $endif without adding the code to FCleanedSrc
FSkippingTillEndif:=true;
FSkipIfLevel:=IfLevel; FSkipIfLevel:=IfLevel;
if (SrcPos<=SrcLen) then begin if (SrcPos<=SrcLen) then begin
while true do begin while true do begin
@ -2885,16 +2851,16 @@ begin
case c1 of case c1 of
'{': begin '{': begin
SkipComment; SkipComment;
if not FSkippingTillEndif then break; if FSkippingDirectives=lssdNone then break;
end; end;
'/': if (Src[SrcPos+1]='/') then begin '/': if (Src[SrcPos+1]='/') then begin
SkipDelphiComment; SkipDelphiComment;
if not FSkippingTillEndif then break; if FSkippingDirectives=lssdNone then break;
end else end else
inc(SrcPos); inc(SrcPos);
'(': if (Src[SrcPos+1]='*') then begin '(': if (Src[SrcPos+1]='*') then begin
SkipOldTPComment; SkipOldTPComment;
if not FSkippingTillEndif then break; if FSkippingDirectives=lssdNone then break;
end else end else
inc(SrcPos); inc(SrcPos);
end; end;
@ -2914,12 +2880,11 @@ begin
AddLink(CleanedLen+1,CommentStartPos,Code); AddLink(CleanedLen+1,CommentStartPos,Code);
{$IFDEF ShowUpdateCleanedSrc} {$IFDEF ShowUpdateCleanedSrc}
DebugLn('TLinkScanner.SkipTillEndifElse B Continuing after: ', DebugLn('TLinkScanner.SkipTillEndifElse B Continuing after: ',
'"',StringToPascalConst(copy(Src,LastCleanSrcPos+1,20)),'"'); ' Src=',DbgStr(copy(Src,CommentStartPos-15,15))+'|'+DbgStr(copy(Src,CommentStartPos,15)));
{$ENDIF} {$ENDIF}
finally
FDirectiveFuncList:=OldDirectiveFuncList; FDirectiveFuncList:=OldDirectiveFuncList;
FSkippingTillEndif:=false; FSkippingDirectives:=lssdNone;
end;
end; end;
procedure TLinkScanner.SetCompilerMode(const AValue: TCompilerMode); procedure TLinkScanner.SetCompilerMode(const AValue: TCompilerMode);
@ -2936,6 +2901,25 @@ begin
Result:=true; Result:=true;
end; end;
function TLinkScanner.InternalIfDirective: boolean;
// {$if expression} or {$ifc expression} or indirectly called by {$elifc expression}
var Expr, ResultStr: string;
begin
//DebugLn(['TLinkScanner.InternalIfDirective FSkippingDirectives=',ord(FSkippingDirectives),' IfLevel=',IfLevel]);
inc(SrcPos);
Expr:=UpperCaseStr(copy(Src,SrcPos,CommentInnerEndPos-SrcPos));
ResultStr:=Values.Eval(Expr);
Result:=true;
//DebugLn(['TLinkScanner.InternalIfDirective ResultStr=',ResultStr]);
if Values.ErrorPosition>=0 then begin
inc(SrcPos,Values.ErrorPosition);
RaiseException(ctsErrorInDirectiveExpression)
end else if ResultStr='0' then
SkipTillEndifElse(lssdTillElse)
else
FSkippingDirectives:=lssdNone;
end;
function TLinkScanner.CursorToCleanPos(ACursorPos: integer; ACode: pointer; function TLinkScanner.CursorToCleanPos(ACursorPos: integer; ACode: pointer;
var ACleanPos: integer): integer; var ACleanPos: integer): integer;
// 0=valid CleanPos // 0=valid CleanPos