Lumiera  0.pre.03
»edit your freedom«
config-lookup.c
Go to the documentation of this file.
1 /*
2  Config-lookup - Lookup functions for the config subsystem
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 
23 #include "include/logging.h"
24 #include "lib/safeclib.h"
25 #include "lib/tmpbuf.h"
26 
27 #include "common/config-lookup.h"
28 #include "common/config.h"
29 
30 /* we only use one fatal error for now, when allocation in the config system fail, something else is pretty wrong */
31 LUMIERA_ERROR_DEFINE (CONFIG_LOOKUP, "config lookup failure");
32 
33 
34 
35 /* === support functions for the splay tree === */
36 
37 static int
38 cmp_fn (const void* a, const void* b);
39 
40 static void
41 delete_fn (PSplaynode node);
42 
43 static const void*
44 key_fn (const PSplaynode node);
45 
46 
47 
48 
49 LumieraConfigLookup
50 lumiera_config_lookup_init (LumieraConfigLookup self)
51 {
52  TRACE (configlookup_dbg);
53  psplay_init (&self->tree, cmp_fn, key_fn, delete_fn);
54  return self;
55 }
56 
57 
58 LumieraConfigLookup
59 lumiera_config_lookup_destroy (LumieraConfigLookup self)
60 {
61  TRACE (configlookup_dbg);
62  if (self)
63  psplay_destroy (&self->tree);
64  return self;
65 }
66 
67 
68 LumieraConfigLookupentry
69 lumiera_config_lookup_insert (LumieraConfigLookup self, LumieraConfigitem item)
70 {
71  TRACE (configlookup_dbg, "%s", item->line);
72  REQUIRE (self);
73  REQUIRE (item);
74  REQUIRE (item->key);
75  REQUIRE (item->key_size);
76 
78 
79  const char* key = lumiera_tmpbuf_strcat3 (NULL, 0, item->key, item->key_size, NULL, 0);
80 
81  LumieraConfigLookupentry entry = (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
82  if (!entry)
83  entry = (LumieraConfigLookupentry)psplay_insert (&self->tree, &lumiera_config_lookupentry_new (key)->node, 100);
84 
85  llist_insert_head (&entry->configitems, &item->lookup);
86  return entry;
87 }
88 
89 
90 LumieraConfigLookupentry
91 lumiera_config_lookup_insert_default (LumieraConfigLookup self, LumieraConfigitem item)
92 {
93  TRACE (configlookup_dbg, "%s", item->line);
94  REQUIRE (self);
95  REQUIRE (item);
96  REQUIRE (item->key);
97  REQUIRE (item->key_size);
98 
99  const char* key = lumiera_tmpbuf_snprintf (SIZE_MAX, "%.*s", item->key_size, item->key);
100  LumieraConfigLookupentry entry = (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
101  if (!entry)
102  entry = (LumieraConfigLookupentry)psplay_insert (&self->tree, &lumiera_config_lookupentry_new (key)->node, 100);
103 
106 
107  llist_insert_tail (&entry->configitems, &item->lookup);
108  return entry;
109 }
110 
111 
112 LumieraConfigitem
113 lumiera_config_lookup_remove (LumieraConfigLookup self, LumieraConfigitem item)
114 {
115  TRACE (configlookup_dbg, "%s", item->line);
116  REQUIRE (!llist_is_empty (&item->lookup), "item is not in a lookup");
117 
118  if (llist_is_single (&item->lookup))
119  {
120  /* last item in lookup, remove it from the splay tree */
121  LumieraConfigLookupentry entry = LLIST_TO_STRUCTP (llist_next (&item->lookup), lumiera_config_lookupentry, configitems);
122  llist_unlink (&item->lookup);
123  psplay_delete_node (&self->tree, (PSplaynode)entry);
124  }
125  else
126  {
127  /* more than this item present in hash, just unlink this item */
128  llist_unlink (&item->lookup);
129  }
130 
131  return item;
132 }
133 
134 
135 LumieraConfigLookupentry
136 lumiera_config_lookup_find (LumieraConfigLookup self, const char* key)
137 {
138  TRACE (configlookup_dbg, "%s", key);
139  return (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
140 }
141 
142 
143 LumieraConfigitem
144 lumiera_config_lookup_item_find (LumieraConfigLookup self, const char* key)
145 {
146  TRACE (configlookup_dbg, "%s", key);
147 
148  LumieraConfigLookupentry entry =
149  lumiera_config_lookup_find (self, key);
150 
151  if (entry && !llist_is_empty (&entry->configitems))
152  return LLIST_TO_STRUCTP (llist_head (&entry->configitems), lumiera_configitem, lookup);
153 
154  return NULL;
155 }
156 
157 
158 LumieraConfigitem
159 lumiera_config_lookup_item_tail_find (LumieraConfigLookup self, const char* key)
160 {
161  TRACE (configlookup_dbg, "%s", key);
162 
163  LumieraConfigLookupentry entry =
164  lumiera_config_lookup_find (self, key);
165 
166  if (entry && !llist_is_empty (&entry->configitems))
167  return LLIST_TO_STRUCTP (llist_tail (&entry->configitems), lumiera_configitem, lookup);
168 
169  return NULL;
170 }
171 
172 
173 
174 /* === Lookup of entries === */
175 
176 LumieraConfigLookupentry
177 lumiera_config_lookupentry_init (LumieraConfigLookupentry self, const char* key)
178 {
179  TRACE (configlookup_dbg, "%s", key);
180  if (self)
181  {
182  psplaynode_init (&self->node);
183  llist_init (&self->configitems);
184  self->full_key = lumiera_strndup (key, SIZE_MAX);
185  }
186  return self;
187 }
188 
189 
190 LumieraConfigLookupentry
191 lumiera_config_lookupentry_new (const char* key)
192 {
193  return lumiera_config_lookupentry_init (lumiera_malloc (sizeof (lumiera_config_lookupentry)), key);
194 }
195 
196 
197 LumieraConfigLookupentry
198 lumiera_config_lookupentry_destroy (LumieraConfigLookupentry self)
199 {
200  TRACE (configlookup_dbg);
201  if (self)
202  {
203  REQUIRE (llist_is_empty (&self->configitems), "lookup node still in use");
204  lumiera_free (self->full_key);
205  }
206  return self;
207 }
208 
209 
210 void
211 lumiera_config_lookupentry_delete (LumieraConfigLookupentry self)
212 {
213  lumiera_free (lumiera_config_lookupentry_destroy (self));
214 }
215 
216 static int
217 cmp_fn (const void* a, const void* b)
218 {
219  return strcmp ((const char*)a, (const char*)b);
220 }
221 
222 static void
223 delete_fn (PSplaynode node)
224 {
225  lumiera_config_lookupentry_delete ((LumieraConfigLookupentry) node);
226 }
227 
228 
229 static const void*
230 key_fn (const PSplaynode node)
231 {
232  return ((LumieraConfigLookupentry) node)->full_key;
233 }
234 
235 /*
236 // Local Variables:
237 // mode: C
238 // c-file-style: "gnu"
239 // indent-tabs-mode: nil
240 // End:
241 */
Portable and safe wrappers around some C-Lib functions.
LumieraConfigLookupentry lumiera_config_lookup_insert(LumieraConfigLookup self, LumieraConfigitem item)
Add a config item to a lookup structure.
Definition: config-lookup.c:69
PSplay psplay_destroy(PSplay self)
Destroy a splay tree Frees all elements and associated resources of a splay tree. ...
Definition: psplay.c:101
LumieraConfigitem lumiera_config_lookup_item_find(LumieraConfigLookup self, const char *key)
Find a the topmost config item stored to a given key.
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
PSplay psplay_init(PSplay self, psplay_cmp_fn cmp, psplay_key_fn key, psplay_delete_fn del)
Initialize a splay tree.
Definition: psplay.c:66
Interface for a lumiera configuration system (draft).
LumieraConfigLookupentry lumiera_config_lookup_find(LumieraConfigLookup self, const char *key)
Find a hashtable entry in the 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.
This header is for including and configuring NoBug.
Round robin temporary buffers.
static void lumiera_free(void *mem)
Free previously allocated memory.
Definition: safeclib.h:73
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
Definition: psplay.c:300
LumieraConfigLookupentry lumiera_config_lookup_insert_default(LumieraConfigLookup self, LumieraConfigitem item)
Definition: config-lookup.c:91
PSplaynode psplay_insert(PSplay self, PSplaynode node, int splayfactor)
Insert a element into a splay tree.
Definition: psplay.c:246
Lookup of configuration keys in a low-level configuration system.
void * lumiera_malloc(size_t size)
Allocate memory.
Definition: safeclib.c:113
char * lumiera_tmpbuf_strcat3(const char *str1, size_t str1_len, const char *str2, size_t str2_len, const char *str3, size_t str3_len)
Concat up to 3 strings in a tmpbuf.
Definition: tmpbuf.c:135
LumieraConfigitem lumiera_config_lookup_remove(LumieraConfigLookup self, LumieraConfigitem item)
Remove a config item from a lookup structure.
LumieraConfigLookup lumiera_config_lookup_destroy(LumieraConfigLookup self)
Destroy a lookup structure.
Definition: config-lookup.c:59
LumieraConfigLookup lumiera_config_lookup_init(LumieraConfigLookup self)
Initialise a lookup structure.
Definition: config-lookup.c:50
#define LLIST_TO_STRUCTP(llist, type, member)
cast back from a member of a structure to a pointer of the structure
Definition: llist.h:111
char * lumiera_strndup(const char *str, size_t len)
Duplicate a C string.
Definition: safeclib.c:166
PSplaynode psplaynode_init(PSplaynode self)
Initialise a splay tree node The user has to place this nodes within his datastructure and must Initi...
Definition: psplay.c:122
void psplay_delete_node(PSplay self, PSplaynode node)
Delete a node from a splay tree.
Definition: psplay.c:398
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:71
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition: tmpbuf.c:116