unit dateiBeziehungen; {$mode objfpc}{$H+} interface uses classes, sysUtils, tools, regExpr; type tZeilenTyp = (ztSuche,ztZiel,ztQuelle,ztBefehl); pTAbhaengigkeit = ^tAbhaengigkeit; tAbhaengigkeit = class; tAbhaengigkeiten = class(tFPList) private function rItem(idx: longint): tAbhaengigkeit; inline; procedure wItem(idx: longint; neu: tAbhaengigkeit); inline; public property items[idx: longint]: tAbhaengigkeit read rItem write wItem; default; procedure kopiereVon(original: tAbhaengigkeiten); procedure mrProper; function add(neu: tAbhaengigkeit): longint; function last: tAbhaengigkeit; procedure sort; end; tAbhaengigkeit = class(tObject) private _erben,_eltern: tAbhaengigkeiten; public quellenRE: tRegExpr; zieleFkt, befehle: tStringlist; quellen, ziele: tDateienMitDaten; constructor create; overload; constructor create(original: tAbhaengigkeit); overload; 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); end; tMach = class private _machDatei,_pruefsummenDatei: string; _oriAbh,_mglAbh,_ztAbh: tAbhaengigkeiten; _dats: tDateienMitDaten; procedure wMachDatei(md: string); procedure wPruefsummenDatei(pd: string); function liesMachDatei: boolean; function liesPruefsummenfile: boolean; public property machDatei: string read _machDatei write wMachDatei; property pruefsummenDatei: string read _pruefsummenDatei write wPruefsummenDatei; constructor create; destructor destroy; override; procedure erzeugeRegeln; procedure findeWasZuTunIst; procedure tueWasZuTunIst(allesNeu, unsicher: boolean; ausgabeDatei: string); procedure setzeGenerischePruefsummenDatei; function anzOriAbh: longint; inline; function anzMglAbh: longint; inline; function anzZtAbh: longint; inline; function anzDats: longint; inline; end; function quellersetzung(var worin: string; quelle, inputfile: string): boolean; procedure sammleDateien(wo: string; rekursiv: boolean; ignoriere: array of tRegExpr; var dats: tDateienMitDaten); procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle,inputfile: string; var dats: tDateienMitDaten); procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); implementation uses lowlevelunit, mystringlistunit; // tAbhaengigkeiten ************************************************************ function tAbhaengigkeiten.rItem(idx: longint): tAbhaengigkeit; begin result:=tAbhaengigkeit(get(idx)); end; procedure tAbhaengigkeiten.wItem(idx: longint; neu: tAbhaengigkeit); begin put(idx,neu); end; procedure tAbhaengigkeiten.kopiereVon(original: tAbhaengigkeiten); var i: longint; begin clear; for i:=0 to original.count-1 do add(original[i]); end; procedure tAbhaengigkeiten.mrProper; var i: longint; begin for i:=0 to count-1 do items[i].free; clear; end; function tAbhaengigkeiten.add(neu: tAbhaengigkeit): longint; 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 tAbhaengigkeiten.last: tAbhaengigkeit; begin result:=tAbhaengigkeit(inherited last); end; procedure tAbhaengigkeiten.sort; var i,j,k,pLen: longint; perm: array of longint; tmp: tAbhaengigkeit; bedingungen: array of tPoint; nehmbare: array of byte; // 0 = ja, 1 = nein, 2 = nie wieder (schon genommen) fortschritt: boolean; begin // Permutation initialisieren setlength(perm,count); for i:=0 to length(perm)-1 do perm[i]:=count; // sollte ohnehin überschrieben werden, aber "count" sorgt unten für einen Fehler! setlength(bedingungen,0); // aka "y hängt (direkt) von x ab" for i:=0 to count-1 do for j:=0 to count-1 do if (i<>j) and (items[i].hatQuelleVonAlsZiel(items[j])) then begin setlength(bedingungen,length(bedingungen)+1); bedingungen[length(bedingungen)-1].x:=i; bedingungen[length(bedingungen)-1].y:=j; end; setlength(nehmbare,count); for i:=0 to length(nehmbare)-1 do nehmbare[i]:=0; pLen:=0; while pLen=0 then begin tmp:=items[i]; j:=i; while perm[j]<>i do begin k:=perm[j]; perm[j]:=-1; items[j]:=items[k]; j:=k; end; items[j]:=tmp; perm[j]:=-1; end; 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; _erben:=tAbhaengigkeiten.create; _eltern:=tAbhaengigkeiten.create; end; constructor tAbhaengigkeit.create(original: tAbhaengigkeit); var i: longint; 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; _erben:=tAbhaengigkeiten.create; _eltern:=tAbhaengigkeiten.create; original.neuerErbe(self); end; destructor tAbhaengigkeit.destroy; begin quellenRE.free; setLength(quellen,0); setLength(ziele,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; inherited destroy; end; function tAbhaengigkeit.hatQuelleVonAlsZiel(abh: tAbhaengigkeit): boolean; var i,j: longint; begin result:=true; for i:=0 to length(ziele)-1 do for j:=0 to length(abh.quellen)-1 do if abh.quellen[j].name = ziele[i].name then exit; result:=false; end; function tAbhaengigkeit.hatErbenMitQuelle(name: string): boolean; var i,j: longint; begin result:=true; for i:=0 to _erben.count-1 do for j:=0 to length(_erben[i].quellen)-1 do if _erben[i].quellen[j].name=name then exit; result:=false; end; function tAbhaengigkeit.erbeMitGleichenZielen(zl: tDateienMitDaten): tAbhaengigkeit; var i: longint; begin result:=nil; for i:=0 to _erben.count-1 do if gleicheDateinamen(_erben[i].ziele,zl) then begin result:=_erben[i]; exit; 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); 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!'); end; procedure tAbhaengigkeit.entferneElterReferenz(elt: tAbhaengigkeit); var i: 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!'); end; // tMach *********************************************************************** constructor tMach.create; begin inherited create; _oriAbh:=tAbhaengigkeiten.create; _mglAbh:=tAbhaengigkeiten.create; _ztAbh:=tAbhaengigkeiten.create; setlength(_dats,0); end; destructor tMach.destroy; var i: longint; begin _oriAbh.mrProper; _oriAbh.free; _mglAbh.mrProper; _mglAbh.free; _ztAbh.mrProper; _ztAbh.free; for i:=0 to length(_dats)-1 do _dats[i].free; setlength(_dats,0); inherited destroy; end; procedure tMach.wMachDatei(md: string); begin _machDatei:=md; if not fileexists(_machDatei) then fehler('Datei '''+_machDatei+''' existiert nicht!'); if not liesMachDatei then fehler('Datei '''+_machDatei+''' ist fehlerhaft!'); end; procedure tMach.wPruefsummenDatei(pd: string); begin _pruefsummenDatei:=pd; if not liesPruefsummenfile then fehler('Datei '''+_pruefsummenDatei+''' ist fehlerhaft!'); end; function tMach.liesMachDatei: boolean; var f: tMyStringList; s: string; na: tAbhaengigkeit; ignoriere: array of tRegExpr; rek: boolean; 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; setlength(ignoriere,0); wasWar:=ztSuche; f:=tMyStringList.create; f.loadFromFile(machDatei); f.add('%%DATEIENDE%%'); if not f.unfoldMacros then begin f.free; exit; end; s:=''; while f.readln(s) do begin if rightStr(s,1)=';' then // ein Befehl(steil) wasIst:=ztBefehl else if rightStr(s,1)=':' then // ein Ziel wasIst:=ztZiel else if wasWar=ztZiel then // eine Quelle wasIst:=ztQuelle else // eine zu überwachende Datei wasIst:=ztSuche; if wasIst in [ztZiel,ztBefehl] then delete(s,length(s),1); if (wasWar=ztBefehl) and (wasIst<>ztBefehl) then begin _oriAbh.add(na); na:=tAbhaengigkeit.create; end; if s='%%DATEIENDE%%' then break; case wasIst of ztSuche: begin if not quellersetzung(s,'',machDatei) then begin writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); aufraeumen; exit; end; if pos('!',s)=1 then begin delete(s,1,1); s:=trim(s); setlength(ignoriere,length(ignoriere)+1); ignoriere[length(ignoriere)-1]:=tRegExpr.create; ignoriere[length(ignoriere)-1].expression:=s; end else begin rek:=startetMit('-r',s); while s<>'' do sammleDateien(erstesArgument(s),rek,ignoriere,_dats); end; end; ztBefehl: begin while unescapedpos(';',s)>0 do begin posi:=unescapedpos(';',s); s:=trim(leftStr(s,posi-1))+' && '+trim(rightStr(s,length(s)-posi)); end; while pos(';;',s)>0 do delete(s,pos(';;',s),1); na.befehle.add(s); end; ztZiel: while s<>'' do na.zieleFkt.add(erstesArgument(s)); ztQuelle: begin if not quellersetzung(s,'',machDatei) then begin writeln('Fehler: Quellersetzung in '''+s+''' fehlgeschlagen!'); aufraeumen; exit; end; na.quellenRE.expression:=s; end; end{of case}; wasWar:=wasIst; end; if s<>'%%DATEIENDE%%' then writeln('Interner Fehler! Die letzte Regel wird vsl. nicht beachtet!'); aufraeumen; result:=true; end; function tMach.liesPruefsummenfile: boolean; var f: textfile; i,j: longint; gutschlecht: tStringlistBArray; gefunden,gut: boolean; begin result:=false; if pruefsummenDatei='' then begin writeln('Leerer Name als Summendatei angegeben!'); exit; end; if not fileexists(pruefsummenDatei) then begin assignfile(f,pruefsummenDatei); rewrite(f); closefile(f); end; if not fileexists(pruefsummenDatei) then begin writeln('Ich bin nicht in der Lage, die bisher nicht existierende Datei '''+pruefsummenDatei+''' anzulegen!'); exit; end; gutschlecht:=testeSummen(pruefsummenDatei); for gut:=false to true do for i:=0 to gutschlecht[gut].count-1 do begin gefunden:=false; for j:=0 to length(_dats)-1 do if _dats[j].name=gutschlecht[gut][i] then begin if gut then _dats[j].aktuell:=aAktuell else _dats[j].aktuell:=aVeraltet; gefunden:=true; break; end; if not gefunden then begin if not gut then begin // dateien mit ungültiger Prüfsumme können auch nicht vorhanden sein, setlength(_dats,length(_dats)+1); // dann werden sie einfach eingefügt _dats[length(_dats)-1]:=tDateiMitDatum.create; _dats[length(_dats)-1].name:=gutschlecht[gut][i]; _dats[length(_dats)-1].aktuell:=aNichtVorhanden; continue; end; writeln('In der Summendatei gibt es eine Datei mit gültiger Prüfsumme, die ich nicht finden kann: '''+gutschlecht[gut][i]+'''!'); for gefunden:=false to true do gutschlecht[gefunden].free; exit; end; end; for gefunden:=false to true do gutschlecht[gefunden].free; result:=true; end; procedure tMach.erzeugeRegeln; var i,j,k,l: longint; neues: boolean; s: string; tmpZiele: tDateienMitDaten; erb: tAbhaengigkeit; begin repeat neues:=false; for i:=0 to _oriAbh.count-1 do for j:=0 to length(_dats)-1 do if _oriAbh[i].quellenRE.exec(_dats[j].name) then begin // 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,machDatei,_dats); if length(tmpZiele)=0 then begin gibAus('Fehler: Keine Ziele für Abhängigkeit!',3); gibAus('Quelle:',3); gibAus(''''+_dats[j].name+'''',3); gibAus('Ziele:',3); for k:=0 to _oriAbh[i].zieleFkt.count-1 do gibAus(' '''+_oriAbh[i].zieleFkt[k]+'''',3); fehler('... ich beende.'); end; 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; until not neues; end; procedure tMach.findeWasZuTunIst; var i,j,k: longint; ziA,quA: tAktualitaet; neues: boolean; begin // 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,machDatei,_dats); if length(_mglAbh[i].ziele)=0 then begin // immer noch keine ziele gibAus('Warnung: Keine Ziele für diese Abhängigkeit!',3); gibAus('quellen:',3); for k:=0 to length(_mglAbh[i].quellen)-1 do gibAus(' '''+_mglAbh[i].quellen[k].name+'''',3); gibAus('zieleFkt:',3); for k:=0 to _mglAbh[i].zieleFkt.count-1 do gibAus(' '''+_mglAbh[i].zieleFkt[k]+'''',3); gibAus(' - wird ignoriert.',3); _mglAbh[i].free; _mglAbh.delete(i); continue; end; quA:=aAktuell; for j:=0 to length(_mglAbh[i].quellen)-1 do if _mglAbh[i].quellen[j].aktuell<>aAktuell then quA:=aWirdErneuert; ziA:=aWirdErneuert; for j:=0 to length(_mglAbh[i].ziele)-1 do if _mglAbh[i].ziele[j].aktuell=aVeraltet then ziA:=min(ziA,aAktuell) else ziA:=min(ziA,_mglAbh[i].ziele[j].aktuell); if ziA0 then begin befehle.add('echo -n "Sha512summen erneuern ..."'); befehl:='sed "'; for i:=0 to geaenderteDateien.count-1 do befehl:=befehl+'/\s'+escape(geaenderteDateien[i],'./','\')+'\$/d; '; befehl:=befehl+'" -i "'+pruefsummenDatei+'"'; befehle.add(befehl); for i:=0 to geaenderteDateien.count-1 do befehle.add('sha512sum "'+geaenderteDateien[i]+'" >> '+pruefsummenDatei); befehle.add('echo " fertig"'); end; if _ztAbh.count=0 then befehle.add('echo "Es gibt hier nichts zu tun!"'); if ausgabeDatei='' then begin writeln('befehle:'); for i:=0 to befehle.count-1 do writeln(befehle[i]); end else begin assignFile(ausg,ausgabeDatei); rewrite(ausg); for i:=0 to befehle.count-1 do writeln(ausg,'('+befehle[i]+') || (read -p "Ein Fehler ist aufgetreten! ... "; exit 1)'); closeFile(ausg); end; befehle.free; geaenderteDateien.free; end; procedure tMach.setzeGenerischePruefsummenDatei; begin pruefsummenDatei:=extractfilepath(machDatei)+'.summen'; end; function tMach.anzOriAbh: longint; begin result:=_oriAbh.count; end; function tMach.anzMglAbh: longint; begin result:=_mglAbh.count; end; function tMach.anzZtAbh: longint; begin result:=_ztAbh.count; end; function tMach.anzDats: longint; begin result:=length(_dats); end; // allgemeine Funktionen ******************************************************* function quellersetzung(var worin: string; quelle, inputfile: string): boolean; var s,anfang,mitte: string; i,li,re: 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); 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: longint; 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+'/*',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; procedure zieleHinzufuegen(var ziele: tDateienMitDaten; ziel,quelle,inputfile: string; var dats: tDateienMitDaten); var i,ebene,ende: longint; s,t,u: string; wasda: boolean; begin if pos('{',ziel)=0 then begin if not quellersetzung(ziel,quelle,inputfile) then exit; ziel:=unescape(ziel); i:=0; wasda:=false; while i0) or (ziel[ende]<>'}') do begin inc(ende); case ziel[ende] of '{': inc(ebene); '}': dec(ebene); end{of case}; end; s:=copy(ziel,1,pos('{',ziel)-1); t:=copy(ziel,pos('{',ziel)+1,ende-pos('{',ziel)-1); u:=copy(ziel,ende+1,length(ziel)); if unescapedpos('..',t)>0 then begin for i:=strtoint(copy(t,1,unescapedpos('..',t)-1)) to strtoint(copy(t,unescapedpos('..',t)+2,length(t))) do zieleHinzufuegen(ziele,s+inttostr(i)+u,quelle,inputfile,dats); end else begin t:=t+','; while unescapedpos(',',t)>0 do begin zieleHinzufuegen(ziele,s+copy(t,1,unescapedpos(',',t)-1)+u,quelle,inputfile,dats); delete(t,1,unescapedpos(',',t)); end; end; end; end; procedure findeMehrZiele(var ziele: tDateienMitDaten; zieleFkt: tStringList; quelle,inputfile: string; var dats: tDateienMitDaten); var i: longint; begin for i:=0 to zieleFkt.count-1 do zieleHinzufuegen(ziele,zieleFkt[i],quelle,inputfile,dats); end; end.