mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-18 14:09:26 +02:00
codetools: implemented start of extern c
git-svn-id: trunk@14283 -
This commit is contained in:
parent
1825f74f2a
commit
9519c2624f
@ -49,6 +49,7 @@ const
|
||||
|
||||
ccnRoot = 1+ccnBase;
|
||||
ccnDirective = 2+ccnBase;// e.g. "#define a" ,can be multiple lines, without line end
|
||||
ccnExtern = 3+ccnBase;// e.g. extern "C" {}
|
||||
|
||||
type
|
||||
TCCodeParserTool = class;
|
||||
@ -70,6 +71,7 @@ type
|
||||
|
||||
function OtherToken: boolean;
|
||||
function DirectiveToken: boolean;
|
||||
function ExternToken: boolean;
|
||||
procedure InitKeyWordList;
|
||||
|
||||
procedure InitParser;
|
||||
@ -78,6 +80,7 @@ type
|
||||
procedure CloseNodes;
|
||||
|
||||
procedure RaiseException(const AMessage: string);
|
||||
procedure RaiseExpectedButAtomFound(const AToken: string);
|
||||
public
|
||||
Code: TCodeBuffer;
|
||||
Src: string;
|
||||
@ -101,6 +104,7 @@ type
|
||||
function AtomIs(const s: shortstring): boolean;
|
||||
function UpAtomIs(const s: shortstring): boolean;
|
||||
function AtomIsIdentifier: boolean;
|
||||
function AtomIsStringConstant: boolean;
|
||||
function GetAtom: string;
|
||||
|
||||
procedure Replace(FromPos, ToPos: integer; const NewSrc: string);
|
||||
@ -152,12 +156,25 @@ begin
|
||||
EndChildNode;
|
||||
end;
|
||||
|
||||
function TCCodeParserTool.ExternToken: boolean;
|
||||
begin
|
||||
Result:=true;
|
||||
CreateChildNode(ccnExtern);
|
||||
ReadNextAtom;
|
||||
if not AtomIsStringConstant then
|
||||
RaiseExpectedButAtomFound('string constant');
|
||||
ReadNextAtom;
|
||||
if not AtomIs('{') then
|
||||
RaiseExpectedButAtomFound('{');
|
||||
end;
|
||||
|
||||
procedure TCCodeParserTool.InitKeyWordList;
|
||||
begin
|
||||
if FDefaultTokenList=nil then begin
|
||||
FDefaultTokenList:=TKeyWordFunctionList.Create;
|
||||
with FDefaultTokenList do begin
|
||||
Add('#',{$ifdef FPC}@{$endif}DirectiveToken);
|
||||
Add('extern',{$ifdef FPC}@{$endif}ExternToken);
|
||||
DefaultKeyWordFunction:={$ifdef FPC}@{$endif}OtherToken;
|
||||
end;
|
||||
end;
|
||||
@ -216,6 +233,11 @@ begin
|
||||
raise ECCodeParserException.Create(Self,AMessage);
|
||||
end;
|
||||
|
||||
procedure TCCodeParserTool.RaiseExpectedButAtomFound(const AToken: string);
|
||||
begin
|
||||
RaiseException(AToken+' expected, but '+GetAtom+' found');
|
||||
end;
|
||||
|
||||
constructor TCCodeParserTool.Create;
|
||||
begin
|
||||
Tree:=TCodeTree.Create;
|
||||
@ -318,6 +340,11 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TCCodeParserTool.AtomIsStringConstant: boolean;
|
||||
begin
|
||||
Result:=(AtomStart<SrcLen) and (Src[AtomStart]='"');
|
||||
end;
|
||||
|
||||
function TCCodeParserTool.GetAtom: string;
|
||||
begin
|
||||
Result:=copy(Src,AtomStart,SrcPos-AtomStart);
|
||||
|
@ -1900,7 +1900,8 @@ var
|
||||
NeededType:=ctnNone;
|
||||
|
||||
if BracketStartPos>0 then begin
|
||||
if WordIsKeyWord.DoIt(@Src[ReferingPos]) then exit;
|
||||
if WordIsKeyWord.DoItCaseInsensitive(@Src[ReferingPos]) then
|
||||
exit;
|
||||
// this is a type cast
|
||||
NeededType:=ctnConstDefinition;
|
||||
//GetReferingNode;
|
||||
|
@ -1930,7 +1930,8 @@ var
|
||||
repeat
|
||||
ReadNextAtom;
|
||||
if (AtomStart<=SrcLen)
|
||||
and IsKeyWordProcedureSpecifier.DoIt(@Src[AtomStart]) then begin
|
||||
and IsKeyWordProcedureSpecifier.DoItCaseInsensitive(@Src[AtomStart])
|
||||
then begin
|
||||
if UpAtomIs('EXTERNAL') then
|
||||
IsExternal:=true;
|
||||
if UpAtomIs('FORWARD') then
|
||||
|
@ -27,6 +27,8 @@ unit KeywordFuncLists;
|
||||
|
||||
{$ifdef FPC}{$mode objfpc}{$endif}{$H+}
|
||||
|
||||
{$R-} // turn range checking off for speed
|
||||
|
||||
interface
|
||||
|
||||
{ $DEFINE MEM_CHECK}
|
||||
@ -49,6 +51,8 @@ type
|
||||
end;
|
||||
PKeyWordFunctionListItem = ^TKeyWordFunctionListItem;
|
||||
|
||||
{ TKeyWordFunctionList }
|
||||
|
||||
TKeyWordFunctionList = class
|
||||
private
|
||||
FItems: PKeyWordFunctionListItem;
|
||||
@ -65,12 +69,14 @@ type
|
||||
public
|
||||
DefaultKeyWordFunction: TKeyWordFunction;
|
||||
function DoIt(const AKeyWord: shortstring): boolean;
|
||||
function DoIt(const ASource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
function DoIt(Identifier: PChar): boolean;
|
||||
function DoItUppercase(const AnUpperSource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
function DoItCaseInsensitive(const AKeyWord: shortstring): boolean;
|
||||
function DoItCaseInsensitive(const ASource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
function DoIt(const ASource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
function DoItUppercase(const AnUpperSource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
function DoItCaseInsensitive(Identifier: PChar): boolean;
|
||||
function DoDataFunction(Start: PChar; Len: integer; Data: pointer): boolean;
|
||||
procedure Clear;
|
||||
procedure Add(const AKeyWord: shortstring;
|
||||
@ -145,9 +151,8 @@ function IsUpperCaseStr(const s: string): boolean;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
var
|
||||
CharToHash: array[char] of integer;
|
||||
CharToIHash: array[char] of integer;
|
||||
UpWords: array[word] of word;
|
||||
|
||||
function UpperCaseStr(const s: string): string;
|
||||
@ -181,11 +186,7 @@ end;
|
||||
constructor TKeyWordFunctionList.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FItems:=nil;
|
||||
FCount:=0;
|
||||
FCapacity:=0;
|
||||
FSorted:=true;
|
||||
FBucketStart:=nil;
|
||||
FMaxHashIndex:=-1;
|
||||
DefaultKeyWordFunction:={$ifdef FPC}@{$endif}AllwaysFalse;
|
||||
end;
|
||||
@ -220,7 +221,7 @@ begin
|
||||
if KeyWordLen>20 then KeyWordLen:=20;
|
||||
Result:=0;
|
||||
for i:=1 to KeyWordLen do
|
||||
inc(Result,CharToHash[AKeyWord[i]]);
|
||||
inc(Result,CharToIHash[AKeyWord[i]]);
|
||||
if Result>FMaxHashIndex then Result:=-1;
|
||||
end;
|
||||
|
||||
@ -232,7 +233,7 @@ begin
|
||||
AEnd:=AStart+ALen-1;
|
||||
Result:=0;
|
||||
for i:=AStart to AEnd do
|
||||
inc(Result,CharToHash[ASource[i]]);
|
||||
inc(Result,CharToIHash[ASource[i]]);
|
||||
if Result>FMaxHashIndex then Result:=-1;
|
||||
end;
|
||||
|
||||
@ -242,7 +243,7 @@ begin
|
||||
Result:=0;
|
||||
i:=20;
|
||||
while (i>0) and IsIdentChar[Identifier[0]] do begin
|
||||
inc(Result,CharToHash[Identifier[0]]);
|
||||
inc(Result,CharToIHash[Identifier[0]]);
|
||||
dec(i);
|
||||
inc(Identifier);
|
||||
end;
|
||||
@ -255,7 +256,7 @@ begin
|
||||
Result:=0;
|
||||
if Len>20 then Len:=20;
|
||||
while (Len>0) do begin
|
||||
inc(Result,CharToHash[Start^]);
|
||||
inc(Result,CharToIHash[Start^]);
|
||||
dec(Len);
|
||||
inc(Start);
|
||||
end;
|
||||
@ -289,7 +290,7 @@ begin
|
||||
Result:=DefaultKeyWordFunction();
|
||||
end;
|
||||
|
||||
function TKeyWordFunctionList.DoIt(const ASource: string;
|
||||
function TKeyWordFunctionList.DoItCaseInsensitive(const ASource: string;
|
||||
KeyWordStart, KeyWordLen: integer): boolean;
|
||||
// ! does not test if length(ASource) >= KeyWordStart+KeyWordLen -1
|
||||
var i, KeyPos, WordPos: integer;
|
||||
@ -328,7 +329,47 @@ begin
|
||||
Result:=DefaultKeyWordFunction();
|
||||
end;
|
||||
|
||||
function TKeyWordFunctionList.DoIt(Identifier: PChar): boolean;
|
||||
function TKeyWordFunctionList.DoIt(const ASource: string; KeyWordStart,
|
||||
KeyWordLen: integer): boolean;
|
||||
// ! does not test if length(ASource) >= KeyWordStart+KeyWordLen -1
|
||||
var
|
||||
i, KeyPos, WordPos: integer;
|
||||
KeyWordFuncItem: PKeyWordFunctionListItem;
|
||||
begin
|
||||
if not FSorted then Sort;
|
||||
i:=KeyWordToHashIndex(ASource,KeyWordStart,KeyWordLen);
|
||||
if i>=0 then begin
|
||||
i:=FBucketStart[i];
|
||||
if i>=0 then begin
|
||||
dec(KeyWordStart);
|
||||
repeat
|
||||
KeyWordFuncItem:=@FItems[i];
|
||||
if length(KeyWordFuncItem^.KeyWord)=KeyWordLen then begin
|
||||
KeyPos:=KeyWordLen;
|
||||
WordPos:=KeyWordStart+KeyWordLen;
|
||||
while (KeyPos>=1)
|
||||
and (KeyWordFuncItem^.KeyWord[KeyPos]=ASource[WordPos]) do
|
||||
begin
|
||||
dec(KeyPos);
|
||||
dec(WordPos);
|
||||
end;
|
||||
if KeyPos<1 then begin
|
||||
if Assigned(KeyWordFuncItem^.DoIt) then
|
||||
Result:=KeyWordFuncItem^.DoIt()
|
||||
else
|
||||
Result:=DefaultKeyWordFunction();
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
if (KeyWordFuncItem^.IsLast) then break;
|
||||
inc(i);
|
||||
until false;
|
||||
end;
|
||||
end;
|
||||
Result:=DefaultKeyWordFunction();
|
||||
end;
|
||||
|
||||
function TKeyWordFunctionList.DoItCaseInsensitive(Identifier: PChar): boolean;
|
||||
// checks
|
||||
var i, KeyPos, KeyWordLen: integer;
|
||||
KeyWordFuncItem: PKeyWordFunctionListItem;
|
||||
@ -638,11 +679,11 @@ var
|
||||
c: char;
|
||||
w: word;
|
||||
begin
|
||||
for c:=Low(UpChars) to High(UpChars) do begin
|
||||
for c:=Low(char) to High(char) do begin
|
||||
case c of
|
||||
'a'..'z':CharToHash[c]:=ord(c)-ord('a')+1;
|
||||
'A'..'Z':CharToHash[c]:=ord(c)-ord('A')+1;
|
||||
else CharToHash[c]:=0;
|
||||
'a'..'z':CharToIHash[c]:=ord(c)-ord('a')+1;
|
||||
'A'..'Z':CharToIHash[c]:=ord(c)-ord('A')+1;
|
||||
else CharToIHash[c]:=ord(c);
|
||||
end;
|
||||
UpChars[c]:=upcase(c);
|
||||
IsLineEndChar[c]:=c in [#10,#13];
|
||||
|
@ -884,7 +884,7 @@ begin
|
||||
DirLen:=SrcPos-DirStart;
|
||||
if DirLen>255 then DirLen:=255;
|
||||
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||
FDirectiveFuncList.DoIt(Src,DirStart,DirLen);
|
||||
FDirectiveFuncList.DoItCaseInsensitive(Src,DirStart,DirLen);
|
||||
SrcPos:=CommentEndPos;
|
||||
end;
|
||||
|
||||
@ -958,7 +958,7 @@ begin
|
||||
while (SrcPos<=SrcLen)
|
||||
and (IsIdentChar[Src[SrcPos]]) do
|
||||
inc(SrcPos);
|
||||
KeywordFuncList.DoIt(Src,TokenStart,SrcPos-TokenStart);
|
||||
KeywordFuncList.DoItCaseInsensitive(Src,TokenStart,SrcPos-TokenStart);
|
||||
end;
|
||||
'''','#':
|
||||
begin
|
||||
@ -2177,7 +2177,7 @@ begin
|
||||
DirLen:=SrcPos-DirStart;
|
||||
if DirLen>255 then DirLen:=255;
|
||||
FDirectiveName:=UpperCaseStr(copy(Src,DirStart,DirLen));
|
||||
Result:=FDirectiveFuncList.DoIt(Src,DirStart,DirLen);
|
||||
Result:=FDirectiveFuncList.DoItCaseInsensitive(Src,DirStart,DirLen);
|
||||
end else
|
||||
Result:=true;
|
||||
end;
|
||||
|
@ -286,18 +286,15 @@ begin
|
||||
'"': // string constant
|
||||
begin
|
||||
while (Position<=Len) do begin
|
||||
case (Source[Position]) of
|
||||
'"':
|
||||
begin
|
||||
if (Source[Position]='"') then
|
||||
begin
|
||||
inc(Position);
|
||||
while (Position<=Len)
|
||||
and (Source[Position]<>'"') do
|
||||
inc(Position);
|
||||
while (Position<=Len)
|
||||
and (Source[Position]<>'"') do
|
||||
inc(Position);
|
||||
inc(Position);
|
||||
end;
|
||||
else
|
||||
inc(Position);
|
||||
end else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'''': // char constant
|
||||
|
@ -1699,7 +1699,8 @@ begin
|
||||
end;
|
||||
// read specifiers
|
||||
while not (CurPos.Flag in [cafSemicolon,cafNone]) do begin
|
||||
if WordIsPropertySpecifier.DoIt(@Src[CurPos.StartPos]) then begin
|
||||
if WordIsPropertySpecifier.DoItCaseInsensitive(@Src[CurPos.StartPos])
|
||||
then begin
|
||||
if AtomIs(s) then exit(true);
|
||||
end else if CurPos.Flag=cafEdgedBracketOpen then begin
|
||||
ReadTilBracketClose(true);
|
||||
|
Loading…
Reference in New Issue
Block a user