OSSP CVS Repository

ossp - ossp-pkg/var/SPEC 1.2
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/var/SPEC 1.2

- 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


CVSTrac 2.0.1