From 394e27efc7906ec40f960d23095dc5aebee84fd6 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Tue, 10 May 2016 11:31:40 +0200 Subject: alles schön in Klassen gepackt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Make.lpr | 426 ++---------------------------- Make.lps | 171 +++++++----- dateibeziehungen.pas | 734 ++++++++++++++++++++++++++++++++++++++++++--------- tools.pas | 13 +- 4 files changed, 739 insertions(+), 605 deletions(-) diff --git a/Make.lpr b/Make.lpr index 7ebbfa9..38da651 100644 --- a/Make.lpr +++ b/Make.lpr @@ -8,7 +8,7 @@ uses {$ENDIF}{$ENDIF} classes, sysUtils, custApp { you can add units after this }, - math, tools, lowlevelunit, dateiBeziehungen, regExpr; + lowlevelunit, dateiBeziehungen, systemunit; type @@ -21,418 +21,35 @@ type constructor create(theOwner: tComponent); override; end; -function liesPruefsummenfile(sumNam: string; var dats: tDateienMitDaten): boolean; -var - f: textfile; - i,j: longint; - gutschlecht: tStringlistBArray; - gefunden,gut: boolean; -begin - result:=false; - if sumNam='' then begin - writeln('Leerer Name als summendatei angegeben!'); - exit; - end; - - if not fileexists(sumNam) then begin - assignfile(f,sumNam); - rewrite(f); - closefile(f); - end; - if not fileexists(sumNam) then begin - writeln('Ich bin nicht in der Lage, die bisher nicht existierende Datei '''+sumNam+''' anzulegen!'); - exit; - end; - - gutschlecht:=testeSummen(sumNam); - - for gut:=false to true do - for i:=0 to gutschlecht[gut].count-1 do begin - gefunden:=false; - for j:=0 to length(dats)-1 do - if dats[j].name=gutschlecht[gut][i] then begin - if gut then - dats[j].aktuell:=aAktuell - else - dats[j].aktuell:=aVeraltet; - gefunden:=true; - break; - end; - if not gefunden then begin - if not gut then begin // dateien mit ungültiger Prüfsumme können auch nicht vorhanden sein, - setlength(dats,length(dats)+1); // dann werden sie einfach eingefügt - dats[length(dats)-1]:=tDateiMitDatum.create; - dats[length(dats)-1].name:=gutschlecht[gut][i]; - dats[length(dats)-1].aktuell:=aVeraltet; - continue; - end; - writeln('In der Summendatei gibt es eine Datei mit gültiger Prüfsumme, die ich nicht finden kann: '''+gutschlecht[gut][i]+'''!'); - for gefunden:=false to true do - gutschlecht[gefunden].free; - exit; - end; - end; - - for gefunden:=false to true do - gutschlecht[gefunden].free; - result:=true; -end; - -procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle,inputfile: string; var dats: tDateienMitDaten); -var - i,ebene,ende: integer; - s,t,u: string; - wasda: boolean; -begin - if pos('{',ziel)=0 then begin - if not quellersetzung(ziel,quelle,inputfile) then exit; - ziel:=unescape(ziel); - i:=0; - wasda:=false; - while i0) or (ziel[ende]<>'}') do begin - inc(ende); - case ziel[ende] of - '{': inc(ebene); - '}': dec(ebene); - end{of case}; - end; - s:=copy(ziel,1,pos('{',ziel)-1); - t:=copy(ziel,pos('{',ziel)+1,ende-pos('{',ziel)-1); - u:=copy(ziel,ende+1,length(ziel)); - if unescapedpos('..',t)>0 then begin - for i:=strtoint(copy(t,1,unescapedpos('..',t)-1)) to strtoint(copy(t,unescapedpos('..',t)+2,length(t))) do - zieleHinzufuegen(ziele,s+inttostr(i)+u,quelle,inputfile,dats); - end - else begin - t:=t+','; - while unescapedpos(',',t)>0 do begin - zieleHinzufuegen(ziele,s+copy(t,1,unescapedpos(',',t)-1)+u,quelle,inputfile,dats); - delete(t,1,unescapedpos(',',t)); - end; - end; - end; -end; - -procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); -var - i: integer; -begin - for i:=0 to zieleFkt.count-1 do - zieleHinzufuegen(ziele,zieleFkt[i],quelle,inputfile,dats); -end; - -procedure findeWasZuTunIst(var mgl: tAbhaengigkeiten; out zuTun: tAbhaengigkeiten; var dats: tDateienMitDaten; inputfile: string); -var - i,j,k,l: integer; - neues,schonDa: boolean; - s: string; - tmpZiele: tDateienMitDaten; - ziA,quA: tAktualitaet; -begin - setlength(zuTun,0); - repeat - neues:=false; - i:=0; - while i0) then begin // quellen stehen schon fest, noch nicht auszuführen - 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 // immer noch keine ziele - writeln('Warnung: Keine ziele für diese Abhängigkeit!'); - writeln('quellen:'); - for k:=0 to length(mgl[i].quellen)-1 do - writeln(' '''+mgl[i].quellen[k].name+''''); - writeln('zieleFkt:'); - for k:=0 to mgl[i].zieleFkt.count-1 do - writeln(' '''+mgl[i].zieleFkt[k]+''''); - writeln(' - wird fortan ignoriert.'); - mgl[i].abhArt:=aaIgnore; - continue; - end; - - quA:=aAktuell; - for j:=0 to length(mgl[i].quellen)-1 do - if mgl[i].quellen[j].aktuell<>aAktuell then - quA:=aWirdErneuert; - ziA:=aWirdErneuert; - for j:=0 to length(mgl[i].ziele)-1 do - ziA:=min(ziA,mgl[i].ziele[j].aktuell); - - if ziA ',mgl[i].befehle.text); - setlength(zuTun,length(zuTun)+1); - zuTun[length(zuTun)-1]:=tAbhaengigkeit.create(mgl[i]); - setlength(mgl[i].erben,1); - mgl[i].erben[0]:=zuTun[length(zuTun)-1]; - for j:=0 to length(mgl[i].ziele)-1 do - mgl[i].ziele[j].aktuell:=aWirdErneuert; - neues:=true; - end; - end; - aaIgnore: ; // keine ziele - end{of case}; - inc(i); - end; - until not neues; -end; - -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,sumDateien: tStringlist; - ms,gefunden: boolean; - lokTest: tRegExpr; -begin - befehle:=tStringlist.create; - prior:=0; - ms:=summendatei<>''; - for i:=0 to length(zuTun)-1 do - 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 - geaenderteDateien.add(alles[i].ziele[j].name); - for j:=0 to length(alles[i].quellen)-1 do - geaenderteDateien.add(alles[i].quellen[j].name); - end; - for i:=0 to length(zuTun)-1 do begin - for j:=0 to length(zuTun[i].ziele)-1 do - geaenderteDateien.add(zuTun[i].ziele[j].name); - for j:=0 to length(zuTun[i].quellen)-1 do - geaenderteDateien.add(zuTun[i].quellen[j].name); - end; - end; - while prior>=0 do begin - for i:=0 to length(zuTun)-1 do - if zuTun[i].prioritaet=prior then - for j:=0 to zuTun[i].befehle.count-1 do - 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 - geaenderteDateien.delete(i); - continue; - end; - for j:=0 to i-1 do - if geaenderteDateien[i]=geaenderteDateien[j] then begin - geaenderteDateien.delete(i); - break; - end; - end; - if geaenderteDateien.count>0 then - befehle.add('echo -ne "Sha512summen erneuern ..."'); - for i:=0 to geaenderteDateien.count-1 do - befehle.add('/usr/bin/sha512sum "'+geaenderteDateien[i]+'" >> '+summendatei); - if geaenderteDateien.count>0 then - befehle.add('echo " fertig"'); - if not nurAnzeigen then begin - alteDateien:=tStringlist.create; - alteDateien.loadFromFile(summendatei); - for i:=alteDateien.count-1 downto 0 do - for j:=0 to geaenderteDateien.count-1 do - if trim(copy(alteDateien[i],pos(' ',alteDateien[i]),length(alteDateien[i])))=geaenderteDateien[j] then begin - alteDateien.delete(i); - break; - end; - alteDateien.saveToFile(summendatei); - alteDateien.free; - end; - end; - - if length(zuTun)=0 then - befehle.add('echo "Es gibt hier nichts zu tun!"'); - if nurAnzeigen then begin - writeln('befehle:'); - for i:=0 to befehle.count-1 do - writeln(befehle[i]); - end - else begin - assignFile(ausg,ausgabedatei); - rewrite(ausg); - for i:=0 to befehle.count-1 do - writeln(ausg,'('+befehle[i]+') || (read -p "Ein Fehler ist aufgetreten! ... "; exit 1)'); - closeFile(ausg); - end; - befehle.free; - if ms then - geaenderteDateien.free; -end; - { tMake } procedure tMake.doRun; var - inputfile,pruefsummenfile,errorMsg: string; - mglAbhaengigkeiten,zutunAbhaengigkeiten: tAbhaengigkeiten; - dateien: tDateienMitDaten; + mach: tMach; + errorMsg: string; begin - errorMsg:=checkOptions('A:WD:P:au','Ausgabe: Watte Datei: Prüfsummen: alleSummenErneuern unsicher'); - if errorMsg<>'' then begin - showException(exception.create(errorMsg+#10'Hilfe: '+exename+' -H/--Hilfe')); - terminate; - exit; - end; + errorMsg:=checkOptions('A:D:P:au','Ausgabe: Datei: Prüfsummen: alleSummenErneuern unsicher',true); + if errorMsg<>'' then + fehler(errorMsg+#10'Hilfe: man Make'); - if (getOptionValue('A','Ausgabe')='') and not hasOption('W','Watte') then begin - showException(exception.create('Ausgabedatei wird benötigt!')); - terminate; - exit; - end; - - if hasOption('D','Datei') then inputfile:=getOptionValue('D','Datei') - else inputfile:='Machdatei'; - - if hasOption('P','Prüfsummen') then pruefsummenfile:=getOptionValue('P','Prüfsummen') - else begin - showException(exception.create('Prüfsummendatei wird benötigt!')); - terminate; - exit; - end; + mach:=tMach.create; - if fileexists(inputfile) then begin - if not liesMakeFile(inputfile,mglAbhaengigkeiten,dateien) then begin - showException(exception.create('Datei '''+inputfile+''' ist fehlerhaft!')); - terminate; - exit; - end; - end - else begin - showException(exception.create('Datei '''+inputfile+''' existiert nicht!')); - terminate; - exit; - end; + if hasOption('D','Datei') then + mach.machDatei:=getOptionValue('D','Datei') + else + mach.machDatei:=myReadLink('Machdatei'); - if not liesPruefsummenfile(pruefsummenfile,dateien) then begin - showException(exception.create('Datei '''+pruefsummenfile+''' ist fehlerhaft!')); - terminate; - exit; - end; + if hasOption('P','Prüfsummen') then + mach.pruefsummenDatei:=getOptionValue('P','Prüfsummen') + else + mach.setzeGenerischePruefsummenDatei; - writeln('Regeln: '+inttostr(length(mglAbhaengigkeiten))+', Dateien: '+inttostr(length(dateien))); - findeWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,dateien,inputfile); - writeln('anzuwendende Regeln: '+inttostr(length(zuTunAbhaengigkeiten))); - tueWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,dateien,hasOption('W','Watte'),hasOption('a','alleSummenErneuern'),hasOption('u','unsicher'),getOptionValue('A','Ausgabe'),pruefsummenfile); + writeln('originale Regeln: '+inttostr(mach.anzOriAbh)+', originale Dateien: '+inttostr(mach.anzDats)); + mach.erzeugeRegeln; + writeln('Regeln: '+inttostr(mach.anzMglAbh)+', Dateien: '+inttostr(mach.anzDats)); + mach.findeWasZuTunIst; + writeln('anzuwendende Regeln: '+inttostr(mach.anzZtAbh)); + mach.tueWasZuTunIst(hasOption('a','alleSummenErneuern'),hasOption('u','unsicher'),getOptionValue('A','Ausgabe')); terminate; end; @@ -446,6 +63,7 @@ end; var application: tMake; begin + __ausgabenMaske:=1; application:=tMake.create(nil); application.run; application.free; diff --git a/Make.lps b/Make.lps index 9b0ff05..c6f6eb9 100644 --- a/Make.lps +++ b/Make.lps @@ -3,50 +3,48 @@ - + - - - - - + + + - + - - - + + + + - - - + + - - - - + + + + @@ -64,7 +62,8 @@ - + + @@ -74,120 +73,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + - - + + - - + + - + - + - + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + + + + + + + + + diff --git a/dateibeziehungen.pas b/dateibeziehungen.pas index 30dedeb..14c1128 100644 --- a/dateibeziehungen.pas +++ b/dateibeziehungen.pas @@ -8,33 +8,115 @@ uses classes, sysUtils, tools, regExpr; type - tAbhArt = (aaFinal,aaPrimaer,aaIgnore); tZeilenTyp = (ztSuche,ztZiel,ztQuelle,ztBefehl); + pTAbhaengigkeit = ^tAbhaengigkeit; tAbhaengigkeit = class; - tAbhaengigkeiten = array of tAbhaengigkeit; + + tAbhaengigkeiten = class(tFPList) + private + function rItem(idx: longint): tAbhaengigkeit; inline; + procedure wItem(idx: longint; neu: tAbhaengigkeit); inline; + public + property items[idx: longint]: tAbhaengigkeit + read rItem + write wItem; default; + procedure kopiereVon(original: tAbhaengigkeiten); + procedure mrProper; + function add(neu: tAbhaengigkeit): longint; + function last: tAbhaengigkeit; + end; + tAbhaengigkeit = class(tObject) - abhArt: tAbhArt; quellenRE: tRegExpr; zieleFkt, befehle: tStringlist; quellen, ziele: tDateienMitDaten; erben: tAbhaengigkeiten; - prioritaet: integer; + prioritaet: longint; constructor create; overload; constructor create(original: tAbhaengigkeit); overload; destructor destroy; override; end; + tMach = class + private + _machDatei,_pruefsummenDatei: string; + _oriAbh,_mglAbh,_ztAbh: tAbhaengigkeiten; + _dats: tDateienMitDaten; + procedure wMachDatei(md: string); + procedure wPruefsummenDatei(pd: string); + function liesMachDatei: boolean; + function liesPruefsummenfile: boolean; + public + property machDatei: string + read _machDatei + write wMachDatei; + property pruefsummenDatei: string + read _pruefsummenDatei + write wPruefsummenDatei; + constructor create; + destructor destroy; override; + procedure erzeugeRegeln; + procedure findeWasZuTunIst; + procedure tueWasZuTunIst(allesNeu, unsicher: boolean; ausgabeDatei: string); + procedure setzeGenerischePruefsummenDatei; + function anzOriAbh: longint; inline; + function anzMglAbh: longint; inline; + function anzZtAbh: longint; inline; + function anzDats: longint; inline; + end; + function quellersetzung(var worin: string; quelle, inputfile: string): boolean; procedure sammleDateien(wo: string; rekursiv: boolean; ignoriere: array of tRegExpr; var dats: tDateienMitDaten); -function liesMakeFile(datNam: string; out abh: tAbhaengigkeiten; out dats: tDateienMitDaten): boolean; +procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle,inputfile: string; var dats: tDateienMitDaten); +procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); implementation uses - lowlevelunit, mystringlistunit; + lowlevelunit, mystringlistunit, math; + +// tAbhaengigkeiten ************************************************************ + +function tAbhaengigkeiten.rItem(idx: longint): tAbhaengigkeit; +begin + result:=tAbhaengigkeit(get(idx)); +end; + +procedure tAbhaengigkeiten.wItem(idx: longint; neu: tAbhaengigkeit); +begin + put(idx,neu); +end; + +procedure tAbhaengigkeiten.kopiereVon(original: tAbhaengigkeiten); +var + i: longint; +begin + clear; + for i:=0 to original.count-1 do + add(original[i]); +end; + +procedure tAbhaengigkeiten.mrProper; +var + i: longint; +begin + for i:=0 to count-1 do + items[i].free; + clear; +end; + +function tAbhaengigkeiten.add(neu: tAbhaengigkeit): longint; +begin + result:=inherited add(neu); +end; + +function tAbhaengigkeiten.last: tAbhaengigkeit; +begin + result:=tAbhaengigkeit(inherited last); +end; // tAbhaengigkeit ************************************************************** @@ -47,14 +129,13 @@ begin setlength(quellen,0); setlength(ziele,0); befehle:=tStringlist.create; - setlength(erben,0); - abhArt:=aaIgnore; + erben:=tAbhaengigkeiten.create; prioritaet:=42; end; constructor tAbhaengigkeit.create(original: tAbhaengigkeit); var - i: integer; + i: longint; begin inherited create; quellenRE:=tRegExpr.create; @@ -69,11 +150,9 @@ begin ziele[i]:=original.ziele[i]; befehle:=tStringlist.create; befehle.text:=original.befehle.text; - setlength(erben,length(original.erben)); - for i:=0 to length(original.erben)-1 do - erben[i]:=original.erben[i]; + erben:=tAbhaengigkeiten.create; + erben.kopiereVon(original.erben); prioritaet:=original.prioritaet; - abhArt:=original.abhArt; end; destructor tAbhaengigkeit.destroy; @@ -83,16 +162,470 @@ begin setLength(ziele,0); zieleFkt.free; befehle.free; - setlength(erben,0); + erben.free; inherited destroy; end; +// tMach *********************************************************************** + +constructor tMach.create; +begin + inherited create; + _oriAbh:=tAbhaengigkeiten.create; + _mglAbh:=tAbhaengigkeiten.create; + _ztAbh:=tAbhaengigkeiten.create; + setlength(_dats,0); +end; + +destructor tMach.destroy; +var + i: longint; +begin + _oriAbh.mrProper; + _oriAbh.free; + _mglAbh.mrProper; + _mglAbh.free; + _ztAbh.mrProper; + _ztAbh.free; + for i:=0 to length(_dats)-1 do + _dats[i].free; + setlength(_dats,0); + inherited destroy; +end; + +procedure tMach.wMachDatei(md: string); +begin + _machDatei:=md; + if not fileexists(_machDatei) then + fehler('Datei '''+_machDatei+''' existiert nicht!'); + if not liesMachDatei then + fehler('Datei '''+_machDatei+''' ist fehlerhaft!'); +end; + +procedure tMach.wPruefsummenDatei(pd: string); +begin + _pruefsummenDatei:=pd; + if not liesPruefsummenfile then + fehler('Datei '''+_pruefsummenDatei+''' ist fehlerhaft!'); +end; + +function tMach.liesMachDatei: boolean; +var + f: tMyStringList; + s: string; + na: tAbhaengigkeit; + ignoriere: array of tRegExpr; + rek: boolean; + num,posi: longint; + wasWar,wasIst: tZeilenTyp; + +procedure aufraeumen; +var + ii: longint; +begin + f.free; + na.free; + for ii:=0 to length(ignoriere)-1 do + ignoriere[ii].free; + setlength(ignoriere,0); +end; + +begin + result:=false; + + na:=tAbhaengigkeit.create; + na.prioritaet:=0; + setlength(ignoriere,0); + num:=0; + wasWar:=ztSuche; + f:=tMyStringList.create; + f.loadFromFile(machDatei); + f.add('%%DATEIENDE%%'); + if not f.unfoldMacros then begin + f.free; + exit; + end; + s:=''; + while f.readln(s) do begin + if rightStr(s,1)=';' then // ein Befehl(steil) + wasIst:=ztBefehl + else if rightStr(s,1)=':' then // ein Ziel + wasIst:=ztZiel + else if wasWar=ztZiel then // eine Quelle + wasIst:=ztQuelle + else // eine zu überwachende Datei + wasIst:=ztSuche; + + if wasIst in [ztZiel,ztBefehl] then + delete(s,length(s),1); + + if (wasWar=ztBefehl) and (wasIst<>ztBefehl) then begin + _oriAbh.add(na); + inc(num); + na:=tAbhaengigkeit.create; + na.prioritaet:=num; + end; + + if s='%%DATEIENDE%%' then break; + + case wasIst of + ztSuche: begin + if not quellersetzung(s,'',machDatei) then begin + writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); + aufraeumen; + exit; + end; + if pos('!',s)=1 then begin + delete(s,1,1); + s:=trim(s); + setlength(ignoriere,length(ignoriere)+1); + ignoriere[length(ignoriere)-1]:=tRegExpr.create; + ignoriere[length(ignoriere)-1].expression:=s; + end + else begin + rek:=startetMit('-r',s); + while s<>'' do + sammleDateien(erstesArgument(s),rek,ignoriere,_dats); + end; + end; + ztBefehl: begin + while unescapedpos(';',s)>0 do begin + posi:=unescapedpos(';',s); + s:=trim(leftStr(s,posi-1))+' && '+trim(rightStr(s,length(s)-posi)); + end; + while pos(';;',s)>0 do + delete(s,pos(';;',s),1); + na.befehle.add(s); + end; + ztZiel: + while s<>'' do + na.zieleFkt.add(erstesArgument(s)); + ztQuelle: begin + if not quellersetzung(s,'',machDatei) then begin + writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); + aufraeumen; + exit; + end; + na.quellenRE.expression:=s; + end; + end{of case}; + wasWar:=wasIst; + end; + + if s<>'%%DATEIENDE%%' then + writeln('Interner Fehler! Die letzte Regel wird vsl. nicht beachtet!'); + + aufraeumen; + result:=true; +end; + +function tMach.liesPruefsummenfile: boolean; +var + f: textfile; + i,j: longint; + gutschlecht: tStringlistBArray; + gefunden,gut: boolean; +begin + result:=false; + if pruefsummenDatei='' then begin + writeln('Leerer Name als Summendatei angegeben!'); + exit; + end; + + if not fileexists(pruefsummenDatei) then begin + assignfile(f,pruefsummenDatei); + rewrite(f); + closefile(f); + end; + if not fileexists(pruefsummenDatei) then begin + writeln('Ich bin nicht in der Lage, die bisher nicht existierende Datei '''+pruefsummenDatei+''' anzulegen!'); + exit; + end; + + gutschlecht:=testeSummen(pruefsummenDatei); + + for gut:=false to true do + for i:=0 to gutschlecht[gut].count-1 do begin + gefunden:=false; + for j:=0 to length(_dats)-1 do + if _dats[j].name=gutschlecht[gut][i] then begin + if gut then + _dats[j].aktuell:=aAktuell + else + _dats[j].aktuell:=aVeraltet; + gefunden:=true; + break; + end; + if not gefunden then begin + if not gut then begin // dateien mit ungültiger Prüfsumme können auch nicht vorhanden sein, + setlength(_dats,length(_dats)+1); // dann werden sie einfach eingefügt + _dats[length(_dats)-1]:=tDateiMitDatum.create; + _dats[length(_dats)-1].name:=gutschlecht[gut][i]; + _dats[length(_dats)-1].aktuell:=aVeraltet; + continue; + end; + writeln('In der Summendatei gibt es eine Datei mit gültiger Prüfsumme, die ich nicht finden kann: '''+gutschlecht[gut][i]+'''!'); + for gefunden:=false to true do + gutschlecht[gefunden].free; + exit; + end; + end; + + for gefunden:=false to true do + gutschlecht[gefunden].free; + result:=true; +end; + +procedure tMach.erzeugeRegeln; +var + i,j,k,l: longint; + neues,schonDa: boolean; + s: string; + tmpZiele: tDateienMitDaten; +begin + + repeat + neues:=false; + + for i:=0 to _oriAbh.count-1 do + for j:=0 to length(_dats)-1 do + if _oriAbh[i].quellenRE.exec(_dats[j].name) then begin + schonDa:=false; + for k:=0 to _oriAbh[i].erben.count-1 do + for l:=0 to length(_oriAbh[i].erben[k].quellen)-1 do + schonDa:=schonDa or (_oriAbh[i].erben[k].quellen[l]=_dats[j]); + + // Falls diese Quelle schon in eine Regel einfließt, brauchen + // wir nichts mehr zu machen, da es für jede Quelle höchstens + // eine Regel gibt. + if schonDa then continue; + + // Andernfalls müssen wir schauen, ob es zu dem Ziel / den Zielen + // der Quelle schon eine Regel gibt. + schonDa:=false; + setlength(tmpZiele,0); + findeMehrZiele(tmpZiele,_oriAbh[i].zieleFkt,_dats[j].name,machDatei,_dats); + + if length(tmpZiele)=0 then begin + gibAus('Fehler: Keine Ziele für Abhängigkeit!',3); + gibAus('Quelle:',3); + gibAus(''''+_dats[j].name+'''',3); + gibAus('Ziele:',3); + for k:=0 to _oriAbh[i].zieleFkt.count-1 do + gibAus(' '''+_oriAbh[i].zieleFkt[k]+'''',3); + fehler('... ich beende.'); + end; + + for k:=0 to _oriAbh[i].erben.count-1 do + if gleicheDateinamen(_oriAbh[i].erben[k].ziele,tmpZiele) then begin + // es gibt schon eine Regel für die Ziele der Quelle + schonDa:=true; + // dann wird dieser Regel nur die Quelle hinzugefügt + setlength(_oriAbh[i].erben[k].quellen,length(_oriAbh[i].erben[k].quellen)+1); + _oriAbh[i].erben[k].quellen[length(_oriAbh[i].erben[k].quellen)-1]:=_dats[j]; + // und womöglich die befehle generiert + for l:=0 to _oriAbh[i].befehle.count-1 do begin + s:=_oriAbh[i].befehle[l]; + if quellersetzung(s,_dats[j].name,machDatei) then begin + if l=0 then _oriAbh[i].erben[k].befehle.clear; + _oriAbh[i].erben[k].befehle.add(s); + end; + end; + neues:=true; + break; // mehr Ziele sollte es ohnehin nicht geben + end; + if schonDa then continue; + + // Ziel(e) ist/sind neu + _mglAbh.add(tAbhaengigkeit.create); + _oriAbh[i].erben.add(_mglAbh.last); + setlength(_mglAbh.last.quellen,1); + _mglAbh.last.quellen[0]:=_dats[j]; + _mglAbh.last.zieleFkt:=_oriAbh[i].zieleFkt; + setlength(_mglAbh.last.ziele,length(tmpZiele)); + for k:=0 to length(tmpZiele)-1 do + _mglAbh.last.ziele[k]:=tmpZiele[k]; + _mglAbh.last.befehle.clear; + for k:=0 to _oriAbh[i].befehle.count-1 do begin + s:=_oriAbh[i].befehle[k]; + if quellersetzung(s,_dats[j].name,machDatei) then + _mglAbh.last.befehle.add(s); + end; + _mglAbh.last.prioritaet:=_oriAbh[i].prioritaet; + end; + + until not neues; +end; + +procedure tMach.findeWasZuTunIst; +var + i,j,k: longint; + ziA,quA: tAktualitaet; +begin + // schauen, welche Regeln angewandt werden müssen + + for i:=0 to _mglAbh.count-1 do begin + for j:=0 to length(_mglAbh[i].quellen)-1 do + findeMehrZiele(_mglAbh[i].ziele,_mglAbh[i].zieleFkt,_mglAbh[i].quellen[j].name,machDatei,_dats); + if length(_mglAbh[i].ziele)=0 then begin // immer noch keine ziele + gibAus('Warnung: Keine ziele für diese Abhängigkeit!',3); + gibAus('quellen:',3); + for k:=0 to length(_mglAbh[i].quellen)-1 do + gibAus(' '''+_mglAbh[i].quellen[k].name+'''',3); + gibAus('zieleFkt:',3); + for k:=0 to _mglAbh[i].zieleFkt.count-1 do + gibAus(' '''+_mglAbh[i].zieleFkt[k]+'''',3); + gibAus(' - wird ignoriert.',3); + continue; + end; + + quA:=aAktuell; + for j:=0 to length(_mglAbh[i].quellen)-1 do + if _mglAbh[i].quellen[j].aktuell<>aAktuell then + quA:=aWirdErneuert; + ziA:=aWirdErneuert; + for j:=0 to length(_mglAbh[i].ziele)-1 do + ziA:=min(ziA,_mglAbh[i].ziele[j].aktuell); + + if ziA=0 do begin + for i:=0 to _ztAbh.count-1 do + if _ztAbh[i].prioritaet=prior then + for j:=0 to _ztAbh[i].befehle.count-1 do + befehle.add(_ztAbh[i].befehle[j]); + dec(prior); + end; + if not unsicher then begin + lokTest:=tRegExpr.create; + if extractfilepath(ausgabeDatei)=extractfilepath(pruefsummenDatei) then + lokTest.expression:='^'+extractfilepath(ausgabeDatei)+'/' + else + lokTest.expression:='^('+extractfilepath(ausgabeDatei)+'|'+extractfilepath(pruefsummenDatei)+')/'; + for i:=0 to befehle.count-1 do + testeObBefehlLokal(befehle[i],extractfiledir(ausgabeDatei),lokTest); + lokTest.free; + end; + for i:=geaenderteDateien.count-1 downto 0 do begin + if geaenderteDateien[i]='.uralt.' then begin + geaenderteDateien.delete(i); + continue; + end; + for j:=0 to i-1 do + if geaenderteDateien[i]=geaenderteDateien[j] then begin + geaenderteDateien.delete(i); + break; + end; + end; + if geaenderteDateien.count>0 then begin + befehle.add('echo -ne "Sha512summen erneuern ..."'); + befehl:='sed "'; + for i:=0 to geaenderteDateien.count-1 do + befehl:=befehl+'/\s'+escape(geaenderteDateien[i],'./','\')+'\$/d; '; + befehl:=befehl+'" -i "'+pruefsummenDatei+'"'; + befehle.add(befehl); + for i:=0 to geaenderteDateien.count-1 do + befehle.add('/usr/bin/sha512sum "'+geaenderteDateien[i]+'" >> '+pruefsummenDatei); + befehle.add('echo " fertig"'); + end; + + if _ztAbh.count=0 then + befehle.add('echo "Es gibt hier nichts zu tun!"'); + if ausgabeDatei='' then begin + writeln('befehle:'); + for i:=0 to befehle.count-1 do + writeln(befehle[i]); + end + else begin + assignFile(ausg,ausgabeDatei); + rewrite(ausg); + for i:=0 to befehle.count-1 do + writeln(ausg,'('+befehle[i]+') || (read -p "Ein Fehler ist aufgetreten! ... "; exit 1)'); + closeFile(ausg); + end; + befehle.free; + geaenderteDateien.free; +end; + +procedure tMach.setzeGenerischePruefsummenDatei; +begin + pruefsummenDatei:=extractfilepath(machDatei)+'.summen'; +end; + +function tMach.anzOriAbh: longint; +begin + result:=_oriAbh.count; +end; + +function tMach.anzMglAbh: longint; +begin + result:=_mglAbh.count; +end; + +function tMach.anzZtAbh: longint; +begin + result:=_ztAbh.count; +end; + +function tMach.anzDats: longint; +begin + result:=length(_dats); +end; + // allgemeine Funktionen ******************************************************* function quellersetzung(var worin: string; quelle, inputfile: string): boolean; var s,anfang,mitte: string; - i,li,re: integer; + i,li,re: longint; begin result:=true; if quelle<>'' then begin @@ -183,7 +716,7 @@ end; procedure sammleDateien(wo: string; rekursiv: boolean; ignoriere: array of tRegExpr; var dats: tDateienMitDaten); var sr: tSearchRec; - err,i: integer; + err,i: longint; weglassen: boolean; begin err:=FindFirst(wo,fareadOnly or faHidden or faSysFile or (byte(rekursiv)*faDirectory),sr); @@ -194,9 +727,9 @@ begin if not weglassen then begin if sr.attr and faDirectory <> 0 then begin if rekursiv and - (sr.name<>'.') and - (sr.name<>'..') then - sammleDateien(extractfilepath(wo)+sr.name+'/*',rekursiv,ignoriere,dats); + (sr.name<>'.') and + (sr.name<>'..') then + sammleDateien(extractfilepath(wo)+sr.name+'/*',rekursiv,ignoriere,dats); end else begin setlength(dats,length(dats)+1); @@ -210,119 +743,68 @@ begin findClose(sr); end; -function liesMakeFile(datNam: string; out abh: tAbhaengigkeiten; out dats: tDateienMitDaten): boolean; +procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle,inputfile: string; var dats: tDateienMitDaten); var - f: tMyStringList; - s: string; - na: tAbhaengigkeit; - ignoriere: array of tRegExpr; - rek: boolean; - num,posi: longint; - wasWar,wasIst: tZeilenTyp; - -procedure aufraeumen; -var - ii: longint; + i,ebene,ende: longint; + s,t,u: string; + wasda: boolean; begin - f.free; - na.free; - for ii:=0 to length(ignoriere)-1 do - ignoriere[ii].free; - setlength(ignoriere,0); -end; - -begin - result:=false; - - na:=tAbhaengigkeit.create; - na.prioritaet:=0; - na.abhArt:=aaPrimaer; - setlength(dats,0); - setlength(abh,0); - setlength(ignoriere,0); - num:=0; - wasWar:=ztSuche; - f:=tMyStringList.create; - f.loadFromFile(datNam); - f.add('%%DATEIENDE%%'); - if not f.unfoldMacros then begin - f.free; - exit; - end; - s:=''; - while f.readln(s) do begin - if rightStr(s,1)=';' then // ein Befehl(steil) - wasIst:=ztBefehl - else if rightStr(s,1)=':' then // ein Ziel - wasIst:=ztZiel - else if wasWar=ztZiel then // eine Quelle - wasIst:=ztQuelle - else // eine zu überwachende Datei - wasIst:=ztSuche; - - if wasIst in [ztZiel,ztBefehl] then - delete(s,length(s),1); - - if (wasWar=ztBefehl) and (wasIst<>ztBefehl) then begin - setlength(abh,length(abh)+1); - abh[length(abh)-1]:=na; - inc(num); - na:=tAbhaengigkeit.create; - na.prioritaet:=num; - na.abhArt:=aaPrimaer; - end; - - if s='%%DATEIENDE%%' then break; - - case wasIst of - ztSuche: begin - if not quellersetzung(s,'',datNam) then begin - writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); - aufraeumen; - exit; - end; - if pos('!',s)=1 then begin - delete(s,1,1); - s:=trim(s); - setlength(ignoriere,length(ignoriere)+1); - ignoriere[length(ignoriere)-1]:=tRegExpr.create; - ignoriere[length(ignoriere)-1].expression:=s; - end - else begin - rek:=startetMit('-r',s); - while s<>'' do - sammleDateien(erstesArgument(s),rek,ignoriere,dats); - end; + if pos('{',ziel)=0 then begin + if not quellersetzung(ziel,quelle,inputfile) then exit; + ziel:=unescape(ziel); + i:=0; + wasda:=false; + while i0 do begin - posi:=unescapedpos(';',s); - s:=trim(leftStr(s,posi-1))+' && '+trim(rightStr(s,length(s)-posi)); - end; - while pos(';;',s)>0 do - delete(s,pos(';;',s),1); - na.befehle.add(s); - end; - ztZiel: - while s<>'' do - na.zieleFkt.add(erstesArgument(s)); - ztQuelle: begin - if not quellersetzung(s,'',datNam) then begin - writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); - aufraeumen; - exit; - end; - na.quellenRE.expression:=s; + inc(i); + end; + if not wasda then begin + setlength(dats,length(dats)+1); + dats[i]:=tDateiMitDatum.create; + if pos('*',ziel)=0 then dats[i].name:=ziel + else dats[i].name:='.uralt.'; // unpassende *-Muster erzeugen formal keine echte Datei + dats[i].aktuell:=aVeraltet; // nicht existente dateien sind formal uralt + setlength(ziele,length(ziele)+1); + ziele[length(ziele)-1]:=dats[i]; + end; + end + else begin + ende:=pos('{',ziel); + ebene:=1; + while (ebene>0) or (ziel[ende]<>'}') do begin + inc(ende); + case ziel[ende] of + '{': inc(ebene); + '}': dec(ebene); + end{of case}; + end; + s:=copy(ziel,1,pos('{',ziel)-1); + t:=copy(ziel,pos('{',ziel)+1,ende-pos('{',ziel)-1); + u:=copy(ziel,ende+1,length(ziel)); + if unescapedpos('..',t)>0 then begin + for i:=strtoint(copy(t,1,unescapedpos('..',t)-1)) to strtoint(copy(t,unescapedpos('..',t)+2,length(t))) do + zieleHinzufuegen(ziele,s+inttostr(i)+u,quelle,inputfile,dats); + end + else begin + t:=t+','; + while unescapedpos(',',t)>0 do begin + zieleHinzufuegen(ziele,s+copy(t,1,unescapedpos(',',t)-1)+u,quelle,inputfile,dats); + delete(t,1,unescapedpos(',',t)); end; - end{of case}; - wasWar:=wasIst; + end; end; +end; - if s<>'%%DATEIENDE%%' then - writeln('Interner Fehler! Die letzte Regel wird vsl. nicht beachtet!'); - - aufraeumen; - result:=true; +procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); +var + i: longint; +begin + for i:=0 to zieleFkt.count-1 do + zieleHinzufuegen(ziele,zieleFkt[i],quelle,inputfile,dats); end; end. diff --git a/tools.pas b/tools.pas index 3d7c895..0767b25 100644 --- a/tools.pas +++ b/tools.pas @@ -20,11 +20,11 @@ type end; tDateienMitDaten = array of tDateiMitDatum; -function min(a1,a2: tAktualitaet): tAktualitaet; overload; -function max(a1,a2: tAktualitaet): tAktualitaet; overload; +function min(a1,a2: tAktualitaet): tAktualitaet; inline; overload; +function max(a1,a2: tAktualitaet): tAktualitaet; inline; overload; function anzCs(c: char; s: string): longint; function notQuotedPos(was,worin: string): longint; -function unescapedpos(was,worin: string): integer; +function unescapedpos(was,worin: string): longint; procedure testeObBefehlLokal(bef, ordner: string; lokTest: tRegExpr); function extrahiereAlleDateien(woraus: string): tMyStringList; function unescape(s: string): string; @@ -79,7 +79,7 @@ begin until false; end; -function unescapedpos(was,worin: string): integer; +function unescapedpos(was,worin: string): longint; var ebene: longint; begin @@ -218,8 +218,9 @@ begin end; function escape(s,toe: string; ec: char): string; -var i,j: longint; - b: boolean; +var + i,j: longint; + b: boolean; begin result:=''; for i:=1 to length(s) do begin -- cgit v1.2.3-54-g00ecf