diff options
Diffstat (limited to 'Make.lpr')
-rw-r--r-- | Make.lpr | 887 |
1 files changed, 269 insertions, 618 deletions
@@ -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 (e<length(worin)) and (worin[e+1]='/') then - inc(e); - t:=extractfilepath(Quelle); - a:=length(t); - while i>0 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 i<length(dats) do begin - if bashMatch(Ziel,dats[i]^.Name) then begin + if bashMatch(ziel,dats[i].name) then begin wasda:=true; - SetLength(Ziele,length(Ziele)+1); - Ziele[length(Ziele)-1]:=dats[i]; + 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); - getmem(dats[i],sizeof(TDateiMitDatum)); - fillchar(dats[i]^,sizeof(TDateiMitDatum),0); - if pos('*',Ziel)=0 then dats[i]^.Name:=Ziel - else dats[i]^.Name:='.uralt.'; // unpassende *-Muster erzeugen formal keine echte Datei - dats[i]^.Datum:=0; // nicht existente Dateien sind formal uralt - SetLength(Ziele,length(Ziele)+1); - Ziele[length(Ziele)-1]:=dats[i]; + setlength(dats,length(dats)+1); + dats[i]:=tDateiMitDatum.create; + if pos('*',ziel)=0 then dats[i].name:=ziel + else dats[i].name:='.uralt.'; // unpassende *-Muster erzeugen formal keine echte Datei + dats[i].aktuell:=aVeraltet; // nicht existente dateien sind formal uralt + setlength(ziele,length(ziele)+1); + ziele[length(ziele)-1]:=dats[i]; end; end else begin - Ende:=pos('{',Ziel); - Anz:=1; - while (Anz>0) 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 i<length(mgl) do begin - case mgl[i]^.AbhArt of - aaNZuN: begin // alle Quellen werden mit einem Mal behandelt - if length(mgl[i]^.Erben)=0 then begin // noch keine davon abgeleitete Abhängigkeit vorhanden - SetLength(mgl,length(mgl)+1); - getmem(mgl[length(mgl)-1],sizeof(TAbhaengigkeiten)); - fillchar(mgl[length(mgl)-1]^,sizeof(TAbhaengigkeiten),0); - mgl[length(mgl)-1]^:=TAbhaengigkeit.create; - SetLength(mgl[i]^.Erben,1); - mgl[i]^.Erben[0]:=mgl[length(mgl)-1]; - mgl[length(mgl)-1]^.AbhArt:=aaFinal; - mgl[length(mgl)-1]^.Prioritaet:=mgl[i]^.Prioritaet; - mgl[length(mgl)-1]^.ZieleFkt.Text:=mgl[i]^.ZieleFkt.Text; - mgl[length(mgl)-1]^.Befehle.Text:=mgl[i]^.Befehle.Text; - end; - for j:=0 to length(dats)-1 do - if mgl[i]^.QuellenRE.Exec(dats[j]^.Name) then begin - schonda:=false; - for k:=0 to length(mgl[i]^.Erben[0]^.Quellen)-1 do - schonda:=schonda or (mgl[i]^.Erben[0]^.Quellen[k]=dats[j]); - if schonda then continue; - - SetLength(mgl[i]^.Erben[0]^.Quellen,length(mgl[i]^.Erben[0]^.Quellen)+1); - mgl[i]^.Erben[0]^.Quellen[length(mgl[i]^.Erben[0]^.Quellen)-1]:=dats[j]; - - for k:=0 to mgl[i]^.Befehle.Count-1 do begin - s:=mgl[i]^.Befehle[k]; - if Quellersetzung(s,dats[j]^.Name,inputfile) then begin - if k=0 then mgl[i]^.Erben[0]^.Befehle.Clear; - mgl[i]^.Erben[0]^.Befehle.Add(s); - end; - end; - end; - end; - aaEinsZuEins: begin // jede Quelle muss einzeln behandelt werden + case mgl[i].abhArt of + aaPrimaer: for j:=0 to length(dats)-1 do - if mgl[i]^.QuellenRE.Exec(dats[j]^.Name) then begin - schonda:=false; - for k:=0 to length(mgl[i]^.Erben)-1 do - for l:=0 to length(mgl[i]^.Erben[k]^.Quellen)-1 do - schonda:=schonda or (mgl[i]^.Erben[k]^.Quellen[l]=dats[j]); - - if schonda then continue; - - SetLength(mgl,length(mgl)+1); - getmem(mgl[length(mgl)-1],sizeof(TAbhaengigkeit)); - fillchar(mgl[length(mgl)-1]^,sizeof(TAbhaengigkeiten),0); - mgl[length(mgl)-1]^:=TAbhaengigkeit.create; - SetLength(mgl[i]^.Erben,length(mgl[i]^.Erben)+1); - mgl[i]^.Erben[length(mgl[i]^.Erben)-1]:=mgl[length(mgl)-1]; - mgl[length(mgl)-1]^.AbhArt:=aaFinal; - SetLength(mgl[length(mgl)-1]^.Quellen,1); - mgl[length(mgl)-1]^.Quellen[0]:=dats[j]; - mgl[length(mgl)-1]^.ZieleFkt:=mgl[i]^.ZieleFkt; -// findeZiele(mgl[length(mgl)-1]^.Ziele,mgl[i]^.ZieleFkt,dats[j]^.name,inputfile,dats); // sollte unten geschehen - mgl[length(mgl)-1]^.Befehle.Clear; - for k:=0 to mgl[i]^.Befehle.Count-1 do begin - s:=mgl[i]^.Befehle[k]; - if Quellersetzung(s,dats[j]^.Name,inputfile) then - mgl[length(mgl)-1]^.Befehle.Add(s); + if mgl[i].quellenRE.exec(dats[j].name) then begin + schonDa:=false; + for k:=0 to length(mgl[i].erben)-1 do + for l:=0 to length(mgl[i].erben[k].quellen)-1 do + schonDa:=schonDa or (mgl[i].erben[k].quellen[l]=dats[j]); + + // Falls diese Quelle schon in eine Regel einfließt, brauchen + // wir nichts mehr zu machen, da es für jede Quelle höchstens + // eine Regel gibt. + if schonDa then continue; + + // Andernfalls müssen wir schauen, ob es zu dem ziel / den Zielen + // der Quelle schon eine Regel gibt. + schonDa:=false; + setlength(tmpZiele,0); + findeMehrZiele(tmpZiele,mgl[i].zieleFkt,dats[j].name,inputfile,dats); + + if length(tmpZiele)=0 then begin + writeln('Fehler: Keine ziele für Abhängigkeit!'); + writeln('Quelle:'); + writeln(''''+dats[j].name+''''); + writeln('Ziele:'); + for k:=0 to mgl[i].zieleFkt.count-1 do + writeln(' '''+mgl[i].zieleFkt[k]+''''); + halt(1); end; - if mgl[length(mgl)-1]^.Befehle.Count=0 then begin - writeln('Fehler: Keine Befehle für diese Abhängigkeit auszuführen!'); - halt; + + for k:=0 to length(mgl[i].erben)-1 do + if gleicheDateinamen(mgl[i].erben[k].ziele,tmpZiele) then begin + // es gibt schon eine Regel für die Ziele der Quelle + schonDa:=true; + // dann wird dieser Regel nur die Quelle hinzugefügt + setlength(mgl[i].erben[k].quellen,length(mgl[i].erben[k].quellen)+1); + mgl[i].erben[k].quellen[length(mgl[i].erben[k].quellen)-1]:=dats[j]; + // und womöglich die befehle generiert + for l:=0 to mgl[i].befehle.count-1 do begin + s:=mgl[i].befehle[l]; + if quellersetzung(s,dats[j].name,inputfile) then begin + if l=0 then mgl[i].erben[k].befehle.clear; + mgl[i].erben[k].befehle.add(s); + end; + end; + break; // mehr Ziele sollte es ohnehin nicht geben + end; + if schonDa then continue; + + // ziel(e) ist/sind neu + setlength(mgl,length(mgl)+1); + mgl[length(mgl)-1]:=tAbhaengigkeit.create; + setlength(mgl[i].erben,length(mgl[i].erben)+1); + mgl[i].erben[length(mgl[i].erben)-1]:=mgl[length(mgl)-1]; + mgl[length(mgl)-1].abhArt:=aaFinal; + setlength(mgl[length(mgl)-1].quellen,1); + mgl[length(mgl)-1].quellen[0]:=dats[j]; + mgl[length(mgl)-1].zieleFkt:=mgl[i].zieleFkt; + setlength(mgl[length(mgl)-1].ziele,length(tmpZiele)); + for i:=0 to length(tmpZiele)-1 do + mgl[length(mgl)-1].ziele[i]:=tmpZiele[i]; + mgl[length(mgl)-1].befehle.clear; + for k:=0 to mgl[i].befehle.count-1 do begin + s:=mgl[i].befehle[k]; + if quellersetzung(s,dats[j].name,inputfile) then + mgl[length(mgl)-1].befehle.add(s); end; - mgl[length(mgl)-1]^.Prioritaet:=mgl[i]^.Prioritaet; - end; - end; - aaFinal: if (length(mgl[i]^.Erben)=0) and - (length(mgl[i]^.Quellen)<>0) 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<quNeu then begin - writeln(ziAlt,' ',quNeu,' ',jetzt,' ',mgl[i]^.Ziele[0]^.Name,' ',length(mgl[i]^.Ziele),' -> ',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<quA then begin + writeln(ziA,' ',quA,' ',mgl[i].ziele[0].name,' ',length(mgl[i].ziele)); + writeln(' -> ',mgl[i].befehle.text); + setlength(zuTun,length(zuTun)+1); + zuTun[length(zuTun)-1]:=tAbhaengigkeit.create(mgl[i]); + setlength(mgl[i].erben,1); + mgl[i].erben[0]:=zuTun[length(zuTun)-1]; + for j:=0 to length(mgl[i].ziele)-1 do + mgl[i].ziele[j].aktuell:=aWirdErneuert; neues:=true; end; end; - aaIgnore: ; // keine Ziele + 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. |