CFG(2)                                                     CFG(2)

     NAME
          Cfg, Record, Tuple, Attr - configuration file parser

     SYNOPSIS
          include "cfg.m";
          cfg := load Cfg Cfg->PATH;

          Attr: adt {
               name: string;
               value: string;
          };

          Tuple: adt {
               lnum: int;
               attrs: list of Attr;
               lookup: fn(t: self ref Tuple, name: string): string;
          };

          Record: adt {
               tuples: list of ref Tuple;
               lookup: fn(r: self ref Record, name: string)
                    : (string, ref Tuple);
          };

          init: fn(path: string): string;
          lookup: fn(name: string): list of (string, ref Record);
          getkeys: fn(): list of string;

     DESCRIPTION
          Cfg parses its configuration file format into a set of
          Records.

          Each line of the configuration file is comprised of a tuple
          of attributes.  Comments are introduced by the '#' character
          and run to the end of the input line.  Empty lines and com-
          ments are ignored.

          An attribute has a name followed by an optional value.  The
          value is specified by separating the name and value by an
          '=' character.  Attribute names and values are input words.
          A word is delimited by spacing characters and the '=' char-
          acter.  If a word needs to include any of these characters
          then the word may be quoted using single or double quotes.
          The start and end quotes must be the same.  The quoting
          character may be included in the word by appearing twice.

          Examples:
               'a b c'   yields    a b c
               "a b c"   yields    a b c

     Page 1                       Plan 9            (printed 11/23/24)

     CFG(2)                                                     CFG(2)

               'a " c'   yields    a " c
               'a '' c'  yields    a ' c

          The name of the first attribute of a tuple is its key. The
          primary tuple value is the value of its first attribute.

          Tuples whose first attribute name appears at the start of a
          line (having no preceeding spacing characters) are treated
          as the start of a new record.  A record incorporates all
          tuples up to the start of the next record.  The record key
          is defined to be the name of its first attribute.  The
          primary record value is the value of the first attribute.

          The adt types Attr, Tuple and Record are direct analogues of
          the constructs defined above.

          init(path)
               Init initialises the Cfg module, causing it to open and
               parse the configuration file given by the path argu-
               ment.  If an error is encountered in processing the
               file then an error string is returned.  If there are no
               errors init returns nil.

          lookup(name)
               Lookup returns the set of Records whose key matches the
               name argument.  The return value is a list of (primary
               record value, record) pairs.

          getkeys()
               Getkeys returns a list of the record keys that appear
               in the configuration file.  Note that more than one
               record can have the same key.  Duplicate key names are
               not returned by getkeys().

          record.lookup(name)
               Returns the first tuple in record whose key matches
               name. The return value is (primary tuple value, tuple).
               If no matching tuple is found then the value (nil, nil)
               is returned.  Note that more than one tuple of the
               record could have a key that matches name. Only the
               first matching tuple is returned.  If an application
               makes use of multiple tuples with the same key then the
               record.tuple list will have to be handled explicitly by
               the application.

          tuple.lookup(name)
               Returns the first attribute in tuple whose name matches
               name. The return value is the value of the attribute or
               nil if no matching attribute was found.

     SOURCE
          /appl/lib/cfg.b

     Page 2                       Plan 9            (printed 11/23/24)