From e6f770890d32de90309fb7951677735645c09fd1 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Tue, 20 Feb 2018 10:40:21 +0100 Subject: dateibeziehungen.pas: quell-"Regex" darf nun auch ein String sein --- Make.1.in | 10 ++++- Make.lps | 117 ++++++++++++++++++++++++++------------------------- dateibeziehungen.pas | 111 ++++++++++++++++++++++++++---------------------- 3 files changed, 127 insertions(+), 111 deletions(-) diff --git a/Make.1.in b/Make.1.in index 8cb4ddf..228d7ad 100644 --- a/Make.1.in +++ b/Make.1.in @@ -39,7 +39,7 @@ The file consists of four types of lines: .TP 2. Definitions of targets. .TP -3. Regular expressions matching sources +3. Definition of sources. .TP 4. Commands to execute for compiling targets from sources. .SH WATCH FILE DEFINITIONS @@ -57,7 +57,13 @@ These lines must end on \fB:\fP. Substitutions marked with (*) are allowed in this type of line. Multiple targets may be defined in one line if separated by spaces or in common bash syntax: \fB*\fP, \fB{one,two,three}\fP, \fB{1..3}\fP are expanded. Alternatively multiple targets may be defined in multiple consecutive lines. -A single line containing the source regex must follow a set of target definition lines. +.SH SOURCE DEFINITIONS +A set of lines containing the source regexes or source names must follow a set of target definition lines. +These lines can either be a regex or a verbatim source file name. +Regexes must start with \fI^\fP and end with \fI$\fP. +Literal source lines must be quoted in \fI"\fP. +Substitutions marked with (*) are partially allowed in these types of lines: +The referenced source must appear before the line referencing it. .SH COMMAND DEFINITIONS Each of these lines must end on \fB;\fP. Substitutions marked with (*) are allowed in this type of line. diff --git a/Make.lps b/Make.lps index eab90cf..6f89b0f 100644 --- a/Make.lps +++ b/Make.lps @@ -8,24 +8,24 @@ - - + + - + - - - - + + + + @@ -34,17 +34,18 @@ - + + - - - + + + @@ -64,7 +65,7 @@ - + @@ -105,7 +106,7 @@ - + @@ -140,122 +141,122 @@ - - + + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + - + - + - - + + - - + - - + + - + + - - + - + + diff --git a/dateibeziehungen.pas b/dateibeziehungen.pas index 5aa60dd..d9b30dd 100644 --- a/dateibeziehungen.pas +++ b/dateibeziehungen.pas @@ -498,11 +498,37 @@ end; function tGenerischeAbhaengigkeit.findeQuellen(dats: tDateienMitDaten): boolean; var - i,lastI: longint; - idx: array of longint; + i: longint; + idxs: array of tLongintArray; tmpQs: tDateienMitDaten; // hierin wird die momentan betrachte Kombination von Quellen gespeichert + +procedure fuelleStelle(ii: longint); +var s: string; - tmpRE: tRegExpr; +begin + if ii>0 then begin // vorherige Stelle "verbrauchen" + tmpQs.add(dats[idxs[ii-1][length(idxs[ii-1])-1]]); + setLength(idxs[ii-1],length(idxs[ii-1])-1); + end; + s:=quellenREs[ii]; + if (leftStr(s,1)='^') and (rightStr(s,1)='$') then begin // es handelt sich um einen regex + if not quellErsetzung(s,rtFpc,tmpQs,ii) then // regex-Substitution nicht erfolgreich - + tmpQs.delete(tmpQs.count-1) // wird behandelt wie nie passender regex + else + dats.matchAll(s,idxs[ii],true); + end + else if (leftStr(s,1)='"') and (rightStr(s,1)='"') then begin // es handelt sich um einen regulären String + delete(s,1,1); + delete(s,length(s),1); + if not quellErsetzung(s,rtKein,tmpQs,ii) then // Substitution nicht erfolgreich - + tmpQs.delete(tmpQs.count-1) // wird behandelt wie nicht existente Datei + else + dats.matchAll(s,idxs[ii],false); + end + else + fehler('Unbekannte Quell-Syntax: '''+s+''' - weder ''"/pfad/zur/Quelle"'' noch ''^/regex/der/auf/Quelle\.passt$''!'); +end; + begin result:=false; for i:=0 to length(_quellens)-1 do @@ -514,61 +540,44 @@ begin if length(quellenREs)=0 then exit; - 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; + setLength(idxs,length(quellenREs)); + for i:=0 to length(idxs)-1 do + setLength(idxs[i],0); - lastI:=-1; + fuelleStelle(0); repeat - if assigned(tmpQs[0]) then - i:=length(idx)-1 - else - i:=0; - while (i>=0) and (ilastI then begin // wir betrachten eine neue Stelle, - s:=quellenREs[i]; // daher ist der RegEx nicht mehr aktuell - if not quellErsetzung(s,rtFpc,tmpQs,i) then begin // regex-substitution nicht erfolgreich - - idx[i]:=-1; // wird behandelt wie nie passender regex - tmpQs[i]:=nil; - dec(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; + while (tmpQs.count>0) and (length(idxs[tmpQs.count])=0) do + tmpQs.delete(tmpQs.count-1); + // jetzt gibt es genau so viele tmpQs bis eins vor der letzten idxs-Position + // mit einem Wert <> 0 - 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 + if length(idxs[tmpQs.count])=0 then // das bedeutet einen Übertrag von der 0. + break; // auf die -1. Stelle + + for i:=tmpQs.count+1 to length(idxs)-1 do begin // um die Stelle i zu füllen, benötigen wir + fuelleStelle(i); // i-1 tmpQs, denn die i-te wird gewählt + if i>tmpQs.count then // die neue Stelle wurde nicht befüllt + break; 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]); + if tmpQs.count