The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

App::Glacier::Config - generalized configuration file parser

SYNOPSIS

    my $cfg = new App::Glacier::Config($filename, %opts);
    $cfg->parse() or die;

    if ($cfg->isset('core', 'variable')) {
       ...
    }

    my $x = $cfg->get('file', 'locking');

    $cfg->set('file', 'locking', 'true');

    $cfg->unset('file', 'locking');

DESCRIPTION

$cfg = new App::Glacier::Config($filename, %opts);

Creates new configuration object for file $filename. Valid options are:

debug => NUM

Sets debug verbosity level.

ci => 0 | 1

If 1, enables case-insensitive keyword matching. Default is 0, i.e. the keywords are case-sensitive.

parameters => \%hash

Defines the syntax table. See below for a description of %hash.

cachefile => FILENAME

Sets the location of the cache file. If passed, the parsed configuration will be stored in binary form in the FILENAME. Before parsing the configuration file, the constructor will chech if the cache file exists and has the same timestamp as the configuration file. If so, the configuration will be loaded from the cache (using Storable(3)), avoiding parsing overhead. Otherwise, the cached data will be discarded, and the source file will be parsed as usual.

The destructor will first check if the configuration was updated, and if so will recreate the cache file prior to destructing the object instance.

rw => 0 | 1

Whether or not the configuration is read-write. This setting is in effect only if cachefile is also set.

If set to 0 (the default) any local changes to the configuration (using set and unset methods), will not be saved to the cache file upon exiting. Otherwise, the eventual modifications will be stored in the cache.

Syntax hash

The hash passed via the parameters keyword defines the keywords and sections allowed within a configuration file. In a simplest case, a keyword is described as

    name => 1

This means that name is a valid keyword, but does not imply anything more about it or its value. A most complex declaration is possible, in which the value is a hash reference, containing on or more of the following keywords:

mandatory => 0 | 1

Whether or not this setting is mandatory.

array => 0 | 1

If 1, the value of the setting is an array. Each subsequent occurrence of the statement appends its value to the end of the array.

re => regexp

Defines a regular expression to which must be matched by the value of the setting, otherwise a syntax error will be reported.

select => coderef

Points to a function to be called to decide whether to apply this hash to a particular configuration setting. The function is called as

    &{$coderef}($vref, @path)

where $vref is a reference to the setting (use $vref->{-value}, to obtain the actual value), and @path is its patname.

check => coderef

Defines a code which will be called after parsing the statement in order to verify its value. The coderef is called as

    $err = &{$coderef}($valref, $prev_value)

where $valref is a reference to its value, and $prev_value is the value of the previous instance of this setting. The function must return undef if the value is OK for that setting. In that case, it is allowed to modify the value, referenced by $varlref. If the value is erroneous, the function must return a textual error message, which will be printed using $cfg-error>.

To define a section, use the section keyword, e.g.:

    core => {
        section => {
            pidfile => {
               mandatory => 1
            },
            verbose => {
               re => qr/^(?:on|off)/i
            }
        }
    }

This says that a section [core] can have two variables: pidfile, which is mandatory, and verbose, whose value must be on, or off (case- insensitive).

To allow for arbitrary keywords, use *. For example, the following declares the [code] section, which must have the pidfile setting and is allowed to have any other settings as well.

    code => {
       section => {
           pidfile => { mandatory => 1 },
           '*' => 1
       }
    }

Everything said above applies to the '*' as well. E.g. the following example declares the [code] section, which must have the pidfile setting and is allowed to have subsections with arbitrary settings.

    code => {
       section => {
           pidfile = { mandatory => 1 },
           '*' => {
               section => {
                   '*' => 1
               }
           }
       }
    }

The special entry

    '*' => '*'

means "any settings and any subsections".

$cfg->error($message)

$cfg->error($message, locus => $loc)

Prints the $message on STDERR. If <locus> is given, its value must be a reference to a valid App::Glacier::Config::Locus(3) object. In that case, the object will be formatted first, then followed by a ": " and the $message.

