summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2015-07-06 12:22:47 +0200
committerErich Eckner <git@eckner.net>2015-07-06 12:22:47 +0200
commit863d06efa0eaf267d27a012edec2bd02e3077438 (patch)
tree99cf2820ad2e2040ca6f9f1278b111c2d7d574fe
parent99b99f8ca1967135221a5d4f24fbae073530e0ff (diff)
downloadMake-863d06efa0eaf267d27a012edec2bd02e3077438.tar.xz
Prüfung, ob gewisse Befehle ihre Ausgaben nicht außerhalb vom aktuellen Wurzelverzeichnis machen
-rwxr-xr-xMakebin1376992 -> 1672864 bytes
-rw-r--r--Make.lpi20
-rw-r--r--Make.lpr189
-rw-r--r--Make.lps166
-rw-r--r--tools.pas274
5 files changed, 445 insertions, 204 deletions
diff --git a/Make b/Make
index 4bcd710..6c41c22 100755
--- a/Make
+++ b/Make
Binary files differ
diff --git a/Make.lpi b/Make.lpi
index 9c353cd..a98aa59 100644
--- a/Make.lpi
+++ b/Make.lpi
@@ -32,16 +32,25 @@
<LaunchingApplication PathPlusParams="/usr/bin/screen -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
- <Units Count="2">
+ <Units Count="4">
<Unit0>
<Filename Value="Make.lpr"/>
<IsPartOfProject Value="True"/>
- <UnitName Value="Make"/>
</Unit0>
<Unit1>
<Filename Value="Machdatei.txt"/>
<IsPartOfProject Value="True"/>
</Unit1>
+ <Unit2>
+ <Filename Value="tools.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="tools"/>
+ </Unit2>
+ <Unit3>
+ <Filename Value="../units/mystringlistunit.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="mystringlistunit"/>
+ </Unit3>
</Units>
</ProjectOptions>
<CompilerOptions>
@@ -51,6 +60,7 @@
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
+ <OtherUnitFiles Value="../units"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
@@ -68,12 +78,6 @@
</Win32>
</Options>
</Linking>
- <Other>
- <CompilerMessages>
- <MsgFileName Value=""/>
- </CompilerMessages>
- <CompilerPath Value="$(CompPath)"/>
- </Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
diff --git a/Make.lpr b/Make.lpr
index 6db584d..7e7f042 100644
--- a/Make.lpr
+++ b/Make.lpr
@@ -8,7 +8,7 @@ uses
{$ENDIF}{$ENDIF}
Classes, SysUtils, CustApp
{ you can add units after this },
- RegExpr, Math, Process;
+ RegExpr, Math, tools;
type
@@ -24,7 +24,6 @@ type
TAbhArt = (aaFinal,aaEinsZuEins,aaNZuN,aaIgnore);
TDateienMitDaten = array of ^TDateiMitDatum;
- tStringlistBArray = array[boolean] of tStringlist;
{ TAbhaengigkeit }
@@ -97,50 +96,6 @@ begin
inherited destroy;
end;
-function testeSummen(sumNam: string): tStringlistBArray;
-var p: tProcess;
- rb,i: longint;
- s: string;
- erg: tStringlist;
- gut: boolean;
-const leseHappen=65536;
-begin
- p:=tProcess.create(nil);
- p.Executable:='/usr/bin/sha512sum';
- p.Parameters.add('-c');
- p.Parameters.add(sumNam);
- p.Options:=p.Options + [poUsePipes];
- p.Execute;
- rb:=0;
- s:='';
- while p.Running do begin
- if p.Output.NumBytesAvailable=0 then sleep(10)
- else begin
- setlength(s,rb+leseHappen);
- rb:=rb+p.Output.Read(s[rb+1],leseHappen);
- end;
- end;
- if p.Output.NumBytesAvailable>0 then begin
- setlength(s,rb+leseHappen);
- rb:=rb+p.Output.Read(s[rb+1],leseHappen);
- end;
- p.free;
- setlength(s,rb);
- erg:=tStringlist.create;
- erg.text:=s;
- s:='';
- for gut:=false to true do begin
- result[gut]:=tStringlist.create;
- rb:=0;
- for i:=0 to erg.count-1 do
- if not gut xor (rightStr(erg[i],4)=': OK') then begin
- result[gut].add(leftStr(erg[i],pos(':',erg[i])-1));
- inc(rb);
- end;
- end;
- erg.free;
-end;
-
function liesZeile(var dat: textfile; out s: string): boolean;
begin
repeat
@@ -177,50 +132,6 @@ begin
FindClose(sr);
end;
-function anzCs(c: char; s: string): longint;
-var i: longint;
-begin
- result:=0;
- for i:=1 to length(s) do
- if s[i]=c then
- inc(result);
-end;
-
-function notQuotedPos(was,worin: string): longint;
-begin
- result:=0;
- repeat
- if pos(was,copy(worin,result+1,length(worin)-result))=0 then begin
- result:=0;
- exit;
- end;
- result:=result+pos(was,copy(worin,result+1,length(worin)-result));
- if not odd(anzCs('"',copy(worin,1,result-1))) then
- exit;
- until false;
-end;
-
-function unescapedpos(was,worin: string): integer;
-var Ebene: longint;
-begin
- result:=0;
- Ebene:=0;
- while pos(was,copy(worin,result+1,length(worin)))>0 do begin
- repeat
- result:=result+1;
- case worin[result] of
- '{': inc(Ebene);
- '}': dec(Ebene);
- end;
- until (result>=length(worin)) or ((copy(worin,result,length(was))=was) and (Ebene=0));
- if
- ((result=1) or ((worin[result-1]<>'\') and (worin[result-1]<>was))) and
- ((result=length(worin)) or (worin[result+1]<>was)) and
- (copy(worin,result,length(was))=was) then exit;
- end;
- result:=0;
-end;
-
function liesMakeFile(datNam: string; out Abh: TAbhaengigkeiten; out dats: TDateienMitDaten): boolean;
var f: textfile;
s,t: string;
@@ -360,6 +271,8 @@ begin
end;
end;
+ for gefunden:=false to true do
+ gutschlecht[gefunden].free;
result:=true;
end;
@@ -584,23 +497,24 @@ begin
mgl[length(mgl)-1]^.ZieleFkt.Text:=mgl[i]^.ZieleFkt.Text;
mgl[length(mgl)-1]^.Befehle.Text:=mgl[i]^.Befehle.Text;
end;
- for j:=0 to length(dats)-1 do if mgl[i]^.QuellenRE.Exec(dats[j]^.Name) then begin
- schonda:=false;
- for k:=0 to length(mgl[i]^.Erben[0]^.Quellen)-1 do
- schonda:=schonda or (mgl[i]^.Erben[0]^.Quellen[k]=dats[j]);
- if schonda then continue;
-
- SetLength(mgl[i]^.Erben[0]^.Quellen,length(mgl[i]^.Erben[0]^.Quellen)+1);
- mgl[i]^.Erben[0]^.Quellen[length(mgl[i]^.Erben[0]^.Quellen)-1]:=dats[j];
-
- for k:=0 to mgl[i]^.Befehle.Count-1 do begin
- s:=mgl[i]^.Befehle[k];
- if Quellersetzung(s,dats[j]^.Name,inputfile) then begin
- if k=0 then mgl[i]^.Erben[0]^.Befehle.Clear;
- mgl[i]^.Erben[0]^.Befehle.Add(s);
+ for j:=0 to length(dats)-1 do
+ if mgl[i]^.QuellenRE.Exec(dats[j]^.Name) then begin
+ schonda:=false;
+ for k:=0 to length(mgl[i]^.Erben[0]^.Quellen)-1 do
+ schonda:=schonda or (mgl[i]^.Erben[0]^.Quellen[k]=dats[j]);
+ if schonda then continue;
+
+ SetLength(mgl[i]^.Erben[0]^.Quellen,length(mgl[i]^.Erben[0]^.Quellen)+1);
+ mgl[i]^.Erben[0]^.Quellen[length(mgl[i]^.Erben[0]^.Quellen)-1]:=dats[j];
+
+ for k:=0 to mgl[i]^.Befehle.Count-1 do begin
+ s:=mgl[i]^.Befehle[k];
+ if Quellersetzung(s,dats[j]^.Name,inputfile) then begin
+ if k=0 then mgl[i]^.Erben[0]^.Befehle.Clear;
+ mgl[i]^.Erben[0]^.Befehle.Add(s);
+ end;
end;
end;
- end;
end;
aaEinsZuEins: begin // jede Quelle muss einzeln behandelt werden
for j:=0 to length(dats)-1 do
@@ -609,7 +523,9 @@ begin
for k:=0 to length(mgl[i]^.Erben)-1 do
for l:=0 to length(mgl[i]^.Erben[k]^.Quellen)-1 do
schonda:=schonda or (mgl[i]^.Erben[k]^.Quellen[l]=dats[j]);
+
if schonda then continue;
+
SetLength(mgl,length(mgl)+1);
getmem(mgl[length(mgl)-1],sizeof(TAbhaengigkeit));
fillchar(mgl[length(mgl)-1]^,sizeof(TAbhaengigkeiten),0);
@@ -619,7 +535,8 @@ begin
mgl[length(mgl)-1]^.AbhArt:=aaFinal;
SetLength(mgl[length(mgl)-1]^.Quellen,1);
mgl[length(mgl)-1]^.Quellen[0]:=dats[j];
- findeZiele(mgl[length(mgl)-1]^.Ziele,mgl[i]^.ZieleFkt,dats[j]^.name,inputfile,dats);
+ mgl[length(mgl)-1]^.ZieleFkt:=mgl[i]^.ZieleFkt;
+// findeZiele(mgl[length(mgl)-1]^.Ziele,mgl[i]^.ZieleFkt,dats[j]^.name,inputfile,dats); // sollte unten geschehen
mgl[length(mgl)-1]^.Befehle.Clear;
for k:=0 to mgl[i]^.Befehle.Count-1 do begin
s:=mgl[i]^.Befehle[k];
@@ -627,32 +544,32 @@ begin
mgl[length(mgl)-1]^.Befehle.Add(s);
end;
if mgl[length(mgl)-1]^.Befehle.Count=0 then begin
- writeln('Keine Befehle für diese Abhängigkeit auszuführen!');
+ writeln('Fehler: Keine Befehle für diese Abhängigkeit auszuführen!');
halt;
end;
mgl[length(mgl)-1]^.Prioritaet:=mgl[i]^.Prioritaet;
end;
end;
- aaFinal: if length(mgl[i]^.Erben)=0 then begin // Quellen stehen schon fest, noch nicht auszuführen
- if length(mgl[i]^.Quellen)=0 then begin
- inc(i);
- continue;
- end;
- quNeu:=mgl[i]^.Quellen[0]^.Datum;
- for j:=1 to length(mgl[i]^.Quellen)-1 do
- quNeu:=max(quNeu,mgl[i]^.Quellen[j]^.Datum);
+ aaFinal: if (length(mgl[i]^.Erben)=0) and
+ (length(mgl[i]^.Quellen)<>0) then begin // Quellen stehen schon fest, noch nicht auszuführen
if length(mgl[i]^.Ziele)=0 then begin
for j:=0 to length(mgl[i]^.Quellen)-1 do
findeMehrZiele(mgl[i]^.Ziele,mgl[i]^.ZieleFkt,mgl[i]^.Quellen[j]^.Name,inputfile,dats);
- if length(mgl[i]^.Ziele)=0 then begin
+ if length(mgl[i]^.Ziele)=0 then begin // immer noch keine Ziele
+ writeln('Warnung: Keine Ziele für diese Abhängigkeit!');
mgl[i]^.AbhArt:=aaIgnore;
continue;
end;
end;
+ quNeu:=mgl[i]^.Quellen[0]^.Datum;
+ for j:=1 to length(mgl[i]^.Quellen)-1 do // neueste Quelle ermitteln
+ quNeu:=max(quNeu,mgl[i]^.Quellen[j]^.Datum);
ziAlt:=mgl[i]^.Ziele[0]^.Datum;
- for j:=1 to length(mgl[i]^.Ziele)-1 do
+ for j:=1 to length(mgl[i]^.Ziele)-1 do // ältestes Ziel ermitteln
ziAlt:=min(ziAlt,mgl[i]^.Ziele[j]^.Datum);
+
if ziAlt<quNeu then begin
+ writeln(ziAlt,' ',quNeu,' ',jetzt,' ',mgl[i]^.Ziele[0]^.Name,' ',length(mgl[i]^.Ziele),' -> ',mgl[i]^.Befehle.text);
SetLength(zuTun,length(zuTun)+1);
getmem(zuTun[length(zuTun)-1],sizeof(TAbhaengigkeit));
fillchar(zuTun[length(zuTun)-1]^,sizeof(TAbhaengigkeit),0);
@@ -671,11 +588,13 @@ begin
until not neues;
end;
-procedure tueWasZuTunIst(alles,zuTun: TAbhaengigkeiten; nurAnzeigen, allesNeu: boolean; Ausgabedatei,Summendatei: string);
+procedure tueWasZuTunIst(alles,zuTun: TAbhaengigkeiten; var dats: TDateienMitDaten; nurAnzeigen, allesNeu, unsicher: boolean; Ausgabedatei,Summendatei: string);
var Prior,i,j: integer;
Ausg: Textfile;
- Befehle,geaenderteDateien,alteDateien: TStringlist;
- ms: boolean;
+ Befehle,geaenderteDateien,
+ alteDateien,sumDateien: TStringlist;
+ ms,gefunden: boolean;
+ lokTest: tRegExpr;
begin
Befehle:=TStringlist.create;
Prior:=0;
@@ -684,6 +603,19 @@ begin
Prior:=max(Prior,zuTun[i]^.Prioritaet);
if ms then begin
geaenderteDateien:=TStringlist.create;
+ sumDateien:=dateienMitGueltigerSumme(Summendatei);
+ for i:=0 to length(dats)-1 do begin
+ gefunden:=(dats[i]^.name=Summendatei) or (dats[i]^.name=Ausgabedatei);
+ for j:=0 to sumDateien.count-1 do
+ if sumDateien[j]=dats[i]^.name then begin
+ gefunden:=true;
+ sumDateien.delete(j);
+ break;
+ end;
+ if not gefunden then
+ geaenderteDateien.add(dats[i]^.name);
+ end;
+ sumDateien.free;
if allesNeu then
for i:=0 to length(alles)-1 do begin
for j:=0 to length(alles[i]^.Ziele)-1 do
@@ -705,6 +637,16 @@ begin
Befehle.Add(zuTun[i]^.Befehle[j]);
dec(Prior);
end;
+ if not unsicher then begin
+ lokTest:=tRegExpr.create;
+ if extractfilepath(Ausgabedatei)=extractfilepath(Summendatei) then
+ lokTest.Expression:='^'+extractfilepath(Ausgabedatei)+'/'
+ else
+ lokTest.Expression:='^('+extractfilepath(Ausgabedatei)+'|'+extractfilepath(Summendatei)+')/';
+ for i:=0 to Befehle.count-1 do
+ testeObBefehlLokal(Befehle[i],extractfiledir(Ausgabedatei),lokTest);
+ lokTest.free;
+ end;
if ms then begin
for i:=geaenderteDateien.count-1 downto 0 do begin
if geaenderteDateien[i]='.uralt.' then begin
@@ -739,7 +681,6 @@ begin
if length(zuTun)=0 then
Befehle.Add('echo "Es gibt hier nichts zu tun!"');
- Befehle.Add('sleep 2');
if nurAnzeigen then begin
writeln('Befehle:');
for i:=0 to Befehle.Count-1 do
@@ -765,7 +706,7 @@ var
mglAbhaengigkeiten,zutunAbhaengigkeiten: TAbhaengigkeiten;
Dateien: TDateienMitDaten;
begin
- ErrorMsg:=CheckOptions('A:HWD:P:a','Ausgabe: Hilfe Watte Datei: Prüfsummen: alleSummenErneuern');
+ ErrorMsg:=CheckOptions('A:HWD:P:au','Ausgabe: Hilfe Watte Datei: Prüfsummen: alleSummenErneuern unsicher');
if ErrorMsg<>'' then begin
ShowException(Exception.Create(ErrorMsg+#10'Hilfe: '+Exename+' -H/--Hilfe'));
Terminate;
@@ -819,7 +760,7 @@ begin
writeln('Regeln: '+inttostr(length(mglAbhaengigkeiten))+', Dateien: '+inttostr(length(Dateien)));
findeWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,Dateien,inputfile,now);
writeln('anzuwendende Regeln: '+inttostr(length(zuTunAbhaengigkeiten)));
- tueWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,HasOption('W','Watte'),HasOption('a','alleSummenErneuern'),GetOptionValue('A','Ausgabe'),pruefsummenfile);
+ tueWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,Dateien,HasOption('W','Watte'),HasOption('a','alleSummenErneuern'),HasOption('u','unsicher'),GetOptionValue('A','Ausgabe'),pruefsummenfile);
Terminate;
end;
@@ -833,7 +774,7 @@ end;
procedure TMake.WriteHelp;
begin
writeln('Verwendung:');
- writeln(' ',ExeName,' -A/--Ausgabe $Ausgabedatei -H/--Hilfe -W/--Watte -D/--Datei $Machdatei -P/--Prüfsummen $Prüfsummendatei -a/--alleSummenErneuern');
+ writeln(' ',ExeName,' -A/--Ausgabe $Ausgabedatei -H/--Hilfe -W/--Watte -D/--Datei $Machdatei -P/--Prüfsummen $Prüfsummendatei -a/--alleSummenErneuern -u/--unsicher');
end;
var
diff --git a/Make.lps b/Make.lps
index 78994fb..5d4fb07 100644
--- a/Make.lps
+++ b/Make.lps
@@ -3,163 +3,185 @@
<ProjectSession>
<Version Value="9"/>
<BuildModes Active="Default"/>
- <Units Count="3">
+ <Units Count="7">
<Unit0>
<Filename Value="Make.lpr"/>
<IsPartOfProject Value="True"/>
- <UnitName Value="Make"/>
- <IsVisibleTab Value="True"/>
- <EditorIndex Value="0"/>
- <WindowIndex Value="0"/>
- <TopLine Value="190"/>
- <CursorPos X="7" Y="219"/>
- <FoldState Value=" T3oD0n3 pjLkZ0B4 pl2lN0{3n"/>
- <UsageCount Value="32"/>
+ <TopLine Value="617"/>
+ <CursorPos X="29" Y="643"/>
+ <FoldState Value=" T3i70C5 pkMl30p3 pjLkb0B413 T0z704("/>
+ <UsageCount Value="46"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Machdatei.txt"/>
<IsPartOfProject Value="True"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
- <CursorPos X="1" Y="1"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="46"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit1>
<Unit2>
+ <Filename Value="tools.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="tools"/>
+ <IsVisibleTab Value="True"/>
+ <EditorIndex Value="1"/>
+ <TopLine Value="53"/>
+ <CursorPos X="79" Y="84"/>
+ <FoldState Value=" T3T07213x"/>
+ <UsageCount Value="25"/>
+ <Loaded Value="True"/>
+ </Unit2>
+ <Unit3>
<Filename Value="Machdatei"/>
- <WindowIndex Value="0"/>
- <TopLine Value="1"/>
<CursorPos X="45" Y="17"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
<DefaultSyntaxHighlighter Value="None"/>
- </Unit2>
+ </Unit3>
+ <Unit4>
+ <Filename Value="../Stabile/lowlevelunit.pas"/>
+ <UnitName Value="lowlevelunit"/>
+ <EditorIndex Value="-1"/>
+ <CursorPos X="26" Y="23"/>
+ <UsageCount Value="10"/>
+ </Unit4>
+ <Unit5>
+ <Filename Value="../units/mystringlistunit.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="mystringlistunit"/>
+ <EditorIndex Value="-1"/>
+ <CursorPos X="10" Y="11"/>
+ <UsageCount Value="22"/>
+ </Unit5>
+ <Unit6>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <UnitName Value="lowlevelunit"/>
+ <EditorIndex Value="2"/>
+ <CursorPos X="15" Y="265"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
+ </Unit6>
</Units>
- <General>
- <ActiveWindowIndexAtStart Value="0"/>
- </General>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
- <Filename Value="Make.lpr"/>
- <Caret Line="635" Column="1" TopLine="633"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="73" Column="41" TopLine="14"/>
</Position1>
<Position2>
- <Filename Value="Make.lpr"/>
- <Caret Line="611" Column="1" TopLine="590"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="78" Column="72" TopLine="52"/>
</Position2>
<Position3>
- <Filename Value="Make.lpr"/>
- <Caret Line="638" Column="50" TopLine="627"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="86" Column="18" TopLine="52"/>
</Position3>
<Position4>
- <Filename Value="Make.lpr"/>
- <Caret Line="22" Column="1" TopLine="22"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="89" Column="41" TopLine="52"/>
</Position4>
<Position5>
- <Filename Value="Make.lpr"/>
- <Caret Line="638" Column="12" TopLine="619"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="106" Column="14" TopLine="76"/>
</Position5>
<Position6>
- <Filename Value="Make.lpr"/>
- <Caret Line="751" Column="35" TopLine="733"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="95" Column="12" TopLine="75"/>
</Position6>
<Position7>
<Filename Value="Make.lpr"/>
- <Caret Line="205" Column="29" TopLine="183"/>
+ <Caret Line="135" TopLine="48"/>
</Position7>
<Position8>
- <Filename Value="Make.lpr"/>
- <Caret Line="294" Column="44" TopLine="276"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="8" Column="43"/>
</Position8>
<Position9>
- <Filename Value="Make.lpr"/>
- <Caret Line="317" Column="42" TopLine="305"/>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <Caret Line="178" Column="3" TopLine="259"/>
</Position9>
<Position10>
- <Filename Value="Make.lpr"/>
- <Caret Line="311" Column="3" TopLine="289"/>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <Caret Line="40" TopLine="22"/>
</Position10>
<Position11>
- <Filename Value="Make.lpr"/>
- <Caret Line="317" Column="43" TopLine="297"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="8" Column="35"/>
</Position11>
<Position12>
- <Filename Value="Make.lpr"/>
- <Caret Line="327" Column="1" TopLine="304"/>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <Caret Line="255" Column="47" TopLine="241"/>
</Position12>
<Position13>
- <Filename Value="Make.lpr"/>
- <Caret Line="334" Column="1" TopLine="306"/>
+ <Filename Value="../units/lowlevelunit.pas"/>
+ <Caret Line="43" Column="34" TopLine="20"/>
</Position13>
<Position14>
<Filename Value="Make.lpr"/>
- <Caret Line="210" Column="18" TopLine="200"/>
+ <Caret Line="641" Column="64" TopLine="606"/>
</Position14>
<Position15>
- <Filename Value="Make.lpr"/>
- <Caret Line="771" Column="61" TopLine="751"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="134" Column="14" TopLine="100"/>
</Position15>
<Position16>
- <Filename Value="Make.lpr"/>
- <Caret Line="312" Column="1" TopLine="293"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="125" Column="3" TopLine="105"/>
</Position16>
<Position17>
- <Filename Value="Make.lpr"/>
- <Caret Line="99" Column="55" TopLine="95"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="126" Column="33" TopLine="102"/>
</Position17>
<Position18>
- <Filename Value="Make.lpr"/>
- <Caret Line="27" Column="53" TopLine="1"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="153" Column="21" TopLine="19"/>
</Position18>
<Position19>
- <Filename Value="Make.lpr"/>
- <Caret Line="303" Column="36" TopLine="288"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="79" Column="24" TopLine="53"/>
</Position19>
<Position20>
- <Filename Value="Make.lpr"/>
- <Caret Line="143" Column="1" TopLine="107"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="8" Column="52"/>
</Position20>
<Position21>
- <Filename Value="Make.lpr"/>
- <Caret Line="136" Column="59" TopLine="115"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="163" Column="21" TopLine="136"/>
</Position21>
<Position22>
- <Filename Value="Make.lpr"/>
- <Caret Line="326" Column="35" TopLine="312"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="79" Column="26" TopLine="20"/>
</Position22>
<Position23>
- <Filename Value="Make.lpr"/>
- <Caret Line="347" Column="47" TopLine="317"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="20" Column="51"/>
</Position23>
<Position24>
<Filename Value="Make.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Caret Line="11" Column="23"/>
</Position24>
<Position25>
<Filename Value="Make.lpr"/>
- <Caret Line="612" Column="115" TopLine="592"/>
+ <Caret Line="641" Column="73" TopLine="621"/>
</Position25>
<Position26>
<Filename Value="Make.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Caret Line="111" Column="21" TopLine="65"/>
</Position26>
<Position27>
<Filename Value="Make.lpr"/>
- <Caret Line="287" Column="1" TopLine="239"/>
+ <Caret Line="590" Column="16" TopLine="51"/>
</Position27>
<Position28>
<Filename Value="Make.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Caret Line="111" Column="24" TopLine="51"/>
</Position28>
<Position29>
<Filename Value="Make.lpr"/>
- <Caret Line="205" Column="39" TopLine="195"/>
+ <Caret Line="134" Column="6" TopLine="51"/>
</Position29>
<Position30>
<Filename Value="Make.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Caret Line="642" Column="91" TopLine="615"/>
</Position30>
</JumpHistory>
</ProjectSession>
- <EditorMacros Count="0"/>
</CONFIG>
diff --git a/tools.pas b/tools.pas
new file mode 100644
index 0000000..0a6feb1
--- /dev/null
+++ b/tools.pas
@@ -0,0 +1,274 @@
+unit tools;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Process, lowlevelunit, regExpr;
+
+type
+ tStringlistBArray = array[boolean] of tStringlist;
+ tSummenDatei = record
+ name: string;
+ inhalt: tStringlistBArray;
+ end;
+
+function anzCs(c: char; s: string): longint;
+function notQuotedPos(was,worin: string): longint;
+function unescapedpos(was,worin: string): integer;
+procedure testeObBefehlLokal(bef, ordner: string; lokTest: tRegExpr);
+function extrahiereAlleDateien(woraus: string): tMyStringList;
+
+// Routinen für sha512-Prüfsummen
+
+function testeSummen(sumNam: string): tStringlistBArray;
+function dateienMitGueltigerSumme(sumNam: string): tStringList;
+
+implementation
+
+function anzCs(c: char; s: string): longint;
+var i: longint;
+begin
+ result:=0;
+ for i:=1 to length(s) do
+ if s[i]=c then
+ inc(result);
+end;
+
+function notQuotedPos(was,worin: string): longint;
+begin
+ result:=0;
+ repeat
+ if pos(was,copy(worin,result+1,length(worin)-result))=0 then begin
+ result:=0;
+ exit;
+ end;
+ result:=result+pos(was,copy(worin,result+1,length(worin)-result));
+ if not odd(anzCs('"',copy(worin,1,result-1))) then
+ exit;
+ until false;
+end;
+
+function unescapedpos(was,worin: string): integer;
+var Ebene: longint;
+begin
+ result:=0;
+ Ebene:=0;
+ while pos(was,copy(worin,result+1,length(worin)))>0 do begin
+ repeat
+ result:=result+1;
+ case worin[result] of
+ '{': inc(Ebene);
+ '}': dec(Ebene);
+ end;
+ until (result>=length(worin)) or ((copy(worin,result,length(was))=was) and (Ebene=0));
+ if
+ ((result=1) or ((worin[result-1]<>'\') and (worin[result-1]<>was))) and
+ ((result=length(worin)) or (worin[result+1]<>was)) and
+ (copy(worin,result,length(was))=was) then exit;
+ end;
+ result:=0;
+end;
+
+procedure testeObBefehlLokal(bef, ordner: string; lokTest: tRegExpr);
+var
+ exe,args,regex,oBef,s: string;
+ dateien,sl,relZeil: tMyStringlist;
+ i,j: longint;
+ re: tRegExpr;
+begin
+ oBef:=bef;
+
+ while notQuotedPos(';',bef)>0 do begin
+ testeObBefehlLokal(trim(leftStr(bef,notQuotedPos(';',bef))),ordner,lokTest);
+ delete(bef,1,notQuotedPos(';',bef));
+ bef:=trim(bef);
+ end;
+
+ args:='';
+ repeat
+ exe:=leftstr(bef,notQuotedPos(' ',bef)-1);
+ delete(bef,1,length(exe));
+ if exe='cat' then begin
+ args:=args+' '+trim(leftStr(bef,notQuotedPos('|',bef)-1));
+ delete(bef,1,notQuotedPos('|',bef));
+ end;
+ bef:=trim(bef);
+ until (notQuotedPos('=',bef)=0) and (exe<>'do') and (exe<>'cat');
+
+ delete(args,1,1);
+ exe:=extractfilename(exe);
+
+ if exe='gnuplot' then begin
+ // set output "~/Dokumente/Erich_Masterarbeit/Bilder/gnuplot/Energiescan.tex"
+ regex:='^ *set +output +';
+ re:=tRegExpr.create;
+ re.Expression:='"[^"]*/[^"]*"';
+ end
+ else if exe='epost' then begin
+ // Datei:
+ regex:='^ *(Datei|Legende): *';
+ re:=tRegExpr.create;
+ re.Expression:='[^ :]*/[^ ]*';
+ end
+ else if exe='math' then begin
+ // das wird vmtl. schwer zu überprüfen, außer man nimmt Muster,
+ // die generisch auf Pfade passen, aber dann erwischt man auch den Input mit ...
+ regex:='^([^"]*"[^"]*")*[^"]*"([^"]*/)+[^"]*"';
+ re:=tRegExpr.create;
+ re.Expression:='"[^"]*/[^"]*"';
+ end
+ else exit;
+
+ // folgende Executables sind unkritisch, da der Name des Outputs i.d.R. direkt
+ // vom Namen des Inputs abhängt bzw. per Kommandozeilenparameter übergeben
+ // wird (und nicht in einer Datei steht):
+ //
+ // 'convert'
+ // 'epstopdf'
+ // 'latexmk'
+ // 'mpost'
+ // 'pdflatex'
+
+ dateien:=extrahiereAlleDateien(args+' '+bef);
+ if dateien.count = 0 then
+ writeln('*** Warnung: Hier ist ein Befehl ohne offensichtliche input-Dateien! ('''+oBef+''')!');
+
+ sl:=tMyStringlist.create;
+ relZeil:=tMyStringlist.create;
+ for i:=0 to dateien.count-1 do begin
+ sl.loadFromFile(dateien[i]);
+ sl.grep(regex);
+ relZeil.addStrings(sl);
+ end;
+ sl.free;
+ dateien.free;
+
+ for i:=0 to relZeil.count-1 do begin
+ re.InputString:=relZeil[i];
+ if re.SubExprMatchCount=0 then
+ writeln('*** Warnung: Hier ist eine Zeile in der Optionsdatei, die keine passende Inputdatei benennt, es aber sollte! ('''+relZeil[i]+''')!');
+ for j:=0 to re.SubExprMatchCount-1 do begin
+ s:=trim(re.Match[j]);
+ if (leftStr(s,1)='"') and (rightStr(s,1)='"') then begin
+ delete(s,1,1);
+ delete(s,length(s),1);
+ end;
+ if not lokTest.Exec(s) then begin
+ writeln('*** FEHLER: '''+relZeil[i]+''' in Befehl '''+oBef+''' hat Lokalitätstest nicht bestanden! ('+lokTest.Expression+')');
+ halt(1);
+ end;
+ end;
+ end;
+ re.free;
+ relZeil.free;
+end;
+
+function extrahiereAlleDateien(woraus: string): tMyStringList;
+var
+ s: string;
+begin
+ result:=tMyStringlist.create;
+ woraus:=woraus+' ';
+ while notQuotedPos(' ',woraus)>0 do begin
+ s:=leftStr(woraus,notQuotedPos(' ',woraus));
+ delete(woraus,1,length(s));
+ s:=trim(s);
+ if fileexists(s) then
+ result.add(s);
+ end;
+end;
+
+// Routinen für sha512-Prüfsummen
+
+var
+ Summenvorrat: array of tSummenDatei;
+
+function testeSummen(sumNam: string): tStringlistBArray;
+var p: tProcess;
+ rb,i: longint;
+ s: string;
+ erg: tStringlist;
+ gut: boolean;
+const leseHappen=65536;
+begin
+ for i:=0 to length(Summenvorrat)-1 do
+ if Summenvorrat[i].name=sumNam then begin
+ for gut:=false to true do begin
+ result[gut]:=tStringlist.create;
+ result[gut].text:=Summenvorrat[i].inhalt[gut].text;
+ end;
+ exit;
+ end;
+
+ p:=tProcess.create(nil);
+ p.Executable:='/usr/bin/sha512sum';
+ p.Parameters.add('-c');
+ p.Parameters.add(sumNam);
+ p.Options:=p.Options + [poUsePipes];
+ p.Execute;
+ rb:=0;
+ s:='';
+ while p.Running do begin
+ if p.Output.NumBytesAvailable=0 then sleep(10)
+ else begin
+ setlength(s,rb+leseHappen);
+ rb:=rb+p.Output.Read(s[rb+1],leseHappen);
+ end;
+ end;
+ if p.Output.NumBytesAvailable>0 then begin
+ setlength(s,rb+leseHappen);
+ rb:=rb+p.Output.Read(s[rb+1],leseHappen);
+ end;
+ p.free;
+ setlength(s,rb);
+ erg:=tStringlist.create;
+ erg.text:=s;
+ s:='';
+ for gut:=false to true do begin
+ result[gut]:=tStringlist.create;
+ rb:=0;
+ for i:=0 to erg.count-1 do
+ if not gut xor (rightStr(erg[i],4)=': OK') then begin
+ result[gut].add(leftStr(erg[i],pos(':',erg[i])-1));
+ inc(rb);
+ end;
+ end;
+ erg.free;
+
+ setlength(Summenvorrat,length(Summenvorrat)+1);
+ with Summenvorrat[length(Summenvorrat)-1] do begin
+ name:=sumNam;
+ for gut:=false to true do begin
+ inhalt[gut]:=tStringlist.create;
+ inhalt[gut].text:=result[gut].text;
+ end;
+ end;
+end;
+
+function dateienMitGueltigerSumme(sumNam: string): tStringList;
+var
+ sums: tStringlistBArray;
+begin
+ sums:=testeSummen(sumNam);
+ result:=sums[true];
+ sums[false].free;
+end;
+
+var
+ i: longint;
+
+initialization
+ setlength(Summenvorrat,0);
+
+finalization
+ for i:=0 to length(Summenvorrat)-1 do
+ with Summenvorrat[i] do begin
+ name:='';
+ inhalt[false].free;
+ inhalt[true].free;
+ end;
+ setlength(Summenvorrat,0);
+end.
+