mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-02 18:00:26 +02:00
h2pas: added tool to convert anonymous c enums to typedef enums
git-svn-id: trunk@14095 -
This commit is contained in:
parent
29d9cb29f8
commit
7a7850a64b
@ -26,8 +26,8 @@ uses
|
|||||||
Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage,
|
Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage,
|
||||||
Forms, Controls, Dialogs, FileUtil, FileProcs, AVL_Tree,
|
Forms, Controls, Dialogs, FileUtil, FileProcs, AVL_Tree,
|
||||||
// CodeTools
|
// CodeTools
|
||||||
CodeAtom, CodeTree, KeywordFuncLists, BasicCodeTools, CodeCache,
|
CodeAtom, CodeTree, KeywordFuncLists, NonPascalCodeTools, BasicCodeTools,
|
||||||
SourceChanger, CodeToolManager,
|
CodeCache, SourceChanger, CodeToolManager,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf,
|
TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf,
|
||||||
IDEMsgIntf, IDETextConverter;
|
IDEMsgIntf, IDETextConverter;
|
||||||
@ -84,6 +84,16 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TConvertEnumsToTypeDef (for C header files)
|
||||||
|
Give anoymous enums a name }
|
||||||
|
|
||||||
|
TConvertEnumsToTypeDef = class(TCustomTextConverterTool)
|
||||||
|
public
|
||||||
|
class function ClassDescription: string; override;
|
||||||
|
function Execute(aText: TIDETextConverter): TModalResult; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TReplaceUnitFilenameWithUnitName -
|
{ TReplaceUnitFilenameWithUnitName -
|
||||||
Replace "unit filename;" with "unit name;" }
|
Replace "unit filename;" with "unit name;" }
|
||||||
|
|
||||||
@ -288,7 +298,8 @@ type
|
|||||||
phRemoveEmptyCMacrosTool, // Remove empty C macros
|
phRemoveEmptyCMacrosTool, // Remove empty C macros
|
||||||
phReplaceEdgedBracketPairWithStar, // Replace [] with *
|
phReplaceEdgedBracketPairWithStar, // Replace [] with *
|
||||||
phReplaceMacro0PointerWithNULL, // Replace macro values 0 pointer like (char *)0
|
phReplaceMacro0PointerWithNULL, // Replace macro values 0 pointer like (char *)0
|
||||||
phConvertFunctionTypesToPointers // Convert function types to pointers
|
phConvertFunctionTypesToPointers, // Convert function types to pointers
|
||||||
|
phConvertEnumsToTypeDef// Convert anonymous enums to ypedef enums
|
||||||
);
|
);
|
||||||
TPreH2PasToolsOptions = set of TPreH2PasToolsOption;
|
TPreH2PasToolsOptions = set of TPreH2PasToolsOption;
|
||||||
const
|
const
|
||||||
@ -3614,6 +3625,8 @@ begin
|
|||||||
TReplaceMacro0PointerWithNULL,Result) then exit;
|
TReplaceMacro0PointerWithNULL,Result) then exit;
|
||||||
if not Run(phConvertFunctionTypesToPointers,
|
if not Run(phConvertFunctionTypesToPointers,
|
||||||
TConvertFunctionTypesToPointers,Result) then exit;
|
TConvertFunctionTypesToPointers,Result) then exit;
|
||||||
|
if not Run(phConvertEnumsToTypeDef,
|
||||||
|
TConvertEnumsToTypeDef,Result) then exit;
|
||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4287,4 +4300,123 @@ begin
|
|||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TConvertEnumsToTypeDef }
|
||||||
|
|
||||||
|
class function TConvertEnumsToTypeDef.ClassDescription: string;
|
||||||
|
begin
|
||||||
|
Result:='Give anoymous c enums a typedef name';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TConvertEnumsToTypeDef.Execute(aText: TIDETextConverter
|
||||||
|
): TModalResult;
|
||||||
|
var
|
||||||
|
Src: String;
|
||||||
|
SrcLen: Integer;
|
||||||
|
|
||||||
|
function CreateEnumName(StartPos, EndPos: integer): string;
|
||||||
|
var
|
||||||
|
AtomStart: LongInt;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
AtomStart:=StartPos;
|
||||||
|
while StartPos<=EndPos do begin
|
||||||
|
ReadNextCAtom(Src,StartPos,AtomStart);
|
||||||
|
if AtomStart>SrcLen then exit;
|
||||||
|
if IsIdentStartChar[Src[AtomStart]] then begin
|
||||||
|
Result:=Result+copy(Src,AtomStart,StartPos-AtomStart);
|
||||||
|
if length(Result)>60 then exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
AtomStart: Integer;
|
||||||
|
LastAtomStart: LongInt;
|
||||||
|
Changed: Boolean;
|
||||||
|
|
||||||
|
procedure AdjustAfterReplace(var APosition: integer;
|
||||||
|
FromPos, ToPos, NewLength: integer);
|
||||||
|
begin
|
||||||
|
if APosition<FromPos then
|
||||||
|
exit
|
||||||
|
else if APosition<ToPos then
|
||||||
|
APosition:=FromPos
|
||||||
|
else
|
||||||
|
inc(APosition,NewLength-(FromPos-ToPos));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Replace(FromPos, ToPos: integer; const NewSrc: string);
|
||||||
|
begin
|
||||||
|
DebugLn(['TConvertEnumsToTypeDef.Execute.Replace ',FromPos,'-',ToPos,' NewSrc="',NewSrc,'"']);
|
||||||
|
Src:=copy(Src,1,FromPos-1)+NewSrc+copy(Src,ToPos,length(Src));
|
||||||
|
AdjustAfterReplace(p,FromPos,ToPos,length(NewSrc));
|
||||||
|
AdjustAfterReplace(AtomStart,FromPos,ToPos,length(NewSrc));
|
||||||
|
AdjustAfterReplace(LastAtomStart,FromPos,ToPos,length(NewSrc));
|
||||||
|
Changed:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
EnumStart: LongInt;
|
||||||
|
EnumEnd: LongInt;
|
||||||
|
EnumName: String;
|
||||||
|
BracketStart: LongInt;
|
||||||
|
begin
|
||||||
|
Result:=mrCancel;
|
||||||
|
if aText=nil then exit;
|
||||||
|
Changed:=false;
|
||||||
|
Src:=aText.Source;
|
||||||
|
SrcLen:=length(Src);
|
||||||
|
p:=1;
|
||||||
|
AtomStart:=1;
|
||||||
|
LastAtomStart:=-1;
|
||||||
|
repeat
|
||||||
|
ReadNextCAtom(Src,p,AtomStart);
|
||||||
|
if p>SrcLen then break;
|
||||||
|
//DebugLn(['TConvertEnumsToTypeDef.Execute ',AtomStart,' "',dbgstr(copy(Src,AtomStart,p-AtomStart)),'"']);
|
||||||
|
case Src[AtomStart] of
|
||||||
|
'a'..'z','A'..'Z','_':
|
||||||
|
begin
|
||||||
|
// identifier
|
||||||
|
if (CompareCIdentifiers(@Src[AtomStart],'enum')=0)
|
||||||
|
and ((LastAtomStart<1)
|
||||||
|
or (CompareCIdentifiers(@Src[AtomStart],'typedef')<>0)) then
|
||||||
|
begin
|
||||||
|
// enum without typedef
|
||||||
|
DebugLn(['TConvertEnumsToTypeDef.Execute enum without typedef found']);
|
||||||
|
EnumStart:=AtomStart;
|
||||||
|
// read curly bracket open
|
||||||
|
ReadNextCAtom(Src,p,AtomStart);
|
||||||
|
if (AtomStart>SrcLen) or (Src[AtomStart]<>'{') then break;
|
||||||
|
BracketStart:=AtomStart;
|
||||||
|
// read til curly bracket close
|
||||||
|
if not ReadTilCBracketClose(Src,AtomStart) then break;
|
||||||
|
p:=AtomStart;
|
||||||
|
// read semicolon
|
||||||
|
ReadNextCAtom(Src,p,AtomStart);
|
||||||
|
if (AtomStart>SrcLen) or (Src[AtomStart]<>';') then break;
|
||||||
|
EnumEnd:=AtomStart;
|
||||||
|
DebugLn(['TConvertEnumsToTypeDef.Execute Enum block: ',copy(Src,EnumStart,EnumEnd-EnumStart)]);
|
||||||
|
// read enums to create a unique name
|
||||||
|
EnumName:=CreateEnumName(BracketStart,EnumEnd);
|
||||||
|
if EnumName='' then begin
|
||||||
|
// empty enum => remove
|
||||||
|
Replace(EnumStart,EnumEnd,'');
|
||||||
|
end else begin
|
||||||
|
// insert 'typedef' and name
|
||||||
|
// IMPORTANT: insert in reverse order
|
||||||
|
Replace(EnumEnd,EnumEnd,EnumName);
|
||||||
|
Replace(EnumStart,EnumStart,'typedef ');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
LastAtomStart:=AtomStart;
|
||||||
|
until false;
|
||||||
|
|
||||||
|
if Changed then
|
||||||
|
aText.Source:=Src;
|
||||||
|
Result:=mrOk;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -215,6 +215,7 @@ begin
|
|||||||
TextConverterToolClasses.RegisterClass(TReplaceEdgedBracketPairWithStar);
|
TextConverterToolClasses.RegisterClass(TReplaceEdgedBracketPairWithStar);
|
||||||
TextConverterToolClasses.RegisterClass(TReplaceMacro0PointerWithNULL);
|
TextConverterToolClasses.RegisterClass(TReplaceMacro0PointerWithNULL);
|
||||||
TextConverterToolClasses.RegisterClass(TConvertFunctionTypesToPointers);
|
TextConverterToolClasses.RegisterClass(TConvertFunctionTypesToPointers);
|
||||||
|
TextConverterToolClasses.RegisterClass(TConvertEnumsToTypeDef);
|
||||||
TextConverterToolClasses.RegisterClass(TPostH2PasTools);
|
TextConverterToolClasses.RegisterClass(TPostH2PasTools);
|
||||||
TextConverterToolClasses.RegisterClass(TReplaceUnitFilenameWithUnitName);
|
TextConverterToolClasses.RegisterClass(TReplaceUnitFilenameWithUnitName);
|
||||||
TextConverterToolClasses.RegisterClass(TRemoveDoubleSemicolons);
|
TextConverterToolClasses.RegisterClass(TRemoveDoubleSemicolons);
|
||||||
|
Loading…
Reference in New Issue
Block a user