From 3a14085bd25270d5912b82a2acfd05de14844fe5 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Mon, 9 May 2016 14:28:10 +0200 Subject: erstmal wieder lauffähig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Make.8.in | 23 +- Make.lpi | 9 +- Make.lpr | 887 ++++++++++++++++----------------------------------- Make.lps | 141 ++++---- dateibeziehungen.pas | 329 +++++++++++++++++++ tools.pas | 169 +++++++--- 6 files changed, 822 insertions(+), 736 deletions(-) create mode 100644 dateibeziehungen.pas diff --git a/Make.8.in b/Make.8.in index 90345bb..3fc1ef3 100644 --- a/Make.8.in +++ b/Make.8.in @@ -40,20 +40,21 @@ recursively add these files and directories to currentness control .PP The rest of the file consists of compilation rules, each consisting of two consecutive lines: .TP -The \fBfirst\fP line is a regex-aware rule for identifying dependencies and must not end on \fB;\fP. +The \fBfirst\fP line is a regex-aware rule for identifying dependencies and must not start with a space or tab. .TP -.B "1>1 target:sourceRegEx" -Each file matching \fIsourceRegEx\fP generates one \fItarget\fP. +.B ">1 target:sourceRegEx" +Each (set of) \fItarget\fP(s) is generated by a separate command, possibly involving many source files matching \fIsourceRegEx\fP. .TP -.B "n>n target:sourceRegEx" -All files matching \fIsourceRegEx\fP contribute simultanously in generating \fItarget\fP (possibly multiple files). +.B ">n target:sourceRegEx" +All \fItarget\fPs are generated by a single command, possibly involving many source files matching \fIsourceRegEx\fP. .TP -The \fBsecond\fP line contains commands to refresh the targets and must end on \fB;\fP. +The \fBfollowing\fP line(s) contain(s) commands to refresh the targets and must start with a space or tab. +The \fBlast\fP line of these must end on \fB;\fP. .SH SUBSTITUTIONS Some substitutions and macros are recognized: .TP .B "%nurmit'filePart'" -only apply rule / consider source file if name of source file contains \fIfilePart\fP +only apply rule / generate target name from source file if name of source file contains \fIfilePart\fP .TP .B "%nurohne'filePart'" opposite of \fB%nurmit'filePart'\fP @@ -67,14 +68,14 @@ file name of source file .B "%basename" file name of source file without extension(s) .TP -.B "%basedir(number)" -path to source file stripped by last \fInumber\fP directory components +.B "%dirname(number)" +last \fInumber\fP components of path so source file .TP -.B "%basedir" +.B "%dirname" path so source file. Identical to \fB%basedir(0)\fP. .TP -.B "%BASEDIR" +.B "%DIRNAME" path to \fIMachdatei\fP .TP .B "%num'string'" diff --git a/Make.lpi b/Make.lpi index a98aa59..809ca7b 100644 --- a/Make.lpi +++ b/Make.lpi @@ -32,7 +32,7 @@ - + @@ -44,13 +44,16 @@ - - + + + + + diff --git a/Make.lpr b/Make.lpr index 0f2b51c..030e0c5 100644 --- a/Make.lpr +++ b/Make.lpr @@ -6,258 +6,32 @@ uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} - Classes, SysUtils, CustApp + classes, sysUtils, custApp { you can add units after this }, - RegExpr, Math, tools; + math, tools, lowlevelunit, dateiBeziehungen, regExpr; type - { TMake } + { tMake } - TMake = class(TCustomApplication) + tMake = class(tCustomApplication) protected - procedure DoRun; override; + procedure doRun; override; public - constructor Create(TheOwner: TComponent); override; - procedure WriteHelp; virtual; + constructor create(theOwner: tComponent); override; + procedure writeHelp; virtual; end; - TAbhArt = (aaFinal,aaEinsZuEins,aaNZuN,aaIgnore); - TDateienMitDaten = array of ^TDateiMitDatum; - - { TAbhaengigkeit } - - TAbhaengigkeit = class(TObject) - AbhArt: TAbhArt; - QuellenRE: TRegExpr; - ZieleFkt, - Befehle: TStringlist; - Quellen, - Ziele: TDateienMitDaten; - Erben: array of ^TAbhaengigkeit; - Prioritaet: Integer; - constructor create; overload; - constructor create(Original: TAbhaengigkeit); overload; - destructor destroy; override; - end; - TAbhaengigkeiten = array of ^TAbhaengigkeit; - TDateiMitDatum = record - Name: AnsiString; - Datum: TDateTime; - end; - - { TAbhaengigkeit } - -constructor TAbhaengigkeit.create; -begin - inherited create; - QuellenRE:=TRegExpr.create; - QuellenRE.Expression:=''; - ZieleFkt:=TStringlist.create; - SetLength(Quellen,0); - SetLength(Ziele,0); - Befehle:=TStringlist.create; - SetLength(Erben,0); - AbhArt:=aaNZuN; - Prioritaet:=42; -end; - -constructor TAbhaengigkeit.create(Original: TAbhaengigkeit); -var i: integer; -begin - inherited create; - QuellenRE:=TRegExpr.create; - QuellenRE.Expression:=Original.QuellenRE.Expression; - ZieleFkt:=TStringlist.create; - ZieleFkt.Text:=Original.ZieleFkt.Text; - SetLength(Quellen,length(Original.Quellen)); - for i:=0 to length(Original.Quellen)-1 do - Quellen[i]:=Original.Quellen[i]; - SetLength(Ziele,length(Original.Ziele)); - for i:=0 to length(Original.Ziele)-1 do - 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]; - Prioritaet:=Original.Prioritaet; - AbhArt:=Original.AbhArt; -end; - -destructor TAbhaengigkeit.destroy; -begin - QuellenRE.free; - SetLength(Quellen,0); - SetLength(Ziele,0); - ZieleFkt.free; - Befehle.free; - SetLength(Erben,0); - inherited destroy; -end; - -function liesZeile(var dat: textfile; out s: string): boolean; -begin - repeat - result:=not eof(dat); - if not result then exit; - readln(dat,s); - if pos('#',s)>0 then delete(s,pos('#',s),length(s)); - while (length(s)>0) and (s[length(s)] in [#9,' ']) do - delete(s,length(s),1); - until s<>''; -end; - -procedure sammleDateien(wo: string; rekursiv: boolean; ignoriere: array of tRegExpr; var dats: TDateienMitDaten); +function liesPruefsummenfile(sumNam: string; var dats: tDateienMitDaten): boolean; var - sr: TSearchRec; - err,i: integer; - weglassen: boolean; -begin - err:=FindFirst(wo,faReadOnly or faHidden or faSysFile or (byte(rekursiv)*faDirectory),sr); - while err=0 do begin - weglassen:=false; - for i:=0 to length(ignoriere)-1 do - weglassen:=weglassen or ignoriere[i].Exec(extractfilepath(wo)+sr.name); - 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+'/'+extractfilename(wo),rekursiv,ignoriere,dats); - end - else begin - setlength(dats,length(dats)+1); - getmem(dats[length(dats)-1],sizeof(TDateiMitDatum)); - fillchar(dats[length(dats)-1]^,sizeof(TDateiMitDatum),0); - dats[length(dats)-1]^.Name:=extractfilepath(wo)+sr.name; - dats[length(dats)-1]^.Datum:=FileDateTodateTime(FileAge(dats[length(dats)-1]^.Name)); - end; - end; - err:=FindNext(sr); - end; - FindClose(sr); -end; - -function liesMakeFile(datNam: string; out Abh: TAbhaengigkeiten; out dats: TDateienMitDaten): boolean; -var f: textfile; - s,t: string; - NA: TAbhaengigkeit; - ignoriere: array of tRegExpr; - beg,fin,rek: boolean; - wo,num,i: integer; -begin - result:=false; - - NA:=TAbhaengigkeit.create; - setlength(dats,0); - setlength(Abh,0); - setlength(ignoriere,0); - wo:=0; - num:=0; - assignfile(f,datNam); - reset(f); - while liesZeile(f,s) do begin - if wo=0 then begin - if notQuotedPos(':',s)=0 then begin - s:=trim(s); - if length(s)=0 then continue; - 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 - s:=s+' '; - rek:=pos('-r',s)=1; - if rek then delete(s,1,pos(' ',s)); - while pos(' ',s)>0 do begin - sammleDateien(copy(s,1,pos(' ',s)-1),rek,ignoriere,dats); - delete(s,1,pos(' ',s)); - end; - end; - end - else begin - for i:=0 to length(ignoriere)-1 do - ignoriere[i].free; - setlength(ignoriere,0); - wo:=1; - end; - end; - if wo=1 then begin - fin:=s[length(s)]=';'; - if fin then delete(s,length(s),1); - beg:=not (s[1] in [' ',#9]); - if (notQuotedPos(':',s)=0) and beg then begin - closefile(f); - writeln('In der Quell-Ziel-Zuordnung muss ein (unzitierter) Doppelpunkt auftauchen!'); - exit; - end; - if beg then begin - SetLength(NA.Quellen,0); - NA.QuellenRE.Expression:=''; - SetLength(NA.Ziele,0); - NA.ZieleFkt.Clear; - NA.AbhArt:=aaFinal; - if pos('1>1 ',s)=1 then NA.AbhArt:=aaEinsZuEins; - if pos('n>n ',s)=1 then NA.AbhArt:=aaNZuN; - if NA.AbhArt=aaFinal then NA.AbhArt:=aaNZuN // der Standard - else delete(s,1,pos(' ',s)); - t:=copy(s,1,notQuotedPos(':',s)-1)+' '; - while pos(' ',t)>0 do begin - while pos(' ',t)=1 do delete(t,1,1); - NA.ZieleFkt.Add(copy(t,1,pos(' ',t)-1)); - delete(t,1,pos(' ',t)); - end; - delete(s,1,notQuotedPos(':',s)); - while pos(' ',s)=1 do delete(s,1,1); - NA.QuellenRE.Expression:=s; - end - else begin - while s[1] in [' ',#9] do - delete(s,1,1); - while unescapedpos(';',s)>0 do - s:=copy(s,1,unescapedpos(';',s)-1)+' &&'+copy(s,unescapedpos(';',s)+1,length(s)-unescapedpos(';',s)); - while pos(';;',s)>0 do - delete(s,pos(';;',s),1); - NA.Befehle.Add(s); - end; - if fin then begin - setlength(Abh,length(Abh)+1); - getmem(Abh[length(Abh)-1],sizeof(TAbhaengigkeit)); - fillchar(Abh[length(Abh)-1]^,sizeof(TAbhaengigkeit),0); - Abh[length(Abh)-1]^:=TAbhaengigkeit.create(NA); - Abh[length(Abh)-1]^.Prioritaet:=num; - inc(num); - SetLength(NA.Quellen,0); - NA.QuellenRE.Expression:=''; - SetLength(NA.Ziele,0); - NA.ZieleFkt.Clear; - setlength(NA.Erben,0); - NA.Befehle.Clear; - end; - end; - end; - closefile(f); - NA.free; - for i:=0 to length(ignoriere)-1 do - ignoriere[i].free; - setlength(ignoriere,0); - - result:=true; -end; - -function liesPruefsummenfile(sumNam: string; var dats: tDateienMitDaten; jetzt: extended): boolean; -var f: textfile; - i,j: longint; - gutschlecht: tStringlistBArray; - gefunden,gut: boolean; + f: textfile; + i,j: longint; + gutschlecht: tStringlistBArray; + gefunden,gut: boolean; begin result:=false; if sumNam='' then begin - writeln('Leerer Name als Summendatei angegeben!'); + writeln('Leerer Name als summendatei angegeben!'); exit; end; @@ -267,7 +41,7 @@ begin closefile(f); end; if not fileexists(sumNam) then begin - writeln('Ich bin nicht in der lage die bisher nicht existierende Date '''+sumNam+''' anzulegen!'); + writeln('Ich bin nicht in der Lage, die bisher nicht existierende Datei '''+sumNam+''' anzulegen!'); exit; end; @@ -277,23 +51,20 @@ begin 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 - dats[j]^.Datum:=jetzt*byte(not gut) + 1; - // Prüfsumme OK => Datei formal (ur)alt: - // -> immer überschreiben, wenn es eine Quelle ohne (gültige) Prüfsumme gibt oder diese entstehen wird - // -> von sich aus nie Auslöser für Kompilation (außer eines der Ziele existiert nicht) - // Prüfsumme nicht OK => Datei formal von morgen: - // -> löst Kompilation aus, wenn es eine Quelle ist - // -> wird weiterhin durch Kompilation als Ziel erneuert + 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, + 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 - getmem(dats[length(dats)-1],sizeof(tDateiMitDatum)); - dats[length(dats)-1]^.Name:=gutschlecht[gut][i]; - dats[length(dats)-1]^.Datum:=0; // siehe oben + 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]+'''!'); @@ -308,375 +79,254 @@ begin result:=true; end; -function unescape(s: string): string; -begin - result:=s; - while pos('\,',result)>0 do - delete(result,pos('\,',result),1); -end; - -function escape(s,toe: string; ec: char): string; -var i,j: longint; - b: boolean; -begin - result:=''; - for i:=1 to length(s) do begin - b:=false; - for j:=1 to length(toe) do - b:=b or (toe[j]=s[i]); - if b then result:=result+ec; - result:=result+s[i]; - end; -end; - -function Quellersetzung(var worin: string; Quelle, inputfile: string): boolean; -var s,t: string; - i,a,e: integer; -begin - result:=false; - while pos('%nurmit''',worin)>0 do begin - i:=pos('%nurmit''',worin); - while worin[i]<>'''' do inc(i); - repeat - inc(i); - until worin[i]=''''; - if pos(copy(worin,pos('%nurmit''',worin)+8,i-pos('%nurmit''',worin)-8),Quelle)=0 then - exit; - delete(worin,pos('%nurmit''',worin),i-pos('%nurmit''',worin)+1); - end; - while pos('%nurohne''',worin)>0 do begin - i:=pos('%nurohne''',worin); - while worin[i]<>'''' do inc(i); - repeat - inc(i); - until worin[i]=''''; - if pos(copy(worin,pos('%nurohne''',worin)+9,i-pos('%nurohne''',worin)-9),Quelle)>0 then - exit; - delete(worin,pos('%nurohne''',worin),i-pos('%nurohne''',worin)+1); - end; - result:=true; - 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('%basedir(',worin)>0 do begin - a:=pos('%basedir(',worin); - s:=copy(worin,1,a-1); - while (a<=length(worin)) and (worin[a]<>'(') do - inc(a); - e:=a; - while (e<=length(worin)) and (worin[e]<>')') do - inc(e); - i:=strtoint(copy(worin,a+1,e-a-1)); - if (e0 do begin - while (a>0) and (t[a]='/') do - dec(a); - while (a>0) and (t[a]<>'/') do - dec(a); - dec(i); - end; - delete(t,1,a); - worin:=s+t+copy(worin,e+1,length(worin)); - end; - s:=extractfilepath(Quelle); - while pos('%basedir/',worin)>0 do - worin:=copy(worin,1,pos('%basedir/',worin)-1)+s+copy(worin,pos('%basedir/',worin)+9,length(worin)); - while pos('%basedir',worin)>0 do - worin:=copy(worin,1,pos('%basedir',worin)-1)+s+copy(worin,pos('%basedir',worin)+8,length(worin)); - while pos('%BASEDIR/',worin)>0 do - worin:=copy(worin,1,pos('%BASEDIR/',worin)-1)+extractfilepath(inputfile)+copy(worin,pos('%BASEDIR/',worin)+9,length(worin)); - while pos('%BASEDIR',worin)>0 do - worin:=copy(worin,1,pos('%BASEDIR',worin)-1)+extractfilepath(inputfile)+copy(worin,pos('%BASEDIR',worin)+8,length(worin)); - while pos('%num''',worin)>0 do begin - a:=pos('%num''',worin); - e:=a; - while (e<=length(worin)) and (worin[e]<>'''') do - inc(e); - inc(e); - while (e<=length(worin)) and (worin[e]<>'''') do - inc(e); - s:=copy(worin,a,e-a-1); - for i:=length(s) downto 1 do - if s[i] in ['0'..'9'] then - break - else - delete(s,i,1); - for i:=length(s) downto 1 do - if not (s[i] in ['0'..'9']) then begin - delete(s,1,i); - break; - end; - worin:=copy(worin,1,a-1)+s+copy(worin,e+1,length(worin)); - end; -end; - -function bashMatch(was,worauf: string): boolean; -var RE: TRegExpr; -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; - -procedure ZieleHinzufuegen(var Ziele: TDateienMitDaten; Ziel,Quelle,inputfile: string; var dats: TDateienMitDaten); -var i,Anz,Ende: integer; - s,t,u: string; - wasda: boolean; +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); + if pos('{',ziel)=0 then begin + if not quellersetzung(ziel,quelle,inputfile) then exit; + ziel:=unescape(ziel); i:=0; wasda:=false; while i0) or (Ziel[Ende]<>'}') do begin - inc(Ende); - case Ziel[Ende] of - '{': inc(Anz); - '}': dec(Anz); + 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)); + 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); + 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); + 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 findeZiele(out Ziele: TDateienMitDaten; ZieleFkt: TStringList; Quelle,inputfile: string; var dats: TDateienMitDaten); +procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); +var + i: integer; begin - setlength(Ziele,0); - findeMehrZiele(Ziele,ZieleFkt,Quelle,inputfile,dats); + 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; jetzt: extended); -var i,j,k,l: integer; - neues,schonda: boolean; - quNeu, - ziAlt: TDateTime; - s: string; +procedure findeWasZuTunIst(var mgl: tAbhaengigkeiten; out zuTun: tAbhaengigkeiten; var dats: tDateienMitDaten; inputfile: string); +var + i,j,k,l: integer; + neues,schonDa: boolean; + s: string; + tmpZiele: tDateienMitDaten; + ziA,quA: tAktualitaet; begin setlength(zuTun,0); repeat neues:=false; i:=0; while i0) then begin // Quellen stehen schon fest, noch nicht auszuführen - if length(mgl[i]^.Ziele)=0 then begin - 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!'); - mgl[i]^.AbhArt:=aaIgnore; - continue; + 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; - quNeu:=mgl[i]^.Quellen[0]^.Datum; - for j:=1 to length(mgl[i]^.Quellen)-1 do // neueste Quelle ermitteln - quNeu:=max(quNeu,mgl[i]^.Quellen[j]^.Datum); - ziAlt:=mgl[i]^.Ziele[0]^.Datum; - for j:=1 to length(mgl[i]^.Ziele)-1 do // ältestes Ziel ermitteln - ziAlt:=min(ziAlt,mgl[i]^.Ziele[j]^.Datum); - - if ziAlt ',mgl[i]^.Befehle.text); - SetLength(zuTun,length(zuTun)+1); - getmem(zuTun[length(zuTun)-1],sizeof(TAbhaengigkeit)); - fillchar(zuTun[length(zuTun)-1]^,sizeof(TAbhaengigkeit),0); - 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]^.Datum:=jetzt+2; // neu erzeugte Dateien sind dann formal von übermorgen + + quA:=aAktuell; + for j:=0 to length(mgl[i].quellen)-1 do + if mgl[i].quellen[j].aktuell<>aAktuell then + quA:=aWirdErneuert; + ziA:=aWirdErneuert; + for j:=0 to length(mgl[i].ziele)-1 do + ziA:=min(ziA,mgl[i].ziele[j].aktuell); + + if ziA ',mgl[i].befehle.text); + setlength(zuTun,length(zuTun)+1); + zuTun[length(zuTun)-1]:=tAbhaengigkeit.create(mgl[i]); + setlength(mgl[i].erben,1); + mgl[i].erben[0]:=zuTun[length(zuTun)-1]; + for j:=0 to length(mgl[i].ziele)-1 do + mgl[i].ziele[j].aktuell:=aWirdErneuert; neues:=true; end; end; - aaIgnore: ; // keine Ziele + 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; +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<>''; + befehle:=tStringlist.create; + prior:=0; + ms:=summendatei<>''; for i:=0 to length(zuTun)-1 do - Prior:=max(Prior,zuTun[i]^.Prioritaet); + prior:=max(prior,zuTun[i].prioritaet); if ms then begin - geaenderteDateien:=TStringlist.create; - sumDateien:=dateienMitGueltigerSumme(Summendatei); + 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); + 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 + if sumDateien[j]=dats[i].name then begin gefunden:=true; sumDateien.delete(j); break; end; if not gefunden then - geaenderteDateien.add(dats[i]^.name); + 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); + 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); + 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 + 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); + 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)+'/' + 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.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 @@ -687,133 +337,134 @@ begin end; for j:=0 to i-1 do if geaenderteDateien[i]=geaenderteDateien[j] then begin - geaenderteDateien.Delete(i); + geaenderteDateien.delete(i); break; end; end; if geaenderteDateien.count>0 then - Befehle.Add('echo -ne "Sha512summen erneuern ..."'); + befehle.add('echo -ne "Sha512summen erneuern ..."'); for i:=0 to geaenderteDateien.count-1 do - Befehle.Add('/usr/bin/sha512sum "'+geaenderteDateien[i]+'" >> '+Summendatei); + befehle.add('/usr/bin/sha512sum "'+geaenderteDateien[i]+'" >> '+summendatei); if geaenderteDateien.count>0 then - Befehle.Add('echo " fertig"'); + befehle.add('echo " fertig"'); if not nurAnzeigen then begin alteDateien:=tStringlist.create; - alteDateien.LoadFromFile(Summendatei); - for i:=alteDateien.Count-1 downto 0 do + 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.saveToFile(summendatei); alteDateien.free; end; end; if length(zuTun)=0 then - Befehle.Add('echo "Es gibt hier nichts zu tun!"'); + 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]); + 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); + 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; + befehle.free; if ms then - geaenderteDateien.Free; + geaenderteDateien.free; end; -{ TMake } +{ tMake } -procedure TMake.DoRun; +procedure tMake.doRun; var - inputfile,pruefsummenfile,ErrorMsg: String; - mglAbhaengigkeiten,zutunAbhaengigkeiten: TAbhaengigkeiten; - Dateien: TDateienMitDaten; + inputfile,pruefsummenfile,errorMsg: string; + mglAbhaengigkeiten,zutunAbhaengigkeiten: tAbhaengigkeiten; + dateien: tDateienMitDaten; + i: longint; begin - ErrorMsg:=CheckOptions('A:HWD:P:au','Ausgabe: Hilfe Watte Datei: Prüfsummen: alleSummenErneuern unsicher'); - if ErrorMsg<>'' then begin - ShowException(Exception.Create(ErrorMsg+#10'Hilfe: '+Exename+' -H/--Hilfe')); - Terminate; - Exit; + errorMsg:=checkOptions('A:HWD:P:au','Ausgabe: Hilfe Watte Datei: Prüfsummen: alleSummenErneuern unsicher'); + if errorMsg<>'' then begin + showException(exception.create(errorMsg+#10'Hilfe: '+exename+' -H/--Hilfe')); + terminate; + exit; end; - if HasOption('H','Hilfe') then begin - WriteHelp; - Terminate; - Exit; + if hasOption('H','Hilfe') then begin + writeHelp; + terminate; + exit; end; - if (GetOptionValue('A','Ausgabe')='') and not HasOption('W','Watte') then begin - ShowException(Exception.Create('Ausgabedatei wird benötigt!')); - Terminate; - Exit; + 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') + if hasOption('D','Datei') then inputfile:=getOptionValue('D','Datei') else inputfile:='Machdatei'; - if HasOption('P','Prüfsummen') then pruefsummenfile:=GetOptionValue('P','Prüfsummen') - else pruefsummenfile:=''; - - if HasOption('a','alleSummenErneuern') and (pruefsummenfile='') then begin - ShowException(Exception.Create('Ich kann alle Summen nur dann erneuern (-a/--alleSummenErneuern), wenn ich eine Prüfsummendatei habe (-P/--Pfrüfsummen)!')); - Terminate; - Exit; + if hasOption('P','Prüfsummen') then pruefsummenfile:=getOptionValue('P','Prüfsummen') + else begin + showException(exception.create('Prüfsummendatei wird benötigt!')); + terminate; + exit; end; if fileexists(inputfile) then begin - if not liesMakeFile(inputfile,mglAbhaengigkeiten,Dateien) then begin - ShowException(Exception.Create('Datei '''+inputfile+''' ist fehlerhaft!')); - Terminate; - Exit; + 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; + showException(exception.create('Datei '''+inputfile+''' existiert nicht!')); + terminate; + exit; end; - if (pruefsummenfile<>'') and - (not liesPruefsummenfile(pruefsummenfile,Dateien,now)) then begin - ShowException(Exception.Create('Datei '''+pruefsummenfile+''' ist fehlerhaft!')); - Terminate; - Exit; + if not liesPruefsummenfile(pruefsummenfile,dateien) then begin + showException(exception.create('Datei '''+pruefsummenfile+''' ist fehlerhaft!')); + terminate; + exit; end; - writeln('Regeln: '+inttostr(length(mglAbhaengigkeiten))+', Dateien: '+inttostr(length(Dateien))); - findeWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,Dateien,inputfile,now); + for i:=0 to length(dateien)-1 do + writeln(dateien[i].aktuell,' ',dateien[i].name); + + 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); + tueWasZuTunIst(mglAbhaengigkeiten,zuTunAbhaengigkeiten,dateien,hasOption('W','Watte'),hasOption('a','alleSummenErneuern'),hasOption('u','unsicher'),getOptionValue('A','Ausgabe'),pruefsummenfile); - Terminate; + terminate; end; -constructor TMake.Create(TheOwner: TComponent); +constructor tMake.create(theOwner: tComponent); begin - inherited Create(TheOwner); - StopOnException:=True; + inherited create(theOwner); + stopOnException:=True; end; -procedure TMake.WriteHelp; +procedure tMake.writeHelp; begin writeln('Verwendung:'); - writeln(' ',ExeName,' -A/--Ausgabe $Ausgabedatei -H/--Hilfe -W/--Watte -D/--Datei $Machdatei -P/--Prüfsummen $Prüfsummendatei -a/--alleSummenErneuern -u/--unsicher'); + writeln(' ',exeName,' -A/--Ausgabe $ausgabedatei -H/--Hilfe -W/--Watte -D/--Datei $Machdatei -P/--Prüfsummen $Prüfsummendatei -a/--alleSummenErneuern -u/--unsicher'); end; var - Application: TMake; + application: tMake; begin - Application:=TMake.Create(nil); - Application.Run; - Application.Free; + application:=tMake.create(nil); + application.run; + application.free; end. diff --git a/Make.lps b/Make.lps index bb8a15f..2ca12b1 100644 --- a/Make.lps +++ b/Make.lps @@ -3,178 +3,199 @@ - + - - - - + + + + - + - - - - + + + + + - - + + + + - + - + - + + + + + + + + + + + + + + + + + + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - + - + - + - + - + - - + + - - + + - - + + - + - + - + - - + + - - + + - + - + - + - + diff --git a/dateibeziehungen.pas b/dateibeziehungen.pas new file mode 100644 index 0000000..5296dd0 --- /dev/null +++ b/dateibeziehungen.pas @@ -0,0 +1,329 @@ +unit dateiBeziehungen; + +{$mode objfpc}{$H+} + +interface + +uses + classes, sysUtils, tools, regExpr; + +type + tAbhArt = (aaFinal,aaPrimaer,aaIgnore); + tZeilenTyp = (ztSuche,ztZiel,ztQuelle,ztBefehl); + + tAbhaengigkeit = class; + tAbhaengigkeiten = array of tAbhaengigkeit; + tAbhaengigkeit = class(tObject) + abhArt: tAbhArt; + quellenRE: tRegExpr; + zieleFkt, + befehle: tStringlist; + quellen, + ziele: tDateienMitDaten; + erben: tAbhaengigkeiten; + prioritaet: integer; + constructor create; overload; + constructor create(original: tAbhaengigkeit); overload; + destructor destroy; override; + 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; + +implementation + +uses + lowlevelunit, mystringlistunit; + +// tAbhaengigkeit ************************************************************** + +constructor tAbhaengigkeit.create; +begin + inherited create; + quellenRE:=tRegExpr.create; + quellenRE.expression:=''; + zieleFkt:=tStringlist.create; + setlength(quellen,0); + setlength(ziele,0); + befehle:=tStringlist.create; + setlength(erben,0); + abhArt:=aaIgnore; + prioritaet:=42; +end; + +constructor tAbhaengigkeit.create(original: tAbhaengigkeit); +var + i: integer; +begin + inherited create; + quellenRE:=tRegExpr.create; + quellenRE.expression:=original.quellenRE.expression; + zieleFkt:=tStringlist.create; + zieleFkt.text:=original.zieleFkt.text; + setlength(quellen,length(original.quellen)); + for i:=0 to length(original.quellen)-1 do + quellen[i]:=original.quellen[i]; + setlength(ziele,length(original.ziele)); + for i:=0 to length(original.ziele)-1 do + 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]; + prioritaet:=original.prioritaet; + abhArt:=original.abhArt; +end; + +destructor tAbhaengigkeit.destroy; +begin + quellenRE.free; + setLength(quellen,0); + setLength(ziele,0); + zieleFkt.free; + befehle.free; + setlength(erben,0); + inherited destroy; +end; + +// allgemeine Funktionen ******************************************************* + +function quellersetzung(var worin: string; quelle, inputfile: string): boolean; +var + s,anfang,mitte: string; + i,li,re: integer; +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); + 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)); + while pos('%num''',worin)>0 do begin + anfang:=erstesArgument(worin,'%num'''); + mitte:=erstesArgument(worin,''''); + for i:=length(mitte) downto 1 do + if mitte[i] in ['0'..'9'] then + break + else + delete(mitte,i,1); + for i:=length(mitte) downto 1 do + if not (mitte[i] in ['0'..'9']) then begin + delete(mitte,1,i); + break; + 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; + +procedure sammleDateien(wo: string; rekursiv: boolean; ignoriere: array of tRegExpr; var dats: tDateienMitDaten); +var + sr: tSearchRec; + err,i: integer; + weglassen: boolean; +begin + err:=FindFirst(wo,fareadOnly or faHidden or faSysFile or (byte(rekursiv)*faDirectory),sr); + while err=0 do begin + weglassen:=false; + for i:=0 to length(ignoriere)-1 do + weglassen:=weglassen or ignoriere[i].exec(extractfilepath(wo)+sr.name); + 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+'/'+extractfilename(wo),rekursiv,ignoriere,dats); + end + else begin + 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; + end; + end; + err:=FindNext(sr); + end; + findClose(sr); +end; + +function liesMakeFile(datNam: string; out abh: tAbhaengigkeiten; out dats: tDateienMitDaten): 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; + 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; + 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; + 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; + +end. + diff --git a/tools.pas b/tools.pas index 49a9251..3d7c895 100644 --- a/tools.pas +++ b/tools.pas @@ -5,20 +5,32 @@ unit tools; interface uses - Classes, SysUtils, Process, mystringlistunit, regExpr; + classes, sysUtils, process, mystringlistunit, regExpr; type + tAktualitaet = (aVeraltet,aAktuell,aWirdErneuert); tStringlistBArray = array[boolean] of tStringlist; tSummenDatei = record name: string; inhalt: tStringlistBArray; end; + tDateiMitDatum = class + name: ansiString; + aktuell: tAktualitaet; + end; + tDateienMitDaten = array of tDateiMitDatum; +function min(a1,a2: tAktualitaet): tAktualitaet; overload; +function max(a1,a2: tAktualitaet): tAktualitaet; overload; function anzCs(c: char; s: string): longint; function notQuotedPos(was,worin: string): longint; function unescapedpos(was,worin: string): integer; procedure testeObBefehlLokal(bef, ordner: string; lokTest: tRegExpr); function extrahiereAlleDateien(woraus: string): tMyStringList; +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; // Routinen für sha512-Prüfsummen @@ -27,8 +39,25 @@ function dateienMitGueltigerSumme(sumNam: string): tStringList; implementation +function min(a1,a2: tAktualitaet): tAktualitaet; +begin + if a1a2 then + result:=a1 + else + result:=a2; +end; + function anzCs(c: char; s: string): longint; -var i: longint; +var + i: longint; begin result:=0; for i:=1 to length(s) do @@ -51,18 +80,19 @@ begin end; function unescapedpos(was,worin: string): integer; -var Ebene: longint; +var + ebene: longint; begin result:=0; - Ebene:=0; + ebene:=0; while pos(was,copy(worin,result+1,length(worin)))>0 do begin repeat result:=result+1; case worin[result] of - '{': inc(Ebene); - '}': dec(Ebene); + '{': inc(ebene); + '}': dec(ebene); end; - until (result>=length(worin)) or ((copy(worin,result,length(was))=was) and (Ebene=0)); + until (result>=length(worin)) or ((copy(worin,result,length(was))=was) and (ebene=0)); if ((result=1) or ((worin[result-1]<>'\') and (worin[result-1]<>was))) and ((result=length(worin)) or (worin[result+1]<>was)) and @@ -104,25 +134,25 @@ begin // set output "~/Dokumente/Erich_Masterarbeit/Bilder/gnuplot/Energiescan.tex" regex:='^ *set +output +'; re:=tRegExpr.create; - re.Expression:='"[^"]*/[^"]*"'; + re.expression:='"[^"]*/[^"]*"'; end else if exe='epost' then begin // Datei: regex:='^ *(Datei|Legende): *'; re:=tRegExpr.create; - re.Expression:='[^ :]*/[^ ]*'; + re.expression:='[^ :]*/[^ ]*'; end else if exe='math' then begin // das wird vmtl. schwer zu überprüfen, außer man nimmt Muster, // die generisch auf Pfade passen, aber dann erwischt man auch den Input mit ... regex:='^([^"]*"[^"]*")*[^"]*"([^"]*/)+[^"]*"'; re:=tRegExpr.create; - re.Expression:='"[^"]*/[^"]*"'; + re.expression:='"[^"]*/[^"]*"'; end else exit; - // folgende Executables sind unkritisch, da der Name des Outputs i.d.R. direkt - // vom Namen des Inputs abhängt bzw. per Kommandozeilenparameter übergeben + // folgende executables sind unkritisch, da der name des outputs i.d.R. direkt + // vom namen des Inputs abhängt bzw. per Kommandozeilenparameter übergeben // wird (und nicht in einer Datei steht): // // 'convert' @@ -146,17 +176,17 @@ begin dateien.free; for i:=0 to relZeil.count-1 do begin - re.InputString:=relZeil[i]; - if re.SubExprMatchCount=0 then - writeln('*** Warnung: Hier ist eine Zeile in der Optionsdatei, die keine passende Inputdatei benennt, es aber sollte! ('''+relZeil[i]+''')!'); - for j:=0 to re.SubExprMatchCount-1 do begin - s:=trim(re.Match[j]); + re.inputString:=relZeil[i]; + if re.subExprMatchCount=0 then + writeln('*** Warnung: Hier ist eine Zeile in der optionsdatei, die keine passende Inputdatei benennt, es aber sollte! ('''+relZeil[i]+''')!'); + for j:=0 to re.subExprMatchCount-1 do begin + s:=trim(re.match[j]); if (leftStr(s,1)='"') and (rightStr(s,1)='"') then begin delete(s,1,1); delete(s,length(s),1); end; - if not lokTest.Exec(s) then begin - writeln('*** FEHLER: '''+relZeil[i]+''' in Befehl '''+oBef+''' hat Lokalitätstest nicht bestanden! ('+lokTest.Expression+')'); + if not lokTest.exec(s) then begin + writeln('*** FEHLER: '''+relZeil[i]+''' in Befehl '''+oBef+''' hat Lokalitätstest nicht bestanden! ('+lokTest.expression+')'); halt(1); end; end; @@ -180,46 +210,97 @@ begin end; end; +function unescape(s: string): string; +begin + result:=s; + while pos('\,',result)>0 do + delete(result,pos('\,',result),1); +end; + +function escape(s,toe: string; ec: char): string; +var i,j: longint; + b: boolean; +begin + result:=''; + for i:=1 to length(s) do begin + b:=false; + for j:=1 to length(toe) do + b:=b or (toe[j]=s[i]); + if b then result:=result+ec; + result:=result+s[i]; + end; +end; + +function bashMatch(was,worauf: string): boolean; +var + re: tRegExpr; +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; + end; +end; + // Routinen für sha512-Prüfsummen var - Summenvorrat: array of tSummenDatei; + summenvorrat: array of tSummenDatei; function testeSummen(sumNam: string): tStringlistBArray; -var p: tProcess; - rb,i: longint; - s: string; - erg: tStringlist; - gut: boolean; +var + p: tProcess; + rb,i: longint; + s: string; + erg: tStringlist; + gut: boolean; const leseHappen=65536; begin - for i:=0 to length(Summenvorrat)-1 do - if Summenvorrat[i].name=sumNam then begin + for i:=0 to length(summenvorrat)-1 do + if summenvorrat[i].name=sumNam then begin for gut:=false to true do begin result[gut]:=tStringlist.create; - result[gut].text:=Summenvorrat[i].inhalt[gut].text; + result[gut].text:=summenvorrat[i].inhalt[gut].text; end; exit; end; p:=tProcess.create(nil); - p.Executable:='/usr/bin/sha512sum'; - p.Parameters.add('-c'); - p.Parameters.add(sumNam); - p.Options:=p.Options + [poUsePipes]; - p.Execute; + p.executable:='sha512sum'; + p.parameters.add('-c'); + p.parameters.add(sumNam); + p.options:=p.options + [poUsePipes]; + p.execute; rb:=0; s:=''; - while p.Running do begin - if p.Output.NumBytesAvailable=0 then sleep(10) + while p.running do begin + if p.output.numBytesAvailable=0 then sleep(10) else begin setlength(s,rb+leseHappen); - rb:=rb+p.Output.Read(s[rb+1],leseHappen); + rb:=rb+p.output.read(s[rb+1],leseHappen); end; end; - if p.Output.NumBytesAvailable>0 then begin + if p.output.numBytesAvailable>0 then begin setlength(s,rb+leseHappen); - rb:=rb+p.Output.Read(s[rb+1],leseHappen); + rb:=rb+p.output.read(s[rb+1],leseHappen); end; p.free; setlength(s,rb); @@ -237,8 +318,8 @@ begin end; erg.free; - setlength(Summenvorrat,length(Summenvorrat)+1); - with Summenvorrat[length(Summenvorrat)-1] do begin + setlength(summenvorrat,length(summenvorrat)+1); + with summenvorrat[length(summenvorrat)-1] do begin name:=sumNam; for gut:=false to true do begin inhalt[gut]:=tStringlist.create; @@ -260,15 +341,15 @@ var i: longint; initialization - setlength(Summenvorrat,0); + setlength(summenvorrat,0); finalization - for i:=0 to length(Summenvorrat)-1 do - with Summenvorrat[i] do begin + for i:=0 to length(summenvorrat)-1 do + with summenvorrat[i] do begin name:=''; inhalt[false].free; inhalt[true].free; end; - setlength(Summenvorrat,0); + setlength(summenvorrat,0); end. -- cgit v1.2.3-54-g00ecf