$cfg->debug($lev, @msg)

If $lev is greater than or equal to the debug value used when creating $cfg, outputs on standard error the strings from @msg, separating them with a single space character.

Otherwise, does nothing.

$cfg->parse()

Parses the configuration file and stores the data in the object. Returns true on success and false on failure. Eventual errors in the configuration are reported using error.

$var = $cfg->get(@path);

Returns the value of the configuration variable represented by its path, or undef if the variable is not set. The path is a list of configuration variables leading to the value in question. For example, the following statement:

    pidfile = /var/run/x.pid

has the path

    ( 'pidfile' )

The path of the pidfile statement in section core, e.g.:

    [core]
        pidfile = /var/run/x.pid

is

    ( 'core', 'pidfile' )

Similarly, the path of the file setting in the following configuration file:

    [item foo]
        file = bar
    

is ( 'item', 'foo', 'bar' )

$ret = $cfg->get({ variable => $pathref, return => all | value | locus })

$pathref is a reference to the configuration setting path as described above. This invocation is similar to get(@{$pathref}), except that it returns additional data as controlled by the return keyword. The valid values for the return are:

'value'

Returns the value of the variable. The call

    $cfg->get({ variable => \@path, return => 'value' })

is completely equivalent to

    $cfg->get(@path);
'locus'

If $cfg was created with locations enabled, returns the source location of this configuration setting (see App::Glacier::Config::Locus(3)).

'order'

If $cfg was created with locations enabled, returns the ordinal number of the statement in the configuration file. Ordinal numbers are integers starting from 0 and assigned in ascending order to each statement.

'all'

Returns a reference to a hash with the following keys: -value, -locus. and -order.

The $ret{-value} contains the value of the setting. The $ret{-order} contains its ordinal number. The $ret{-locus} contains a reference to App::Glacier::Config::Locus(3) describing the source location where the setting was defined. It is available only if the locations mode is enabled.

If the return key is absent, the result is the same as for return => 'all'.

$cfg->isset(@path)

Returns true if the configuration variable addressed by @path is set.

$cfg->issection(@path)

Returns true if the configuration section addressed by @path is set.

$cfg->isvariable(@path)

Returns true if the configuration variable addressed by @path is set.

$cfg->set(@path, $value)

Sets the configuration variable @path to $value.

cfg->unset(@path)

Unsets the configuration variable.

@array = $cfg->names_of(@path)

If @path refers to an existing configuration section, returns a list of names of variables and subsections defined within that section. E.g., if you have

    [item foo]
       x = 1
    [item bar]
       x = 1
    [item baz]
       y = 2

the call

    $cfg->names_of('item')

will return

    ( 'foo', 'bar', 'baz' )
    

@array = $cfg->flatten()

@array = $cfg->flatten(sort => $sort)

Returns a flattened representation of the configuration, as a list of pairs [ $path, $value ], where $path is a reference to the variable pathname, and $value is a reference to a hash containing the following keys:

-value

The value of the setting.

-order

The ordinal number of the setting.

-locus

Location of the setting in the configuration file. See App::Glacier::Config::Locus(3). It is available only if the locations mode is enabled.

The $sort argument controls the ordering of the entries in the returned @array. It is either a code reference suitable to pass to the Perl sort function, or one of the following constants:

NO_SORT

Don't sort the array. Statements will be placed in an apparently random order.

SORT_NATURAL

Preserve relative positions of the statements. Entries in the array will be in the same order as they appeared in the configuration file. This is the default.

SORT_PATH

Sort by pathname.

These constants are not exported by default. You can either import the ones you need, or use the :sort keyword to import them all, e.g.:

    use App::Glacier::Config qw(:sort);
    @array = $cfg->flatten(sort => SORT_PATH);
    

$cfg->lint(\%synt)

Checks the syntax according to the syntax table %synt. On success, applies eventual default values and returns true. On errors, reports them using error and returns false.

This method provides a way to delay syntax checking for a later time, which is useful, e.g. if some parts of the parser are loaded as modules after calling parse.