- Name: OSSP var (Variable Expansion Library) - Description: OSSP var is a library providing an API which allows one to expand one or more variables in text templates in a flexible way. The generability comes from using a callback function to actually resolve the value of a variable. The flexiblity comes from providing various manipulation functions which can be applied to the resolved values before they are substituted instead of the variable construct in the text template. - Features (german): - Eine Variable kann im Text in der Form $name oder ${name} angegeben werden, wobei die Wahl der Klammern '{' '}' und des '$' parametriesiert werden können. - Gültige Zeichen für einen Variablennamen sind konfigurierbar. Garbage in -- garbage out. - Ein echtes '$'-Zeichen im Text kann durch Voranstellung eines wählbaren Escapezeichen dargestellt werden. Default ist der Backslash ('\'). - Der Aufrufer der Funktion soll steuern können, wie sich die Library verhält, wenn eine Variable nicht existiert. Denkbar sind: - Abbruch mit Fehler, - die Variable wird zu "", oder - der Ausdruck wird unverändert in den Ausgabetext übernommen, sodaß eventuell ein zweiter Pass gemacht werden kann. - ${parameter:-word} wird normal expandiert. Wenn "parameter" leer ist, wird stattdessen "word" eingesetzt. - ${parameter:+word} substituiert die Expansion von "${word}" wenn "parameter" nicht leer ist, sonst wird "" substituiert. - ${parameter:o-}, ${parameter:o-} - ${parameter:o,}, ${parameter:o,} - ${parameter:#} expandiert zur Länge des Inhaltes von "parameter". - ${parameter:s/pattern/string/[gti]} expandiert "parameter" und führt dann eine Ersetzung mittels des regulären Ausdrucks "pattern" durch. Wird das 'g'-Flag angegeben, wird nicht nur eine Instanz von "pattern" durch "string" ersetzt, sondern alle. Das 't'-Flag signalisiert, daß eine reine Text-Ersetzung ohne Unterstützung von regulären Ausdrücken gewünscht ist. Das 'i'-Flag besagt, daß die Suche nach "pattern" case-insensitiv durchgeführt wird. - ${parameter:y/ochars/nchars/} expandiert den Inhalt von "parameter" und transformiert dabei nach dem Prinzip von tr(1) die "ochars" im Text zu "nchars". - ${parameter:l} wandelt den Inhalt von "parameter" in Kleinbuchstaben, bevor es die Variable expandiert. Dies geschieht über toupper(3). - ${parameter:u} wandelt den Inhalt von "parameter" in Großbuchstaben, bevor es die Variable expandiert. Dies geschieht über tolower(3). - ${parameter:*word} expandiert zum leeren Wort, wenn "parameter" nicht leer ist, sonst zu "word". - Jedes Vorkommen eines der folgenden Konstrukte im Text wird durch das zugehörige Sonderzeichen ersetzt. \t tab \n newline \r return \033 octal char \x1B hex char \x{263a} wide hex char - Padding: ${parameter:p///} expandiert "parameter" in einen String der Mindestbreite , wobei abhaengig von ("r" = right, "l" = left, "c" = center) noch fehlende Zeichen mit aufgefuellt werden. Diest ist gedacht, um in Templates saubere Tabellen erzeugen zu koennen. Beispiele (foo="bar"): "${foo:p/6/./r}" -> "bar..." "${foo:p/6/./l}" -> "...bar" "${foo:p/6/./c}" -> ".bar.." (oder "..bar.", egal) "${foo:p/20/-=/c}" -> "-=-=-=-=-bar-=-=-=-=" - API (var.h): | int (*var_cb_t)(void *context, | const char *varname, | size_t name_len, | char *const *data, | size_t *data_len, | char *malloced_buffer); | | typdef struct { | char varinit; | char startdelim; | char enddelim; | char escape; | char* namechars; | char force_expand; | } var_config_t; | | extern const var_config_t var_config_default; | | int var_expand(const char *input, | size_t input_len, | char **result, | size_t *result_len, | const char **error_msg, | varexp_lookup_cb lookup, | void *lookup_context, | struct varexp_configuration *config); - Results: Makefile ..... build procedure (minimal only!) var.ac ....... Autoconf macro OSSP_VAR var.h ........ OSSP var public API var.c ........ OSSP var implementation var.pod ...... OSSP var manual page var_test.c ... OSSP var test suite - Implementation Languages/Style: var.ac ....... lang: Autoconf 2.52, style: any var*.{h,c} ... lang: ANSI-C (< C99), style: Classical K&R var.pod ...... lang: POD (as of Perl 5.6), style: any - Implementation Namespaces: var_ ......... for all global linker symbols VAR_ ......... for all pre-processor symbols - Implementation Points: o The variable expansion process for "text" has to be O(n) where n is the length of "text". The hidden constant before n has to be very small, i.e., the text under ideal circumstances should be processed/glanced-over just once. Expansion speed is very important, but should be achieved by using any unportable things. The speed has to come from algorithmic decisions. o For regular expression based constructs (s///, etc.) the supported regex syntax has to be either POSIX or PCRE. Which one is used is decided under configure/build time via Autoconf and can be overridden with --with-regex-api=posix or --with-regex-api=pcre. The libraries are either found in system locations or in locations specified with --with-regex-prefix=DIR (or alternatively with more granular --with-regex-inc=DIR and --with-regex-lib=DIR) autoconf options. o Care should be taken so that the following things can be achieved later without having to fiddle around too much with the code: - adding support for Unicode through UTF-8 (means: no assumption that a character is represented by exactly one byte), so iterations over buffers should be done through iteration macros (e.g. ADVANCE(cp,n)). - adding support for easy addition of more value manipulation functions, i.e. the XXX part of ${var:XXX}. This means the manipulation functions should be coded self-contained and mostly independent of other code and their linkage into the code should be minimal. o The code should be carefully and fully documented. Additionally the manpage should contain complete description of the whole API plus examples which show most of the important or typical use cases plus a complete EBNF grammar which describes the supported syntax. o The implementation should explicitly allow and support the nesting of constructs, i.e., (foo=1, bar=2, quux=3, foo2quux=abcdef) ${foo${bar}quux} has to expand to "abcdef". Additionally the implementation should explicitly allow and support the susequent application of manipulation functions. i.e. ${foo2quux:s/cd/xy/:o2,4} has to expand to "bxye". - Timeline: 15-Oct-2001 start of implementation by P.S. 05-Nov-2001 end of implementation by P.S. & availability for review by C&W 12-Nov-2001 final acceptance by C&W