diff options
author | Erich Eckner <git@eckner.net> | 2015-07-06 12:22:47 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2015-07-06 12:22:47 +0200 |
commit | 863d06efa0eaf267d27a012edec2bd02e3077438 (patch) | |
tree | 99cf2820ad2e2040ca6f9f1278b111c2d7d574fe /tools.pas | |
parent | 99b99f8ca1967135221a5d4f24fbae073530e0ff (diff) | |
download | Make-863d06efa0eaf267d27a012edec2bd02e3077438.tar.xz |
Prüfung, ob gewisse Befehle ihre Ausgaben nicht außerhalb vom aktuellen Wurzelverzeichnis machen
Diffstat (limited to 'tools.pas')
-rw-r--r-- | tools.pas | 274 |
1 files changed, 274 insertions, 0 deletions
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. + |