OSSP var o document loop construct --------------------------------------------------------------------- - Man braucht ein Schleifenkonstrukt, das über Arrays iteriert: [${foo}${bar}] Dies wird so interpretiert, daß der Parser an den Variablennamen den jeweiligen Index anhängt, und die ganze Zeile expandiert, solange, bis _alle_ in dem Konstrukt verwandten Variablen für den derzeitigen Index undefiniert sind -- sind nur einzelne Variablen undefiniert, werden sie durch den Leerstring "" ersetzt. Text innerhalb des Konstrukten wird "verbatim" in jeder Zeile erhalten, beispielsweise: [${foo}: ${bar}\n] Hierzu muß var_expand() wissen, wie sie einen indizierten Variablenzugriff erzeugen kann. Hierzu wird var_config_t um "char startindex" und "char endindex" erweitert. Weiterhin wird in var_config_t "char current_index" ein Zeichen konfiguriert, unter dem der aktuelle Index der Schleife zu bekommen ist. Defaults werden sein: "[", "]" und "#" respektive. Wenn Variablen innerhalb des Konstruktes bereits einen Index haben, wird dieser (unter Beachtung eventuell notwendiger Arithmetik) berechnet und "fest" verwendet, zum Beispiel: [${foo[1]}] oder [${foo[(#+1)/2]}] Dementsprechend sind die folgenden Ausdrück equivalent: [${foo[#]}] == [${foo}] Wir unterstützen die vier Grundrechenarten, Modulo und Klammerung für arithmetische Operationen. Weiterhin wird der Callback um einen Parameter "int index" erweitert, welchen im Falle eines "normalen Variablenzugriffs" auf Null gesetzt wird. Zugriffe auf Indices, die nicht existieren, müssen vom Callback mit "UNDEFINED" quittiert werden. Ein Zugriff auf einen negativen Index liefert die Anzahl der Elemente in dem Array als String zurück. Ebenso liefert das Konstrukt ${foo:#} die Anzahl der Elemente zurück, wenn $foo ein Array ist. [...]-Konstrukte können beliebig tief geschachtelt werden. Innerhalb von Indixangaben dürfen erneut Variablen verwendet werden. Arrays werden nur in "expressions" erkannt, und im Konstrukt werden auch nur "expressions" gesondert behandelt; normale Variablen werden in jedem Pass normal expandiert. Sind "stardindex", "endindex" oder "current_index" leer (gleich '\0'), wird dieses Konstrukt vom Parser nicht erkannt und als Text interpretiert -- abgesehen von den Variablen, natürlich, welche aber nicht in einer Schleife expandiert werden, noch werden beim Callback Array-Elemente abgefragt. **** CLARIFICATION **** < [ $HOME ${ARRAY} ] is same as > [ $HOME ${ARRAY[0]} ] must use > [ $HOME ${ARRAY[#]} ] Correction to termination condition: we loop unless all ARRAYs containing '#' somewhere in the index expression return undefined. Any array using an constant index and scalar variables are ignored when evaluating the termination condition. Additionally we need support for explicit indexing, ranges and stepping using the following "regex-style" quantifiers: [ ... body ... ]{begin,step,end} [ ... body ... ]{begin,end} begin, step and end can be digits or arithmetic expressions using variables (exactly like the index expressions) or empty string with default for the empty string - begin = 0 - step = 1 - end = maximum of all $#{anyvar} where ${anyvar[...#...]} occurs in body. {,,} is same as {0,end} and can be omitted. < ${ARRAY:s/foo/bar:#} is same as > ${ARRAY[0]:s/foo/bar/:#} This means that operation has nothing to do with arrays but works on scalars. Correction to index variable from var_cb_t: this is a signed integer and allows negative, zero and positive indexes. It's up to the lookup callback to decide what is undefined. Some callbacks may support negative indices to support indexing from the end backwards through the array. This means negative numbers can not be used as the magic identifier for "gimme the number of elements for this variable". The callback needs another input, enum { VAR_LOOKUP_VALUE, VAR_LOOKUP_ELEMENTS, ... } var_lookup_t which tells the callback what to look up. Initially, only these modes are supported but we have room for future expansion here. The syntax change to adopt these changes is: $#{foo} returns the number of elements in foo while ${foo:#} returns the number of characters in the expanded value of foo. This keeps :# an command and makes ${foo} executing callback with VAR_LOOKUP_VALUE and $#{foo} executing callback with VAR_LOOKUP_ELEMENTS. Additionally it adopts Perl syntax. Extreme case: $#{foo:#} tells you how many digits the number of elements of foo has. Examples now working correctly: - Creation of a Newsgroups: header from To: headers w/o the last comma Newsgroup: [${To[#]}${To[#+1]:+${Separator} }] Newsgroup: [${To[#-1]:+${Separator} }${To[#]}] - Assume index zero is a header and the last element is a footer. Print a table with header, ruler, body, ruler and footer. ${foo[0]} ${empty:p/-/${foo[0]:#}/} [$foo{#}\n]{1,$#{foo}-1} ${empty:p/-/${foo[$#{foo}]:#}/} ${foo[$#{foo}]} --------------------------------------------------------------------- o manual page style cleanup and perhaps merge with var_qref.pod? o add library context and move initialization and configuration into this context. o bugfix?: (thl) habe einen Bug in lib_var gefunden, scheint konzeptioneller Art zu sein. Ich benoetige zwei Passes fuer eine Anwendung, da es zwei verschiedene Arten von Variablen gibt. Eine hat nur Zahlen als gueltigen Namen, die andere Zahlen, Buchstaben, Punkt und Strich. Und die Ergebnisse des ersten Passes koennen die Namen des zweiten beeinflussen, daher muessen es zwei Passes sein. Sollte eigentlich funktionieren, dafuer gibt es die namechars im var_config_t und das force_expand feature. Ich setze also zuerst die namechars auf "0-9" und force_expand auf FALSE, anschliessend die namechars auf "0-9a-zA-Z.-" und force_expand auf TRUE. Aber bei einem Input von "${0}${abc}" bricht der Parser den ersten Pass bei "abc" mit "failed: incomplete variable" ab! Workaround: gleiche Namespaces, d.h. namechar's, verwenden - aber das ist nicht wirklich die ultimative Loesung. o additional feature: functions via callback. ${foo:F:F} calls callback for bar with result of foo expansion and then callback for quux with the result returned from bar.