diff options
-rwxr-xr-x | Make | bin | 1376992 -> 1672864 bytes | |||
-rw-r--r-- | Make.lpi | 20 | ||||
-rw-r--r-- | Make.lpr | 189 | ||||
-rw-r--r-- | Make.lps | 166 | ||||
-rw-r--r-- | tools.pas | 274 |
5 files changed, 445 insertions, 204 deletions
Binary files differ @@ -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"> @@ -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 @@ -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. + |