program epost; {$DEFINE UseCThreads} {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, { you can add units after this } sysutils, epostunit, mystringlistunit, lowlevelunit; var maxthreads,i,j,k: longint; inf: tMyStringlist; s: string; b,syntaxtest,parallelLesen: boolean; wertes: tWerteArray; Konturen: tKonturenArray; Warnstufe: tWarnstufe; procedure werte_aufraeumen; var i: integer; begin for i:=0 to length(wertes)-1 do if assigned(wertes[i]) then wertes[i].free; setlength(wertes,0); for i:=0 to length(Konturen)-1 do if assigned(Konturen[i]) then Konturen[i].free; setlength(Konturen,0); end; procedure aufraeumen; begin warte_auf_externeBefehle; werte_aufraeumen; inf.free; end; begin cleanupLogs; if (not (paramcount in [1,2])) or ((paramcount=2) and (paramstr(2)<>'-L')) or not fileexists(paramstr(1)) then begin gibAus('Verwendung: '+paramstr(0)+' input.epost',3); gibAus('oder: '+paramstr(0)+' input.epost -L',3); halt(1); end; maxthreads:=1; Warnstufe:=wsStreng; parallelLesen:=false; setlength(wertes,0); setlength(Konturen,0); behalteLogs:=(paramcount=2) and (paramstr(2)='-L'); inf:=tMyStringlist.create(nil,''); inf.nichtInSubRoutine('^lösche Werte '); // Zeilen, die hierauf passen, werden nicht an subRoutinen-Aufrufe inf.nichtInSubRoutine('^lösche Kontur '); // von metaReadln gegeben, sondern nach hinten ans Hauptprogramm verschoben inf.loadFromFile(paramstr(1)); if not inf.unfoldMacros then begin inf.free; fehler('Fehlerhafte input-Datei '''+paramstr(1)+'''!'); end; for syntaxtest:=true downto false do begin if not syntaxtest then gibAus('Syntaxtest bestanden!',3); inf.rewind; repeat if not inf.metaReadln(s,false) then begin gibAus('Unerwartetes Dateiende in '''+paramstr(1)+'''!',3); aufraeumen; halt(1); end; for i:=0 to length(wertes)-1 do wertes[i].beendeLeseThreadWennFertig; beendeExterneBefehleWennFertig; if s='streng warnen' then begin Warnstufe:=wsStreng; continue; end; if s='lasch warnen' then begin Warnstufe:=wsLasch; continue; end; if s='parallel lesen' then begin parallelLesen:=true; continue; end; if s='sequentiell lesen' then begin parallelLesen:=false; continue; end; if s='ohne Logdateien' then begin __ausgabenMaske:=__ausgabenMaske or 1; continue; end; if s='mit Logdateien' then begin __ausgabenMaske:=__ausgabenMaske and not 1; continue; end; if s='ohne Bildschirmausgaben' then begin __ausgabenMaske:=__ausgabenMaske or 2; continue; end; if s='mit Bildschirmausgaben' then begin __ausgabenMaske:=__ausgabenMaske and not 2; continue; end; if startetMit('externer Befehl:',s) then begin if externerBefehl(syntaxtest,s) then continue; aufraeumen; halt(1); end; if s='warte auf externe Befehle' then begin if not syntaxtest then begin warte_auf_externeBefehle; for i:=0 to length(wertes)-1 do wertes[i].warteAufBeendigungDesLeseThreads; end; continue; end; if startetMit('exprtofloat-Test:',s) then begin gibAus('exprtofloat-Test: '+s+'='+floattostr(wertes[length(wertes)-1].exprtofloat(syntaxtest,s)),3); continue; end; if startetMit('dupliziere ',s) then begin i:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''dupliziere $Original zu $Kopie''',3); aufraeumen; halt(1); end; j:=findeWerte(s,inf,@wertes,@Konturen,true); if j<0 then begin aufraeumen; halt(1); end; wertes[j].kopiereVon(syntaxtest,wertes[i]); continue; end; if startetMit('erzeuge Dummy-Werte ',s) then begin i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; wertes[i].free; wertes[i]:=tWerte.create(@Konturen,@wertes); wertes[i].bezeichner:=s; continue; end; if startetMit('Daten einlesen ',s) then begin b:=not startetMit('(ohne Ausgaben)',s); i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].ladeDateien(syntaxtest,inf,parallelLesen,b) then begin continue; end; aufraeumen; halt(1); end; if startetMit('Ascii laden ',s) then begin i:=findeWerte(erstesArgument(s),inf,@wertes,@Konturen,true); if wertes[i].ladeAscii(syntaxtest,s) then continue; aufraeumen; halt(1); end; if startetMit('Linearkombination ',s) then begin i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneLiKo(syntaxtest,inf,maxthreads) then continue; aufraeumen; halt(1); end; if startetMit('Agglomeration ',s) then begin i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneAgglomeration(syntaxtest,inf) then continue; aufraeumen; halt(1); end; if startetMit('teile ',s) then begin i:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if not startetMit('durch ',s) then begin gibAus('Fehlende Parameter, erwartet: ''teile $Dividend durch $Divisor zu $Quotient''',3); aufraeumen; halt(1); end; j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''teile $Dividend durch $Divisor zu $Quotient''',3); aufraeumen; halt(1); end; k:=findeWerte(s,inf,@wertes,@Konturen,true); if k<0 then begin aufraeumen; halt(1); end; if wertes[k].berechneQuotient(syntaxtest,inf,maxthreads,i,j) then continue; aufraeumen; halt(1); end; if startetMit('multipliziere ',s) then begin i:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if not startetMit('mal ',s) then begin gibAus('Fehlende Parameter, erwartet: ''multipliziere $Faktor mal $Faktor zu $Produkt''',3); aufraeumen; halt(1); end; j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''multipliziere $Faktor mal $Faktor zu $Produkt''',3); aufraeumen; halt(1); end; k:=findeWerte(s,inf,@wertes,@Konturen,true); if k<0 then begin aufraeumen; halt(1); end; if wertes[k].berechneProdukt(syntaxtest,inf,maxthreads,i,j) then continue; aufraeumen; halt(1); end; if startetMit('FFT2d ',s) then begin i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneFFT2d(syntaxtest,inf,maxthreads,Warnstufe) then continue; aufraeumen; halt(1); end; if startetMit('FFT ',s) then begin i:=findeWerte(s,inf,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneFFT(syntaxtest,inf,maxthreads,Warnstufe) then continue; aufraeumen; halt(1); end; if startetMit('Fitte Gauße an ',s) then begin i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].fitteGausze(syntaxtest,inf,maxthreads) then continue; aufraeumen; halt(1); end; if startetMit('Zeitfrequenzanalyse ',s) then begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''Zeitfrequenzanalyse $Original zu $Analyse''',3); aufraeumen; halt(1); end; i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneZeitfrequenzanalyse(syntaxtest,inf,maxthreads,wertes[j],Warnstufe) then continue; aufraeumen; halt(1); end; if startetMit('Verzerrung ',s) then begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''Verzerrung $Original zu $Bild''',3); aufraeumen; halt(1); end; i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneVerzerrung(syntaxtest,inf,maxthreads,wertes[j],Warnstufe) then continue; aufraeumen; halt(1); end; if startetMit('integriere ',s) then begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''integriere $Funktion zu $Stammfunktion''',3); aufraeumen; halt(1); end; i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneIntegral(syntaxtest,inf,maxthreads,wertes[j]) then continue; aufraeumen; halt(1); end; if startetMit('korreliere ',s) then begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; if not startetMit('zu ',s) then begin gibAus('Fehlende Parameter, erwartet: ''korreliere $Original zu $Korrelation''',3); aufraeumen; halt(1); end; i:=findeWerte(s,inf,@wertes,@Konturen,true); if i<0 then begin aufraeumen; halt(1); end; if wertes[i].berechneKorrelation(syntaxtest,inf,maxthreads,wertes[j]) then continue; aufraeumen; halt(1); end; if startetMit('Threadanzahl:',s) then begin maxThreads:=strtoint(s); continue; end; if startetMit('maximale und minimale Dichten bestimmen ',s) then begin b:=startetMit('(symmetrisch) ',s); i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; wertes[i].ermittleMinMaxDichten(syntaxtest,maxThreads,b); continue; end; if startetMit('maximale und minimale Dichten angleichen ',s) then begin b:=startetMit('(symmetrisch) ',s); i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; wertes[i].gleicheMinMaxDichtenAn(syntaxtest,inf,b); continue; end; if startetMit('lineares Bild ',s) then begin i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if not wertes[i].erzeugeLinearesBild(syntaxtest,inf,maxthreads) then begin aufraeumen; halt(1); end; continue; end; if startetMit('Ascii ',s) then begin i:=findeWerte(s,nil,@wertes,@Konturen,false); if i<0 then begin aufraeumen; halt(1); end; if not wertes[i].erzeugeAscii(syntaxtest,inf) then begin aufraeumen; halt(1); end; continue; end; if startetMit('Lineout ',s) then begin i:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if (i<0) or not wertes[i].erzeugeLineout(syntaxtest,s) then begin aufraeumen; halt(1); end; continue; end; if startetMit('Binning ',s) then begin i:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if (i<0) or not wertes[i].erzeugeBinning(syntaxtest,s) then begin aufraeumen; halt(1); end; continue; end; if startetMit('lösche Werte ',s) then begin while s<>'' do begin j:=findeWerte(erstesArgument(s),nil,@wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; wertes[j].free; for i:=j+1 to length(wertes)-1 do wertes[i-1]:=wertes[i]; setlength(wertes,length(wertes)-1); end; continue; end; if startetMit('lösche Kontur ',s) then begin while s<>'' do begin j:=findeKontur(erstesArgument(s),nil,@Wertes,@Konturen,false); if j<0 then begin aufraeumen; halt(1); end; konturen[j].free; for i:=j+1 to length(konturen)-1 do konturen[i-1]:=konturen[i]; setlength(konturen,length(konturen)-1); end; continue; end; if s='Palette' then begin if neuePalette(inf) then continue; aufraeumen; halt(1); end; if startetMit('Kontur',s) then begin i:=findeKontur(s,inf,@Wertes,@Konturen,true); if (i>=0) and Konturen[i].Init(syntaxtest,inf,@wertes,maxthreads) then continue; aufraeumen; halt(1); end; if s='Dateiende' then break; gibAus('Befehl '''+s+''' ist unverständlich in '''+paramstr(1)+'''!',3); aufraeumen; halt(1); until false; werte_aufraeumen; end; aufraeumen; if not behalteLogs then cleanupLogs; end.