diff options
author | Erich Eckner <git@eckner.net> | 2016-05-10 11:31:40 +0200 |
---|---|---|
committer | Erich Eckner <git@eckner.net> | 2016-05-10 11:31:40 +0200 |
commit | 394e27efc7906ec40f960d23095dc5aebee84fd6 (patch) | |
tree | 0bf506a085ebd01ada795d42597ede19dee6ac61 | |
parent | eb86e555f015200e3bb3ac6d839df0b6ca13248d (diff) | |
download | Make-394e27efc7906ec40f960d23095dc5aebee84fd6.tar.xz |
alles schön in Klassen gepackt
-rw-r--r-- | Make.lpr | 426 | ||||
-rw-r--r-- | Make.lps | 171 | ||||
-rw-r--r-- | dateibeziehungen.pas | 734 | ||||
-rw-r--r-- | tools.pas | 13 |
4 files changed, 739 insertions, 605 deletions
@@ -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 i<length(dats) do begin - if bashMatch(ziel,dats[i].name) then begin - wasda:=true; - setlength(ziele,length(ziele)+1); - ziele[length(ziele)-1]:=dats[i]; - end; - 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; - 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 i<length(mgl) do begin - case mgl[i].abhArt of - aaPrimaer: - 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)-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]); - - // 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,mgl[i].zieleFkt,dats[j].name,inputfile,dats); - - if length(tmpZiele)=0 then begin - writeln('Fehler: Keine ziele für Abhängigkeit!'); - writeln('Quelle:'); - writeln(''''+dats[j].name+''''); - writeln('Ziele:'); - for k:=0 to mgl[i].zieleFkt.count-1 do - writeln(' '''+mgl[i].zieleFkt[k]+''''); - halt(1); - end; - - for k:=0 to length(mgl[i].erben)-1 do - if gleicheDateinamen(mgl[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(mgl[i].erben[k].quellen,length(mgl[i].erben[k].quellen)+1); - mgl[i].erben[k].quellen[length(mgl[i].erben[k].quellen)-1]:=dats[j]; - // und womöglich die befehle generiert - for l:=0 to mgl[i].befehle.count-1 do begin - s:=mgl[i].befehle[l]; - if quellersetzung(s,dats[j].name,inputfile) then begin - if l=0 then mgl[i].erben[k].befehle.clear; - mgl[i].erben[k].befehle.add(s); - end; - end; - break; // mehr Ziele sollte es ohnehin nicht geben - end; - if schonDa then continue; - - // ziel(e) ist/sind neu - setlength(mgl,length(mgl)+1); - mgl[length(mgl)-1]:=tAbhaengigkeit.create; - setlength(mgl[i].erben,length(mgl[i].erben)+1); - mgl[i].erben[length(mgl[i].erben)-1]:=mgl[length(mgl)-1]; - mgl[length(mgl)-1].abhArt:=aaFinal; - setlength(mgl[length(mgl)-1].quellen,1); - mgl[length(mgl)-1].quellen[0]:=dats[j]; - mgl[length(mgl)-1].zieleFkt:=mgl[i].zieleFkt; - setlength(mgl[length(mgl)-1].ziele,length(tmpZiele)); - for i:=0 to length(tmpZiele)-1 do - mgl[length(mgl)-1].ziele[i]:=tmpZiele[i]; - mgl[length(mgl)-1].befehle.clear; - for k:=0 to mgl[i].befehle.count-1 do begin - s:=mgl[i].befehle[k]; - if quellersetzung(s,dats[j].name,inputfile) then - mgl[length(mgl)-1].befehle.add(s); - end; - mgl[length(mgl)-1].prioritaet:=mgl[i].prioritaet; - end; - aaFinal: if (length(mgl[i].erben)=0) and - (length(mgl[i].quellen)<>0) 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<quA then begin - writeln(ziA,' ',quA,' ',mgl[i].ziele[0].name,' ',length(mgl[i].ziele)); - writeln(' -> ',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; @@ -3,50 +3,48 @@ <ProjectSession> <Version Value="9"/> <BuildModes Active="Default"/> - <Units Count="9"> + <Units Count="13"> <Unit0> <Filename Value="Make.lpr"/> <IsPartOfProject Value="True"/> - <IsVisibleTab Value="True"/> - <TopLine Value="2"/> - <CursorPos Y="22"/> - <FoldState Value=" T3N0t3 plCmW0{S%"/> - <UsageCount Value="60"/> + <TopLine Value="19"/> + <CursorPos X="55" Y="47"/> + <UsageCount Value="64"/> <Loaded Value="True"/> </Unit0> <Unit1> <Filename Value="Machdatei.txt"/> <IsPartOfProject Value="True"/> - <UsageCount Value="60"/> + <UsageCount Value="64"/> <DefaultSyntaxHighlighter Value="None"/> </Unit1> <Unit2> <Filename Value="tools.pas"/> <IsPartOfProject Value="True"/> <EditorIndex Value="2"/> - <TopLine Value="300"/> - <CursorPos Y="50"/> - <UsageCount Value="39"/> + <TopLine Value="68"/> + <CursorPos X="10" Y="37"/> + <FoldState Value=" T3f065 pk9kR0D]9jIk5070"/> + <UsageCount Value="43"/> <Loaded Value="True"/> </Unit2> <Unit3> <Filename Value="../units/mystringlistunit.pas"/> <IsPartOfProject Value="True"/> <EditorIndex Value="-1"/> - <TopLine Value="37"/> - <CursorPos Y="111"/> <FoldState Value=" T3i7039 pj2jP0B716."/> - <UsageCount Value="36"/> + <UsageCount Value="40"/> </Unit3> <Unit4> <Filename Value="dateibeziehungen.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="dateiBeziehungen"/> + <IsVisibleTab Value="True"/> <EditorIndex Value="1"/> - <TopLine Value="55"/> - <CursorPos X="60" Y="199"/> - <FoldState Value=" T3e0C3j"/> - <UsageCount Value="28"/> + <TopLine Value="490"/> + <CursorPos X="80" Y="515"/> + <FoldState Value=" T3id03A pifjR0721226 pjIt40S2v"/> + <UsageCount Value="32"/> <Loaded Value="True"/> </Unit4> <Unit5> @@ -64,7 +62,8 @@ <Unit7> <Filename Value="../units/lowlevelunit.pas"/> <EditorIndex Value="-1"/> - <CursorPos X="15" Y="265"/> + <TopLine Value="381"/> + <CursorPos X="53" Y="414"/> <UsageCount Value="10"/> </Unit7> <Unit8> @@ -74,120 +73,154 @@ <CursorPos X="10" Y="160"/> <UsageCount Value="10"/> </Unit8> + <Unit9> + <Filename Value="/usr/lib/fpc/src/rtl/objpas/math.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="162"/> + <CursorPos X="10" Y="167"/> + <UsageCount Value="10"/> + </Unit9> + <Unit10> + <Filename Value="../units/matheunit.pas"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + </Unit10> + <Unit11> + <Filename Value="/usr/lib/fpc/src/rtl/objpas/sysutils/finah.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="4"/> + <CursorPos X="10" Y="23"/> + <UsageCount Value="10"/> + </Unit11> + <Unit12> + <Filename Value="/usr/lib/fpc/src/rtl/objpas/classes/classesh.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="210"/> + <CursorPos X="3" Y="218"/> + <UsageCount Value="10"/> + </Unit12> </Units> - <JumpHistory Count="28" HistoryIndex="27"> + <JumpHistory Count="30" HistoryIndex="29"> <Position1> - <Filename Value="Make.lpr"/> - <Caret Line="143" Column="129" TopLine="123"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="451" Column="27" TopLine="431"/> </Position1> <Position2> - <Filename Value="Make.lpr"/> - <Caret Line="424" Column="53" TopLine="404"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="453" Column="44" TopLine="433"/> </Position2> <Position3> - <Filename Value="Make.lpr"/> - <Caret Line="431" Column="77" TopLine="396"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="481" Column="58" TopLine="461"/> </Position3> <Position4> - <Filename Value="Make.lpr"/> - <Caret Line="222" Column="59" TopLine="195"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="482" Column="36" TopLine="462"/> </Position4> <Position5> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="205" Column="44" TopLine="50"/> + <Caret Line="483" Column="45" TopLine="463"/> </Position5> <Position6> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="11" Column="40"/> + <Caret Line="508" Column="27" TopLine="488"/> </Position6> <Position7> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="109" Column="46" TopLine="87"/> + <Caret Line="525" Column="30" TopLine="506"/> </Position7> <Position8> - <Filename Value="Make.lpr"/> - <Caret Line="203" Column="79" TopLine="172"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="531" Column="27" TopLine="511"/> </Position8> <Position9> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="213" TopLine="16"/> + <Caret Line="538" Column="29" TopLine="518"/> </Position9> <Position10> - <Filename Value="Make.lpr"/> - <Caret Line="55" Column="36" TopLine="36"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="577" Column="18" TopLine="557"/> </Position10> <Position11> - <Filename Value="Make.lpr"/> - <Caret Line="64" Column="50" TopLine="44"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="602" Column="24" TopLine="577"/> </Position11> <Position12> - <Filename Value="Make.lpr"/> - <Caret Line="103" Column="35" TopLine="84"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="600" TopLine="574"/> </Position12> <Position13> - <Filename Value="Make.lpr"/> - <Caret Line="149" Column="3" TopLine="123"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="27" Column="14" TopLine="7"/> </Position13> <Position14> - <Filename Value="Make.lpr"/> - <Caret Line="242" Column="32" TopLine="224"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="90" Column="15" TopLine="67"/> </Position14> <Position15> - <Filename Value="Make.lpr"/> - <Caret Line="245" Column="33" TopLine="224"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="99" Column="15" TopLine="73"/> </Position15> <Position16> - <Filename Value="Make.lpr"/> - <Caret Line="244" Column="66" TopLine="225"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="25" Column="25" TopLine="5"/> </Position16> <Position17> - <Filename Value="Make.lpr"/> - <Caret Line="242" Column="37" TopLine="224"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="93" Column="38" TopLine="60"/> </Position17> <Position18> - <Filename Value="Make.lpr"/> - <Caret Line="244" Column="65" TopLine="224"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="11"/> </Position18> <Position19> - <Filename Value="Make.lpr"/> - <Caret Line="255" Column="40" TopLine="235"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="46" Column="35" TopLine="28"/> </Position19> <Position20> - <Filename Value="Make.lpr"/> - <Caret Line="149" Column="18" TopLine="120"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="179" TopLine="109"/> </Position20> <Position21> - <Filename Value="Make.lpr"/> - <Caret Line="244" Column="40" TopLine="222"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="134" TopLine="108"/> </Position21> <Position22> - <Filename Value="Make.lpr"/> - <Caret Line="250" Column="37" TopLine="227"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="210" TopLine="155"/> </Position22> <Position23> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="297" Column="69" TopLine="272"/> + <Caret Line="265" TopLine="245"/> </Position23> <Position24> <Filename Value="dateibeziehungen.pas"/> - <Caret Line="220" Column="12" TopLine="209"/> + <Caret Line="491" TopLine="460"/> </Position24> <Position25> - <Filename Value="Make.lpr"/> - <Caret Line="25" Column="29" TopLine="17"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="407" Column="13" TopLine="387"/> </Position25> <Position26> - <Filename Value="Make.lpr"/> - <Caret Line="437" Column="53" TopLine="407"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="412" Column="55" TopLine="407"/> </Position26> <Position27> - <Filename Value="Make.lpr"/> - <Caret Line="390" TopLine="137"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="481" TopLine="452"/> </Position27> <Position28> - <Filename Value="Make.lpr"/> - <Caret Line="447" TopLine="414"/> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="448" Column="86" TopLine="425"/> </Position28> + <Position29> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="460" TopLine="450"/> + </Position29> + <Position30> + <Filename Value="dateibeziehungen.pas"/> + <Caret Line="463" Column="12" TopLine="171"/> + </Position30> </JumpHistory> </ProjectSession> </CONFIG> 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<quA then begin + _ztAbh.add(tAbhaengigkeit.create(_mglAbh[i])); + _mglAbh[i].erben.add(_ztAbh.last); + for j:=0 to length(_mglAbh[i].ziele)-1 do + _mglAbh[i].ziele[j].aktuell:=aWirdErneuert; + end; + end; +end; + +procedure tMach.tueWasZuTunIst(allesNeu, unsicher: boolean; ausgabeDatei: string); +var + prior,i,j: longint; + ausg: textfile; + befehle,geaenderteDateien, + sumDateien: tStringlist; + gefunden: boolean; + lokTest: tRegExpr; + befehl: string; +begin + befehle:=tStringlist.create; + prior:=0; + for i:=0 to _ztAbh.count-1 do + prior:=max(prior,_ztAbh[i].prioritaet); + geaenderteDateien:=tStringlist.create; + sumDateien:=dateienMitGueltigerSumme(pruefsummenDatei); + for i:=0 to length(_dats)-1 do begin + gefunden:=(_dats[i].name=pruefsummenDatei) 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 _mglAbh.count-1 do begin + for j:=0 to length(_mglAbh[i].ziele)-1 do + geaenderteDateien.add(_mglAbh[i].ziele[j].name); + for j:=0 to length(_mglAbh[i].quellen)-1 do + geaenderteDateien.add(_mglAbh[i].quellen[j].name); + end; + for i:=0 to _ztAbh.count-1 do begin + for j:=0 to length(_ztAbh[i].ziele)-1 do + geaenderteDateien.add(_ztAbh[i].ziele[j].name); + for j:=0 to length(_ztAbh[i].quellen)-1 do + geaenderteDateien.add(_ztAbh[i].quellen[j].name); + end; + while prior>=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 i<length(dats) do begin + if bashMatch(ziel,dats[i].name) then begin + wasda:=true; + setlength(ziele,length(ziele)+1); + ziele[length(ziele)-1]:=dats[i]; 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,'',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. @@ -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 |