root/cherokee/trunk/cherokee/config_node.c

Revision 1878, 8.0 kB (checked in by alo, 3 weeks ago)

--

Line 
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Cherokee
4  *
5  * Authors:
6  *      Alvaro Lopez Ortega <alvaro@alobbs.com>
7  *
8  * Copyright (C) 2001-2008 Alvaro Lopez Ortega
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of version 2 of the GNU General Public
12  * License as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  */
24
25 #include "common-internal.h"
26
27 #include "config_node.h"
28 #include "config_reader.h"
29 #include "util.h"
30
31 #define ENTRIES "config"
32
33
34 /* Implements _new() and _free()
35  */
36 CHEROKEE_ADD_FUNC_NEW  (config_node);
37 CHEROKEE_ADD_FUNC_FREE (config_node);
38
39
40 ret_t
41 cherokee_config_node_init (cherokee_config_node_t *conf)
42 {
43         INIT_LIST_HEAD (&conf->entry);
44         INIT_LIST_HEAD (&conf->child);
45        
46         cherokee_buffer_init (&conf->key);
47         cherokee_buffer_init (&conf->val);
48        
49         return ret_ok;
50 }
51
52
53 ret_t
54 cherokee_config_node_mrproper (cherokee_config_node_t *conf)
55 {
56         cherokee_list_t *i, *j;
57
58         cherokee_buffer_mrproper (&conf->key);
59         cherokee_buffer_mrproper (&conf->val);
60
61         list_for_each_safe (i, j, &conf->child) {
62                 cherokee_config_node_free (CONFIG_NODE(i));
63         }
64
65         return ret_ok;
66 }
67
68
69 static cherokee_config_node_t *
70 search_child (cherokee_config_node_t *current, cherokee_buffer_t *child)
71 {
72         cherokee_list_t        *i;
73         cherokee_config_node_t *entry;
74
75         list_for_each (i, &current->child) {
76                 entry = CONFIG_NODE(i);
77
78                 if (strcmp (entry->key.buf, child->buf) == 0)
79                         return entry;
80         }
81
82         return NULL;
83 }
84
85
86 static cherokee_config_node_t *
87 add_new_child (cherokee_config_node_t *entry, cherokee_buffer_t *key)
88 {
89         ret_t                   ret;
90         cherokee_config_node_t *n;
91
92         ret = cherokee_config_node_new (&n);
93         if (ret != ret_ok) return NULL;
94
95         cherokee_buffer_add_buffer (&n->key, key);         
96
97         cherokee_list_add_tail (LIST(n), &entry->child);
98         return n;
99 }
100
101
102 ret_t
103 cherokee_config_node_add (cherokee_config_node_t *conf, const char *key, cherokee_buffer_t *val)
104 {
105         char                   *sep;
106         cherokee_config_node_t *child;
107         cherokee_config_node_t *current = conf;
108         const char             *begin   = key;
109         cherokee_buffer_t       tmp     = CHEROKEE_BUF_INIT;
110         cherokee_boolean_t      final   = false;
111        
112         /* 'include' is a special case
113          */
114         if (equal_str (key, "include")) {
115                 return cherokee_config_reader_parse (conf, val);
116         } else if (equal_str (key, "try_include")) {
117                 cherokee_config_reader_parse (conf, val);
118         }
119
120         do {
121                 /* Extract current child
122                  */
123                 sep = strchr (begin, '!');
124                 if (sep != NULL) {
125                         cherokee_buffer_add (&tmp, begin, sep - begin);
126                 } else {
127                         cherokee_buffer_add (&tmp, begin, strlen(begin));
128                         final = true;
129                 }
130
131                 /* Look for the child entry
132                  */
133                 child = search_child (current, &tmp);
134                 if (child == NULL) {
135                         child = add_new_child (current, &tmp);
136                         if (child == NULL) return ret_error;
137                 }
138
139                 if (final) {
140                         cherokee_buffer_clean (&child->val);
141                         cherokee_buffer_add_buffer (&child->val, val);
142                 }
143
144                 /* Prepare for next step
145                  */
146                 begin = sep + 1;
147                 current = child;
148
149                 cherokee_buffer_clean (&tmp);
150
151         } while (! final);
152
153         cherokee_buffer_mrproper (&tmp);
154         return ret_ok;
155 }
156
157
158 ret_t
159 cherokee_config_node_add_buf (cherokee_config_node_t *conf, cherokee_buffer_t *key, cherokee_buffer_t *val)
160 {
161         return cherokee_config_node_add (conf, key->buf, val);
162 }
163
164
165 ret_t
166 cherokee_config_node_get (cherokee_config_node_t *conf, const char *key, cherokee_config_node_t **entry)
167 {
168         char                   *sep;
169         cherokee_config_node_t *child;
170         cherokee_config_node_t *current = conf;
171         const char             *begin   = key;
172         cherokee_buffer_t       tmp     = CHEROKEE_BUF_INIT;
173         cherokee_boolean_t      final   = false;
174
175         do {
176                 /* Extract current child
177                  */
178                 sep = strchr (begin, '!');
179                 if (sep != NULL) {
180                         cherokee_buffer_add (&tmp, begin, sep - begin);
181                 } else {
182                         cherokee_buffer_add (&tmp, begin, strlen(begin));
183                         final = true;
184                 }
185
186                 /* Look for the child entry
187                  */
188                 child = search_child (current, &tmp);
189                 if (child == NULL) {
190                         cherokee_buffer_mrproper (&tmp);
191                         return ret_not_found;
192                 }
193
194                 if (final) {
195                         *entry = child;
196                 }
197
198                 /* Prepare for next step
199                  */
200                 begin = sep + 1;
201                 current = child;
202
203                 cherokee_buffer_clean (&tmp);
204
205         } while (! final);
206        
207         cherokee_buffer_mrproper (&tmp);
208         return ret_ok;
209 }
210
211
212 ret_t
213 cherokee_config_node_get_buf (cherokee_config_node_t *conf, cherokee_buffer_t *key, cherokee_config_node_t **entry)
214 {
215         return cherokee_config_node_get (conf, key->buf, entry);
216 }
217
218
219 ret_t
220 cherokee_config_node_while (cherokee_config_node_t *conf, cherokee_config_node_while_func_t func, void *data)
221 {
222         ret_t            ret;
223         cherokee_list_t *i;
224
225         cherokee_config_node_foreach (i, conf) {
226                 ret = func (CONFIG_NODE(i), data);
227                 if (ret != ret_ok) return ret;
228         }
229
230         return ret_ok;
231 }
232
233
234 ret_t
235 cherokee_config_node_read (cherokee_config_node_t *conf, const char *key, cherokee_buffer_t **buf)
236 {
237         ret_t                   ret;
238         cherokee_config_node_t *tmp;
239
240         ret = cherokee_config_node_get (conf, key, &tmp);
241         if (ret != ret_ok) return ret;
242
243         *buf = &tmp->val;
244         return ret_ok;
245 }
246
247
248 ret_t
249 cherokee_config_node_copy (cherokee_config_node_t *conf, const char *key, cherokee_buffer_t *buf)
250 {
251         ret_t              ret;
252         cherokee_buffer_t *tmp = NULL;
253        
254         ret = cherokee_config_node_read (conf, key, &tmp);
255         if (ret != ret_ok) return ret;
256
257         return cherokee_buffer_add_buffer (buf, tmp);
258 }
259
260
261 ret_t
262 cherokee_config_node_read_int (cherokee_config_node_t *conf, const char *key, int *num)
263 {
264         ret_t                   ret;
265         cherokee_config_node_t *tmp;
266
267         ret = cherokee_config_node_get (conf, key, &tmp);
268         if (ret != ret_ok) return ret;
269
270         *num = atoi (tmp->val.buf);
271         return ret_ok;
272 }
273
274
275 ret_t
276 cherokee_config_node_read_long (cherokee_config_node_t *conf, const char *key, long *num)
277 {
278         ret_t                   ret;
279         cherokee_config_node_t *tmp;
280
281         ret = cherokee_config_node_get (conf, key, &tmp);
282         if (ret != ret_ok) return ret;
283
284         *num = atol (tmp->val.buf);
285         return ret_ok;
286 }
287
288
289 ret_t
290 cherokee_config_node_read_bool (cherokee_config_node_t *conf, const char *key, cherokee_boolean_t *val)
291 {
292         ret_t ret;
293         int   tmp;
294
295         ret = cherokee_config_node_read_int (conf, key, &tmp);
296         if (ret != ret_ok) return ret;
297
298         *val = !! tmp;
299         return ret_ok;
300 }
301
302
303 ret_t
304 cherokee_config_node_read_path (cherokee_config_node_t *conf, const char *key, cherokee_buffer_t **buf)
305 {
306         ret_t                   ret;
307         cherokee_config_node_t *tmp;
308
309         if (key != NULL) {
310                 ret = cherokee_config_node_get (conf, key, &tmp);
311                 if (ret != ret_ok) return ret;
312         } else {
313                 tmp = conf;
314         }
315
316         if (cherokee_buffer_end_char (&tmp->val) != '/')
317                 cherokee_buffer_add_str (&tmp->val, "/");
318
319         *buf = &tmp->val;
320         return ret_ok;
321 }
322
323
324 ret_t
325 cherokee_config_node_read_list (cherokee_config_node_t           *conf,
326                                 const char                       *key,
327                                 cherokee_config_node_list_func_t  func,
328                                 void                             *param)
329 {
330         ret_t                   ret;
331         char                   *ptr;
332         char                   *stop;
333         cherokee_config_node_t *tmp;
334
335         if (key != NULL) {
336                 ret = cherokee_config_node_get (conf, key, &tmp);
337                 if (ret != ret_ok) return ret;
338         } else {
339                 tmp = conf;
340         }
341
342         ptr = tmp->val.buf;
343
344         if (ptr == NULL)
345                 return ret_not_found;
346
347         for (;;) {
348                 while ((*ptr == ' ') && (*ptr != '\0'))
349                         ptr++;
350
351                 stop = strchr (ptr, ',');
352                 if (stop != NULL) *stop = '\0';
353        
354                 ret = func (ptr, param);
355                 if (ret != ret_ok) return ret;
356                
357                 if (stop == NULL)
358                         break;
359                
360                 *stop = ',';
361                 ptr = stop + 1;
362         }
363        
364         return ret_ok;
365 }
366
367
368 static ret_t
369 convert_to_list_step (char *entry, void *data)
370 {
371         return cherokee_list_add_tail_content (LIST(data), strdup(entry));
372 }
373
374
375 ret_t
376 cherokee_config_node_convert_list (cherokee_config_node_t *conf, const char *key, cherokee_list_t *list)
377 {
378         return cherokee_config_node_read_list (conf, key, convert_to_list_step, list);
379 }
Note: See TracBrowser for help on using the browser.