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) Lumiera.org
5  2008, Christian Thaeter <ct@pipapo.org>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
32 #include "include/logging.h"
33 #include "lib/safeclib.h"
34 #include "lib/tmpbuf.h"
35 
36 #include "common/config-lookup.h"
37 #include "common/config.h"
38 
39 /* we only use one fatal error for now, when allocation in the config system fail, something else is pretty wrong */
40 LUMIERA_ERROR_DEFINE (CONFIG_LOOKUP, "config lookup failure");
41 
42 
43 
44 /* === support functions for the splay tree === */
45 
46 static int
47 cmp_fn (const void* a, const void* b);
48 
49 static void
50 delete_fn (PSplaynode node);
51 
52 static const void*
53 key_fn (const PSplaynode node);
54 
55 
56 
57 
58 LumieraConfigLookup
59 lumiera_config_lookup_init (LumieraConfigLookup self)
60 {
61  TRACE (configlookup_dbg);
62  psplay_init (&self->tree, cmp_fn, key_fn, delete_fn);
63  return self;
64 }
65 
66 
67 LumieraConfigLookup
68 lumiera_config_lookup_destroy (LumieraConfigLookup self)
69 {
70  TRACE (configlookup_dbg);
71  if (self)
72  psplay_destroy (&self->tree);
73  return self;
74 }
75 
76 
77 LumieraConfigLookupentry
78 lumiera_config_lookup_insert (LumieraConfigLookup self, LumieraConfigitem item)
79 {
80  TRACE (configlookup_dbg, "%s", item->line);
81  REQUIRE (self);
82  REQUIRE (item);
83  REQUIRE (item->key);
84  REQUIRE (item->key_size);
85 
87 
88  const char* key = lumiera_tmpbuf_strcat3 (NULL, 0, item->key, item->key_size, NULL, 0);
89 
90  LumieraConfigLookupentry entry = (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
91  if (!entry)
92  entry = (LumieraConfigLookupentry)psplay_insert (&self->tree, &lumiera_config_lookupentry_new (key)->node, 100);
93 
94  llist_insert_head (&entry->configitems, &item->lookup);
95  return entry;
96 }
97 
98 
99 LumieraConfigLookupentry
100 lumiera_config_lookup_insert_default (LumieraConfigLookup self, LumieraConfigitem item)
101 {
102  TRACE (configlookup_dbg, "%s", item->line);
103  REQUIRE (self);
104  REQUIRE (item);
105  REQUIRE (item->key);
106  REQUIRE (item->key_size);
107 
108  const char* key = lumiera_tmpbuf_snprintf (SIZE_MAX, "%.*s", item->key_size, item->key);
109  LumieraConfigLookupentry entry = (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
110  if (!entry)
111  entry = (LumieraConfigLookupentry)psplay_insert (&self->tree, &lumiera_config_lookupentry_new (key)->node, 100);
112 
115 
116  llist_insert_tail (&entry->configitems, &item->lookup);
117  return entry;
118 }
119 
120 
121 LumieraConfigitem
122 lumiera_config_lookup_remove (LumieraConfigLookup self, LumieraConfigitem item)
123 {
124  TRACE (configlookup_dbg, "%s", item->line);
125  REQUIRE (!llist_is_empty (&item->lookup), "item is not in a lookup");
126 
127  if (llist_is_single (&item->lookup))
128  {
129  /* last item in lookup, remove it from the splay tree */
130  LumieraConfigLookupentry entry = LLIST_TO_STRUCTP (llist_next (&item->lookup), lumiera_config_lookupentry, configitems);
131  llist_unlink (&item->lookup);
132  psplay_delete_node (&self->tree, (PSplaynode)entry);
133  }
134  else
135  {
136  /* more than this item present in hash, just unlink this item */
137  llist_unlink (&item->lookup);
138  }
139 
140  return item;
141 }
142 
143 
144 LumieraConfigLookupentry
145 lumiera_config_lookup_find (LumieraConfigLookup self, const char* key)
146 {
147  TRACE (configlookup_dbg, "%s", key);
148  return (LumieraConfigLookupentry)psplay_find (&self->tree, key, 100);
149 }
150 
151 
152 LumieraConfigitem
153 lumiera_config_lookup_item_find (LumieraConfigLookup self, const char* key)
154 {
155  TRACE (configlookup_dbg, "%s", key);
156 
157  LumieraConfigLookupentry entry =
158  lumiera_config_lookup_find (self, key);
159 
160  if (entry && !llist_is_empty (&entry->configitems))
161  return LLIST_TO_STRUCTP (llist_head (&entry->configitems), lumiera_configitem, lookup);
162 
163  return NULL;
164 }
165 
166 
167 LumieraConfigitem
168 lumiera_config_lookup_item_tail_find (LumieraConfigLookup self, const char* key)
169 {
170  TRACE (configlookup_dbg, "%s", key);
171 
172  LumieraConfigLookupentry entry =
173  lumiera_config_lookup_find (self, key);
174 
175  if (entry && !llist_is_empty (&entry->configitems))
176  return LLIST_TO_STRUCTP (llist_tail (&entry->configitems), lumiera_configitem, lookup);
177 
178  return NULL;
179 }
180 
181 
182 
183 /* === Lookup of entries === */
184 
185 LumieraConfigLookupentry
186 lumiera_config_lookupentry_init (LumieraConfigLookupentry self, const char* key)
187 {
188  TRACE (configlookup_dbg, "%s", key);
189  if (self)
190  {
191  psplaynode_init (&self->node);
192  llist_init (&self->configitems);
193  self->full_key = lumiera_strndup (key, SIZE_MAX);
194  }
195  return self;
196 }
197 
198 
199 LumieraConfigLookupentry
200 lumiera_config_lookupentry_new (const char* key)
201 {
202  return lumiera_config_lookupentry_init (lumiera_malloc (sizeof (lumiera_config_lookupentry)), key);
203 }
204 
205 
206 LumieraConfigLookupentry
207 lumiera_config_lookupentry_destroy (LumieraConfigLookupentry self)
208 {
209  TRACE (configlookup_dbg);
210  if (self)
211  {
212  REQUIRE (llist_is_empty (&self->configitems), "lookup node still in use");
213  lumiera_free (self->full_key);
214  }
215  return self;
216 }
217 
218 
219 void
220 lumiera_config_lookupentry_delete (LumieraConfigLookupentry self)
221 {
222  lumiera_free (lumiera_config_lookupentry_destroy (self));
223 }
224 
225 static int
226 cmp_fn (const void* a, const void* b)
227 {
228  return strcmp ((const char*)a, (const char*)b);
229 }
230 
231 static void
232 delete_fn (PSplaynode node)
233 {
234  lumiera_config_lookupentry_delete ((LumieraConfigLookupentry) node);
235 }
236 
237 
238 static const void*
239 key_fn (const PSplaynode node)
240 {
241  return ((LumieraConfigLookupentry) node)->full_key;
242 }
243 
244 /*
245 // Local Variables:
246 // mode: C
247 // c-file-style: "gnu"
248 // indent-tabs-mode: nil
249 // End:
250 */
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:78
PSplay psplay_destroy(PSplay self)
Destroy a splay tree Frees all elements and associated resources of a splay tree. ...
Definition: psplay.c:110
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:75
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:82
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
Definition: psplay.c:309
LumieraConfigLookupentry lumiera_config_lookup_insert_default(LumieraConfigLookup self, LumieraConfigitem item)
PSplaynode psplay_insert(PSplay self, PSplaynode node, int splayfactor)
Insert a element into a splay tree.
Definition: psplay.c:255
Lookup of configuration keys in a low-level configuration system.
void * lumiera_malloc(size_t size)
Allocate memory.
Definition: safeclib.c:122
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:144
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:68
LumieraConfigLookup lumiera_config_lookup_init(LumieraConfigLookup self)
Initialise a lookup structure.
Definition: config-lookup.c:59
#define LLIST_TO_STRUCTP(llist, type, member)
cast back from a member of a structure to a pointer of the structure
Definition: llist.h:121
char * lumiera_strndup(const char *str, size_t len)
Duplicate a C string.
Definition: safeclib.c:175
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:131
void psplay_delete_node(PSplay self, PSplaynode node)
Delete a node from a splay tree.
Definition: psplay.c:407
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:80
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition: tmpbuf.c:125