ossp-pkg/var/SPEC
- 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<start>-}, ${parameter:o<start>-<end>}
- ${parameter:o<start>,}, ${parameter:o<start>,<length>}
- ${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/<width>/<string>/<align>} expandiert
"parameter" in einen String der Mindestbreite <width>, wobei abhaengig
von <align> ("r" = right, "l" = left, "c" = center) noch fehlende
Zeichen mit <string> 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