/* config.h - Lumiera configuration system Copyright (C) Lumiera.org 2008, Christian Thaeter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef LUMIERA_CONFIG_H #define LUMIERA_CONFIG_H //TODO: Support library includes// #include "lib/error.h" #include "lib/mutex.h" //TODO: Forward declarations// struct lumiera_config_struct; /* master config subsystem debug flag */ //NOBUG_DECLARE_FLAG (config_all); /* config subsystem internals */ //NOBUG_DECLARE_FLAG (configsys); /* high level typed interface operations */ //NOBUG_DECLARE_FLAG (config_typed); /* file operations */ //NOBUG_DECLARE_FLAG (config_file); /* single config items */ //NOBUG_DECLARE_FLAG (config_item); /* lookup config keys */ //NOBUG_DECLARE_FLAG (config_lookup); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX_KEY); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX_VALUE); LUMIERA_ERROR_DECLARE (CONFIG_NO_ENTRY); //TODO: Lumiera header includes// #include "common/config_lookup.h" #include "common/configitem.h" //TODO: System includes// #include #include /** * @file * TODO documentation, http://www.pipapo.org/pipawiki/Lumiera/ConfigLoader */ #define LUMIERA_CONFIG_KEY_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_." #define LUMIERA_CONFIG_ENV_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789__" struct lumiera_config_struct { lumiera_config_lookup keys; lumiera_configitem defaults; /* registered default values */ lumiera_configitem files; /* all loaded files */ lumiera_configitem TODO_unknown; /* all values which are not part of a file and not default TODO: this will be removed when file support is finished */ lumiera_mutex lock; }; typedef struct lumiera_config_struct lumiera_config; typedef lumiera_config* LumieraConfig; /** * Supported high level types: TODO documenting */ /* TODO: add here as 'LUMIERA_CONFIG_TYPE(name, ctype)' the _get/_set prototypes are declared automatically below, you still have to implement them in config.c */ #define LUMIERA_CONFIG_TYPES \ LUMIERA_CONFIG_TYPE(link, const char*) \ LUMIERA_CONFIG_TYPE(number, long long) \ LUMIERA_CONFIG_TYPE(real, long double) \ LUMIERA_CONFIG_TYPE(string, const char*) \ LUMIERA_CONFIG_TYPE(wordlist, const char*) \ LUMIERA_CONFIG_TYPE(word, const char*) \ LUMIERA_CONFIG_TYPE(bool, int) // * does only initialize the variables, so that they get valid values, but does not allocate them as they will be allocated before as they are singleton. // * lumiera_config_init (const char* searchpath) searchpath is a builtin-default, can be changed via configure and can be appended and overridden by using a flag, e.g. {{{ --config-path-append="" }}} or {{{ --config-path="" }}} /** * Initialize the configuration subsystem. * @param path search path for config files. * Must be called only once */ int lumiera_config_init (const char* path); // * frees all space allocated by the ConfigLoader. /** * Destroys the configuration subsystem. * Subsequent calls are no-ops. */ void lumiera_config_destroy (); // * reads '''one''' single configuration file that will include all settings from other files. // * does not read itself but give delegates reading. The actual reading and parsing will be done in configfile object. s.later. /** * */ int lumiera_config_load (const char* file); //{{{ lumiera_config_save () { LLIST_FOREACH(config_singleton.files, f) { LumieraFile file = (LumieraFile) f; if(lumiera_configfile_isdirty (file)) lumiera_configfile_save(file); } } }}} // * saves all the changed settings to user's configuration files, but recognizes where settings came from and will write them to an appropriate named file. Example: '''changed''' values from ''/usr/local/share/lumiera/plugins/blur.conf'' will be saved into ''~/.lumiera/plugins/blur.conf'' // * finds out which files are dirty and which settings have to be written to user's config files. // * does initiate the actual saving procedure by delegating the save to the actual configfile objects, see below. // * empty user configuration files in RAM will be deleted from disk on write. // * checks whether the file has changed since last read, and will print out an error if necessary instead of overriding it without notification. /** * */ int lumiera_config_save (); // * `lumiera_config_purge(const char* filename)` removes all configs loaded from filename /** * */ int lumiera_config_purge (const char* filename); /** * Does a diagnostic dump of the whole config database */ void lumiera_config_dump (FILE* out); // * {{{ lumiera_config_get(...) }}} // * get a value by key // * handles internally everything as string:string key:value pair. // * lowlevel function // * lumiera_config_integer_get (const char* key, int *value) will return integers instead of strings and return 0 if succeeded and -1 if it failed. /** * */ const char* lumiera_config_get (const char* key, const char** value); const char* lumiera_config_get_default (const char* key, const char** value); // * {{{ lumiera_config_set(...) }}} // * set a value by key // * handles internally everything as string:string key:value pair. // * lowlevel function // * tag file as dirty // * set will create a new user configuration file if it does not exist yet or will append a line to the existing one in RAM. These files, tagged as 'dirty', will be only written if save() is called. /** * * * @param key * @param delim_value delimiter (= or <) followed by the value to be set * */ LumieraConfigitem lumiera_config_set (const char* key, const char* delim_value); /** * Installs a default value for a config key. * Any key might have an associated default value which is used when * no other configuration is available, this can be set once. * Any subsequent call will be a no-op. This function locks the config system. * @param line line with key, delimiter and value to store as default value * @return NULL in case of an error, else a pointer to the default configitem */ LumieraConfigitem lumiera_config_setdefault (const char* line); // * {{{int lumiera_config_TYPE_get(const char* key, TYPE* value, const char* default) }}} // High level config interface for different types. // if default is given (!NULL) then value is set to default in case key was not found or any other error occured. // error code is still set and -1 (fail) is returned in case of an error, but it might be cleared with no ill effects. // NOTE: errors are persistent in our error handler, they must still be cleared, even when ignored. // if default is given then 'KEY_NOT_FOUND' is not a error here, if default is NULL then it is // NOTE2: default values are given as strings, the config loader remembers a given default value and checks if it got changed // when it is _set(). Thus a default value can be supressed when set/written /** * */ #define LUMIERA_CONFIG_TYPE(name, type) \ const char* \ lumiera_config_##name##_get (const char* key, type* value); LUMIERA_CONFIG_TYPES #undef LUMIERA_CONFIG_TYPE /** * Wordlists * Wordlists are lists of single words delimited by any of " \t,;". * They can be used to store groups of keys and other kinds of simple references into the config * system. Here are some functions to manipulate single word entries in a wordlist. */ /** * Get nth word of a wordlist. * @param key key under which this wordlist is stored * @param nth index of the word to get, starting with 0 * @param delims a string literal listing all characters which are treated as delimiters * @return pointer to a tempbuf holding the nth word or NULL in case of error */ const char* lumiera_config_wordlist_get_nth (const char* key, unsigned nth, const char* delims); /** * Find the index of a word in a wordlist. * @param key key under which this wordlist is stored * @param value word to find * @param delims a string literal listing all characters which are treated as delimiters * @return index of the first occurrence of the word or -1 in case of failure */ int lumiera_config_wordlist_find (const char* key, const char* value, const char* delims); /** * Universal word replacement function. * Replaces a word with up to two new words. This can be used to delete a word (no replacements), * insert a new word before an existing word (giving the new word as subst1 and the old word as subst2) * insert a new word after an existing word (giving the old word as subst1 and the new word as subst2) * or simply give 2 new words. * @param key key under which this wordlist is stored * @param value word to be replaced * @param subst1 first replacement word * @param subst2 second replacement word * @param delims a string literal listing all characters which are treated as delimiters * @return internal representation of the wordlist in a tmpbuf or NULL in case of an error */ const char* lumiera_config_wordlist_replace (const char* key, const char* value, const char* subst1, const char* subst2, const char* delims); /** * Add a word to the end of a wordlist if it doesnt exist already * @param key key under which this wordlist is stored * @param value new word to add * @param delims a string literal listing all characters which are treated as delimiters * @return internal representation of the wordlist in a tmpbuf or NULL in case of an error */ const char* lumiera_config_wordlist_add (const char* key, const char* value, const char* delims); // * {{{ lumiera_config_TYPE_set (const char* key, TYPE*value, const char* fmt) }}} // Highlevel interface for different types, fmt is a printf format specifier for the desired format, when NULL, defaults apply. /** * */ #define LUMIERA_CONFIG_TYPE(name, type) \ LumieraConfigitem \ lumiera_config_##name##_set (const char* key, type* value); LUMIERA_CONFIG_TYPES #undef LUMIERA_CONFIG_TYPE // * {{{ lumiera_config_reset(...) }}} // * reset a value by key to the system default values, thus removes a user's configuration line. /** * */ int lumiera_config_reset (const char* key); // * Find exact place of a setting. /** * */ int lumiera_config_info (const char* key, const char** filename, unsigned* line); #endif /* // Local Variables: // mode: C // c-file-style: "gnu" // indent-tabs-mode: nil // End: */