summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2016-05-12 16:48:36 +0200
committerErich Eckner <git@eckner.net>2016-05-12 16:48:36 +0200
commit79a631d1b1958bc802ac0bf35282fe2de7cc9858 (patch)
tree0e092b4bdc33e25937ce43e4cc387a7bb1644ea9
parent3513fe55b2d1b2a2bd3e12f72fb2ed0bd81abeb0 (diff)
downloadMake-79a631d1b1958bc802ac0bf35282fe2de7cc9858.tar.xz
sollte jetzt gehen und die erwarteten Features haben
-rw-r--r--Make.lpr2
-rw-r--r--Make.lps128
-rw-r--r--dateibeziehungen.pas991
-rw-r--r--tools.pas120
4 files changed, 646 insertions, 595 deletions
diff --git a/Make.lpr b/Make.lpr
index 0574565..b0e6ff0 100644
--- a/Make.lpr
+++ b/Make.lpr
@@ -68,7 +68,7 @@ begin
mach.erzeugeRegeln;
gibAus('Regeln: '+inttostr(mach.anzMglAbh)+', Dateien: '+inttostr(mach.anzDats),3);
mach.findeWasZuTunIst;
- gibAus('anzuwendende Regeln: '+inttostr(mach.anzZtAbh),3);
+ gibAus('anzuwendende Regeln: '+inttostr(mach.anzMglAbh),3);
mach.tueWasZuTunIst(hasOption('a','alleSummenErneuern'),hasOption('u','unsicher'),getOptionValue('A','Ausgabe'));
terminate;
diff --git a/Make.lps b/Make.lps
index bc74b0c..eb6820a 100644
--- a/Make.lps
+++ b/Make.lps
@@ -3,27 +3,30 @@
<ProjectSession>
<Version Value="9"/>
<BuildModes Active="Default"/>
- <Units Count="15">
+ <Units Count="16">
<Unit0>
<Filename Value="Make.lpr"/>
<IsPartOfProject Value="True"/>
- <TopLine Value="19"/>
- <CursorPos Y="41"/>
- <UsageCount Value="76"/>
+ <TopLine Value="2"/>
+ <CursorPos Y="26"/>
+ <FoldState Value=" T3P0ns"/>
+ <UsageCount Value="85"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Machdatei.txt"/>
<IsPartOfProject Value="True"/>
- <UsageCount Value="76"/>
+ <UsageCount Value="85"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit1>
<Unit2>
<Filename Value="tools.pas"/>
<IsPartOfProject Value="True"/>
- <EditorIndex Value="3"/>
- <CursorPos X="3" Y="21"/>
- <UsageCount Value="55"/>
+ <EditorIndex Value="2"/>
+ <TopLine Value="39"/>
+ <CursorPos Y="64"/>
+ <FoldState Value=" T3iF03B pibjN0K1 pj4jS0D4]91jT07,"/>
+ <UsageCount Value="64"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
@@ -33,7 +36,7 @@
<TopLine Value="83"/>
<CursorPos Y="221"/>
<FoldState Value=" T3i803718 pialE0E116I"/>
- <UsageCount Value="52"/>
+ <UsageCount Value="61"/>
</Unit3>
<Unit4>
<Filename Value="dateibeziehungen.pas"/>
@@ -41,71 +44,69 @@
<UnitName Value="dateiBeziehungen"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
- <TopLine Value="267"/>
- <CursorPos X="19" Y="376"/>
- <FoldState Value=" T3jD036 pj3jM0B7 picje0431512]DgpT0s1[B4k8nM034e"/>
- <UsageCount Value="44"/>
+ <TopLine Value="54"/>
+ <FoldState Value=" T3k103C pjYkO0A4]9DjX0n3]97kL0P8]91k5071[R4I042 piel70G]9k1kN033("/>
+ <UsageCount Value="53"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="Machdatei"/>
<CursorPos X="45" Y="17"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
<DefaultSyntaxHighlighter Value="None"/>
</Unit5>
<Unit6>
<Filename Value="../Stabile/lowlevelunit.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="26" Y="23"/>
- <UsageCount Value="7"/>
+ <UsageCount Value="6"/>
</Unit6>
<Unit7>
<Filename Value="../units/lowlevelunit.pas"/>
<EditorIndex Value="-1"/>
- <TopLine Value="644"/>
- <CursorPos X="17" Y="671"/>
- <UsageCount Value="9"/>
+ <TopLine Value="592"/>
+ <CursorPos X="24" Y="616"/>
+ <UsageCount Value="10"/>
</Unit7>
<Unit8>
<Filename Value="/usr/lib/fpc/src/rtl/objpas/sysutils/datih.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="140"/>
<CursorPos X="10" Y="160"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</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="8"/>
+ <UsageCount Value="7"/>
</Unit9>
<Unit10>
<Filename Value="../units/matheunit.pas"/>
<EditorIndex Value="-1"/>
- <UsageCount Value="8"/>
+ <UsageCount Value="7"/>
</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="8"/>
+ <UsageCount Value="7"/>
</Unit11>
<Unit12>
<Filename Value="/usr/lib/fpc/src/rtl/objpas/classes/classesh.inc"/>
<EditorIndex Value="-1"/>
- <TopLine Value="225"/>
- <CursorPos X="15" Y="244"/>
- <UsageCount Value="9"/>
+ <TopLine Value="743"/>
+ <CursorPos X="14" Y="763"/>
+ <UsageCount Value="10"/>
</Unit12>
<Unit13>
<Filename Value="../units/systemunit.pas"/>
- <EditorIndex Value="2"/>
+ <EditorIndex Value="-1"/>
<TopLine Value="228"/>
<CursorPos Y="252"/>
- <UsageCount Value="13"/>
- <Loaded Value="True"/>
+ <UsageCount Value="15"/>
</Unit13>
<Unit14>
<Filename Value="/usr/lib/fpc/src/packages/fcl-base/src/custapp.pp"/>
@@ -113,127 +114,134 @@
<EditorIndex Value="-1"/>
<TopLine Value="516"/>
<CursorPos X="61" Y="411"/>
- <UsageCount Value="9"/>
+ <UsageCount Value="8"/>
</Unit14>
+ <Unit15>
+ <Filename Value="/usr/lib/fpc/src/rtl/inc/objpash.inc"/>
+ <EditorIndex Value="-1"/>
+ <TopLine Value="173"/>
+ <CursorPos X="23" Y="193"/>
+ <UsageCount Value="10"/>
+ </Unit15>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="212" Column="20" TopLine="86"/>
+ <Caret Line="322" Column="9" TopLine="289"/>
</Position1>
<Position2>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="402" Column="45" TopLine="383"/>
+ <Caret Line="485" Column="9" TopLine="310"/>
</Position2>
<Position3>
<Filename Value="dateibeziehungen.pas"/>
+ <Caret Line="491" Column="9" TopLine="316"/>
</Position3>
<Position4>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="38" Column="15" TopLine="5"/>
+ <Caret Line="492" Column="9" TopLine="317"/>
</Position4>
<Position5>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="212" Column="4" TopLine="89"/>
+ <Caret Line="499" Column="21" TopLine="324"/>
</Position5>
<Position6>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="238" Column="2" TopLine="95"/>
+ <Caret Line="500" Column="14" TopLine="325"/>
</Position6>
<Position7>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="48" Column="3" TopLine="27"/>
+ <Caret Line="594" Column="12" TopLine="476"/>
</Position7>
<Position8>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="401" Column="45" TopLine="339"/>
</Position8>
<Position9>
<Filename Value="dateibeziehungen.pas"/>
+ <Caret Line="89" Column="12" TopLine="56"/>
</Position9>
<Position10>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="38" Column="15" TopLine="5"/>
+ <Caret Line="486" Column="14" TopLine="311"/>
</Position10>
<Position11>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="237" Column="15" TopLine="127"/>
+ <Caret Line="627" Column="10" TopLine="594"/>
</Position11>
<Position12>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="246" Column="20" TopLine="205"/>
+ <Caret Line="635" Column="16" TopLine="602"/>
</Position12>
<Position13>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="266" Column="24" TopLine="223"/>
+ <Caret Line="636" Column="12" TopLine="603"/>
</Position13>
<Position14>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="400" Column="13" TopLine="376"/>
+ <Caret Line="637" Column="10" TopLine="604"/>
</Position14>
<Position15>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="404" Column="45" TopLine="381"/>
+ <Caret Line="672" Column="22" TopLine="616"/>
</Position15>
<Position16>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="37" Column="29" TopLine="28"/>
+ <Caret Line="673" Column="15" TopLine="617"/>
</Position16>
<Position17>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="1067" TopLine="238"/>
+ <Caret Line="674" Column="14" TopLine="618"/>
</Position17>
<Position18>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="403" Column="66" TopLine="384"/>
</Position18>
<Position19>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="37" Column="29" TopLine="16"/>
+ <Caret Line="90" TopLine="56"/>
</Position19>
<Position20>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="1067" TopLine="789"/>
+ <Caret Line="292" TopLine="219"/>
</Position20>
<Position21>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="403" Column="66" TopLine="375"/>
+ <Caret Line="311" TopLine="291"/>
</Position21>
<Position22>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="1067" TopLine="789"/>
+ <Caret Line="471" TopLine="403"/>
</Position22>
<Position23>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="91" TopLine="51"/>
+ <Caret Line="560" TopLine="471"/>
</Position23>
<Position24>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="399" TopLine="376"/>
+ <Caret Line="588" TopLine="568"/>
</Position24>
<Position25>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="1066" TopLine="788"/>
+ <Caret Line="595" TopLine="575"/>
</Position25>
<Position26>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="420" Column="9" TopLine="397"/>
+ <Caret Line="625" TopLine="598"/>
</Position26>
<Position27>
<Filename Value="dateibeziehungen.pas"/>
- <Caret Line="398" Column="11" TopLine="378"/>
+ <Caret Line="928" Column="30" TopLine="908"/>
</Position27>
<Position28>
- <Filename Value="dateibeziehungen.pas"/>
- <Caret Line="441" Column="38" TopLine="410"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="124" TopLine="45"/>
</Position28>
<Position29>
- <Filename Value="dateibeziehungen.pas"/>
- <Caret Line="375" Column="17" TopLine="333"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="112" Column="28" TopLine="88"/>
</Position29>
<Position30>
- <Filename Value="dateibeziehungen.pas"/>
- <Caret Line="21" TopLine="21"/>
+ <Filename Value="tools.pas"/>
+ <Caret Line="32" Column="41" TopLine="12"/>
</Position30>
</JumpHistory>
</ProjectSession>
diff --git a/dateibeziehungen.pas b/dateibeziehungen.pas
index d951ff3..fcaec5f 100644
--- a/dateibeziehungen.pas
+++ b/dateibeziehungen.pas
@@ -10,57 +10,91 @@ uses
type
tZeilenTyp = (ztSuche,ztZiel,ztQuelle,ztBefehl);
- pTAbhaengigkeit = ^tAbhaengigkeit;
- tAbhaengigkeit = class;
+ pTGenerischeAbhaengigkeit = ^tGenerischeAbhaengigkeit;
+ tGenerischeAbhaengigkeit = class;
+ pTExpliziteAbhaengigkeit = ^tExpliziteAbhaengigkeit;
+ tExpliziteAbhaengigkeit = class;
- tAbhaengigkeiten = class(tFPList)
+ tGenerischeAbhaengigkeiten = class(tFPList)
private
- function rItem(idx: longint): tAbhaengigkeit; inline;
- procedure wItem(idx: longint; neu: tAbhaengigkeit); inline;
+ function rItem(idx: longint): tGenerischeAbhaengigkeit; inline;
+ procedure wItem(idx: longint; neu: tGenerischeAbhaengigkeit); inline;
public
- property items[idx: longint]: tAbhaengigkeit
+ property items[idx: longint]: tGenerischeAbhaengigkeit
read rItem
write wItem; default;
- procedure kopiereVon(original: tAbhaengigkeiten);
+ procedure kopiereVon(original: tGenerischeAbhaengigkeiten);
procedure mrProper;
- function add(neu: tAbhaengigkeit): longint;
- function last: tAbhaengigkeit;
+ function add(neu: tGenerischeAbhaengigkeit): longint;
+ function last: tGenerischeAbhaengigkeit;
+ end;
+
+ tExpliziteAbhaengigkeiten = class(tFPList)
+ private
+ function rItem(idx: longint): tExpliziteAbhaengigkeit; inline;
+ procedure wItem(idx: longint; neu: tExpliziteAbhaengigkeit); inline;
+ public
+ property items[idx: longint]: tExpliziteAbhaengigkeit
+ read rItem
+ write wItem; default;
+ procedure kopiereVon(original: tExpliziteAbhaengigkeiten);
+ procedure mrProper;
+ function add(neu: tExpliziteAbhaengigkeit): longint;
+ function last: tExpliziteAbhaengigkeit;
procedure sort;
end;
- tAbhaengigkeit = class(tObject)
+ // Die goldene Regel bzgl. Abhängigkeiten ist,
+ // dass jedes Ziel nur ein Mal erzeugt werden kann und muss (logisch)
+ // und somit für zwei Regeln mit Zielmengen A und B
+ // A \cut B \neq \emptyset => A \cut B \in {A,B}
+ // gilt. Von diesen beiden Regeln ist dann höchstens eine anzuwenden.
+
+ // Mit den Informationen jeder einzelnen Quelle muss die gesamte Regel
+ // konstruiert werden können. Das beinhaltet:
+ // - weitere Quellen (per regex matchbar)
+ // - auszuführende Befehle (darf von "weiteren Quellen" abhängen)
+ // - erzeugte Ziele (darf von "weiteren Quellen" abhängen)
+
+ tGenerischeAbhaengigkeit = class(tObject)
private
- _erben,_eltern: tAbhaengigkeiten;
_quellens,_zieles: array of tDateienMitDaten;
+ _dats: tDateienMitDaten;
function rQuellen(idx: longint): tDateienMitDaten;
function rZiele(idx: longint): tDateienMitDaten;
+ function quellersetzung(var worin: string; quellen: tDateienMitDaten; momentanePosition: longint): boolean;
+ function zieleHinzufuegen(ziele, quellen: tDateienMitDaten; zielFkt: string): boolean;
+ function findeMehrZiele(ziele, quellen: tDateienMitDaten): boolean;
+ function matchCount: longint;
public
- quellenREs: array of tRegExpr; // regexes der Quellen
- qrePack: array of boolean; // sind mehrere matches obiger regexes zu einem Paket zu bündeln?
- zieleFkt,
- befehle: tStringlist;
+ machDatei: string;
+ quellenREs: array of string; // regexe der Quellen - nur deshalb kein tRegExpr, weil es ohnehin zuerst substituiert werden muss
+ zieleFkt,befehleFkt: tStringlist;
property quellen[idx: longint]: tDateienMitDaten
read rQuellen;
property ziele[idx: longint]: tDateienMitDaten
read rZiele;
- function matchCount: longint;
- constructor create; overload;
-// constructor create(original: tAbhaengigkeit); overload;
+ constructor create(dats: tDateienMitDaten);
destructor destroy; override;
- function hatQuelleVonAlsZiel(abh: tAbhaengigkeit): boolean;
- function hatErbenMitQuelle(name: string): boolean;
- function erbeMitGleichenZielen(zl: tDateienMitDaten): tAbhaengigkeit;
- procedure neuerErbe(erb: tAbhaengigkeit);
- procedure entferneErben(i: longint); overload;
- procedure entferneErben(erb: tAbhaengigkeit); overload;
- procedure entferneElterReferenz(elt: tAbhaengigkeit);
function findeQuellen(dats: tDateienMitDaten): boolean;
+ procedure generiereErben(var es: tExpliziteAbhaengigkeiten);
+ end;
+
+ tExpliziteAbhaengigkeit = class(tObject)
+ ziele,quellen: tDateienMitDaten;
+ befehle: tStringlist;
+ constructor create;
+ destructor destroy; override;
+ function hatQuelleVonAlsZiel(abh: tExpliziteAbhaengigkeit): boolean;
+ function ersetzbarDurch(abh: tExpliziteAbhaengigkeit): boolean;
+ function pruefeObZuTun: boolean;
end;
tMach = class
private
_machDatei,_pruefsummenDatei: string;
- _oriAbh,_mglAbh,_ztAbh: tAbhaengigkeiten;
+ _oriAbh: tGenerischeAbhaengigkeiten;
+ _mglAbh: tExpliziteAbhaengigkeiten;
_dats: tDateienMitDaten;
_ign: array of tRegExpr;
procedure wMachDatei(md: string);
@@ -68,8 +102,6 @@ type
function liesMachDatei: boolean;
function liesPruefsummenfile: boolean;
function sammleDateien(wo: string; rekursiv: boolean): longint;
- procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle: string);
- procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle: string);
public
property machDatei: string
read _machDatei
@@ -84,30 +116,74 @@ type
procedure tueWasZuTunIst(allesNeu, unsicher: boolean; ausgabeDatei: string);
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 allgemeineErsetzungen(var worin: string; machDatei: string);
implementation
uses
lowlevelunit, mystringlistunit, systemunit;
-// tAbhaengigkeiten ************************************************************
+// tGenerischeAbhaengigkeiten ************************************************************
+
+function tGenerischeAbhaengigkeiten.rItem(idx: longint): tGenerischeAbhaengigkeit;
+begin
+ result:=tGenerischeAbhaengigkeit(get(idx));
+end;
+
+procedure tGenerischeAbhaengigkeiten.wItem(idx: longint; neu: tGenerischeAbhaengigkeit);
+begin
+ put(idx,neu);
+end;
+
+procedure tGenerischeAbhaengigkeiten.kopiereVon(original: tGenerischeAbhaengigkeiten);
+var
+ i: longint;
+begin
+ clear;
+ for i:=0 to original.count-1 do
+ add(original[i]);
+end;
+
+procedure tGenerischeAbhaengigkeiten.mrProper;
+var
+ i: longint;
+begin
+ for i:=0 to count-1 do
+ items[i].free;
+ clear;
+end;
+
+function tGenerischeAbhaengigkeiten.add(neu: tGenerischeAbhaengigkeit): longint;
+var
+ i: longint;
+begin
+ for i:=0 to count-1 do
+ if items[i]=neu then
+ fehler('Fehler: Ich soll etwas zur Liste hinzufügen, was schon drin ist!');
+ result:=inherited add(neu);
+end;
+
+function tGenerischeAbhaengigkeiten.last: tGenerischeAbhaengigkeit;
+begin
+ result:=tGenerischeAbhaengigkeit(inherited last);
+end;
+
+// tExpliziteAbhaengigkeiten ************************************************************
-function tAbhaengigkeiten.rItem(idx: longint): tAbhaengigkeit;
+function tExpliziteAbhaengigkeiten.rItem(idx: longint): tExpliziteAbhaengigkeit;
begin
- result:=tAbhaengigkeit(get(idx));
+ result:=tExpliziteAbhaengigkeit(get(idx));
end;
-procedure tAbhaengigkeiten.wItem(idx: longint; neu: tAbhaengigkeit);
+procedure tExpliziteAbhaengigkeiten.wItem(idx: longint; neu: tExpliziteAbhaengigkeit);
begin
put(idx,neu);
end;
-procedure tAbhaengigkeiten.kopiereVon(original: tAbhaengigkeiten);
+procedure tExpliziteAbhaengigkeiten.kopiereVon(original: tExpliziteAbhaengigkeiten);
var
i: longint;
begin
@@ -116,7 +192,7 @@ begin
add(original[i]);
end;
-procedure tAbhaengigkeiten.mrProper;
+procedure tExpliziteAbhaengigkeiten.mrProper;
var
i: longint;
begin
@@ -125,7 +201,7 @@ begin
clear;
end;
-function tAbhaengigkeiten.add(neu: tAbhaengigkeit): longint;
+function tExpliziteAbhaengigkeiten.add(neu: tExpliziteAbhaengigkeit): longint;
var
i: longint;
begin
@@ -135,16 +211,16 @@ begin
result:=inherited add(neu);
end;
-function tAbhaengigkeiten.last: tAbhaengigkeit;
+function tExpliziteAbhaengigkeiten.last: tExpliziteAbhaengigkeit;
begin
- result:=tAbhaengigkeit(inherited last);
+ result:=tExpliziteAbhaengigkeit(inherited last);
end;
-procedure tAbhaengigkeiten.sort;
+procedure tExpliziteAbhaengigkeiten.sort;
var
i,j,k,pLen: longint;
perm: array of longint;
- tmp: tAbhaengigkeit;
+ tmp: tExpliziteAbhaengigkeit;
bedingungen: array of tPoint;
nehmbare: array of byte; // 0 = ja, 1 = nein, 2 = nie wieder (schon genommen)
fortschritt: boolean;
@@ -203,251 +279,366 @@ begin
end;
end;
-// tAbhaengigkeit **************************************************************
+// tGenerischeAbhaengigkeit **************************************************************
-constructor tAbhaengigkeit.create;
+constructor tGenerischeAbhaengigkeit.create(dats: tDateienMitDaten);
begin
inherited create;
+ _dats:=dats;
setlength(quellenREs,0);
- setlength(qrePack,0);
zieleFkt:=tStringlist.create;
- befehle:=tStringlist.create;
- _erben:=tAbhaengigkeiten.create;
- _eltern:=tAbhaengigkeiten.create;
+ befehleFkt:=tStringlist.create;
+ machDatei:='';
setlength(_quellens,0);
setlength(_zieles,0);
end;
-(*
-constructor tAbhaengigkeit.create(original: tAbhaengigkeit);
-var
- i: longint;
-begin
- inherited create;
- setlength(quellenREs,0);
- setlength(qrePack,0);
- zieleFkt:=tStringlist.create;
- zieleFkt.text:=original.zieleFkt.text;
- setlength(_quellens,0);
- setlength(_zieles,0);
- befehle:=tStringlist.create;
- befehle.text:=original.befehle.text;
- _erben:=tAbhaengigkeiten.create;
- _eltern:=tAbhaengigkeiten.create;
- original.neuerErbe(self);
-end;
-*)
-destructor tAbhaengigkeit.destroy;
+
+destructor tGenerischeAbhaengigkeit.destroy;
var
i: longint;
begin
- for i:=0 to length(quellenREs)-1 do
- quellenREs[i].free;
- setlength(quellenREs,0);
- setlength(qrePack,0);
for i:=0 to length(_quellens)-1 do
- setlength(_quellens[i],0);
+ _quellens[i].free;
setLength(_quellens,0);
+ for i:=0 to length(quellenREs)-1 do
+ setlength(quellenREs[i],0);
+ setlength(quellenREs,0);
for i:=0 to length(_zieles)-1 do
- setlength(_zieles[i],0);
+ _zieles[i].free;
setLength(_zieles,0);
zieleFkt.free;
- befehle.free;
- while _erben.count>0 do
- entferneErben(0);
- while _eltern.count>0 do
- _eltern[0].entferneErben(self);
- _erben.free;
- _eltern.free;
+ befehleFkt.free;
for i:=0 to length(_quellens)-1 do
- setlength(_quellens[i],0);
+ _quellens[i].free;
setlength(_quellens,0);
inherited destroy;
end;
-function tAbhaengigkeit.rQuellen(idx: longint): tDateienMitDaten;
+function tGenerischeAbhaengigkeit.rQuellen(idx: longint): tDateienMitDaten;
begin
result:=_quellens[idx];
end;
-function tAbhaengigkeit.rZiele(idx: longint): tDateienMitDaten;
+function tGenerischeAbhaengigkeit.rZiele(idx: longint): tDateienMitDaten;
begin
result:=_zieles[idx];
end;
-function tAbhaengigkeit.matchCount: longint;
-begin
- if length(_quellens)<>length(_zieles) then
- fehler('unterschiedlich viele Sätze an Quellen ('+inttostr(length(_quellens))+') und Zielen ('+inttostr(length(_zieles))+').');
- result:=length(_quellens);
-end;
-
-function tAbhaengigkeit.hatQuelleVonAlsZiel(abh: tAbhaengigkeit): boolean;
-var
- i,j: longint;
-begin
- result:=true;
- if (matchCount>1) or (abh.matchCount>1) then
- fehler('hatQuelleVonAlsZiel geht nur für Abhängigkeiten mit einem Satz Quellen und Zielen.');
- if (matchCount=1) and (abh.matchCount=1) then
- for i:=0 to length(ziele[0])-1 do
- for j:=0 to length(abh.quellen[0])-1 do
- if abh.quellen[0][j].name = ziele[0][i].name then
- exit;
- result:=false;
-end;
-
-function tAbhaengigkeit.hatErbenMitQuelle(name: string): boolean;
+function tGenerischeAbhaengigkeit.quellersetzung(var worin: string; quellen: tDateienMitDaten; momentanePosition: longint): boolean;
var
- i,j: longint;
+ s,anfang,mitte: string;
+ i,li,re,qNum: longint;
+ tmpRE: tRegExpr;
begin
result:=true;
- for i:=0 to _erben.count-1 do
- with _erben[i] do begin
- if matchCount=0 then
- continue;
- if matchCount>1 then
- fehler('hatErbenMitQuelle geht nur für Abhängigkeiten mit Erben mit je einem Satz Quellen.');
- for j:=0 to length(quellen[0])-1 do
- if quellen[0][j].name=name then
- exit;
+ for qNum:=0 to momentanePosition-1 do begin
+ ersetzeAlleVorkommen(worin,'%in('+inttostr(qNum)+')',quellen[qnum].name);
+ s:=extractfilename(quellen[qnum].name);
+ ersetzeAlleVorkommen(worin,'%ifile('+inttostr(qNum)+')',s);
+ if pos('.',s)>0 then
+ delete(s,pos('.',s),length(s));
+ ersetzeAlleVorkommen(worin,'%basename('+inttostr(qNum)+')',s);
+
+ while pos('%dirname('+inttostr(qNum)+',',worin)>0 do begin
+ anfang:=erstesArgument(worin,'%dirname('+inttostr(qNum)+',',false);
+ mitte:=erstesArgument(worin,')',false);
+ s:=extractfilepath(quellen[qnum].name);
+ if rightStr(s,1)='/' then
+ delete(s,length(s),1);
+ i:=anzCs('/',s)+1;
+ li:=strtoint(trim(erstesArgument(mitte,',',false)));
+ if li<0 then li:=li+i;
+ if mitte='' then
+ re:=0
+ else
+ re:=strtoint(mitte);
+ if re<=0 then re:=re+i;
+ while li>0 do begin
+ dec(li);
+ dec(re);
+ erstesArgument(s,'/',false);
+ end;
+ mitte:='';
+ while re>0 do begin
+ dec(re);
+ mitte:=mitte+'/'+erstesArgument(s,'/',false);
+ end;
+ delete(mitte,1,1);
+ worin:=anfang+mitte+worin;
end;
+ s:=extractfilepath(quellen[qnum].name);
+ if rightStr(s,1)='/' then
+ delete(s,length(s),1);
+ ersetzeAlleVorkommen(worin,'%dirname('+inttostr(qnum)+')',s);
+ end;
+
+ allgemeineErsetzungen(worin,machDatei);
+
result:=false;
+ tmpRE:=tRegExpr.create;
+ for qNum:=0 to momentanePosition-1 do begin
+ while pos('%nurmit('+inttostr(qnum)+')''',worin)>0 do begin
+ anfang:=erstesArgument(worin,'%nurmit('+inttostr(qnum)+')''',false);
+ tmpRE.expression:=erstesArgument(worin,'''',false);
+ if not tmpRE.exec(quellen[qnum].name) then begin
+ tmpRE.free;
+ exit;
+ end;
+ worin:=anfang+worin;
+ end;
+ while pos('%nurohne('+inttostr(qnum)+')''',worin)>0 do begin
+ anfang:=erstesArgument(worin,'%nurohne('+inttostr(qnum)+')''',false);
+ tmpRE.expression:=erstesArgument(worin,'''',false);
+ if tmpRE.exec(quellen[qnum].name) then begin
+ tmpRE.free;
+ exit;
+ end;
+ worin:=anfang+worin;
+ end;
+ end;
+ result:=true;
+ tmpRE.free;
end;
-function tAbhaengigkeit.erbeMitGleichenZielen(zl: tDateienMitDaten): tAbhaengigkeit;
+function tGenerischeAbhaengigkeit.zieleHinzufuegen(ziele, quellen: tDateienMitDaten; zielFkt: string): boolean;
var
- i: longint;
+ i,ebene,ende: longint;
+ s,t,u: string;
+ wasda: boolean;
begin
- result:=nil;
- for i:=0 to _erben.count-1 do begin
- if _erben[i].matchCount=0 then
- continue;
- if _erben[i].matchCount>1 then
- fehler('erbeMitGleichenZielen geht nur für Abhängigkeiten mit Erben mit je einem Satz Ziele.');
- if gleicheDateinamen(_erben[i].ziele[0],zl) then begin
- result:=_erben[i];
- exit;
+ result:=false;
+ if pos('{',zielFkt)=0 then begin
+ if not quellersetzung(zielFkt,quellen,quellen.count) then exit;
+ zielFkt:=unescape(zielFkt);
+ wasda:=false;
+ for i:=0 to _dats.count-1 do
+ if zielFkt=_dats[i].name then begin
+ wasda:=true;
+ ziele.add(_dats[i]);
+ end;
+ if not wasda then begin
+ result:=true;
+ _dats.add(tDateiMitDatum.create);
+ _dats.last.name:=zielFkt;
+ _dats.last.aktuell:=aNichtVorhanden;
+ ziele.add(_dats[i]);
+ end;
+ end
+ else begin
+ ende:=pos('{',zielFkt);
+ ebene:=1;
+ while (ebene>0) or (zielFkt[ende]<>'}') do begin
+ inc(ende);
+ case zielFkt[ende] of
+ '{': inc(ebene);
+ '}': dec(ebene);
+ end{of case};
+ end;
+ s:=copy(zielFkt,1,pos('{',zielFkt)-1);
+ t:=copy(zielFkt,pos('{',zielFkt)+1,ende-pos('{',zielFkt)-1);
+ u:=copy(zielFkt,ende+1,length(zielFkt));
+ 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,quellen,s+inttostr(i)+u);
+ end
+ else begin
+ t:=t+',';
+ while unescapedpos(',',t)>0 do begin
+ zieleHinzufuegen(ziele,quellen,s+copy(t,1,unescapedpos(',',t)-1)+u);
+ delete(t,1,unescapedpos(',',t));
+ end;
end;
end;
end;
-procedure tAbhaengigkeit.neuerErbe(erb: tAbhaengigkeit);
-begin
- _erben.add(erb);
- erb._eltern.add(self);
-end;
-
-procedure tAbhaengigkeit.entferneErben(i: longint);
-begin
- _erben[i].entferneElterReferenz(self);
- _erben.delete(i);
-end;
-
-procedure tAbhaengigkeit.entferneErben(erb: tAbhaengigkeit);
+function tGenerischeAbhaengigkeit.findeMehrZiele(ziele, quellen: tDateienMitDaten): boolean;
var
i: longint;
begin
- for i:=0 to _erben.count-1 do
- if _erben[i]=erb then begin
- entferneErben(i);
- exit;
- end;
- fehler('Fehler: Kann Erben nicht finden zum Entfernen!');
+ result:=false;
+ for i:=0 to zieleFkt.count-1 do
+ if zieleHinzufuegen(ziele,quellen,zieleFkt[i]) then
+ result:=true;
end;
-procedure tAbhaengigkeit.entferneElterReferenz(elt: tAbhaengigkeit);
-var
- i: longint;
+function tGenerischeAbhaengigkeit.matchCount: longint;
begin
- for i:=0 to _eltern.count-1 do
- if _eltern[i]=elt then begin
- _eltern.delete(i);
- exit;
- end;
- fehler('Fehler: Kann Elter nicht finden zum Entfernen der Referenz!');
+ if length(_quellens)<>length(_zieles) then
+ fehler('unterschiedlich viele Sätze an Quellen ('+inttostr(length(_quellens))+') und Zielen ('+inttostr(length(_zieles))+').');
+ result:=length(_quellens);
end;
-function tAbhaengigkeit.findeQuellen(dats: tDateienMitDaten): boolean;
+function tGenerischeAbhaengigkeit.findeQuellen(dats: tDateienMitDaten): boolean;
var
- i,j,k: longint;
- treffer: array of tDateienMitDaten;
+ i,lastI: longint;
idx: array of longint;
- tmpQs: tDateienMitDaten;
+ tmpQs: tDateienMitDaten; // hierin wird die momentan betrachte Kombination von Quellen gespeichert
s: string;
+ tmpRE: tRegExpr;
begin
+ result:=false;
for i:=0 to length(_quellens)-1 do
- setlength(_quellens[i],0);
+ _quellens[i].free;
setlength(_quellens,0);
+ for i:=0 to length(_zieles)-1 do
+ _zieles[i].free;
+ setlength(_zieles,0);
if length(quellenREs)=0 then exit;
- setlength(treffer,length(quellenREs));
- for i:=0 to length(treffer)-1 do
- for j:=0 to length(dats)-1 do
- if quellenREs[i].exec(dats[j].name) then begin
- setlength(treffer[i],length(treffer[i])+1);
- treffer[i,length(treffer[i])-1]:=dats[j];
- end;
-
- for i:=0 to length(treffer)-1 do
- if length(treffer[i])=0 then
- exit;
-
- setlength(idx,length(treffer));
- idx[0]:=-1;
- for i:=1 to length(idx)-1 do
- idx[i]:=length(treffer[i])-1;
-
- j:=0;
- for i:=0 to length(idx)-1 do
- if qrePack[i] then
- j:=j+length(treffer[i])
- else
- inc(j);
- setlength(tmpQs,j);
-
- // feste Bestandteile von tmpQs initialisieren
- j:=length(treffer);
- for i:=0 to length(idx)-1 do
- if qrePack[i] then begin
- tmpQs[i]:=treffer[i][0];
- for k:=1 to length(treffer[i])-1 do begin
- tmpQs[j]:=treffer[i][k];
- inc(j);
- end;
- end;
+ tmpRE:=tRegExpr.create;
+ tmpQs:=tDateienMitDaten.create;
+ tmpQs.count:=length(quellenREs);
+ setlength(idx,tmpQs.count);
+ for i:=0 to length(idx)-1 do begin
+ idx[i]:=-1;
+ tmpQs[i]:=nil;
+ end;
+ lastI:=-1;
repeat
- i:=length(idx)-1;
- while (i>=0) and qrePack[i] do
- dec(i);
- if i<0 then break;
- repeat
- inc(idx[i]);
- if idx[i]>=length(treffer[i]) then begin
- idx[i]:=0;
- repeat
+ if assigned(tmpQs[0]) then
+ i:=length(idx)-1
+ else
+ i:=0;
+ while (i>=0) and (i<length(idx)) do begin // alle Stellen von idx müssen gefüllt werden!
+ if i<>lastI then begin // wir betrachten eine neue Stelle,
+ s:=quellenREs[i]; // daher ist der RegEx nicht mehr aktuell
+ if not quellErsetzung(s,tmpQs,i) then begin // regex-substitution nicht erfolgreich -
+ idx[i]:=-1; // wird behandelt wie nie passender regex
+ tmpQs[i]:=nil;
dec(i);
- until (i<0) or not qrePack[i];
+ continue;
+ end;
+ tmpRE.expression:=s;
+ lastI:=i;
+ end;
+ repeat
+ inc(idx[i]);
+ until (idx[i]>=dats.count) or (tmpRE.exec(dats[idx[i]].name));
+
+ if idx[i]>=dats.count then begin // Überlauf
+ idx[i]:=-1;
+ tmpQs[i]:=nil;
+ dec(i);
continue;
end;
- break;
- until i<0;
- if i<0 then break;
- // idx und qrePack codieren, welche "treffer" die aktuellen Quellen sind.
- for i:=0 to length(idx)-1 do
- if not qrePack[i] then
- tmpQs[i]:=treffer[i][idx[i]];
+ tmpQs[i]:=dats[idx[i]];
+ inc(i); // nächste Stelle
+ if i>=length(idx) then // zu weit?
+ break; // dann fertig
+ idx[i]:=-1; // sonst initialisieren
+ end;
+ if i<0 then break; // Überlauf auf -1 => fertig
+
+ setlength(_quellens,length(_quellens)+1);
+ _quellens[length(_quellens)-1]:=tDateienMitDaten.create;
+ for i:=0 to tmpQs.count-1 do
+ _quellens[length(_quellens)-1].add(tmpQs[i]);
+ until false;
- for i:=0 to zieleFkt.count-1 do begin
- s:=zieleFkt[i];
- if quellersetzung(s,tmpQs,machDatei) then begin
+ tmpRE.free;
+ tmpQs.free;
+ setlength(idx,0);
- end;
+ setlength(_zieles,length(_quellens));
+ for i:=0 to length(_zieles)-1 do begin
+ _zieles[i]:=tDateienMitDaten.create;
+ if findeMehrZiele(_zieles[i],_quellens[i]) then
+ result:=true;
+ end;
+end;
+
+procedure tGenerischeAbhaengigkeit.generiereErben(var es: tExpliziteAbhaengigkeiten);
+var
+ i,j: longint;
+ s: string;
+begin
+ for i:=0 to matchCount-1 do begin
+ es.add(tExpliziteAbhaengigkeit.create);
+ for j:=0 to quellen[i].count-1 do
+ es.last.quellen.add(quellen[i][j]);
+ for j:=0 to ziele[i].count-1 do
+ es.last.ziele.add(ziele[i][j]);
+ for j:=0 to befehleFkt.count-1 do begin
+ s:=befehleFkt[j];
+ if quellersetzung(s,quellen[i],quellen[i].count) then
+ es.last.befehle.add(s);
end;
- until false;
- setlength(tmpQs,0);
+ if es.last.befehle.count=0 then
+ fehler(
+ 'Keine Befehle auszuführen für explizite Abhängigkeit!'#10+
+ 'Befehle:'#10+
+ befehleFkt.text+
+ 'Quellen:'#10+
+ quellen[i].toString
+ );
+ end;
+end;
+
+// tExpliziteAbhaengigkeit **************************************************************
+
+constructor tExpliziteAbhaengigkeit.create;
+begin
+ inherited create;
+ quellen:=tDateienMitDaten.create;
+ ziele:=tDateienMitDaten.create;
+ befehle:=tStringlist.create;
+end;
+
+destructor tExpliziteAbhaengigkeit.destroy;
+begin
+ quellen.free;
+ ziele.free;
+ befehle.free;
+ inherited destroy;
+end;
+
+function tExpliziteAbhaengigkeit.hatQuelleVonAlsZiel(abh: tExpliziteAbhaengigkeit): boolean;
+var
+ i,j: longint;
+begin
+ result:=true;
+ for i:=0 to ziele.count-1 do
+ for j:=0 to abh.quellen.count-1 do
+ if abh.quellen[j].name = ziele[i].name then
+ exit;
+ result:=false;
+end;
+
+function tExpliziteAbhaengigkeit.ersetzbarDurch(abh: tExpliziteAbhaengigkeit): boolean;
+var
+ i,j: longint;
+begin
+ result:=true;
+ for i:=0 to ziele.count-1 do begin
+ result:=false;
+ for j:=0 to abh.ziele.count-1 do
+ if abh.ziele[j].name = ziele[i].name then
+ result:=true;
+ if not result then
+ exit;
+ end;
+end;
+
+function tExpliziteAbhaengigkeit.pruefeObZuTun: boolean;
+var
+ i: longint;
+ quA,ziA: tAktualitaet;
+begin
+ quA:=aAktuell; // bis auf weiteres gehen wir davon aus, dass die Quellen aktuell sind
+ for i:=0 to quellen.count-1 do
+ if quellen[i].aktuell<>aAktuell then // nicht aktuelle Quellen
+ quA:=aWirdErneuert; // werden sicherlich erneuert werden
+ ziA:=aAktuell; // bis auf weiteres gehen wir davon aus, dass die Ziele aktuell sind
+ for i:=0 to ziele.count-1 do
+ ziA:=min(ziA,ziele[i].aktuell);
+
+ result:=ziA<quA;
+ if result then
+ for i:=0 to ziele.count-1 do
+ ziele[i].aktuell:=aWirdErneuert;
end;
// tMach ***********************************************************************
@@ -455,10 +646,9 @@ end;
constructor tMach.create;
begin
inherited create;
- _oriAbh:=tAbhaengigkeiten.create;
- _mglAbh:=tAbhaengigkeiten.create;
- _ztAbh:=tAbhaengigkeiten.create;
- setlength(_dats,0);
+ _oriAbh:=tGenerischeAbhaengigkeiten.create;
+ _mglAbh:=tExpliziteAbhaengigkeiten.create;
+ _dats:=tDateienMitDaten.create;
end;
destructor tMach.destroy;
@@ -469,11 +659,8 @@ begin
_oriAbh.free;
_mglAbh.mrProper;
_mglAbh.free;
- _ztAbh.mrProper;
- _ztAbh.free;
- for i:=0 to length(_dats)-1 do
- _dats[i].free;
- setlength(_dats,0);
+ _dats.mrProper;
+ _dats.free;
for i:=0 to length(_ign)-1 do
_ign[i].free;
setlength(_ign,0);
@@ -510,7 +697,7 @@ function tMach.liesMachDatei: boolean;
var
f: tMyStringList;
s: string;
- na: tAbhaengigkeit;
+ na: tGenerischeAbhaengigkeit;
rek: boolean;
posi: longint;
wasWar,wasIst: tZeilenTyp;
@@ -524,7 +711,8 @@ end;
begin
result:=false;
- na:=tAbhaengigkeit.create;
+ na:=tGenerischeAbhaengigkeit.create(_dats);
+ na.machDatei:=machDatei;
wasWar:=ztSuche;
f:=tMyStringList.create;
f.loadFromFile(machDatei);
@@ -553,18 +741,15 @@ begin
if (wasWar=ztBefehl) and (wasIst<>ztBefehl) then begin
_oriAbh.add(na);
- na:=tAbhaengigkeit.create;
+ na:=tGenerischeAbhaengigkeit.create(_dats);
+ na.machDatei:=machDatei;
end;
if s='%%DATEIENDE%%' then break;
case wasIst of
ztSuche: begin
- if not quellersetzung(s,'',machDatei) then begin
- gibAus('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!',3);
- aufraeumen;
- exit;
- end;
+ allgemeineErsetzungen(s,machDatei);
if startetMit('!',s) then begin
setlength(_ign,length(_ign)+1);
_ign[length(_ign)-1]:=tRegExpr.create;
@@ -589,20 +774,14 @@ begin
end;
while pos(';;',s)>0 do
delete(s,pos(';;',s),1);
- na.befehle.add(s);
+ na.befehleFkt.add(s);
end;
ztZiel:
while s<>'' do
na.zieleFkt.add(erstesArgument(s));
ztQuelle: begin
- if not quellersetzung(s,'',machDatei) then begin
- gibAus('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!',3);
- aufraeumen;
- exit;
- end;
setlength(na.quellenREs,length(na.quellenREs)+1);
- na.quellenREs[length(na.quellenREs)-1]:=tRegExpr.create;
- na.quellenREs[length(na.quellenREs)-1].expression:=s;
+ na.quellenREs[length(na.quellenREs)-1]:=s;
end;
end{of case};
wasWar:=wasIst;
@@ -643,7 +822,7 @@ begin
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
+ for j:=0 to _dats.count-1 do
if _dats[j].name=gutschlecht[gut][i] then begin
if gut then
_dats[j].aktuell:=aAktuell
@@ -654,10 +833,9 @@ begin
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:=aNichtVorhanden;
+ _dats.add(tDateiMitDatum.create); // dann werden sie einfach eingefügt
+ _dats.last.name:=gutschlecht[gut][i];
+ _dats.last.aktuell:=aNichtVorhanden;
continue;
end;
gibAus('Fehler: In der Summendatei gibt es eine Datei mit gültiger Prüfsumme, die ich nicht finden kann: '''+gutschlecht[gut][i]+'''!',3);
@@ -693,10 +871,9 @@ begin
end
else begin
inc(result);
- setlength(_dats,length(_dats)+1);
- _dats[length(_dats)-1]:=tDateiMitDatum.create;
- _dats[length(_dats)-1].name:=extractfilepath(wo)+sr.name;
- _dats[length(_dats)-1].aktuell:=aVeraltet;
+ _dats.add(tDateiMitDatum.create);
+ _dats.last.name:=extractfilepath(wo)+sr.name;
+ _dats.last.aktuell:=aVeraltet;
end;
end;
err:=FindNext(sr);
@@ -704,192 +881,64 @@ begin
findClose(sr);
end;
-procedure tMach.zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle: string);
-var
- i,ebene,ende: longint;
- s,t,u: string;
- wasda: boolean;
-begin
- if pos('{',ziel)=0 then begin
- if not quellersetzung(ziel,quelle,machDatei) 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:=aNichtVorhanden;
- 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);
- end
- else begin
- t:=t+',';
- while unescapedpos(',',t)>0 do begin
- zieleHinzufuegen(ziele,s+copy(t,1,unescapedpos(',',t)-1)+u,quelle);
- delete(t,1,unescapedpos(',',t));
- end;
- end;
- end;
-end;
-
-procedure tMach.findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle: string);
-var
- i: longint;
-begin
- for i:=0 to zieleFkt.count-1 do
- zieleHinzufuegen(ziele,zieleFkt[i],quelle);
-end;
-
procedure tMach.erzeugeRegeln;
var
- i,j,k,l: longint;
- neues: boolean;
- s: string;
- tmpZiele: tDateienMitDaten;
- erb: tAbhaengigkeit;
+ i: longint;
+ neues: boolean;
begin
repeat
neues:=false;
- for i:=0 to _oriAbh.count-1 do begin
- _oriAbh[i].findeQuellen(_dats);
-
- for j:=0 to _oriAbh[i].matchCount-1 do
- if _oriAbh[i].quellenRE.exec(_dats[j].name) then begin
- // 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 _oriAbh[i].hatErbenMitQuelle(_dats[j].name) then continue;
-
- // Andernfalls müssen wir schauen, ob es zu dem Ziel / den Zielen
- // der Quelle schon eine Regel gibt.
- setlength(tmpZiele,0);
- findeMehrZiele(tmpZiele,_oriAbh[i].zieleFkt,_dats[j].name);
-
- 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;
-
- erb:=_oriAbh[i].erbeMitGleichenZielen(tmpZiele);
- if assigned(erb) then begin
- // es gibt schon eine Regel für die Ziele der Quelle,
- // dann wird dieser Regel nur die Quelle hinzugefügt
- setlength(erb.quellen,length(erb.quellen)+1);
- erb.quellen[length(erb.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 erb.befehle.clear;
- erb.befehle.add(s);
- end;
- end;
- neues:=true;
- continue;
- end;
-
- // Ziel(e) ist/sind neu
- _mglAbh.add(tAbhaengigkeit.create);
- _oriAbh[i].neuerErbe(_mglAbh.last);
- setlength(_mglAbh.last.quellen,1);
- _mglAbh.last.quellen[0]:=_dats[j];
- _mglAbh.last.zieleFkt:=tStringlist.create;
- _mglAbh.last.zieleFkt.text:=_oriAbh[i].zieleFkt.text;
- 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;
- end;
+ for i:=0 to _oriAbh.count-1 do
+ if _oriAbh[i].findeQuellen(_dats) then
+ neues:=true; // neue Dateien sind entstanden
until not neues;
+
+ for i:=0 to _oriAbh.count-1 do
+ _oriAbh[i].generiereErben(_mglAbh);
end;
procedure tMach.findeWasZuTunIst;
var
- i,j,k: longint;
- ziA,quA: tAktualitaet;
- neues: boolean;
+ i,j: longint;
+ neues: boolean;
+ zuTun: array of boolean;
begin
+ setlength(zuTun,_mglAbh.count);
+ for i:=0 to length(zuTun)-1 do
+ zuTun[i]:=false;
+
// schauen, welche Regeln angewandt werden müssen
repeat
neues:=false;
- for i:=_mglAbh.count-1 downto 0 do begin
- for j:=0 to length(_mglAbh[i].quellen)-1 do
- findeMehrZiele(_mglAbh[i].ziele,_mglAbh[i].zieleFkt,_mglAbh[i].quellen[j].name);
- 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);
- _mglAbh[i].free;
- _mglAbh.delete(i);
- continue;
- end;
+ for i:=0 to length(zuTun)-1 do
+ if not zuTun[i] then
+ if _mglAbh[i].pruefeObZuTun then begin
+ zuTun[i]:=true;
+ neues:=true;
+ end;
+ until not neues;
- quA:=aAktuell; // bis auf weiteres gehen wir davon aus, dass die Quellen aktuell sind
- for j:=0 to length(_mglAbh[i].quellen)-1 do
- if _mglAbh[i].quellen[j].aktuell<>aAktuell then // nicht aktuelle Quellen
- quA:=aWirdErneuert; // werden sicherlich erneuert werden
- ziA:=aAktuell; // bis auf weiteres gehen wir davon aus, dass die Ziele aktuell sind
- for j:=0 to length(_mglAbh[i].ziele)-1 do
- ziA:=min(ziA,_mglAbh[i].ziele[j].aktuell);
-
- if ziA<quA then begin
- neues:=true;
- _ztAbh.add(tAbhaengigkeit.create(_mglAbh[i]));
- for j:=0 to length(_mglAbh[i].ziele)-1 do
- _mglAbh[i].ziele[j].aktuell:=aWirdErneuert;
- _mglAbh[i].free;
- _mglAbh.delete(i);
- end;
+ // schauen, welche Regeln redundant sind
+ for i:=0 to length(zuTun)-1 do
+ if zuTun[i] then
+ for j:=0 to length(zuTun)-1 do
+ if zuTun[j] and (i<>j) and _mglAbh[i].ersetzbarDurch(_mglAbh[j]) then begin
+ _mglAbh[j].quellen.append(_mglAbh[i].quellen);
+ zuTun[i]:=false;
+ break;
+ end;
+
+ for i:=length(zuTun)-1 downto 0 do
+ if not zuTun[i] then begin
+ _mglAbh[i].free;
+ _mglAbh.delete(i);
end;
- until not neues;
+ setlength(zuTun,0);
// anzuwendende Regeln sortieren
- _ztAbh.sort;
+ _mglAbh.sort;
end;
procedure tMach.tueWasZuTunIst(allesNeu, unsicher: boolean; ausgabeDatei: string);
@@ -905,7 +954,7 @@ begin
befehle:=tStringlist.create;
geaenderteDateien:=tStringlist.create;
sumDateien:=dateienMitGueltigerSumme(pruefsummenDatei);
- for i:=0 to length(_dats)-1 do begin
+ for i:=0 to _dats.count-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
@@ -919,20 +968,20 @@ begin
sumDateien.free;
if allesNeu then
for i:=0 to _mglAbh.count-1 do begin
- for j:=0 to length(_mglAbh[i].ziele)-1 do
+ for j:=0 to _mglAbh[i].ziele.count-1 do
geaenderteDateien.add(_mglAbh[i].ziele[j].name);
- for j:=0 to length(_mglAbh[i].quellen)-1 do
+ for j:=0 to _mglAbh[i].quellen.count-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);
+ for i:=0 to _mglAbh.count-1 do begin
+ for j:=0 to _mglAbh[i].ziele.count-1 do
+ geaenderteDateien.add(_mglAbh[i].ziele[j].name);
+ for j:=0 to _mglAbh[i].quellen.count-1 do
+ geaenderteDateien.add(_mglAbh[i].quellen[j].name);
end;
- for i:=0 to _ztAbh.count-1 do
- for j:=0 to _ztAbh[i].befehle.count-1 do
- befehle.add(_ztAbh[i].befehle[j]);
+ for i:=0 to _mglAbh.count-1 do
+ for j:=0 to _mglAbh[i].befehle.count-1 do
+ befehle.add(_mglAbh[i].befehle[j]);
if not unsicher then begin
lokTest:=tRegExpr.create;
if extractfilepath(ausgabeDatei)=extractfilepath(pruefsummenDatei) then
@@ -966,7 +1015,7 @@ begin
befehle.add('echo " fertig"');
end;
- if _ztAbh.count=0 then
+ if _mglAbh.count=0 then
befehle.add('echo "Es gibt hier nichts zu tun!"');
if ausgabeDatei='' then begin
gibAus('befehle:',3);
@@ -994,74 +1043,22 @@ begin
result:=_mglAbh.count;
end;
-function tMach.anzZtAbh: longint;
-begin
- result:=_ztAbh.count;
-end;
-
function tMach.anzDats: longint;
begin
- result:=length(_dats);
+ result:=_dats.count;
end;
-// allgemeine Funktionen *******************************************************
+// allgemeine Funktionen
-function quellersetzung(var worin: string; quelle, inputfile: string): boolean;
+procedure allgemeineErsetzungen(var worin: string; machDatei: string);
var
+ i: longint;
s,anfang,mitte: string;
- i,li,re: longint;
begin
- result:=true;
- if quelle<>'' then begin
- while pos('%in',worin)>0 do
- worin:=copy(worin,1,pos('%in',worin)-1)+quelle+copy(worin,pos('%in',worin)+3,length(worin));
- s:=extractfilename(quelle);
- while pos('%ifile',worin)>0 do
- worin:=copy(worin,1,pos('%ifile',worin)-1)+s+copy(worin,pos('%ifile',worin)+6,length(worin));
- if pos('.',s)>0 then begin
- while s[length(s)]<>'.' do delete(s,length(s),1);
- delete(s,length(s),1);
- end;
- while pos('%basename',worin)>0 do
- worin:=copy(worin,1,pos('%basename',worin)-1)+s+copy(worin,pos('%basename',worin)+9,length(worin));
- while pos('%dirname(',worin)>0 do begin
- anfang:=erstesArgument(worin,'%dirname(');
- mitte:=erstesArgument(worin,')');
- s:=extractfilepath(quelle);
- if rightStr(s,1)='/' then
- delete(s,length(s),1);
- i:=anzCs('/',s)+1;
- li:=strtoint(erstesArgument(mitte,','));
- if li<0 then li:=li+i;
- if mitte='' then
- re:=0
- else
- re:=strtoint(mitte);
- if re<=0 then re:=re+i;
- while li>0 do begin
- dec(li);
- dec(re);
- erstesArgument(s,'/');
- end;
- mitte:='';
- while re>0 do begin
- dec(re);
- mitte:=mitte+'/'+erstesArgument(s,'/');
- end;
- delete(mitte,1,1);
- worin:=anfang+mitte+worin;
- end;
- s:=extractfilepath(quelle);
- if rightStr(s,1)='/' then
- delete(s,length(s),1);
- while pos('%dirname',worin)>0 do
- worin:=copy(worin,1,pos('%dirname',worin)-1)+s+copy(worin,pos('%dirname',worin)+8,length(worin));
- end;
- s:=extractfilepath(inputfile);
+ s:=extractfilepath(machDatei);
if rightStr(s,1)='/' then
delete(s,length(s),1);
- while pos('%DIRNAME',worin)>0 do
- worin:=copy(worin,1,pos('%DIRNAME',worin)-1)+s+copy(worin,pos('%DIRNAME',worin)+8,length(worin));
+ ersetzeAlleVorkommen(worin,'%DIRNAME',s);
while pos('%num''',worin)>0 do begin
anfang:=erstesArgument(worin,'%num''');
mitte:=erstesArgument(worin,'''');
@@ -1077,24 +1074,6 @@ begin
end;
worin:=anfang+mitte+worin;
end;
- if quelle<>'' then begin
- result:=false;
- while pos('%nurmit''',worin)>0 do begin
- anfang:=erstesArgument(worin,'%nurmit''');
- mitte:=erstesArgument(worin,'''');
- if pos(mitte,quelle)=0 then
- exit;
- worin:=anfang+worin;
- end;
- while pos('%nurohne''',worin)>0 do begin
- anfang:=erstesArgument(worin,'%nurohne''');
- mitte:=erstesArgument(worin,'''');
- if pos(mitte,quelle)>0 then
- exit;
- worin:=anfang+worin;
- end;
- result:=true;
- end;
end;
end.
diff --git a/tools.pas b/tools.pas
index 4ba44a7..3b9671b 100644
--- a/tools.pas
+++ b/tools.pas
@@ -18,7 +18,20 @@ type
name: ansiString;
aktuell: tAktualitaet;
end;
- tDateienMitDaten = array of tDateiMitDatum;
+ tDateienMitDaten = class(tFPList)
+ function rItem(idx: longint): tDateiMitDatum; inline;
+ procedure wItem(idx: longint; neu: tDateiMitDatum); inline;
+ public
+ property items[idx: longint]: tDateiMitDatum
+ read rItem
+ write wItem; default;
+ procedure mrProper;
+ function add(neu: tDateiMitDatum): longint;
+ function last: tDateiMitDatum;
+ function gleicheNamenWie(dmd: tDateienMitDaten): boolean;
+ function toString: string; override;
+ procedure append(dmd: tDateienMitDaten);
+ end;
function min(a1,a2: tAktualitaet): tAktualitaet; inline; overload;
function max(a1,a2: tAktualitaet): tAktualitaet; inline; overload;
@@ -29,8 +42,7 @@ procedure testeObBefehlLokal(bef, ordner: string; lokTest: tRegExpr);
function extrahiereAlleDateien(woraus: string): tMyStringList;
function unescape(s: string): string;
function escape(s,toe: string; ec: char): string;
-function bashMatch(was,worauf: string): boolean;
-function gleicheDateinamen(dl1,dl2: tDateienMitDaten): boolean;
+procedure ersetzeAlleVorkommen(var worin: string; was,wodurch: string);
// Routinen für sha512-Prüfsummen
@@ -42,6 +54,77 @@ implementation
uses
lowlevelunit;
+// tDateienMitDaten ************************************************************
+
+function tDateienMitDaten.rItem(idx: longint): tDateiMitDatum;
+begin
+ result:=tDateiMitDatum(get(idx));
+end;
+
+procedure tDateienMitDaten.wItem(idx: longint; neu: tDateiMitDatum);
+begin
+ put(idx,neu);
+end;
+
+procedure tDateienMitDaten.mrProper;
+var
+ i: longint;
+begin
+ for i:=0 to count-1 do
+ items[i].free;
+ clear;
+end;
+
+function tDateienMitDaten.add(neu: tDateiMitDatum): longint;
+begin
+ result:=inherited add(neu);
+end;
+
+function tDateienMitDaten.last: tDateiMitDatum;
+begin
+ result:=tDateiMitDatum(inherited last);
+end;
+
+function tDateienMitDaten.gleicheNamenWie(dmd: tDateienMitDaten): boolean;
+var
+ i,j: longint;
+begin
+ result:=count=dmd.count;
+ if not result then
+ exit;
+ for i:=0 to count-1 do begin
+ result:=false;
+ for j:=0 to dmd.count-1 do
+ result:=result or (items[i].name = dmd[j].name);
+ if not result then exit;
+ end;
+end;
+
+function tDateienMitDaten.toString: string;
+var
+ i: longint;
+begin
+ result:='';
+ for i:=0 to count-1 do
+ result:=result+''''+items[i].name+''''#10;
+end;
+
+procedure tDateienMitDaten.append(dmd: tDateienMitDaten);
+var
+ i,j: longint;
+ found: boolean;
+begin
+ for i:=0 to dmd.count-1 do begin
+ found:=false;
+ for j:=0 to count-1 do
+ found:=found or (items[j].name = dmd[i].name);
+ if not found then
+ add(dmd[i]);
+ end;
+end;
+
+// allgemeine Funktionen
+
function min(a1,a2: tAktualitaet): tAktualitaet;
begin
if a1<a2 then
@@ -233,32 +316,13 @@ begin
end;
end;
-function bashMatch(was,worauf: string): boolean;
-var
- re: tRegExpr;
+procedure ersetzeAlleVorkommen(var worin: string; was,wodurch: string);
begin
- if pos('*',was)=0 then begin
- result:=was=worauf;
- exit;
- end;
- re:=tRegExpr.create;
- re.expression:='^'+escape(escape(was,'.|()^$','\'),'*','.')+'$';
- result:=re.exec(worauf);
- re.free;
-end;
-
-function gleicheDateinamen(dl1,dl2: tDateienMitDaten): boolean;
-var
- i,j: longint;
-begin
- result:=length(dl1)=length(dl2);
- if not result then
- exit;
- for i:=0 to length(dl1)-1 do begin
- result:=false;
- for j:=0 to length(dl2)-1 do
- result:=result or (dl1[i].name=dl2[j].name);
- if not result then exit;
+ while pos(was,worin)>0 do begin
+ worin:=
+ leftStr(worin,pos(was,worin)-1) +
+ wodurch +
+ rightStr(worin,length(worin)-pos(was,worin)-length(was)+1);
end;
end;