O p t i o n s - C o m p i l e r
Eine C-Funktion übernimmt die ganzheitliche Verarbeitung und Prüfung aller Optionsargumente von Kommandos und setzt sie in eine Gebrauchsform um.
Möglicherweise müssen Sie die rechte Maustaste zum Laden verwenden.
Für einen ersten Eindruck folgt zunächst die
allgemeine Anwendungsvorschrift mit Syntaxbeispielen,
danach der komplette Artikel:
extern int compilo(int, char**, char*, char*, int(*)(int,char*,int)); int main(int argc, char **argv) { register int n; n= compilo(argc, argv, "options_syntax", oflags, ofunc); if (n<0) /* ...ERROR... */ ; argc-=n, argv+=n; //... return (0); } Options-Syntax von compilo(): bgrep "c,l,v,f{},F{},e{}" bgrep1 "c,l,v,[f|F|e]{}" bgrep2 "c,l,v,{f|F|e}{}" DIR "<^/,[:,l>,p,w,s,b,l,[ch|c],a[h|-h][s|-s][d|-d][a|-a][r|-r]" tar "<^>#({c|r|u|x|t}[l,v,m,n,o,p,e,f!,b!,k!])" ar "<^>,#{r|x|d|tv|t}{}" dd "<^,{>,if={},of={},bs={},count={},skip={}" dd1 "<^,{=>,if{},of{},bs{},count{},skip{}" cc "c,S,s,J,o{},O[0|1|2|3],K{frame,space,nolu}" usw.,usw.,... Der Quellkode compilo.c wird hier nicht gezeigt. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Beschreibender Artikel ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # Anm.: Ich unterscheide nachfolgend 'Listing' und 'Liste' ! O p t i o n s - C o m p i l e r HELMUT SCHELLONG Eine C-Funktion übernimmt die ganzheitliche Verarbeitung und Prüfung aller Optionsargumente von Kommandos und setzt sie in eine Gebrauchsform um. Nahezu jedes ausführbare Programm ist ein Kommando, das nach seinem Namen weitere Argumente berücksichtigt oder deren Angabe verlangt. Bei Kennzeichnung, Anordnung, Ausgestaltung und sonstigen Festlegungen von Optionen und ihren Werten gibt es einen großen Variantenreichtum, wenngleich hier auch betriebssystemzugeordnete Schwerpunkte erkennbar sind. Die in diesem Artikel beschriebene und abgedruckte C-Funktion 'compilo()' kann innerhalb von Kommandos deren gesamte Argumentliste einschließlich aller Werte und Wertkonstanten verarbeiten, prüfen und umsetzen und den damit verbundenen, stets wiederkehrenden Programmieraufwand fast vollkommen überflüssig machen. Desweiteren verbessert sie -ganz unwillkürlich- die Einheitlichkeit und Vollständigkeit von Kommandos. Zusätzliche Wertschöpfungen werden möglich oder erleichtert, wenn man mit Hilfe dieser Funktion beispielsweise verschiedene Hilfsprogramme, die im Rahmen größerer Projekte für Test- und Analyse= zwecke entstanden waren, nachträglich aufmöbelt und zu eigenen Standard-Kommandos erhebt. Der Auslöser zur Entwicklung von 'compilo' war dadurch begründet, daß die Argumenteverarbeitung, wie übrigens auch die Programmierung von ordentlichen Fehlermeldungs-Funktionen, durchaus von erheblichem Aufwand sein kann und zudem häufig als sehr lästig empfunden und (daher) mit schwankender Qualität uneinheitlich fertiggestellt wurde. Es ist nun mal spannender, den eigentlichen Kern von Programmen zu entwickeln, als immer wieder gleiches und dann doch nicht gleiches in Angriff zu nehmen! Aufruf genügt: -------------- Als erstes übergibt man der Funktion 'argc' und 'argv', so wie sie in der Parameterliste der Hauptfunktion 'main' stehen (Listing 1). Es folgt ein Zeichenketten-Parameter, der die Options-Syntax enthält, mit der man die gewünschten Options-Worte und -Werte detailliert und mit unterschiedlicher Restriktivität definieren kann. Die letzten beiden Parameter sind Adressen von Objekten, die von der Funktion beschrieben bzw. aufgerufen werden. Hier kann jeweils eine Nulladresse (0) übergeben werden, um die Verwendung auszuschließen. 'oflags' zeigt auf ein char-Array, in das Options-Flags und ab 'oflags+128' strukturierte Informationen abgelegt werden. 'ofu' zeigt auf eine Protokoll-Funktion, die von 'compilo' zu jedem Vorgang mit drei Parametern aufgerufen wird. Mittels dieser Funktion wird man gegebenenfalls besser informiert als nur mit den Daten aus dem Protokoll-Array. Der Rückgabewert von 'compilo' ist die Anzahl der von ihr bearbeiteten Kommandoargumente, oder aber eine Fehlernummer, falls negativ. Kann oder Muß: -------------- Vorrang bei der Konzeption der Syntax hatte eine besonders einfache Schreibweise für die Definition der meistgebrauchten Optionsvarianten. Außerdem wurde darauf geachtet, möglichst umfassend eine bereits bekannte Symbolik zu verwenden. Wichtig war auch, einen guten und praxisorientierten Kompromiß zwischen Syntax-Komplexität, dargebotenen Möglichkeiten und Code-Größe der Funktion zu finden. Zur Beschreibung von Kommandos und von Programmiersprachen wird meistens eine bestimmte Syntax ergänzend verwendet, eine Syntax also, mit der man eine andere Syntax beschreibt. Hieraus dürfte zumindest die Optionalklammerung [] weithin bekannt sein. Die Syntax von 'compilo' enthält viele Elemente daraus, beispielsweise gibt es Kann-Klammern [] und Muß-Klammern {}. Wer sich mal eine mächtige Anwendung dieser Syntax in allerbester Ausführung anschauen möchte, der sei auf das Buch zur Programmiersprache PEARL von Werum/Windauer, Vieweg Verlag, verwiesen. Die Options-Syntax von 'compilo' wird schwerpunktmäßig mit Hilfe dieser Beschreibungssyntax (Liste 1) und mittels vieler Beispiele erklärt. Die Darstellungen in Liste 1 sind aus praktischen Gründen stellenweise vereinfacht und damit leicht unpräzise. Nachfolgend ein einführendes Anwendungsbeispiel anhand des hypothetischen Kommandos 'bgrep', das drei Flag-Optionen -c,-l,-v und drei Optionen mit Wert -e,-f,-F berücksichtigt. (Listing 1) Im Kopfteil einer Handbuch-Beschreibung würde dann wohl folgende Aufrufvorschrift (usage) zu sehen sein: bgrep [-clv] { {-f|-F} sm_datei | [-e] sm } [datei ...] Die zugehörige compilo-Syntax ergibt sich folgendermaßen: "c,l,v,f{},F{},e{}" oder "c,l,v,[f|F|e]{}" 1 2 3 4 5 6 1 2 3 4 5 6 7 Die Nummern werden von 'compilo' vergeben, zur identifizierenden Verwendung in 'ofu' und 'oflags'. Für das Anwendungsbeispiel in Listing 1 wurde diejenige Syntax mit der größten resultierenden Flexibilität ausgewählt, die andererseits jedoch einige Anweisungen zusätzlich erfordert. Dies soll darauf aufmerksam machen, daß hier mehrere Optionen dem selben Endzweck dienen und somit gegenseitig verriegelt werden müssen, und daß Optionen im Regelfall mehrmals angegeben werden können. Einfache Flag-Optionen dürfen untereinander in beliebiger Reihenfolge, Häufigkeit und Kombination gesetzt werden. 'compilo' folgt dieser Praxis, kann aber mit unterschiedlichem Grad restriktiv eingestellt werden, wovon der Aufwand abhängig ist, mit dem man diese Funktion unterstützen muß. Die zweite Syntax-Variante erzwingt, daß nur eine der Wert-Optionen gegeben werden darf und spart etwas Aufwand, jedoch ein Wert kann nicht mehr bündig (z.B. -Fdatei) angegeben werden. Der minimalste Aufruf von 'bgrep' ist 'bgrep sm', woran man erkennt, daß dieser Aufruf ohne jede Option erfolgt und zumindest in diesem Zusammenhang nicht von 'compilo' allein bearbeitet werden kann. Wenn Option -e oben nicht optional wäre, entstünde die Möglichkeit zu einer weiteren Definition der Options-Syntax: "c,l,v,{f|F|e}{}" Damit könnte man in Listing 1 den Aufwand noch weiter reduzieren, indem nur noch Pointer-Zuweisungen nötig wären und nur noch auf einen negativen Rückgabewert von 'compilo' reagiert werden müßte. Die bisher gezeigten Syntax-Strings benutzen Voreinstellungen bezüglich Options-Vorzeichen und Wert-Folgeart. Es kann aber auch eine Kommando-Klammer <kommandos> hinzugefügt werden, die diese und andere Einstellungen explizit angibt. Die Listen 1 und 2 informieren hierüber. Gar keins bis maximal drei einschaltende und maximal zwei abschaltende Options-Vorzeichen können zugelassen werden. Eine die Abarbeitung der Argumentliste abbrechende Zeichenkette, die auch leer sein darf (-'') und in der Praxis zumeist -'-' ist, kann angegeben werden. Um bei mehreren Vorzeichen eine gemischte Angabe innerhalb eines Kommandoaufrufs zuzulassen, muß 'vorzeichen-mix' gewählt werden. Andernfalls wird das erste erkannte Vorzeichen festgeschrieben. Flag-Optionen (Ein-Zeichen-Optionen ohne Wert) dürfen standardmäßig untereinander hinter einem Vorzeichen kombiniert werden. Um dies zu unterbinden, muß 'einzeln' gesetzt werden. Kommando 'kommandoname' verhindert das Überspringen des Argumentes 'argv[0]', das durch diese Maßnahme ebenfalls prüfbar wird. Kommando <l> bewirkt, daß Wert-Listen als Ein-Buchstaben-Listen interpretiert werden, ohne das standardmäßige Komma (,) als Trennzeichen zu erwarten. (s.u. dir-Beispiel) Dann macht man's einfach: ------------------------- Nachfolgend werden einige von UNIX und DOS her bekannte Kommandos gezeigt, mit zugehöriger compilo-Syntax und Ident-Nummern, allerdings nicht mit Angabe sämtlicher Original-Optionen. Die Ident-Nummer beginnt mit 1 und wird hochgezählt nach jedem Namen und jedem leeren Klammerpaar. Die einzige Ausnahme bildet eine Standard-Wertoption (z.B. uvw{}), bei der Options-Name und Beliebig-Wert (oder n-Zeichen-Wert) mit der gleichen Nummer belegt und gleichzeitig an 'ofu' übergeben werden. tar cruxt[vlmnopefbk] [file] [blocking] [size] [file...] "<^>,#({c|r|u|x|t}[v,l,m,n,o,p,e,f!,b!,k!])" 1 2 3 4 5 6 7 8 9 10 .. 13 14 15 tar: Hier sind gleich mehrere besondere Bestandteile der Syntax zu sehen. Es gibt kein Vorzeichen <^>. Es wird eine Wort-Namen-Liste gebildet, durch Angabe einer Muß-Oder- gefolgt von einer Kann-UndOder-Klammer. Die beiden Klammerpaare werden durch runde Klammern ({}[]) eingefaßt, damit auch die zweite Klammer als Options-Wort und nicht schon als Wert interpretiert wird. Eine solche Option besteht aus mehreren Wort-Namen, die in ein einziges Kommando-Argument gezwungen werden. Das vordere Zeichen # erzwingt zusätzlich die erste Options-Position und macht eigentlich erst Sinn, wenn zwei oder mehr Optionen (option,option) im Syntax-String enthalten sind. Jedes Zeichen # erhöht diesen Wert um 1. Das Zeichen ! ist eine Argument-Anforderung, gekoppelt an das Vorkommen des zugehörigen Namens, die bewirkt, daß (zuvor) unmittelbar das nächste Kommando-Argument als Wert gemeinsam mit der Wort/Wert-Name-ID an 'ofu' weitergegeben wird. Normal-Werte werden gegebenenfalls anschließend berücksichtigt. Pro Name können mehrere Zeichen ! angegeben werden, erkannt wird es nur innerhalb von Klammern. Auch Wort-Namen dürfen mehr als ein Zeichen enthalten, solange Eindeutigkeit erhalten wird. ar rxdt[v] file.a [name...] "<^>,#{r|x|d|tv|t}{}" oder "<^>,#({r|x|d|t}[v]){}" 1 2 3 4 5 6 1 2 3 4 5 6 ar: Hierher kann man das zuvor Erklärte weitgehend übernehmen. Ein Muß-Wert wurde definiert; Werte können bei Kombi-Optionen niemals bündig sein, auch wenn das mittels <{> verlangt wurde. Gemäß der zweiten Syntax-Variante kann 'v' auch ohne 't' vorkommen und an beliebiger Position stehen. dir [/pwsbl/c[h]] [/a[[:]{[-]hsdar}]] [datei] "<^/,[:,l>,p,w,s,b,l,[ch|c],a[h|-h][s|-s][d|-d][a|-a][r|-r]" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 "<^/,[:,l>,p,w,s,b,l,ch,c,a[h,s,d,a,r,-h,-s,-d,-a,-r]" dir: Hier ist erstmals eine Namen-Kombination im Wert-Bereich zu sehen, die als Wert-Liste keine runden Klammern ([][]) benötigt. Die zweite Variante ist weniger restriktiv. Folgenden DOS-typischen Aufruf kann 'compilo' nicht verarbeiten: dir/p \dos/a/oe/s Das wäre einfach zu speziell und ist auch gar nicht nötig, denn unter DOS kann man auch mit Zwischenraumzeichen eingeben. Zudem ermöglicht 'compilo' die Kombination von Flag-Optionen. Wer das trotzdem realisiert haben möchte, muß 'argv' transformieren. Umwandlung in Großbuchstaben ist möglich, indem man 'memcmp()' durch eine entsprechende eigene Version ersetzt. dd [if=inp_file] [of=outp_file] [bs=n] [count=n] [skip=n] "<^,{>,if={},of={},bs={},count={},skip={}" 1 2 3 4 5 "<^,{=>,if{},of{},bs{},count{},skip{}" dd: Auch hier ist die erste Variante etwas einengender, da die zweite zuläßt, daß ein leerer String als Wert gegeben wird ('opt='). Bei Definitionen ohne Vorzeichen darf eine mehrfach angegebene Option unter Umständen nicht die letzte beim Kommando-Aufruf sein. Das hängt mit der hier geltenden Abbruchbedingung für 'compilo' zusammen. Bei diesem Beispiel wird beendet, wenn kein Argument mehr da ist oder 5 Optionen verarbeitet wurden. Falls jedoch rechtzeitig eine Doppelangabe erkannt ist, wird das Maximum auf 6 erhöht. cc [-cSsJ] [-o exefile] [-O[0123]] [-K frame,space,nolu] "c,S,s,J,o{},O[0|1|2|3],K{frame,space,nolu}" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 "c,S,s,J,o{},O[?],K{frame,space,nolu}" 1 2 3 4 5 6 7 8 9 10 cc: Bei diesem Compiler-Kommando sind Standard-Wertlisten definiert. Wertlisten werden zuvor gelöscht, damit sich bei mehrfacher Angabe Namen nicht aufsummieren, was bei Oder-Klammern Fehlermeldungen gäbe. Beim realen Kommando cc schließen sich -c,-S,-o gegenseitig aus, -s macht bei -S und -c keinen Sinn, und so weiter. Solche speziellen Abhängigkeiten müssen weitgehend außerhalb von 'compilo' behandelt werden. vi [-RLl] [+cmd|-c cmd] [-w#] [-t tag] [-r file] [file...] "<0,^-+,?>,#{view|vi|vedit},R,L,l,c{},w{},t{},r{},-{}" 1 2 3 4 5 6 7 8 9 10 11 vi: Dieses Beispiel zeigt, wie ein Kommandoname kontrolliert wird. Wegen '+cmd' ==> (-+,? -{}) ist überdurchschnittlich viel Zusatzaufwand nötig. Nicht ohne Grund wird in Kommando-Beschreibungen darauf hingewiesen, daß so manche traditionelle Schreibweise in Zukunft nicht mehr implementiert sein könnte. Bestrebungen allerdings, daß zukünftig eine Options-Syntax sich in "abc:d" erschöpfen soll, Werte (:) nur noch nichtbündig sind, es nur noch Ein-Buchstaben-Optionen gibt, unbedingt mit einem bestimmten Vorzeichen, gehen doch unverständlich weit. Wie wollte man dann 'skip' und 'seek' des dd-Kommandos darstellen? Protokoll komplett: ------------------- Die Protokoll-Funktion 'ofu' wird für gegebene Optionen mit den jeweils zugehörigen Ident-Nummern mindestens einmal aufgerufen und gestattet eine genaue Kontrolle über alle Vorgänge. Insbesondere kann die Reihenfolge des Eingangs der Optionen berücksichtigt werden. Bei Erstanwendungen wird empfohlen, die gesamte Arbeitsweise mittels Ausgabe durch einen printf()-Aufruf zu begutachten. Ein NULL-Pointer in 'wert' fordert auf, den entsprechenden Wert zu löschen, falls einer definiert wurde. Das ist bei Mehrfachangaben wichtig, besonders bei Wert-Listen. Generell zeigt ein NULL-Pointer an, daß zur Ident-Nummer kein Wert erlangt werden konnte oder sollte. Das gegebene Vorzeichen kann man hier zurückgewinnen, indem ein positiver Wert von 'ovz' bereits das Einschalt-Vorzeichen und ein negierter negativer Wert das Ausschalt-Vorzeichen ist. Wenn 'compilo' einen Fehler feststellt, wird 'ofu' mit einer negativen ID aufgerufen, die die Fehlernummer darstellt. Danach wird 'compilo' verlassen - ebenfalls mit dieser Nummer. Standardmäßig verläßt man die Protokoll-Funktion mit return=0, jedoch bei Werten kleiner Null verhält sich 'compilo' so wie bei internen Fehlern, mit der Ausnahme, daß dann vor Schluß nicht noch 'ofu' aufgerufen wird. Bei return>1 wird 'compilo' sofort beendet, während bei return=1 erst noch die aktuelle Option abgearbeitet wird, allerdings ohne 'ofu' aufzurufen. Protokoll einfach: ------------------ Im Array 'oflags' werden Vorkommnisse von Ein-Zeichen-Optionen aufaddiert. Eine Abfrage wäre beispielsweise 'if (O['a']) ;'. Ab Adresse 'oflags+128' werden strukturierte Daten abgelegt: #pragma pack(1) struct { uchar nvk, *wert; }; #pragma pack() Abgefragt werden kann per Pointer-Konversion oder Struktur-Pointer, wobei die Ident-Nummern als Index verwendet werden müssen. nvk=0 ist Löschzustand und 'wert' hat dann keine Bedeutung. Dieses Array sollte mindestens 200 Byte enthalten und muß mit Null initialisiert sein. Letzteres ist bei global-Definition automatisch der Fall. Logisch: -------- Die Syntax nach Liste 1 läßt logische Unkorrektheiten zu. Einige Einschränkungen müssen daher aufgezählt werden. Kann-Werte (o[]) sind implizit bündig. Bei mehreren Werten (o{}{}) kann nur der erste bündig sein, alle müssen Muß-Werte sein, und bei 'o{}{}' werden drei ID vergeben - nicht zwei. Ein Kombi-Optionswort darf nur einmal vorkommen. Ein bündiger Wert dahinter ist nicht möglich. <Kommandos> werden hier übertrumpft. Eine Wertliste besteht aus einer ununterbrochenen Reihe von Namen und wird argumentmäßig als ein einziger Wert betrachtet. Ein Beliebig-Wert ({}) säße unterbrechend zwischen zwei Listen und besetzte ein separates Kommando-Argument. Längere Wort- und Wertnamen sollten vor kürzeren stehen, falls Eindeutigkeit bei vorderen Zeichen nicht vorliegt. "<^-+,?>,a{}{},-{}" Alles, was nicht mit 'a' beginnt, ist ein Wert für die zweite Option. Nach Positionswechsel finge sie auch 'a' als Wert ab. Ein Trick besteht darin, einen Namen doppelt anzugeben, um dadurch eine Wort-Namen-Liste zu erzeugen: "...,[dop|dop],..." Namen dürfen hier nämlich nur innerhalb eines Argumentes erneut auftauchen, was eine nutzbare Restriktion darstellt. Schaltwerk compilo: ------------------- Eine programmiermäßige Erklärung zur Funktion erfolgt in diesem Artikel nicht. Sie ist von der Intention her als Library-Funktion konzipiert, daher sehr kompakt und abschnittweise unübersichtlich programmiert und in diesem Sinne als Vorführobjekt ungeeignet. Deshalb nur ein paar kurze Hinweise: In der ersten Schleife wird der Syntax-String in eine Datentabelle umgesetzt. Weitere Tabellenspalten werden in den beiden darauf folgenden Schleifen gefüllt. Danach wird die Argumentliste (C,*A) unter Berücksichtigung der Tabelle abgearbeitet. In der beendenden Schleife werden weitere Fehlersituationen geprüft. Zwei Größen-Limits gibt es, und zwar beim Struktur-Array und beim internen Syntax-String. Die Größenangaben brauchen nur an den Definitionsstellen geändert werden, falls dafür Bedarf entsteht. Der Code-Umfang liegt je nach Compiler und dessen Einstellungen bei ungefähr 4000 Byte. Wer eine Objekt-Datei (*.o) erzeugen will, muß zuvor die Speicherklasse 'static' entfernen! Angesichts des Quelltextes könnte man meinen, 'compilo' wäre langsam. Dem ist aber nicht so! Die Funktion läuft durchschnittlich in etwa hundert Mikrosekunden bzw. 6000 Pentium-Takten durch. AUTOR: Copyright (c) 1996 Helmut Schellong Tiefer Grund 12 32108 Bad Salzuflen schellong@t-online.de http://home.t-online.de/home/schellong Listing 1: ------------------------------------------------------------------------ // Anwendungs-Beispiel compilo(): static char oflags[200], *Sm; static int ofu(int id, char *wert, int ovz) { //printf("%d, '%s', %d\n", id, wert, ovz); if (id<0) Err(-id, wert); if (id==4) Sm=wert, oflags['F']=oflags['e']=0; if (id==5) Sm=wert, oflags['f']=oflags['e']=0; if (id==6) Sm=wert, oflags['f']=oflags['F']=0; return (0); } int main(int argc, char **argv) { register int n; n= compilo(argc, argv, "c,l,v,f{},F{},e{}", oflags, ofu); argc-=n; argv+=n; if (!Sm) if (argc<1) Err(E_ARGLST, "Suchmuster fehlt"); else Sm=*argv++, --argc; //. . . return (n); } ------------------------------------------------------------------------ # Hinweis: # Beide Syntaxformen verwenden | [] {} # Deshalb: # compilo-Syntax: | [ ] { } # Beschr.-Syntax: ¦ ^[^] ^{^} # Ideal wäre es, bei letzterer größer und dünner darzustellen, # und natürlich dann ^ wegfallen zu lassen. Liste 1: ------------------------------------------------------------------------ options-syntax := ^[<kdo^[,kdo^]...>,^]option^[,option^]... option := kann-option ¦ muß-option ¦ mußn-option kann-option := kann-wort^[wert^] muß-option := muß-wort^[wert^] mußn-option := #muß-wort^[wert^] kann-wort := name ¦ [liste] ¦ ([liste]...) ¦ - ¦ [] muß-wort := {liste} ¦ ({liste}^[{liste}¦[liste]^]...) ¦ {} leer-wort := - ¦ [] ¦ {} wert := kann-wert ¦ muß-wert kann-wert := ^{ []¦[liste] ^}... muß-wert := ^{ {}¦{liste} ^}^[ {}¦[]¦{liste}¦[liste] ^]... beliebig-wert := [] ¦ {} liste := name^[ ^{|¦,^}name ^]... name := zeichen... ¦ n-zeichen-wert n-zeichen-wert := ?... wert-anford. := !...name ¦ name!... (innerh. []{}) kommando := on-vorzeichen ¦ off-vorzeichen ¦ abbruch wertfolgeart ¦ vorzeichen-mix ¦ einzeln kommandoname ¦ 1-buchst-liste on-vorzeichen := ^ccc ¦ ^cc ¦ ^c ¦ ^ (^-) off-vorzeichen := ~cc ¦ ~c ¦ ~ abbruch := $ccc ¦ $cc ¦ $c ¦ $ wertfolgeart := [¦{¦[c¦{c¦[ ¦{ ¦[ c¦{ c ([ ) vorzeichen-mix := ? einzeln := e kommandoname := 0 1-buchst-liste := l (-o ^{^[!a-zA-Z^]...a-zA-Z^}...) std-wertliste := (-o name^[,name^]...) maskierzeichen := % ------------------------------------------------------------------------ Liste 2: ------------------------------------------------------------------------ Wert-Folgearten: "<[>" bündig "<{>" bündig "<[:>" bündig | bündig: "<{:>" bündig: "<[ >" bündig | nächstes arg "<{ >" nächstes arg "<[ :>" bündig | bündig: | nächstes arg "<[: >" bündig | bündig: | nächstes arg "<{ :>" bündig: | nächstes arg "<{: >" bündig: | nächstes arg Fehler-Nummern: -1 Syntax-Fehler (compilo-Anwendung) -2 Unbekannte Option -3 Vorzeitiges Ende der Argumentliste -4 Falsche Options-Position -5 Unbekannter Wertname -6 Falsche Wertlänge bei ?... -7 Zuviel oder zuwenig Vorkommnisse von Namen bzw. Werten -8 Verteiltes Kombi-Optionswort <=-10 Selbstdefiniert: ofu(){return <=-1;} ------------------------------------------------------------------------ Listing 2: ------------------------------------------------------------------------ # Siehe Datei compilo.c ------------------------------------------------------------------------