NAME

libslack(prop) - program properties file module


SYNOPSIS

    #include <slack/std.h>
    #include <slack/prop.h>

    const char *prop_get(const char *name);
    const char *prop_get_or(const char *name, const char *default_value);
    const char *prop_set(const char *name, const char *value);
    int prop_get_int(const char *name);
    int prop_get_int_or(const char *name, int default_value);
    int prop_set_int(const char *name, int value);
    double prop_get_double(const char *name);
    double prop_get_double_or(const char *name, double default_value);
    double prop_set_double(const char *name, double value);
    int prop_get_bool(const char *name);
    int prop_get_bool_or(const char *name, int default_value);
    int prop_set_bool(const char *name, int value);
    int prop_unset(const char *name);
    int prop_save(void);
    int prop_clear(void);
    int prop_locker(Locker *locker);


DESCRIPTION

This module provides support for system-wide and user-specific (generic and program-specific) properties in "well-known" locations:

    /etc/properties/app             - system-wide, generic properties
    $HOME/.properties/app           - user-defined, generic properties
    /etc/properties/app.progname    - system-wide, program-specific properties
    $HOME/.properties/app.progname  - user-defined, program-specific properties

When the client first requests, sets or unsets a property, all properties relevant to the current program are loaded from these files in the order given above. This order ensures that program-specific properties override generic properties and user-defined properties override system-wide properties. The client can change properties at runtime and save the current properties back to disk (to the user-defined, program-specific properties file).

Program names (as returned by prog_name(3)) are converted into file name suffixes by replacing every occurrence of the file path separator ('/') with a '-'. Properties files consist of one property per line.

Each property is specified by its name, followed by '=' followed by its value. The name must not have a '=' in it unless it is quoted with a preceding '\'. Special characters are expressed in C string literal notation (e.g. \a\b\f\n\r\t\v\x1b). Spaces immediately before and after the '=' are stripped unless they are quoted with a preceding '\'. The properties files may also contain blank lines and comments ('#' until the end of the line).

Boolean property values can be expressed as 0 or 1, true or false, yes or no, on or off (case insensitive).

const char *prop_get(const char *name)

Returns the value of the property named name. Returns null if there is no such property. On error, returns null with errno set appropriately.

const char *prop_get_or(const char *name, const char *default_value)

Returns the value of the property named name. Returns default_value on error or if there is no such property.

const char *prop_set(const char *name, const char *value)

Sets the property named name to a copy of value. If prop_save(3) is called after a call to this function, the new property will be saved to disk and will be available the next time this program is executed. On success, returns the copy of value. On error, returns null with errno set appropriately.

int prop_get_int(const char *name)

Returns the value of the property named name as an integer. Returns 0 on error or if there is no such property or if it is not interpretable as a decimal integer.

int prop_get_int_or(const char *name, int default_value)

Returns the value of the property named name as an integer. Returns default_value on error or if there is no such property or if it is not interpretable as a decimal integer.

int prop_set_int(const char *name, int value)

Sets the property named name to value. If prop_save(3) is called after a call to this function, the new property will be saved to disk and will be available the next time this program is executed. On success, returns value. On error, returns 0.

double prop_get_double(const char *name)

Returns the value of the property named name as a double. Returns 0.0 on error or if there is no such property or if it is not interpretable as a floating point number.

double prop_get_double_or(const char *name, double default_value)

Returns the value of the property named name as a double. Returns default_value on error or if there is no such property or if it is not interpretable as a floating point number.

double prop_set_double(const char *name, double value)

Sets the property named name to value. If prop_save(3) is called after a call to this function, the new property will be saved to disk and will be available the next time this program is executed. On success, returns value. On error, returns 0.0.

int prop_get_bool(const char *name)

Returns the value of the property named name as a boolean value. Returns 0 on error or if there is no such property. The values: "true", "yes", "on" and "1" are all interpreted as true. All other values are interpreted as false.

int prop_get_bool_or(const char *name, int default_value)

Returns the value of the property named name as a boolean value. Returns default_value on error or if there is no such property or if it is not interpretable as a boolean value. The values: "true", "yes", "on" and "1" are all interpreted as true. The values: "false", "no", "off" and "0" are all interpreted as false. All other values are disregarded and will cause default_value to be returned.

int prop_set_bool(const char *name, int value)

Sets the property named name to value. If prop_save(3) is called after a call to this function, the new property will be saved to disk and will be available the next time this program is executed. On success, returns value. On error, returns 0.

int prop_unset(const char *name)

Removes the property named name. Property removal is only saved to disk when prop_save(3) is called, if the property existed only in the user-defined, program-specific properties file, or was created by the program at runtime. On success, returns 0. On error, returns -1 with errno set appropriately.

int prop_save(void)

Saves the program's properties to disk. If the "save" property is set to "false", "no", "off" or "0", nothing is written to disk. If no properties were added, removed or changed, nothing is written to disk. Only the user-defined, program-specific properties are saved. Generic and system-wide properties files must be edited by hand. Each program can only save its own properties. They are saved in the following file:

    $HOME/.properties/app.progname

Where progname is the name of the program after being translated as described at the top of the DESCRIPTION section.

The .properties directory is created if necessary. On success, returns 0. On error, returns -1 with errno set appropriately.

int prop_clear(void)

Clears the properties as though they were never initialised. On success, returns 0. On error, returns -1 with errno set appropriately.

int prop_locker(Locker *locker)

Sets the locking strategy for the prop(3) module to locker. This is only needed in multi threaded programs. It must only be called once, from the main thread. On success, returns 0. On error, returns -1 with errno set appropriately.


ERRORS

On error, errno is set either by an underlying function, or as follows:

EINVAL

When there is no prog_name or home directory or when there is a parse error in a properties file or if the ~/.properties exists but is not a directory. prop_locker(3) sets this when an attempt is made to change the locker that has already been set.


MT-Level

MT-Disciplined


FILES

    /etc/properties/app
    $HOME/.properties/app
    /etc/properties/app.*
    $HOME/.properties/app.*


EXAMPLE

    #include <slack/std.h>
    #include <slack/prog.h>
    #include <slack/prop.h>
    #include <slack/err.h>

    int main(int ac, char **av)
    {
        const char *s; int i; double d; int b;

        prog_init();
        prog_set_name(*av);

        s = prop_get("string");
        i = prop_get_int_or("int", 1);
        d = prop_get_double_or("double", 1.0);
        b = prop_get_bool("boolean");

        msg("s = '%s'\ni = %d\nd = %g\nb = %s\n", s, i, d, (b) ? "true" : "false");

        prop_set("string", "strung");
        prop_set_int("int", i += 4);
        prop_set_double("double", d *= 1.75);
        prop_set_bool("boolean", !b);
        prop_save();

        return EXIT_SUCCESS;
    }


BUGS

This only provides coarse-grained persistence. If multiple instances of the same program are setting properties, the last to exit wins. This can be overcome by calling prop_save() after setting any property and prop_clear() before getting any property.


SEE ALSO

libslack(3), prog(3)


AUTHOR

20100612 raf <raf@raf.org>