123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202 |
- {
- This file is part of the Free Pascal test suite.
- Copyright (c) 1999-2002 by the Free Pascal development team.
- This program makes the compilation and
- execution of individual test sources.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- {$goto on}
- {$H+}
- program dotest;
- uses
- sysutils,
- strutils,
- dos,
- {$ifdef macos}
- macutils,
- {$endif}
- tsstring,
- tsutils,
- tstypes,
- redir,
- bench,
- classes;
- {$ifdef go32v2}
- {$define LIMIT83FS}
- {$endif}
- {$ifdef os2}
- {$define LIMIT83FS}
- {$endif}
- {$ifdef msdos}
- {$define LIMIT83FS}
- {$endif}
- type
- tcompinfo = (compver,comptarget,compcpu);
- tdelexecutable = (deBefore, deAfter);
- tdelexecutables = set of tdelexecutable;
- const
- ObjExt='o';
- PPUExt='ppu';
- {$ifdef UNIX}
- SrcExeExt='';
- {$else UNIX}
- {$ifdef MACOS}
- SrcExeExt='';
- {$else MACOS}
- SrcExeExt='.exe';
- {$endif MACOS}
- {$endif UNIX}
- ExeExt : string = '';
- DllExt : string = '.so';
- DllPrefix: string = 'lib';
- DefaultTimeout=60;
- READ_ONLY = 0;
- var
- Config : TConfig;
- CompilerLogFile,
- ExeLogFile,
- LongLogfile,
- FailLogfile,
- RTLUnitsDir,
- TestOutputDir,
- OutputDir : string;
- CompilerBin,
- { CompilerCPU and CompilerTarget are lowercased at start
- to avoid need to call lowercase again and again ... }
- CompilerCPU,
- CompilerTarget,
- CompilerVersion,
- DefaultCompilerCPU,
- DefaultCompilerTarget,
- DefaultCompilerVersion : string;
- PPFile : TStringList;
- PPFileInfo : TStringList;
- TestName : string;
- Current : longint;
- const
- DoGraph : boolean = false;
- UseOSOnly : boolean = false;
- DoInteractive : boolean = false;
- DoExecute : boolean = false;
- DoKnown : boolean = false;
- DoAll : boolean = false;
- DoUsual : boolean = true;
- ForceTestThreads : Boolean = false;
- { TargetDir : string = ''; unused }
- BenchmarkInfo : boolean = false;
- ExtraCompilerOpts : string = '';
- DelExecutable : TDelExecutables = [];
- RemoteAddr : string = '';
- RemotePathPrefix : string = '';
- RemotePath : string = '/tmp';
- RemotePara : string = '';
- RemoteRshParas : string = '';
- RemoteShell : string = '';
- RemoteShellBase : string = '';
- RemoteShellNeedsExport : boolean = false;
- rshprog : string = 'rsh';
- rcpprog : string = 'rcp';
- rquote : string = '''';
- UseTimeout : boolean = false;
- emulatorname : string = '';
- EmulatorOpts : string = '';
- TargetCanCompileLibraries : boolean = true;
- UniqueSuffix: string = '';
- const
- NoSharedLibSupportPattern='$nosharedlib';
- TargetHasNoSharedLibSupport = 'msdos,go32v2';
- NoWorkingUnicodeSupport='$nounicode';
- TargetHasNoWorkingUnicodeSupport = 'msdos';
- NoWorkingThread='$nothread';
- TargetHasNoWorkingThreadSupport = 'go32v2,msdos,wasip1';
- procedure TranslateConfig(var AConfig: TConfig);
- begin
- AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoSharedLibSupportPattern, TargetHasNoSharedLibSupport);
- AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoWorkingUnicodeSupport, TargetHasNoWorkingUnicodeSupport);
- if not ForceTestThreads then
- AConfig.SkipTarget:=ReplaceText(AConfig.SkipTarget, NoWorkingThread, TargetHasNoWorkingThreadSupport);
- end;
- const
- VerbosePrefix : string = '';
- procedure Verbose(lvl:TVerboseLevel;const s:string);
- var
- su : string;
- begin
- if UniqueSuffix<>'' then
- begin
- if VerbosePrefix='' then
- VerbosePrefix:='#'+UniqueSuffix+'# ';
- su:=VerbosePrefix+s;
- tsutils.Verbose(lvl,su);
- end
- else
- tsutils.Verbose(lvl,s);
- end;
- function ToStr(l:longint):string;
- var
- s : string;
- begin
- Str(l,s);
- ToStr:=s;
- end;
- function ToStrZero(l:longint;nbzero : byte):string;
- var
- s : string;
- begin
- Str(l,s);
- while length(s)<nbzero do
- s:='0'+s;
- ToStrZero:=s;
- end;
- function trimspace(const s:string):string;
- var
- i,j : longint;
- begin
- i:=length(s);
- while (i>0) and (s[i] in [#9,' ']) do
- dec(i);
- j:=1;
- while (j<i) and (s[j] in [#9,' ']) do
- inc(j);
- trimspace:=Copy(s,j,i-j+1);
- end;
- function IsInList(const entry,list:string):boolean;
- var
- i,istart : longint;
- begin
- IsInList:=false;
- i:=0;
- while (i<length(list)) do
- begin
- { Find list item }
- istart:=i+1;
- while (i<length(list)) and
- (list[i+1]<>',') do
- inc(i);
- if Upcase(entry)=Upcase(TrimSpace(Copy(list,istart,i-istart+1))) then
- begin
- IsInList:=true;
- exit;
- end;
- { skip , }
- inc(i);
- end;
- end;
- procedure SetPPFileInfo;
- Var
- info : searchrec;
- dt : DateTime;
- begin
- FindFirst (PPFile[current],anyfile,Info);
- If DosError=0 then
- begin
- UnpackTime(info.time,dt);
- PPFileInfo.Insert(current,PPFile[current]+' '+ToStr(dt.year)+'/'+ToStrZero(dt.month,2)+'/'+
- ToStrZero(dt.day,2)+' '+ToStrZero(dt.Hour,2)+':'+ToStrZero(dt.min,2)+':'+ToStrZero(dt.sec,2));
- end
- else
- PPFileInfo.Insert(current,PPFile[current]);
- FindClose (Info);
- end;
- function ForceExtension(Const HStr,ext:String):String;
- {
- Return a filename which certainly has the extension ext
- }
- var
- j : longint;
- begin
- j:=length(Hstr);
- while (j>0) and (Hstr[j]<>'.') do
- dec(j);
- if j=0 then
- j:=length(Hstr)+1;
- if Ext<>'' then
- begin
- if Ext[1]='.' then
- ForceExtension:=Copy(Hstr,1,j-1)+Ext
- else
- ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext
- end
- else
- ForceExtension:=Copy(Hstr,1,j-1);
- end;
- procedure mkdirtree(const s:string);
- var
- SErr, hs : string;
- Err: longint;
- begin
- if s='' then
- exit;
- if s[length(s)] in ['\','/'{$IFDEF MACOS},':'{$ENDIF}] then
- hs:=Copy(s,1,length(s)-1)
- else
- hs:=s;
- if not PathExists(hs) then
- begin
- { Try parent first }
- mkdirtree(SplitPath(hs));
- { make this dir }
- Verbose(V_Debug,'Making directory '+s);
- {$I-}
- MkDir (HS);
- {$I+}
- Err := IOResult;
- if Err <> 0 then
- begin
- { did another parallel instance create it in the mean time? }
- if not PathExists(hs) then
- begin
- { no -> error }
- Str (Err, SErr);
- Verbose (V_Error, 'Directory creation of "'+HS+'" failed ' + SErr);
- end;
- end;
- end;
- end;
- Function RemoveFile(const f:string):boolean;
- var
- g : file;
- begin
- assign(g,f);
- {$I-}
- erase(g);
- {$I+}
- RemoveFile:=(ioresult=0);
- end;
- function Copyfile(const fn1,fn2:string;append:boolean) : longint;
- const
- bufsize = 16384;
- var
- f,g : file;
- oldfilemode : byte;
- st : string;
- addsize,
- i : longint;
- buf : pointer;
- begin
- if Append then
- Verbose(V_Debug,'Appending '+fn1+' to '+fn2)
- else
- Verbose(V_Debug,'Copying '+fn1+' to '+fn2);
- assign(g,fn2);
- if append then
- begin
- {$I-}
- reset(g,1);
- {$I+}
- if ioresult<>0 then
- append:=false
- else
- seek(g,filesize(g));
- end;
- if not append then
- begin
- {$I-}
- rewrite(g,1);
- {$I+}
- if ioresult<>0 then
- Verbose(V_Error,'Can''t open '+fn2+' for output');
- end;
- assign(f,fn1);
- {$I-}
- { Try using read only file mode }
- oldfilemode:=filemode;
- filemode:=READ_ONLY;
- reset(f,1);
- {$I+}
- addsize:=0;
- getmem(buf,bufsize);
- if ioresult<>0 then
- begin
- sleep(1000);
- {$I-}
- reset(f,1);
- {$I+}
- if ioresult<>0 then
- begin
- Verbose(V_Warning,'Can''t open '+fn1);
- st:='Can''t open '+fn1;
- i:=length(st);
- // blocksize is larger than 255, so no check is needed
- move(st[1],buf^,i);
- blockwrite(g,buf^,i);
- freemem(buf,bufsize);
- close(g);
- filemode:=oldfilemode;
- exit;
- end;
- end;
- filemode:=oldfilemode;
- repeat
- blockread(f,buf^,bufsize,i);
- blockwrite(g,buf^,i);
- addsize:=addsize+i;
- until i<bufsize;
- freemem(buf,bufsize);
- close(f);
- close(g);
- CopyFile:=addsize;
- end;
- procedure AddLog(const logfile,s:string);
- var
- t : text;
- begin
- assign(t,logfile);
- {$I-}
- append(t);
- {$I+}
- if ioresult<>0 then
- begin
- {$I-}
- rewrite(t);
- {$I+}
- if ioresult<>0 then
- Verbose(V_Abort,'Can''t append to '+logfile);
- end;
- writeln(t,s);
- close(t);
- end;
- procedure ForceLog(const logfile:string);
- var
- t : text;
- begin
- assign(t,logfile);
- {$I-}
- append(t);
- {$I+}
- if ioresult<>0 then
- begin
- {$I-}
- rewrite(t);
- {$I+}
- if ioresult<>0 then
- Verbose(V_Abort,'Can''t Create '+logfile);
- end;
- close(t);
- end;
- function GetCompilerInfo(c:tcompinfo):boolean;
- var
- t : text;
- hs : string;
- begin
- GetCompilerInfo:=false;
- { Try to get all information in one call, this is
- supported in 1.1. Older compilers 1.0.x will only
- return the first info }
- case c of
- compver :
- begin
- if DefaultCompilerVersion<>'' then
- begin
- GetCompilerInfo:=true;
- exit;
- end;
- hs:='-iVTPTO';
- end;
- compcpu :
- begin
- if DefaultCompilerCPU<>'' then
- begin
- GetCompilerInfo:=true;
- exit;
- end;
- hs:='-iTPTOV';
- end;
- comptarget :
- begin
- if DefaultCompilerTarget<>'' then
- begin
- GetCompilerInfo:=true;
- exit;
- end;
- hs:='-iTOTPV';
- end;
- end;
- ExecuteRedir(CompilerBin,hs,'','out.'+UniqueSuffix,'');
- assign(t,'out.'+UniqueSuffix);
- {$I-}
- reset(t);
- {$ifdef windows}
- { try to cope with Windows problems related to AntiVirus scanner
- that generate lag time during which access to a given if is forbidden }
- if (inoutres=5) then
- begin
- Sleep(5000);
- ioresult;
- Verbose(V_Warning,'Windows file not accessible out.'+UniqueSuffix);
- reset(t);
- end;
- {$endif windows}
- readln(t,hs);
- close(t);
- erase(t);
- {$I+}
- if ioresult<>0 then
- Verbose(V_Error,'Can''t get Compiler Info')
- else
- begin
- Verbose(V_Debug,'Retrieved Compiler Info: "'+hs+'"');
- case c of
- compver :
- begin
- DefaultCompilerVersion:=GetToken(hs);
- DefaultCompilerCPU:=GetToken(hs);
- DefaultCompilerTarget:=GetToken(hs);
- end;
- compcpu :
- begin
- DefaultCompilerCPU:=GetToken(hs);
- DefaultCompilerTarget:=GetToken(hs);
- DefaultCompilerVersion:=GetToken(hs);
- end;
- comptarget :
- begin
- DefaultCompilerTarget:=GetToken(hs);
- DefaultCompilerCPU:=GetToken(hs);
- DefaultCompilerVersion:=GetToken(hs);
- end;
- end;
- GetCompilerInfo:=true;
- end;
- end;
- function GetCompilerVersion:boolean;
- const
- CompilerVersionDebugWritten : boolean = false;
- begin
- if CompilerVersion='' then
- begin
- GetCompilerVersion:=GetCompilerInfo(compver);
- CompilerVersion:=DefaultCompilerVersion;
- end
- else
- GetCompilerVersion:=true;
- if GetCompilerVersion and not CompilerVersionDebugWritten then
- begin
- Verbose(V_Debug,'Compiler Version: "'+CompilerVersion+'"');
- CompilerVersionDebugWritten:=true;
- end;
- end;
- function GetCompilerCPU:boolean;
- const
- CompilerCPUDebugWritten : boolean = false;
- begin
- if CompilerCPU='' then
- begin
- GetCompilerCPU:=GetCompilerInfo(compcpu);
- CompilerCPU:=lowercase(DefaultCompilerCPU);
- end
- else
- GetCompilerCPU:=true;
- if GetCompilerCPU and not CompilerCPUDebugWritten then
- begin
- Verbose(V_Debug,'Compiler CPU: "'+CompilerCPU+'"');
- CompilerCPUDebugWritten:=true;
- end;
- end;
- function GetCompilerTarget:boolean;
- const
- CompilerTargetDebugWritten : boolean = false;
- begin
- if CompilerTarget='' then
- begin
- GetCompilerTarget:=GetCompilerInfo(comptarget);
- CompilerTarget:=lowercase(DefaultCompilerTarget);
- end
- else
- GetCompilerTarget:=true;
- if GetCompilerTarget and not CompilerTargetDebugWritten then
- begin
- Verbose(V_Debug,'Compiler Target: "'+CompilerTarget+'"');
- CompilerTargetDebugWritten:=true;
- end;
- end;
- function CompilerFullTarget:string;
- begin
- if UseOSOnly then
- CompilerFullTarget:=CompilerTarget
- else
- CompilerFullTarget:=CompilerCPU+'-'+CompilerTarget;
- end;
- { Set the three constants above according to
- the current target }
- procedure SetTargetDirectoriesStyle;
- var
- LTarget : string;
- begin
- { Call this first to ensure that CompilerTarget is not empty }
- GetCompilerTarget;
- LTarget := CompilerTarget;
- TargetHasDosStyleDirectories :=
- (LTarget='emx') or
- (LTarget='go32v2') or
- (LTarget='msdos') or
- (LTarget='nativent') or
- (LTarget='os2') or
- (LTarget='symbian') or
- (LTarget='watcom') or
- (LTarget='wdosx') or
- (LTarget='win16') or
- (LTarget='win32') or
- (LTarget='win64');
- TargetAmigaLike:=
- (LTarget='amiga') or
- (LTarget='morphos');
- TargetIsMacOS:=
- (LTarget='macos');
- { Base on whether UNIX is defined as default macro
- in extradefines in systesms/i_XXX.pas units }
- TargetIsUnix:=
- (LTarget='linux') or
- (LTarget='linux6432') or
- (LTarget='freebsd') or
- (LTarget='openbsd') or
- (LTarget='netbsd') or
- (LTarget='beos') or
- (LTarget='haiku') or
- (LTarget='solaris') or
- (LTarget='iphonesim') or
- (LTarget='darwin') or
- (LTarget='aix') or
- (LTarget='android');
- { Set ExeExt for CompilerTarget.
- This list has been set up 2013-01 using the information in
- compiler/system/i_XXX.pas units.
- We should update this list when adding new targets PM }
- if (TargetHasDosStyleDirectories) or (LTarget='wince') then
- begin
- ExeExt:='.exe';
- DllExt:='.dll';
- DllPrefix:='';
- end
- else if LTarget='atari' then
- begin
- ExeExt:='.tpp';
- DllExt:='.dll';
- DllPrefix:='';
- end
- else if LTarget='gba' then
- ExeExt:='.gba'
- else if LTarget='nds' then
- ExeExt:='.bin'
- else if (LTarget='netware') or (LTarget='netwlibc') then
- begin
- ExeExt:='.nlm';
- DllExt:='.nlm';
- DllPrefix:='';
- end
- else if LTarget='wii' then
- ExeExt:='.dol'
- else if (LTarget='wasip1') or (LTarget='wasip1threads') then
- ExeExt:='.wasm';
- end;
- {$ifndef LIMIT83FS}
- { Set the UseOSOnly constant above according to
- the current target }
- procedure SetUseOSOnly;
- var
- LTarget : string;
- begin
- { Call this first to ensure that CompilerTarget is not empty }
- GetCompilerTarget;
- LTarget := CompilerTarget;
- UseOSOnly:= (LTarget='emx') or
- (LTarget='go32v2') or
- (LTarget='msdos') or
- (LTarget='os2');
- end;
- {$endif not LIMIT83FS}
- procedure SetTargetCanCompileLibraries;
- var
- LTarget : string;
- begin
- { Call this first to ensure that CompilerTarget is not empty }
- GetCompilerTarget;
- LTarget := CompilerTarget;
- { Feel free to add other targets here }
- if (LTarget='go32v2') then
- TargetCanCompileLibraries:=false;
- end;
- function OutputFileName(Const s,ext:String):String;
- begin
- {$ifndef macos}
- OutputFileName:=OutputDir+'/'+ForceExtension(s,ext);
- {$else macos}
- OutputFileName:=ConcatMacPath(OutputDir,ForceExtension(s,ext));
- {$endif macos}
- end;
- function TestOutputFileName(Const pref,base,ext:String):String;
- begin
- {$ifndef macos}
- TestOutputFileName:=TestOutputDir+'/'+ForceExtension(pref+SplitFileName(base),ext);
- {$else macos}
- TestOutputFileName:=ConcatMacPath(TestOutputDir,ForceExtension(pref+SplitFileName(base),ext));
- {$endif macos}
- end;
- function TestLogFileName(Const pref,base,ext:String):String;
- var
- LogDir: String;
- begin
- LogDir:=TestOutputDir;
- {$ifndef macos}
- if UniqueSuffix<>'' then
- LogDir:=LogDir+'/..';
- TestLogFileName:=LogDir+'/'+ForceExtension(pref+SplitFileName(base),ext);
- {$else macos}
- if UniqueSuffix<>'' then
- LogDir:=LogDir+'::';
- TestLogFileName:=ConcatMacPath(LogDir,ForceExtension(pref+SplitFileName(base),ext));
- {$endif macos}
- end;
- function ExitWithInternalError(const OutName:string):boolean;
- var
- t : text;
- s : string;
- begin
- ExitWithInternalError:=false;
- { open logfile }
- assign(t,Outname);
- {$I-}
- reset(t);
- {$I+}
- if ioresult<>0 then
- exit;
- while not eof(t) do
- begin
- readln(t,s);
- if (pos('Fatal: Internal error ',s)>0) or
- (pos('Error: Compilation raised exception internally',s)>0) then
- begin
- ExitWithInternalError:=true;
- break;
- end;
- end;
- close(t);
- end;
- function CheckForMessages(const OutName:string;const Msgs:array of longint;var Found:array of boolean):boolean;
- var
- t : text;
- s,id : string;
- fnd,i : longint;
- begin
- CheckForMessages:=false;
- for i:=0 to high(Found) do
- Found[i]:=False;
- if length(Msgs)<>length(Found) then
- exit;
- assign(t,Outname);
- {$I-}
- reset(t);
- {$I+}
- if ioresult<>0 then
- exit;
- fnd:=0;
- for i:=0 to high(Found) do
- Found[i]:=False;
- while not eof(t) do
- begin
- readln(t,s);
- for i:=0 to high(Msgs) do
- begin
- str(Msgs[i],id);
- id:='('+id+')';
- if startsstr(id,s) or (pos(': '+id,s)>0) then
- begin
- if not Found[i] then
- inc(fnd);
- Found[i]:=True;
- { there can only be a single message per line }
- break;
- end;
- end;
- end;
- close(t);
- CheckForMessages:=fnd=Length(Msgs);
- end;
- { Takes each option from AddOptions list
- considered as a space separated list
- and adds the option to args
- unless option contains a percent sign,
- in that case, the option after % will be added
- to args only if CompilerTarget is listed in
- the string part before %.
- NOTE: this function does not check for
- quoted options...
- The list before % must of course contain no spaces. }
- procedure AppendOptions(AddOptions : string;var args : string);
- var
- endopt,percentpos : longint;
- opttarget, currentopt : string;
- begin
- Verbose(V_Debug,'AppendOptions called with AddOptions="'+AddOptions+'"');
- AddOptions:=trimspace(AddOptions);
- repeat
- endopt:=pos(' ',AddOptions);
- if endopt=0 then
- endopt:=length(AddOptions);
- currentopt:=trimspace(copy(AddOptions,1,endopt));
- AddOptions:=trimspace(copy(Addoptions,endopt+1,length(AddOptions)));
- if currentopt<>'' then
- begin
- percentpos:=pos('%',currentopt);
- if (percentpos=0) then
- begin
- Verbose(V_Debug,'Adding option="'+currentopt+'"');
- args:=args+' '+currentopt;
- end
- else
- begin
- opttarget:=lowercase(copy(currentopt,1,percentpos-1));
- if IsInList(CompilerTarget, opttarget) then
- begin
- Verbose(V_Debug,'Adding target specific option="'+currentopt+'" for '+opttarget);
- args:=args+' '+copy(currentopt,percentpos+1,length(currentopt))
- end
- else
- Verbose(V_Debug,'No matching target "'+currentopt+'"');
- end;
- end;
- until AddOptions='';
- end;
- { This function removes some incompatible
- options from TEST_OPT before adding them to
- the list of options passed to the compiler.
- %DELOPT=XYZ will remove XYZ exactly
- %DELOPT=XYZ* will remove all options starting with XYZ.
- NOTE: This fuinction does not handle quoted options. }
- function DelOptions(Pattern, opts : string) : string;
- var
- currentopt : string;
- optpos, endopt, startpos, endpos : longint;
- iswild : boolean;
- begin
- opts:=trimspace(opts);
- pattern:=trimspace(pattern);
- repeat
- endpos:=pos(' ',pattern);
- if endpos=0 then
- endpos:=length(pattern);
- currentopt:=trimspace(copy(pattern,1,endpos));
- pattern:=trimspace(copy(pattern,endpos+1,length(pattern)));
- if currentopt<>'' then
- begin
- if currentopt[length(currentopt)]='*' then
- begin
- iswild:=true;
- system.delete(currentopt,length(currentopt),1);
- end
- else
- iswild:=false;
- startpos:=1;
- repeat
- optpos:=pos(currentopt,copy(opts,startpos,length(opts)));
- if optpos>0 then
- begin
- { move to index in full opts string }
- optpos:=optpos+startpos-1;
- { compute position of end of opt }
- endopt:=optpos+length(currentopt);
- { use that end as start position for next round }
- startpos:=endopt;
- if iswild then
- begin
- while (opts[endopt]<>' ') and
- (endopt<length(opts)) do
- begin
- inc(endopt);
- inc(startpos);
- end;
- Verbose(V_Debug,'Pattern match found "'+currentopt+'*" in "'+opts+'"');
- system.delete(opts,optpos,endopt-optpos+1);
- Verbose(V_Debug,'After opts="'+opts+'"');
- end
- else
- begin
- if (endopt>length(opts)) or (opts[endopt]=' ') then
- begin
- Verbose(V_Debug,'Exact match found "'+currentopt+'" in "'+opts+'"');
- system.delete(opts,optpos,endopt-optpos+1);
- Verbose(V_Debug,'After opts="'+opts+'"');
- end
- else
- begin
- Verbose(V_Debug,'No exact match "'+currentopt+'" in "'+opts+'"');
- end;
- end;
- end;
- until optpos=0;
- end;
- until pattern='';
- DelOptions:=opts;
- end;
- function RunCompiler(const ExtraPara: string):boolean;
- var
- args,LocalExtraArgs,msgid,
- wpoargs,wposuffix : string;
- i,
- passnr,
- passes : longint;
- execres : boolean;
- EndTicks,
- StartTicks : int64;
- fndmsgs : array of boolean;
- begin
- RunCompiler:=false;
- args:='-n -T'+CompilerTarget+' -Fu'+RTLUnitsDir;
- if ExtraPara<>'' then
- args:=args+' '+ExtraPara;
- { the helper object files have been copied to the common directory }
- if UniqueSuffix<>'' then
- args:=args+' -Fo'+TestOutputDir+'/..';
- args:=args+' -FE'+TestOutputDir;
- if TargetIsMacOS then
- args:=args+' -WT '; {tests should be compiled as MPWTool}
- if Config.DelOptions<>'' then
- LocalExtraArgs:=DelOptions(Config.DelOptions,ExtraCompilerOpts)
- else
- LocalExtraArgs:=ExtraCompilerOpts;
- if LocalExtraArgs<>'' then
- args:=args+' '+LocalExtraArgs;
- if TargetIsUnix then
- begin
- { Add runtime library path to current dir to find .so files }
- if Config.NeedLibrary then
- begin
- if (CompilerTarget='darwin') or
- (CompilerTarget='aix') then
- args:=args+' -Fl'+TestOutputDir
- else
- { do not use single quote for -k as they are mishandled on
- Windows Shells }
- args:=args+' -Fl'+TestOutputDir+' -k-rpath -k.'
- end;
- end;
- if Config.NeedOptions<>'' then
- AppendOptions(Config.NeedOptions,args);
- { we need to check for message IDs, so request them }
- if Length(Config.ExpectMsgs) <> 0 then
- begin
- AppendOptions('-vq',args);
- SetLength(fndmsgs,Length(Config.ExpectMsgs));
- end;
- wpoargs:='';
- wposuffix:='';
- if (Config.WpoPasses=0) or
- (Config.WpoParas='') then
- passes:=1
- else
- passes:=config.wpopasses+1;
- args:=args+' '+PPFile[current];
- for passnr:=1 to passes do
- begin
- if (passes>1) then
- begin
- wposuffix:='_'+tostr(passnr);
- wpoargs:=' -OW'+config.wpoparas+' -FW'+TestOutputFileName('',PPFile[current],'wp'+tostr(passnr));
- if (passnr>1) then
- wpoargs:=wpoargs+' -Ow'+config.wpoparas+' -Fw'+TestOutputFileName('',PPFile[current],'wp'+tostr(passnr-1));
- end;
- Verbose(V_Debug,'Executing '+compilerbin+' '+args+wpoargs);
- { also get the output from as and ld that writes to stderr sometimes }
- StartTicks:=GetMicroSTicks;
- {$ifndef macos}
- execres:=ExecuteRedir(CompilerBin,args+wpoargs,'',CompilerLogFile+wposuffix,'stdout');
- {$else macos}
- {Due to that Toolserver is not reentrant, we have to asm and link via script.}
- execres:=ExecuteRedir(CompilerBin,'-s '+args+wpoargs,'',CompilerLogFile+wposuffix,'stdout');
- if execres then
- execres:=ExecuteRedir(TestOutputDir + ':ppas','','',CompilerLogFile+wpo_suffix,'stdout');
- {$endif macos}
- EndTicks:=GetMicroSTicks;
- Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
- if BenchmarkInfo then
- begin
- Verbose(V_Normal,'Compilation took '+ToStr(EndTicks-StartTicks)+' us');
- end;
- if passes > 1 then
- CopyFile(CompilerLogFile+wposuffix,CompilerLogFile,true);
- { Error during execution? }
- if (not execres) and (ExecuteResult=0) then
- begin
- AddLog(FailLogFile,TestName);
- AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
- if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
- AddLog(LongLogFile,'IOStatus'+ToStr(IOStatus));
- { avoid to try again }
- AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
- Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
- exit;
- end;
- { Check for internal error }
- if ExitWithInternalError(CompilerLogFile) then
- begin
- AddLog(FailLogFile,TestName);
- if Config.Note<>'' then
- AddLog(FailLogFile,Config.Note);
- AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]+' internalerror generated');
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
- if Config.Note<>'' then
- AddLog(LongLogFile,Config.Note);
- if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
- AddLog(LongLogFile,'Internal error in compiler');
- { avoid to try again }
- AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
- Verbose(V_Warning,'Internal error in compiler');
- exit;
- end;
- if length(Config.ExpectMsgs)<>0 then
- begin
- Verbose(V_Debug,'Checking for messages: '+ToStr(Length(Config.ExpectMsgs)));
- if not CheckForMessages(CompilerLogFile,Config.ExpectMsgs,fndmsgs) then
- begin
- AddLog(FailLogFile,TestName);
- if Config.Note<>'' then
- AddLog(FailLogFile,Config.Note);
- AddLog(ResLogFile,message_missing+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,message_missing+PPFileInfo[current]);
- if Config.Note<>'' then
- AddLog(LongLogFile,Config.Note);
- for i:=0 to length(Config.ExpectMsgs) do
- if not fndmsgs[i] then
- begin
- str(Config.ExpectMsgs[i],msgid);
- AddLog(LongLogFile,message_missing+msgid);
- end;
- CopyFile(CompilerLogFile,LongLogFile,true);
- { avoid to try again }
- AddLog(ExeLogFile,message_missing+PPFileInfo[current]);
- exit;
- end
- else
- Verbose(V_Debug,'All messages found');
- end;
- end;
- { Should the compile fail ? }
- if Config.ShouldFail then
- begin
- if ExecuteResult<>0 then
- begin
- AddLog(ResLogFile,success_compilation_failed+PPFileInfo[current]);
- { avoid to try again }
- AddLog(ExeLogFile,success_compilation_failed+PPFileInfo[current]);
- RunCompiler:=true;
- end
- else
- begin
- AddLog(FailLogFile,TestName);
- if Config.Note<>'' then
- AddLog(FailLogFile,Config.Note);
- AddLog(ResLogFile,failed_compilation_successful+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_compilation_successful+PPFileInfo[current]);
- { avoid to try again }
- AddLog(ExeLogFile,failed_compilation_successful+PPFileInfo[current]);
- if Config.Note<>'' then
- AddLog(LongLogFile,Config.Note);
- CopyFile(CompilerLogFile,LongLogFile,true);
- end;
- end
- else
- begin
- if (ExecuteResult<>0) and
- (((Config.KnownCompileNote<>'') and (Config.KnownCompileError=0)) or
- ((Config.KnownCompileError<>0) and (ExecuteResult=Config.KnownCompileError))) then
- begin
- AddLog(FailLogFile,TestName+known_problem+Config.KnownCompileNote);
- AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]+known_problem+Config.KnownCompileNote);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,known_problem+Config.KnownCompileNote);
- AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
- if Copyfile(CompilerLogFile,LongLogFile,true)=0 then
- AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult));
- Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult));
- end
- else if ExecuteResult<>0 then
- begin
- AddLog(FailLogFile,TestName);
- if Config.Note<>'' then
- AddLog(FailLogFile,Config.Note);
- AddLog(ResLogFile,failed_to_compile+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_to_compile+PPFileInfo[current]);
- if Config.Note<>'' then
- AddLog(LongLogFile,Config.Note);
- if CopyFile(CompilerLogFile,LongLogFile,true)=0 then
- AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
- { avoid to try again }
- AddLog(ExeLogFile,failed_to_compile+PPFileInfo[current]);
- Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected 0)');
- end
- else
- begin
- AddLog(ResLogFile,successfully_compiled+PPFileInfo[current]);
- RunCompiler:=true;
- end;
- end;
- end;
- function CheckTestExitCode(const OutName:string):boolean;
- var
- t : text;
- s : string;
- i,code : integer;
- is_wasi :boolean;
- begin
- CheckTestExitCode:=false;
- { open logfile }
- assign(t,Outname);
- {$I-}
- reset(t);
- {$I+}
- if ioresult<>0 then
- exit;
- GetCompilerTarget;
- is_wasi:=(CompilerTarget='wasip1') or (CompilerTarget='wasip1threads');
- while not eof(t) do
- begin
- readln(t,s);
- if is_wasi then
- begin
- i:=pos('##WASI-EXITCODE: ',s);
- if i>0 then
- begin
- delete(s,1,i+17-1);
- val(s,ExecuteResult,code);
- if code>1 then
- val(copy(s,1,code-1),ExecuteResult,code);
- if code=0 then
- CheckTestExitCode:=true;
- break;
- end;
- end
- else
- begin
- i:=pos('TestExitCode: ',s);
- if i>0 then
- begin
- delete(s,1,i+14-1);
- val(s,ExecuteResult,code);
- if code=0 then
- CheckTestExitCode:=true;
- break;
- end;
- end;
- end;
- close(t);
- end;
- function LibraryExists(const PPFile : string; out FileName : string) : boolean;
- begin
- { Check if a dynamic library XXX was created }
- { Windows XXX.dll style }
- FileName:=TestOutputFilename('',PPFile,'dll');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- { Linux libXXX.so style }
- FileName:=TestOutputFilename('lib',PPFile,'so');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- { Darwin libXXX.dylib style }
- FileName:=TestOutputFilename('lib',PPFile,'dylib');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- { MacOS LibXXX style }
- FileName:=TestOutputFilename('Lib',PPFile,'');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- { Netware wlic XXX.nlm style }
- FileName:=TestOutputFilename('',PPFile,'nlm');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- { Amiga XXX.library style }
- FileName:=TestOutputFilename('',PPFile,'library');
- if FileExists(FileName) then
- begin
- LibraryExists:=true;
- exit;
- end;
- LibraryExists:=false;
- end;
- function ExecuteRemote(prog,args:string;out StartTicks,EndTicks : int64):boolean;
- const
- MaxTrials = 5;
- var
- Trials : longint;
- Res : boolean;
- begin
- if SplitFileExt(prog)='' then
- prog:=prog+SrcExeExt;
- Verbose(V_Debug,'RemoteExecuting '+Prog+' '+args);
- StartTicks:=GetMicroSTicks;
- Res:=false;
- Trials:=0;
- While (Trials<MaxTrials) and not Res do
- begin
- inc(Trials);
- Res:=ExecuteRedir(prog,args,'',EXELogFile,'stdout');
- if not Res then
- Verbose(V_Debug,'Call to '+prog+' failed: '+
- 'IOStatus='+ToStr(IOStatus)+
- ' RedirErrorOut='+ToStr(RedirErrorOut)+
- ' RedirErrorIn='+ToStr(RedirErrorIn)+
- ' RedirErrorError='+ToStr(RedirErrorError)+
- ' ExecuteResult='+ToStr(ExecuteResult));
- end;
- if Trials>1 then
- Verbose(V_Debug,'Done in '+tostr(trials)+' trials');
- EndTicks:=GetMicroSTicks;
- ExecuteRemote:=res;
- end;
- function ExecuteEmulated(const prog,args,FullExeLogFile:string;out StartTicks,EndTicks : int64):boolean;
- begin
- Verbose(V_Debug,'EmulatorExecuting '+Prog+' '+args);
- StartTicks:=GetMicroSTicks;
- ExecuteEmulated:=ExecuteRedir(prog,args,'',FullExeLogFile,'stdout');
- EndTicks:=GetMicroSTicks;
- end;
- function MaybeCopyFiles(const FileToCopy : string) : boolean;
- var
- TestRemoteExe,
- pref : string;
- LocalFile, RemoteFile, s: string;
- LocalPath: string;
- i : integer;
- execres : boolean;
- EndTicks,
- StartTicks : int64;
- FileList : TStringList;
- RelativeToConfigMarker : TObject;
- function BuildFileList: TStringList;
- var
- s : string;
- index : longint;
- begin
- s:=Config.Files;
- if (length(s) = 0) and (Config.ConfigFileSrc='') then
- begin
- Result:=nil;
- exit;
- end;
- Result:=TStringList.Create;
- if s<>'' then
- repeat
- index:=pos(' ',s);
- if index=0 then
- LocalFile:=s
- else
- LocalFile:=copy(s,1,index-1);
- Result.Add(LocalFile);
- if index=0 then
- break;
- s:=copy(s,index+1,length(s)-index);
- until false;
- if Config.ConfigFileSrc<>'' then
- begin
- if Config.ConfigFileSrc=Config.ConfigFileDst then
- Result.AddObject(Config.ConfigFileSrc,RelativeToConfigMarker)
- else
- Result.AddObject(Config.ConfigFileSrc+'='+Config.ConfigFileDst,RelativeToConfigMarker);
- end;
- end;
- begin
- RelativeToConfigMarker:=TObject.Create;
- if RemoteAddr='' then
- begin
- FileList:=BuildFileList;
- if assigned(FileList) then
- begin
- LocalPath:=SplitPath(PPFile[current]);
- if Length(LocalPath) > 0 then
- LocalPath:=LocalPath+'/';
- for i:=0 to FileList.count-1 do
- begin
- if FileList.Names[i]<>'' then
- begin
- LocalFile:=FileList.Names[i];
- RemoteFile:=FileList.ValueFromIndex[i];
- end
- else
- begin
- LocalFile:=FileList[i];
- RemoteFile:=LocalFile;
- end;
- if FileList.Objects[i]=RelativeToConfigMarker then
- s:='config/'+LocalFile
- else
- s:=LocalPath+LocalFile;
- CopyFile(s,TestOutputDir+'/'+RemoteFile,false);
- end;
- FileList.Free;
- end;
- RelativeToConfigMarker.Free;
- exit(true);
- end;
- execres:=true;
- { Check if library should be deleted. Do not copy to remote target in such case. }
- if (deAfter in DelExecutable) and (Config.DelFiles <> '') then
- if SplitFileName(FileToCopy) = DllPrefix + Trim(Config.DelFiles) + DllExt then
- exit;
- { We don't want to create subdirs, remove paths from the test }
- TestRemoteExe:=RemotePath+'/'+SplitFileName(FileToCopy);
- if deBefore in DelExecutable then
- begin
- s:=RemoteRshParas+' rm ';
- if rshprog <> 'adb' then
- s:=s+'-f ';
- ExecuteRemote(rshprog,s+TestRemoteExe,
- StartTicks,EndTicks);
- end;
- execres:=ExecuteRemote(rcpprog,RemotePara+' '+FileToCopy+' '+
- RemotePathPrefix+TestRemoteExe,StartTicks,EndTicks);
- if not execres then
- begin
- Verbose(V_normal, 'Could not copy executable '+FileToCopy);
- RelativeToConfigMarker.Free;
- exit(execres);
- end;
- FileList:=BuildFileList;
- if assigned(FileList) then
- begin
- LocalPath:=SplitPath(PPFile[current]);
- if Length(LocalPath) > 0 then
- LocalPath:=LocalPath+'/';
- for i:=0 to FileList.count-1 do
- begin
- if FileList.Names[i]<>'' then
- begin
- LocalFile:=FileList.Names[i];
- RemoteFile:=FileList.ValueFromIndex[i];
- end
- else
- begin
- LocalFile:=FileList[i];
- RemoteFile:=LocalFile;
- end;
- RemoteFile:=RemotePath+'/'+SplitFileName(RemoteFile);
- if FileList.Objects[i]=RelativeToConfigMarker then
- LocalFile:='config/'+LocalFile
- else
- LocalFile:=LocalPath+LocalFile;
- if DoVerbose and (rcpprog='pscp') then
- pref:='-v '
- else
- pref:='';
- execres:=ExecuteRemote(rcpprog,pref+RemotePara+' '+LocalFile+' '+
- RemotePathPrefix+RemoteFile,StartTicks,EndTicks);
- if not execres then
- begin
- Verbose(V_normal, 'Could not copy required file '+LocalFile);
- FileList.Free;
- RelativeToConfigMarker.Free;
- exit(false);
- end;
- end;
- end;
- FileList.Free;
- MaybeCopyFiles:=execres;
- RelativeToConfigMarker.Free;
- end;
- function RunExecutable:boolean;
- const
- {$ifdef unix}
- CurrDir = './';
- {$else}
- CurrDir = '';
- {$endif}
- var
- OldDir, s, ss,
- execcmd,
- FullExeLogFile,
- TestRemoteExe,
- TestExe : string;
- execres : boolean;
- EndTicks,
- StartTicks : int64;
- OldExecuteResult: longint;
- begin
- RunExecutable:=false;
- execres:=true;
- TestExe:=TestOutputFilename('',PPFile[current],ExeExt);
- execres:=MaybeCopyFiles(TestExe);
- if EmulatorName<>'' then
- begin
- { Get full name out log file, because we change the directory during
- execution }
- FullExeLogFile:=FExpand(EXELogFile);
- {$I-}
- GetDir(0,OldDir);
- ChDir(TestOutputDir);
- {$I+}
- ioresult;
- s:=CurrDir+SplitFileName(TestExe);
- { Add -Ssource_file_name for dosbox_wrapper }
- if pos('dosbox_wrapper',EmulatorName)>0 then
- s:=s+' -S'+PPFile[current];
- execres:=ExecuteEmulated(EmulatorName,EmulatorOpts+' '+s,FullExeLogFile,StartTicks,EndTicks);
- {$I-}
- ChDir(OldDir);
- {$I+}
- GetCompilerTarget;
- if (CompilerTarget='wasip1') or (CompilerTarget='wasip1threads') then
- begin
- CheckTestExitCode(FullEXELogFile);
- end;
- end
- else if RemoteAddr<>'' then
- begin
- TestRemoteExe:=RemotePath+'/'+SplitFileName(TestExe);
- { rsh doesn't pass the exitcode, use a second command to print the exitcode
- on the remoteshell to stdout }
- if DoVerbose and (rshprog='plink') then
- execcmd:='-v '+RemoteRshParas
- else
- execcmd:=RemoteRshParas;
- execcmd:=execcmd+' '+rquote+
- 'chmod 755 '+TestRemoteExe+
- ' && cd '+RemotePath+' && { ';
- { Using -rpath . at compile time does not seem
- to work for programs copied over to remote machine,
- at least not for FreeBSD.
- Does this work for all shells? }
- if Config.NeedLibrary then
- begin
- if RemoteShellNeedsExport then
- if CompilerTarget='darwin' then
- execcmd:=execcmd+' DYLD_LIBRARY_PATH=.; export DYLD_LIBRARY_PATH;'
- else
- execcmd:=execcmd+' LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH;'
- else
- if CompilerTarget='darwin' then
- execcmd:=execcmd+' setenv DYLD_LIBRARY_PATH=.; '
- else
- execcmd:=execcmd+' setenv LD_LIBRARY_PATH=.; '
- end;
- if UseTimeout then
- begin
- if Config.Timeout=0 then
- Config.Timeout:=DefaultTimeout;
- str(Config.Timeout,s);
- if (RemoteShellBase='bash') then
- execcmd:=execcmd+'ulimit -t '+s+'; '
- else
- execcmd:=execcmd+'timeout -9 '+s;
- end;
- { as we moved to RemotePath, if path is not absolute
- we need to use ./execfilename only }
- if not isabsolute(TestRemoteExe) then
- execcmd:=execcmd+' ./'+SplitFileName(TestRemoteExe)
- else
- execcmd:=execcmd+' '+TestRemoteExe;
- execcmd:=execcmd+' ; echo TestExitCode: $?';
- if (deAfter in DelExecutable) and
- not Config.NeededAfter then
- begin
- { Delete executable if not needed after }
- execcmd:=execcmd+' ; rm ';
- if rshprog <> 'adb' then
- execcmd:=execcmd+'-f ';
- execcmd:=execcmd+SplitFileName(TestRemoteExe);
- end;
- execcmd:=execcmd+'; }'+rquote;
- execres:=ExecuteRemote(rshprog,execcmd,StartTicks,EndTicks);
- { Check for TestExitCode error in output, sets ExecuteResult }
- if not CheckTestExitCode(EXELogFile) then
- Verbose(V_Debug,'Failed to check exit code for '+execcmd);
- if (deAfter in DelExecutable) and ( (Config.DelFiles <> '') or (Config.Files <> '')) then
- begin
- ss:=Trim(Config.DelFiles + ' ' + Config.Files);
- execcmd:=RemoteRshParas+' ' + rquote + 'cd ' + RemotePath + ' && { ';
- while ss <> '' do
- begin
- s:=Trim(GetToken(ss, [' ',',',';']));
- if s = '' then
- break;
- if ExtractFileExt(s) = '' then
- // If file has no extension, treat it as exe or shared lib
- execcmd:=execcmd + 'rm ' + s + ExeExt + '; rm ' + DllPrefix + s + DllExt
- else
- execcmd:=execcmd + 'rm ' + s;
- execcmd:=execcmd + '; ';
- end;
- execcmd:=execcmd+'}'+rquote;
- // Save ExecuteResult and EXELogFile
- OldExecuteResult:=ExecuteResult;
- s:=EXELogFile;
- // Output results of cleanup commands to stdout
- EXELogFile:='';
- ExecuteRemote(rshprog,execcmd,StartTicks,EndTicks);
- // Restore
- EXELogFile:=s;
- ExecuteResult:=OldExecuteResult;
- end;
- end
- else
- begin
- { Get full name out log file, because we change the directory during
- execution }
- FullExeLogFile:=FExpand(EXELogFile);
- Verbose(V_Debug,'Executing '+TestExe);
- {$I-}
- GetDir(0,OldDir);
- ChDir(TestOutputDir);
- {$I+}
- ioresult;
- { don't redirect interactive and graph programs }
- StartTicks:=GetMicroSTicks;
- if Config.IsInteractive or Config.UsesGraph then
- execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','','','')
- else
- execres:=ExecuteRedir(CurrDir+SplitFileName(TestExe),'','',FullExeLogFile,'stdout');
- EndTicks:=GetMicroSTicks;
- {$I-}
- ChDir(OldDir);
- {$I+}
- ioresult;
- end;
- { Error during execution? }
- Verbose(V_Debug,'Exitcode '+ToStr(ExecuteResult));
- if BenchmarkInfo then
- begin
- Verbose(V_Normal,'Execution took '+ToStr(EndTicks-StartTicks)+' us');
- end;
- if (not execres) and (ExecuteResult=0) then
- begin
- AddLog(FailLogFile,TestName);
- AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_to_run+PPFileInfo[current]);
- if CopyFile(EXELogFile,LongLogFile,true)=0 then
- AddLog(LongLogFile,'IOStatus: '+ToStr(IOStatus));
- { avoid to try again }
- AddLog(ExeLogFile,failed_to_run+PPFileInfo[current]);
- Verbose(V_Warning,'IOStatus: '+ToStr(IOStatus));
- exit;
- end;
- if ExecuteResult<>Config.ResultCode then
- begin
- if (ExecuteResult<>0) and
- (ExecuteResult=Config.KnownRunError) then
- begin
- AddLog(FailLogFile,TestName+known_problem+Config.KnownRunNote);
- AddLog(ResLogFile,failed_to_run+PPFileInfo[current]+known_problem+Config.KnownRunNote);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,known_problem+Config.KnownRunNote);
- AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
- if Copyfile(EXELogFile,LongLogFile,true)=0 then
- begin
- AddLog(LongLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- AddLog(ExeLogFile,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- end;
- Verbose(V_Warning,known_problem+'exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- end
- else
- begin
- AddLog(FailLogFile,TestName);
- AddLog(ResLogFile,failed_to_run+PPFileInfo[current]);
- AddLog(LongLogFile,line_separation);
- AddLog(LongLogFile,failed_to_run+PPFileInfo[current]+' ('+ToStr(ExecuteResult)+')');
- if Copyfile(EXELogFile,LongLogFile,true)=0 then
- begin
- AddLog(LongLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- AddLog(ExeLogFile,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- end;
- Verbose(V_Warning,'Exitcode: '+ToStr(ExecuteResult)+' (expected '+ToStr(Config.ResultCode)+')');
- end
- end
- else
- begin
- AddLog(ResLogFile,successfully_run+PPFileInfo[current]);
- RunExecutable:=true;
- end;
- if (deAfter in DelExecutable) and not Config.NeededAfter then
- begin
- Verbose(V_Debug,'Deleting executable '+TestExe);
- RemoveFile(TestExe);
- RemoveFile(ForceExtension(TestExe,ObjExt));
- RemoveFile(ForceExtension(TestExe,PPUExt));
- end;
- end;
- { Try to collect information concerning the remote configuration
- Currently only records RemoteShell name and sets
- RemoteShellNeedsExport boolean variable }
- procedure SetRemoteConfiguration;
- var
- f : text;
- StartTicks,EndTicks : int64;
- begin
- if RemoteAddr='' then
- exit;
- if rshprog = 'adb' then
- begin
- RemoteShellNeedsExport:=true;
- exit;
- end;
- ExeLogFile:='__remote.tmp';
- ExecuteRemote(rshprog,RemoteRshParas+
- ' "echo SHELL=${SHELL}"',StartTicks,EndTicks);
- Assign(f,ExeLogFile);
- Reset(f);
- While not eof(f) do
- begin
- Readln(f,RemoteShellBase);
- if pos('SHELL=',RemoteShellBase)>0 then
- begin
- RemoteShell:=TrimSpace(Copy(RemoteShellBase,pos('SHELL=',RemoteShellBase)+6,
- length(RemoteShellBase)));
- Verbose(V_Debug,'Remote shell is "'+RemoteShell+'"');
- RemoteShellBase:=SplitFileBase(RemoteShell);
- if (RemoteShellBase='bash') or (RemoteShellBase='sh') then
- RemoteShellNeedsExport:=true;
- end;
- end;
- Close(f);
- end;
- procedure getargs;
- procedure helpscreen;
- begin
- writeln('dotest [Options] <File>');
- writeln;
- writeln('Options can be:');
- writeln(' !ENV_NAME parse environment variable ENV_NAME for options');
- writeln(' -A include ALL tests');
- writeln(' -ADB use ADB to run tests');
- writeln(' -B delete executable before remote upload');
- writeln(' -C<compiler> set compiler to use');
- writeln(' -D display execution time');
- writeln(' -E execute test also');
- writeln(' -G include graph tests');
- writeln(' -I include interactive tests');
- writeln(' -K include known bug tests');
- writeln(' -L<ext> set extension of temporary files (prevent conflicts with parallel invocations)');
- writeln(' -M<emulator> run the tests using the given emulator');
- writeln(' -N<emulator opts.> pass options to the emulator');
- writeln(' -O use timeout wrapper for (remote) execution');
- writeln(' -P<path> path to the tests tree on the remote machine');
- writeln(' -R<remote> run the tests remotely with the given rsh/ssh address');
- writeln(' -S use ssh instead of rsh');
- writeln(' -T[cpu-]<os> run tests for target cpu and os');
- writeln(' -U<remotepara>');
- writeln(' pass additional parameter to remote program. Multiple -U can be used');
- writeln(' -V be verbose');
- writeln(' -W use putty compatible file names when testing (plink and pscp)');
- writeln(' -X don''t use COMSPEC');
- writeln(' -Y<opts> extra options passed to the compiler. Several -Y<opt> can be given.');
- writeln(' -Z remove temporary files (executable,ppu,o)');
- halt(1);
- end;
- procedure interpret_option (para : string);
- var
- ch : char;
- j : longint;
- begin
- Verbose(V_Debug,'Interpreting option"'+para+'"');
- ch:=Upcase(para[2]);
- delete(para,1,2);
- case ch of
- 'A' :
- if UpperCase(para) = 'DB' then
- begin
- rshprog:='adb';
- rcpprog:='adb';
- rquote:='"';
- if RemoteAddr = '' then
- RemoteAddr:='1'; // fake remote addr (default device will be used)
- end
- else
- begin
- DoGraph:=true;
- DoInteractive:=true;
- DoKnown:=true;
- DoAll:=true;
- end;
- 'B' : Include(DelExecutable,deBefore);
- 'C' : CompilerBin:=Para;
- 'D' : BenchMarkInfo:=true;
- 'E' : DoExecute:=true;
- 'G' : begin
- DoGraph:=true;
- if para='-' then
- DoUsual:=false;
- end;
- 'I' : begin
- DoInteractive:=true;
- if para='-' then
- DoUsual:=false;
- end;
- 'K' : begin
- DoKnown:=true;
- if para='-' then
- DoUsual:=false;
- end;
- 'L' : begin
- UniqueSuffix:=Para;
- if UniqueSuffix='' then
- UniqueSuffix:=toStr(system.GetProcessID);
- end;
- 'M' : EmulatorName:=Para;
- 'N' : EmulatorOpts:=Para;
- 'O' : UseTimeout:=true;
- 'P' : RemotePath:=Para;
- 'R' : RemoteAddr:=Para;
- 'S' :
- begin
- rshprog:='ssh';
- rcpprog:='scp';
- end;
- 'T' :
- begin
- j:=Pos('-',Para);
- if j>0 then
- begin
- CompilerCPU:=Copy(Para,1,j-1);
- CompilerTarget:=Copy(Para,j+1,length(para));
- end
- else
- CompilerTarget:=Para
- end;
- 'U' :
- RemotePara:=RemotePara+' '+Para;
- 'V' : DoVerbose:=true;
- 'W' :
- begin
- rshprog:='plink';
- rcpprog:='pscp';
- rquote:='"';
- end;
- 'X' : UseComSpec:=false;
- 'Y' : ExtraCompilerOpts:= ExtraCompilerOpts +' '+ Para;
- 'Z' : Include(DelExecutable,deAfter);
- end;
- end;
- procedure interpret_env(arg : string);
- var
- para : string;
- pspace : longint;
- begin
- Verbose(V_Debug,'Interpreting environment option"'+arg+'"');
- { Get rid of leading '!' }
- delete(arg,1,1);
- arg:=getenv(arg);
- Verbose(V_Debug,'Environment value is "'+arg+'"');
- while (length(arg)>0) do
- begin
- while (length(arg)>0) and (arg[1]=' ') do
- delete(arg,1,1);
- pspace:=pos(' ',arg);
- if pspace=0 then
- pspace:=length(arg)+1;
- para:=copy(arg,1,pspace-1);
- if (length(para)>0) and (para[1]='-') then
- interpret_option (para)
- else
- begin
- PPFile.Insert(current,ForceExtension(Para,'pp'));
- inc(current);
- end;
- delete(arg,1,pspace);
- end;
- end;
- var
- param : string;
- i : longint;
- begin
- CompilerBin:='ppc386'+srcexeext;
- for i:=1 to paramcount do
- begin
- param:=Paramstr(i);
- if (param[1]='-') then
- interpret_option(param)
- else if (param[1]='!') then
- interpret_env(param)
- else
- begin
- PPFile.Insert(current,ForceExtension(Param,'pp'));
- inc(current);
- end;
- end;
- if current=0 then
- HelpScreen;
- { disable graph,interactive when running remote }
- if RemoteAddr<>'' then
- begin
- DoGraph:=false;
- DoInteractive:=false;
- end;
- { If we use PuTTY plink program with -load option,
- the IP address or name should not be added to
- the command line }
- if (rshprog='plink') and (pos('-load',RemotePara)>0) then
- RemoteRshParas:=RemotePara
- else
- if rshprog='adb' then
- begin
- if RemoteAddr <> '1' then
- RemotePara:=Trim('-s ' + RemoteAddr + ' ' + RemotePara);
- RemoteRshParas:=Trim(RemotePara + ' shell');
- end
- else
- RemoteRshParas:=RemotePara+' '+RemoteAddr;
- if rcpprog = 'adb' then
- begin
- RemotePathPrefix:='';
- RemotePara:=Trim(RemotePara + ' push');
- end
- else
- RemotePathPrefix:=RemoteAddr + ':';
- end;
- procedure RunTest;
- var
- PPDir,LibraryName,LogSuffix,PPPrefix : string;
- Res : boolean;
- begin
- Res:=GetConfig('',PPFile[current],Config);
- TranslateConfig(Config);
- if Res then
- begin
- Res:=GetCompilerCPU;
- Res:=GetCompilerTarget;
- {$ifndef MACOS}
- RTLUnitsDir:='tstunits/'+CompilerFullTarget;
- {$else MACOS}
- RTLUnitsDir:=':tstunits:'+CompilerFullTarget;
- {$endif MACOS}
- if not PathExists(RTLUnitsDir) then
- Verbose(V_Abort,'Unit path "'+RTLUnitsDir+'" does not exists');
- {$ifndef MACOS}
- OutputDir:='output/'+CompilerFullTarget;
- {$else MACOS}
- OutputDir:=':output:'+CompilerFullTarget;
- {$endif MACOS}
- if not PathExists(OutputDir) then
- Verbose(V_Abort,'Output path "'+OutputDir+'" does not exists');
- { Make subdir in output if needed }
- PPDir:=SplitPath(PPFile[current]);
- if PPDir[length(PPDir)] in ['/','\'{$ifdef MACOS},':'{$endif MACOS}] then
- Delete(PPDir,length(PPDir),1);
- if PPDir<>'' then
- begin
- {$ifndef MACOS}
- { handle paths that are parallel to the tests directory (let's hope
- that noone uses ../../ -.- ) }
- { ToDo: check relative paths on MACOS }
- PPPrefix:=Copy(PPDir,1,3);
- if (PPPrefix='../') or (PPPrefix='..\') then
- PPDir:='root/'+Copy(PPDir,4,length(PPDir));
- TestOutputDir:=OutputDir+'/'+PPDir;
- if UniqueSuffix<>'' then
- TestOutputDir:=TestOutputDir+'/'+UniqueSuffix;
- {$else MACOS}
- TestOutputDir:=OutputDir+PPDir;
- if UniqueSuffix<>'' then
- TestOutputDir:=TestOutputDir+':'+UniqueSuffix;
- {$endif MACOS}
- mkdirtree(TestOutputDir);
- end
- else
- TestOutputDir:=OutputDir;
- if UniqueSuffix<>'' then
- LogSuffix:=UniqueSuffix
- else
- LogSuffix:=SplitBasePath(PPDir)+'log';
- ResLogFile:=OutputFileName('log',LogSuffix);
- LongLogFile:=OutputFileName('longlog',LogSuffix);
- FailLogFile:=OutputFileName('faillist',LogSuffix);
- ForceLog(ResLogFile);
- ForceLog(LongLogFile);
- ForceLog(FailLogFile);
- { Per test logfiles }
- CompilerLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'log');
- ExeLogFile:=TestLogFileName('',SplitFileName(PPFile[current]),'elg');
- Verbose(V_Debug,'Using Compiler logfile: '+CompilerLogFile);
- Verbose(V_Debug,'Using Execution logfile: '+ExeLogFile);
- end;
- if Res then
- begin
- if Config.UsesGraph and (not DoGraph) then
- begin
- AddLog(ResLogFile,skipping_graph_test+PPFileInfo[current]);
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_graph_test+PPFileInfo[current]);
- Verbose(V_Warning,skipping_graph_test);
- Res:=false;
- end;
- end;
- if Res then
- begin
- if Config.IsInteractive and (not DoInteractive) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_interactive_test+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_interactive_test+PPFileInfo[current]);
- Verbose(V_Warning,skipping_interactive_test);
- Res:=false;
- end;
- end;
- if Res then
- begin
- if Config.IsKnownCompileError and (not DoKnown) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
- Verbose(V_Warning,skipping_known_bug);
- Res:=false;
- end;
- end;
- if Res and not DoUsual then
- res:=(Config.IsInteractive and DoInteractive) or
- (Config.IsKnownRunError and DoKnown) or
- (Config.UsesGraph and DoGraph);
- if Res then
- begin
- if (Config.MinVersion<>'') and not DoAll then
- begin
- Verbose(V_Debug,'Required compiler version: '+Config.MinVersion);
- Res:=GetCompilerVersion;
- if CompilerVersion<Config.MinVersion then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_compiler_version_too_low+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler version too low '+CompilerVersion+' < '+Config.MinVersion);
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if (Config.MaxVersion<>'') and not DoAll then
- begin
- Verbose(V_Debug,'Highest compiler version: '+Config.MaxVersion);
- Res:=GetCompilerVersion;
- if CompilerVersion>Config.MaxVersion then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_compiler_version_too_high+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler version too high '+CompilerVersion+' > '+Config.MaxVersion);
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if Config.NeedCPU<>'' then
- begin
- Verbose(V_Debug,'Required compiler cpu: '+Config.NeedCPU);
- if not IsInList(CompilerCPU,Config.NeedCPU) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is not in list "'+Config.NeedCPU+'"');
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if Config.SkipCPU<>'' then
- begin
- Verbose(V_Debug,'Skip compiler cpu: '+Config.SkipCPU);
- if IsInList(CompilerCPU,Config.SkipCPU) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler cpu "'+CompilerCPU+'" is in list "'+Config.SkipCPU+'"');
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if Config.SkipEmu<>'' then
- begin
- Verbose(V_Debug,'Skip emulator: '+emulatorname);
- if IsInList(emulatorname,Config.SkipEmu) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_other_cpu+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_other_cpu+PPFileInfo[current]);
- Verbose(V_Warning,'Emulator "'+emulatorname+'" is in list "'+Config.SkipEmu+'"');
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if Config.NeedTarget<>'' then
- begin
- Verbose(V_Debug,'Required compiler target: '+Config.NeedTarget);
- if not IsInList(CompilerTarget,Config.NeedTarget) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is not in list "'+Config.NeedTarget+'"');
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- if Config.SkipTarget<>'' then
- begin
- Verbose(V_Debug,'Skip compiler target: '+Config.SkipTarget);
- if IsInList(CompilerTarget,Config.SkipTarget) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_other_target+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_other_target+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" is in list "'+Config.SkipTarget+'"');
- Res:=false;
- end;
- end;
- end;
- if Res then
- begin
- { Use known bug, to avoid adding a new entry for this PM 2011-06-24 }
- if Config.NeedLibrary and not TargetCanCompileLibraries then
- begin
- AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
- Verbose(V_Warning,'Compiler target "'+CompilerTarget+'" does not support library compilation');
- Res:=false;
- end;
- end;
- if Res then
- begin
- Res:=RunCompiler('');
- if Res and Config.NeedRecompile then
- Res:=RunCompiler(Config.RecompileOpt);
- end;
- if Res and (not Config.ShouldFail) then
- begin
- if (Config.NoRun) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_run_test+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_run_test+PPFileInfo[current]);
- Verbose(V_Debug,skipping_run_test);
- if LibraryExists(PPFile[current],LibraryName) then
- MaybeCopyFiles(LibraryName);
- end
- else if Config.IsKnownRunError and (not DoKnown) then
- begin
- { avoid a second attempt by writing to elg file }
- AddLog(EXELogFile,skipping_known_bug+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_known_bug+PPFileInfo[current]);
- Verbose(V_Warning,skipping_known_bug);
- end
- else
- begin
- if DoExecute then
- begin
- if FileExists(TestOutputFilename('',PPFile[current],'ppu')) or
- FileExists(TestOutputFilename('',PPFile[current],'ppo')) or
- FileExists(TestOutputFilename('',PPFile[current],'ppw')) then
- begin
- AddLog(ExeLogFile,skipping_run_unit+PPFileInfo[current]);
- AddLog(ResLogFile,skipping_run_unit+PPFileInfo[current]);
- Verbose(V_Debug,'Unit found, skipping run test')
- end
- else if LibraryExists(PPFile[current],LibraryName) then
- begin
- Verbose(V_Debug,'Library found, skipping run test');
- MaybeCopyFiles(LibraryName);
- end
- else
- Res:=RunExecutable;
- end;
- end;
- end;
- end;
- begin
- if GetEnvironmentVariable('TEST_THREADS')='1' then
- ForceTestThreads:=True;
- Current:=0;
- PPFile:=TStringList.Create;
- PPFile.Capacity:=10;
- PPFileInfo:=TStringList.Create;
- PPFileInfo.Capacity:=10;
- GetArgs;
- SetTargetDirectoriesStyle;
- SetTargetCanCompileLibraries;
- SetRemoteConfiguration;
- {$ifdef LIMIT83fs}
- UseOSOnly:=true;
- {$else not LIMIT83fs}
- SetUseOSOnly;
- {$endif not LIMIT83fs}
- Verbose(V_Debug,'Found '+ToStr(PPFile.Count)+' tests to run');
- if current>0 then
- for current:=0 to PPFile.Count-1 do
- begin
- SetPPFileInfo;
- TestName:=Copy(PPFile[current],1,Pos('.pp',PPFile[current])-1);
- Verbose(V_Normal,'Running test '+TestName+', file '+PPFile[current]);
- RunTest;
- end;
- PPFile.Free;
- PPFileInfo.Free;
- end.
|