mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-05 19:52:33 +02:00
284 lines
9.0 KiB
ObjectPascal
284 lines
9.0 KiB
ObjectPascal
{
|
|
Test with:
|
|
./runtests --format=plain --suite=TTestCodetoolsH2Pas
|
|
./runtests --format=plain --suite=TestCTH2PMergeHeaderFiles
|
|
./runtests --format=plain --suite=TestCTH2PReplaceMacros
|
|
./runtests --format=plain --suite=TestCTH2PConvertSimpleVars
|
|
./runtests --format=plain --suite=TestCTH2PConvertEnumsTypes
|
|
./runtests --format=plain --suite=TestCTH2PConvertConst
|
|
./runtests --format=plain --suite=TestCTH2PConvertSimpleTypedefs
|
|
./runtests --format=plain --suite=TestCTH2PConvertSimpleStructs
|
|
}
|
|
unit TestCTH2Pas;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
{$DEFINE VerboseTestCTH2Pas}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, fpcunit, testregistry, FileProcs,
|
|
CodeToolManager, BasicCodeTools, CodeCache, CCodeParserTool, H2PasTool;
|
|
|
|
type
|
|
|
|
{ TTestCodetoolsH2Pas }
|
|
|
|
TTestCodetoolsH2Pas = class(TTestCase)
|
|
protected
|
|
procedure Test(Title, CHeaderSrc, ExpectedPasSrc: string);
|
|
procedure TestIntf(Title, CHeaderSrc, ExpectedPasSrc: string);
|
|
published
|
|
procedure TestCTH2PMergeHeaderFiles;
|
|
procedure TestCTH2PReplaceMacros;
|
|
procedure TestCTH2PConvertSimpleVars;
|
|
procedure TestCTH2PConvertEnumsTypes;
|
|
procedure TestCTH2PConvertConst;
|
|
procedure TestCTH2PConvertSimpleTypedefs;
|
|
procedure TestCTH2PConvertSimpleStructs;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TTestCodetoolsH2Pas }
|
|
|
|
procedure TTestCodetoolsH2Pas.Test(Title, CHeaderSrc, ExpectedPasSrc: string);
|
|
var
|
|
Tool: TH2PasTool;
|
|
Header1: TCodeBuffer;
|
|
PasCode: TCodeBuffer;
|
|
begin
|
|
Tool:=TH2PasTool.Create;
|
|
Header1:=nil;
|
|
PasCode:=nil;
|
|
try
|
|
Header1:=CodeToolBoss.CreateFile('header1.h');
|
|
PasCode:=CodeToolBoss.CreateFile('header1.pas');
|
|
Header1.Source:=CHeaderSrc;
|
|
Tool.Convert(Header1,PasCode);
|
|
if CompareTextIgnoringSpace(ExpectedPasSrc,PasCode.Source,true)<>0 then begin
|
|
// failed
|
|
debugln(['TTestCodetoolsH2Pas.Test C Source="',CHeaderSrc,'"']);
|
|
debugln(['TTestCodetoolsH2Pas.Test Expected pas="',ExpectedPasSrc,'"']);
|
|
debugln(['TTestCodetoolsH2Pas.Test Found pas="',PasCode.Source,'"']);
|
|
Tool.WriteH2PNodeReport;
|
|
Tool.WriteH2PDirectivesNodeReport;
|
|
AssertEquals(Title,ExpectedPasSrc,PasCode.Source);
|
|
end else begin
|
|
//debugln(['TTestCodetoolsH2Pas.Test Found pas="',PasCode.Source,'"']);
|
|
AssertEquals(Title,true,true);
|
|
end;
|
|
finally
|
|
if Header1<>nil then Header1.IsDeleted:=true;
|
|
if PasCode<>nil then PasCode.IsDeleted:=true;
|
|
Tool.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestIntf(Title, CHeaderSrc, ExpectedPasSrc: string
|
|
);
|
|
var
|
|
UsesCTypes: String;
|
|
EmpytImplementation: String;
|
|
begin
|
|
UsesCTypes:='uses ctypes;'+LineEnding;
|
|
EmpytImplementation:=LineEnding+'implementation'+LineEnding+'end.';
|
|
Test(Title,CHeaderSrc,UsesCTypes+ExpectedPasSrc+EmpytImplementation);
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PMergeHeaderFiles;
|
|
var
|
|
Header1, Header2: TCodeBuffer;
|
|
Merger: TCHeaderFileMerger;
|
|
Filenames: TStringList;
|
|
Src: String;
|
|
Header1Start: LongInt;
|
|
Header2Start: LongInt;
|
|
Header1End: LongInt;
|
|
begin
|
|
Header1:=CodeToolBoss.CreateFile('header1.h');
|
|
Header2:=CodeToolBoss.CreateFile('header2.h');
|
|
|
|
Header1.Source:='// header1.h'+LineEnding
|
|
+'#include header2.h'+LineEnding
|
|
+'// end of header1.h';
|
|
Header2.Source:='// header2.h';
|
|
Merger:=TCHeaderFileMerger.Create;
|
|
Filenames:=TStringList.Create;
|
|
try
|
|
Filenames.Add('header1.h');
|
|
Filenames.Add('header2.h');
|
|
Merger.Merge(Filenames,CodeToolBoss.SourceCache,[]);
|
|
Src:=Merger.CombinedSource.Source;
|
|
Header1Start:=System.Pos('// header1.h',Src);
|
|
Header2Start:=System.Pos('// header2.h',Src);
|
|
Header1End:=System.Pos('// end of header1.h',Src);
|
|
//debugln(['TTestCodetoolsH2Pas.TestCTH2PMergeHeaderFiles ',Src]);
|
|
AssertEquals('start comment header1.h',1,Header1Start);
|
|
AssertEquals('start comment header1.h in front of header2.h',true,Header1Start<Header2Start);
|
|
AssertEquals('start comment header2.h in front of end of header1.h',true,Header2Start<Header1End);
|
|
finally
|
|
Merger.Free;
|
|
Filenames.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PReplaceMacros;
|
|
var
|
|
Header1: TCodeBuffer;
|
|
Buffers: TFPList;
|
|
Merger: TCHeaderFileMerger;
|
|
|
|
procedure Check(Msg, Src, ExpectedSrc: string);
|
|
var
|
|
NewSrc: String;
|
|
begin
|
|
Header1.Source:=Src;
|
|
Merger.Merge(Buffers,[]);
|
|
NewSrc:=Trim(Merger.CombinedSource.Source);
|
|
AssertEquals(Msg,dbgstr(ExpectedSrc),dbgstr(NewSrc));
|
|
end;
|
|
|
|
begin
|
|
Header1:=CodeToolBoss.CreateFile('header1.h');
|
|
|
|
Merger:=TCHeaderFileMerger.Create;
|
|
Buffers:=TFPList.Create;
|
|
try
|
|
Buffers.Add(Header1);
|
|
// undefine
|
|
Merger.Macros['remove1']:='';
|
|
Check('undefine remove1','remove1','');
|
|
// define
|
|
Merger.Macros['macro1']:='newvalue';
|
|
Check('define macro1','macro1','newvalue');
|
|
// define macro function
|
|
Merger.Macros['macrofunc1()']:='newvalue';
|
|
Check('define macrofunc1','macrofunc1(param)','newvalue');
|
|
// do not replace #define
|
|
Merger.Macros['macro1']:='newvalue';
|
|
Check('do not replace macros in #define','#define macro1','#define macro1');
|
|
Check('do not replace macros in #undef','#undef macro1','#undef macro1');
|
|
Check('do not replace macros in #ifdef','#ifdef macro1','#ifdef macro1');
|
|
Check('do not replace macros in #ifndef','#ifndef macro1','#ifndef macro1');
|
|
finally
|
|
Buffers.Free;
|
|
Merger.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PConvertSimpleVars;
|
|
begin
|
|
TestIntf('convert int i;', 'int i;', 'var i: cint; cvar; external;');
|
|
TestIntf('convert #define c 1', '#define c 1', 'const c=1;');
|
|
TestIntf('convert int y = 7;', 'int y = 7;', 'var y:cint;cvar;external;');
|
|
TestIntf('convert short signed int ssi_octal = 0123;',
|
|
'short signed int ssi_octal = 0123;',
|
|
'var ssi_octal:csshort;cvar;external;');
|
|
TestIntf('convert unsigned short unsigned_short;',
|
|
'unsigned short unsigned_short;',
|
|
'var unsigned_short:cushort;cvar;external;');
|
|
TestIntf('convert unsigned long long unsigned_long_long;',
|
|
'unsigned long long unsigned_long_long;',
|
|
'var unsigned_long_long:culonglong;cvar;external;');
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PConvertEnumsTypes;
|
|
begin
|
|
TestIntf('convert anonymous enum{ENUM1};',
|
|
'enum{ENUM1};',
|
|
'type enumENUM1 = (ENUM1);');
|
|
TestIntf('convert one named enum color{red};',
|
|
'enum color{red};',
|
|
'type color = (red);');
|
|
TestIntf('convert named enum with id: color{red=1};',
|
|
'enum color{red=1};',
|
|
'type color = (red=1);');
|
|
TestIntf('convert multi enums: color{red,green,blue};',
|
|
'enum color{red,green,blue};',
|
|
'type color = (red,green,blue);');
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PConvertConst;
|
|
begin
|
|
// const char a; // A constant character
|
|
TestIntf('convert const char a;',
|
|
'const char a;',
|
|
'var a: cchar;cvar;external;');
|
|
|
|
//char const b; // A constant character (the same)
|
|
TestIntf('convert char const b;',
|
|
'char const b;',
|
|
'var b: cchar;cvar;external;');
|
|
|
|
//char *const c; // A constant pointer to a character
|
|
TestIntf('convert char *const c;',
|
|
'char *const c;',
|
|
'var c: pcchar;cvar;external;');
|
|
|
|
//const char *const d; // A constant pointer to a constant character
|
|
TestIntf('convert char *const d;',
|
|
'char *const d;',
|
|
'var d: pcchar;cvar;external;');
|
|
|
|
//const char *e; // A pointer to a constant character. The pointer may be modified.
|
|
TestIntf('convert const char *e;',
|
|
'const char *e;',
|
|
'var e: pcchar;cvar;external;');
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PConvertSimpleTypedefs;
|
|
begin
|
|
TestIntf('convert typedef unsigned short sa_family_t;',
|
|
'typedef unsigned short sa_family_t;',
|
|
'type sa_family_t = cushort;');
|
|
end;
|
|
|
|
procedure TTestCodetoolsH2Pas.TestCTH2PConvertSimpleStructs;
|
|
begin
|
|
(*TestIntf('convert struct SwsContext;',
|
|
'struct SwsContext;',
|
|
'type SwsContext = record end;');
|
|
|
|
TestIntf('convert struct hidp_connlist_req {uint32_t cnum;};',
|
|
'struct hidp_connlist_req {'+LineEnding
|
|
+' uint32_t cnum;'+LineEnding
|
|
+'};',
|
|
'type hidp_connlist_req = record cnum:cuint32; end;');*)
|
|
|
|
// nested struct
|
|
TestIntf('convert struct hidp_connlist_req {uint32_t cnum;struct hidp_conninfo ci;};',
|
|
'struct hidp_connlist_req {'+LineEnding
|
|
+' uint32_t cnum;'+LineEnding
|
|
+' struct hidp_conninfo ci;'+LineEnding
|
|
+'};',
|
|
'type'+LineEnding
|
|
+' hidp_connlist_req = record'+LineEnding
|
|
+' cnum:cuint32;'+LineEnding
|
|
+' ci:hidp_conninfo;'+LineEnding
|
|
+' end;'+LineEnding
|
|
+' hidp_conninfo = record'+LineEnding
|
|
+' end;');
|
|
|
|
// nested pointer of struct
|
|
(*TestIntf('convert struct hidp_connlist_req {uint32_t cnum;struct hidp_conninfo *ci;};',
|
|
'struct hidp_connlist_req {'+LineEnding
|
|
+' uint32_t cnum;'+LineEnding
|
|
+' struct hidp_conninfo *ci;'+LineEnding
|
|
+'};',
|
|
'type'+LineEnding
|
|
+' hidp_connlist_req = record'+LineEnding
|
|
+' cnum:cuint32;'+LineEnding
|
|
+' ci:Phidp_conninfo;'+LineEnding
|
|
+' end;'+LineEnding
|
|
+' hidp_conninfo = record'+LineEnding
|
|
+' end;'); *)
|
|
end;
|
|
|
|
initialization
|
|
RegisterTest(TTestCodetoolsH2Pas);
|
|
|
|
end.
|
|
|