Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
config.c
Go to the documentation of this file.
1/*
2 Config - Lumiera configuration system
3
4 Copyright (C)
5 2008, Christian Thaeter <ct@pipapo.org>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
22#include "include/logging.h"
23#include "lib/safeclib.h"
24#include "lib/tmpbuf.h"
25#include "common/config.h"
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <ctype.h>
30
31
32LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX, "syntax error in configfile");
33LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_KEY, "syntax error in key");
34LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_VALUE, "syntax error in value");
35LUMIERA_ERROR_DEFINE (CONFIG_NO_ENTRY, "no configuration entry");
36
37
42 {
43 /* Low level formating, don't change these */
44 "config.formatstr.link = '< %s'",
45 "config.formatstr.number.dec = '= %lld'",
46 "config.formatstr.number.hex = '= 0x%llX'",
47 "config.formatstr.number.oct = '= 0%llo'",
48 "config.formatstr.real = '= %Lg'",
49 "config.formatstr.real.dec = '= %Lf'",
50 "config.formatstr.real.sci = '= %Le'",
51 "config.formatstr.string = '= %s'",
52 "config.formatstr.string.dquoted = '= \"%s\"'",
53 "config.formatstr.string.quoted = '= ''%s'''",
54 "config.formatstr.word = '= %s'",
55 "config.formatstr.bool = '= %d'",
56
57 /* default representations per type */
58 "config.formatdef.link < config.formatstr.link",
59 "config.formatdef.number < config.formatstr.number.dec",
60 "config.formatdef.real < config.formatstr.real",
61 "config.formatdef.string < config.formatstr.string",
62 "config.formatdef.word < config.formatstr.word",
63 "config.formatdef.bool < config.formatstr.bool",
64
65 /* per key formatting override stored under */
66 "config.formatkey ='config.format.%s'",
67
68 NULL
69 };
70
71
72/* singleton config */
74
75
76int
77lumiera_config_init (const char* path)
78{
79 TRACE (config_dbg);
80 REQUIRE (!lumiera_global_config, "Configuration subsystem already initialised");
81 REQUIRE (path);
82
83
86
90
91 lumiera_mutex_init (&lumiera_global_config->lock, "config mutex", &NOBUG_FLAG (mutex_dbg), NOBUG_CONTEXT);
92
93 lumiera_config_setdefault (lumiera_tmpbuf_snprintf (SIZE_MAX, "config.path = %s", path));
94
95 for (const char** itr = lumiera_config_defaults; *itr; ++itr)
96 {
98 }
99
100 return 0;
101}
102
103
104void
106{
107 TRACE (config_dbg);
109 {
110 lumiera_mutex_destroy (&lumiera_global_config->lock, &NOBUG_FLAG (mutex_dbg), NOBUG_CONTEXT);
117 }
118 else
119 WARN (config_dbg, "Config system not initialised or already destroyed");
120}
121
122
123int
124lumiera_config_load (const char* file)
125{
126 (void) file;
127 TRACE (config_dbg);
128 UNIMPLEMENTED();
129 return -1;
130}
131
132
133int
135{
136 TRACE (config_dbg);
137 UNIMPLEMENTED();
138 return -1;
139}
140
141
142int
143lumiera_config_purge (const char* filename)
144{
145 (void) filename;
146 TRACE (config_dbg);
147
148 UNIMPLEMENTED();
149 return -1;
150}
151
152
153const char*
154lumiera_config_get (const char* key, const char** value)
155{
156 TRACE (config_dbg);
157 REQUIRE (key);
158 REQUIRE (value);
159
160 *value = NULL;
161
162 /* we translate the key for the env var override by making it uppercase and replace . with _,
163 as side effect, this also checks the key syntax */
164 char* tr_key = lumiera_tmpbuf_tr (key,
167 NULL);
168
169 if (tr_key)
170 {
171 char* env = lumiera_tmpbuf_snprintf (2048, "LUMIERA_%s", tr_key);
172
173 *value = getenv (env);
174 if (*value)
175 {
176 NOTICE (config, "envvar override for config %s = %s", env, *value);
177 }
178 else
179 {
182
183 if (item)
184 {
185 *value = item->delim+1;
186 }
187 else
188 LUMIERA_ERROR_SET_WARNING (config, CONFIG_NO_ENTRY, key);
189 }
190 }
191 else
192 {
193 LUMIERA_ERROR_SET (config, CONFIG_SYNTAX_KEY, key);
194 }
195
196 return *value;
197}
198
199
200const char*
201lumiera_config_get_default (const char* key, const char** value)
202{
203 TRACE (config_dbg);
204 REQUIRE (key);
205 REQUIRE (value);
206
207 *value = NULL;
208
212
213 if (item && item->parent == &lumiera_global_config->defaults)
214 {
215 *value = item->delim+1;
216 }
217
218 return *value;
219}
220
221
223lumiera_config_set (const char* key, const char* delim_value)
224{
225 TRACE (config_dbg);
226
228 if (item && item->parent != &lumiera_global_config->defaults)
229 {
230 TODO ("is a user writable file?");
231 TODO (" replace delim_value");
232 lumiera_configitem_set_value (item, delim_value);
233 }
234 else
235 {
236 TODO ("create item");
237 TODO (" find matching prefix");
238 TODO (" find matching suffix");
239 TODO (" find proper prefix indentation, else use config.indent");
240 TODO (" create configitem with prefix/suffix removed");
241
242 char* line = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s %s", key, delim_value);
243 item = lumiera_configitem_new (line);
244
245 if (item)
246 {
247 TODO ("next 2 ensure must generate runtime errors");
248 ENSURE (item->delim, "syntax error");
249 ENSURE (*item->delim == '=' || *item->delim == '<', "syntax error,");
250
251 TODO ("insert in proper parent (file)");
252 llist_insert_tail (&lumiera_global_config->TODO_unknown.children, &item->link);
253 item->parent = &lumiera_global_config->TODO_unknown;
255
256 TODO ("tag file as dirty");
257 }
258 }
259
260 return item;
261}
262
263
266{
267 TRACE (config_dbg);
268 REQUIRE (line);
269
270 LumieraConfigitem item = NULL;
271
273 {
274 const char* key = line;
275 while (*key && isspace (*key))
276 key++;
277
278 key = lumiera_tmpbuf_strndup (line, strspn (line, LUMIERA_CONFIG_KEY_CHARS));
279
280 if (!(item = lumiera_config_lookup_item_find (&lumiera_global_config->keys, key)) || item->parent != &lumiera_global_config->defaults)
281 {
282 item = lumiera_configitem_new (line);
283
284 if (item)
285 {
286 ENSURE (item->delim, "default must be a configentry with key=value or key<delegate syntax");
287 ENSURE (*item->delim == '=' || *item->delim == '<', "default must be a configentry with key=value or key<delegate syntax");
288 TRACE (config_dbg, "registering default: '%s'", item->line);
289
290 llist_insert_head (&lumiera_global_config->defaults.children, &item->link);
291 item->parent = &lumiera_global_config->defaults;
292
294 }
295 }
296 }
297
298 return item;
299}
300
301
302void
304{
305 fprintf (out, "# registered defaults:\n");
306
307 LLIST_FOREACH (&lumiera_global_config->defaults.children, node)
308 fprintf (out, "%s\n", ((LumieraConfigitem) node)->line);
309
310 fprintf (out, "# end of defaults\n\n");
311
312#if 0 /*TODO UNIMPLEMENTED */
313 fprintf (out, "# files:\n");
314 lumiera_configitem files;
315 fprintf (out, "# volatiles:")
316 lumiera_configitem TODO_unknown;
317#endif
318}
319
320
321int
322lumiera_config_reset (const char* key)
323{
324 (void) key;
325 TRACE (config_dbg);
326 UNIMPLEMENTED();
327 return -1;
328}
329
330
331int
332lumiera_config_info (const char* key, const char** filename, unsigned* line)
333{
334 (void) key;
335 (void) filename;
336 (void) line;
337 TRACE (config_dbg);
338 UNIMPLEMENTED();
339 return -1;
340}
341
342/*
343// Local Variables:
344// mode: C
345// c-file-style: "gnu"
346// indent-tabs-mode: nil
347// End:
348*/
LumieraConfigitem lumiera_config_lookup_item_find(LumieraConfigLookup self, const char *key)
Find a the topmost config item stored to a given key.
LumieraConfigLookup lumiera_config_lookup_destroy(LumieraConfigLookup self)
Destroy a lookup structure.
LumieraConfigLookupentry lumiera_config_lookup_insert(LumieraConfigLookup self, LumieraConfigitem item)
Add a config item to a lookup structure.
LumieraConfigLookup lumiera_config_lookup_init(LumieraConfigLookup self)
Initialise a lookup structure.
LumieraConfigitem lumiera_config_lookup_item_tail_find(LumieraConfigLookup self, const char *key)
Find a the bottom most config item stored to a given key.
int lumiera_config_purge(const char *filename)
Definition config.c:143
void lumiera_config_dump(FILE *out)
Does a diagnostic dump of the whole config database.
Definition config.c:303
int lumiera_config_info(const char *key, const char **filename, unsigned *line)
Definition config.c:332
LumieraConfigitem lumiera_config_set(const char *key, const char *delim_value)
Definition config.c:223
int lumiera_config_load(const char *file)
Definition config.c:124
int lumiera_config_init(const char *path)
Initialise the configuration subsystem.
Definition config.c:77
int lumiera_config_save()
Definition config.c:134
const char * lumiera_config_defaults[]
defaults for the configuration system itself
Definition config.c:41
LumieraConfigitem lumiera_config_setdefault(const char *line)
Installs a default value for a config key.
Definition config.c:265
const char * lumiera_config_get(const char *key, const char **value)
Definition config.c:154
void lumiera_config_destroy()
Destroys the configuration subsystem.
Definition config.c:105
LumieraConfig lumiera_global_config
Definition config.c:73
int lumiera_config_reset(const char *key)
Definition config.c:322
const char * lumiera_config_get_default(const char *key, const char **value)
Definition config.c:201
Interface for a lumiera configuration system (draft).
#define LUMIERA_CONFIG_KEY_CHARS
Definition config.h:50
lumiera_config * LumieraConfig
Definition config.h:67
#define LUMIERA_CONFIG_ENV_CHARS
Definition config.h:51
LumieraConfigitem lumiera_configitem_set_value(LumieraConfigitem self, const char *delim_value)
Definition configitem.c:122
LumieraConfigitem lumiera_configitem_new(const char *line)
Definition configitem.c:96
LumieraConfigitem lumiera_configitem_destroy(LumieraConfigitem self, LumieraConfigLookup lookup)
Definition configitem.c:70
LumieraConfigitem lumiera_configitem_init(LumieraConfigitem self)
Definition configitem.c:47
lumiera_configitem * LumieraConfigitem
Definition configitem.h:53
#define LUMIERA_ERROR_SET(flag, err, extra)
Helper macro to raise an error for the current thread.
Definition error.h:82
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition error.h:71
#define LUMIERA_ERROR_SET_WARNING(flag, err, extra)
Helper macro to raise an error for the current thread.
Definition error.h:127
#define llist_insert_tail(list, element)
Definition llist.h:96
return NULL
Definition llist.h:586
#define LLIST_FOREACH(list, node)
Iterate forward over a list.
Definition llist.h:119
#define llist_insert_head(list, element)
Definition llist.h:95
This header is for including and configuring NoBug.
LumieraMutex lumiera_mutex_destroy(LumieraMutex self, struct nobug_flag *flag, const struct nobug_context ctx)
Destroy a mutex variable.
Definition mutex.c:39
LumieraMutex lumiera_mutex_init(LumieraMutex self, const char *purpose, struct nobug_flag *flag, const struct nobug_context ctx)
Initialise a mutex variable This initialises a 'fast' default mutex which must not be locked recursiv...
Definition mutex.c:21
#define LUMIERA_MUTEX_SECTION(nobugflag, mtx)
Mutual exclusive section.
Definition mutex.h:32
void * lumiera_malloc(size_t size)
Allocate memory.
Definition safeclib.c:113
Portable and safe wrappers around some C-Lib functions.
static void lumiera_free(void *mem)
Free previously allocated memory.
Definition safeclib.h:73
char * lumiera_tmpbuf_tr(const char *in, const char *from, const char *to, const char *def)
Translates characters in a string, similar to the shell 'tr' utility.
Definition tmpbuf.c:147
char * lumiera_tmpbuf_strndup(const char *src, size_t size)
Duplicate string to a tmpbuf.
Definition tmpbuf.c:102
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition tmpbuf.c:116
Round robin temporary buffers.