diff --git a/components/h2pas/h2pasconvert.pas b/components/h2pas/h2pasconvert.pas index 818aae113f..adda2dcd33 100644 --- a/components/h2pas/h2pasconvert.pas +++ b/components/h2pas/h2pasconvert.pas @@ -26,8 +26,8 @@ uses Classes, SysUtils, LCLProc, LResources, LazConfigStorage, XMLPropStorage, Forms, Controls, Dialogs, FileUtil, FileProcs, AVL_Tree, // CodeTools - CodeAtom, CodeTree, KeywordFuncLists, BasicCodeTools, CodeCache, - SourceChanger, CodeToolManager, + CodeAtom, CodeTree, KeywordFuncLists, NonPascalCodeTools, BasicCodeTools, + CodeCache, SourceChanger, CodeToolManager, // IDEIntf TextTools, IDEExternToolIntf, IDEDialogs, LazIDEIntf, SrcEditorIntf, IDEMsgIntf, IDETextConverter; @@ -84,6 +84,16 @@ type 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 - Replace "unit filename;" with "unit name;" } @@ -288,7 +298,8 @@ type phRemoveEmptyCMacrosTool, // Remove empty C macros phReplaceEdgedBracketPairWithStar, // Replace [] with * 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; const @@ -3614,6 +3625,8 @@ begin TReplaceMacro0PointerWithNULL,Result) then exit; if not Run(phConvertFunctionTypesToPointers, TConvertFunctionTypesToPointers,Result) then exit; + if not Run(phConvertEnumsToTypeDef, + TConvertEnumsToTypeDef,Result) then exit; Result:=mrOk; end; @@ -4287,4 +4300,123 @@ begin Result:=mrOk; 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 APositionSrcLen 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. diff --git a/components/h2pas/h2pasdlg.pas b/components/h2pas/h2pasdlg.pas index e1f812ac58..e85c8d5e3e 100644 --- a/components/h2pas/h2pasdlg.pas +++ b/components/h2pas/h2pasdlg.pas @@ -215,6 +215,7 @@ begin TextConverterToolClasses.RegisterClass(TReplaceEdgedBracketPairWithStar); TextConverterToolClasses.RegisterClass(TReplaceMacro0PointerWithNULL); TextConverterToolClasses.RegisterClass(TConvertFunctionTypesToPointers); + TextConverterToolClasses.RegisterClass(TConvertEnumsToTypeDef); TextConverterToolClasses.RegisterClass(TPostH2PasTools); TextConverterToolClasses.RegisterClass(TReplaceUnitFilenameWithUnitName); TextConverterToolClasses.RegisterClass(TRemoveDoubleSemicolons);