root/src/noit_conf.c

Revision caa7b86e0a2913bf4f9e3254320a05dd636b2e06, 6.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

glue up some actual XML

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include <stdio.h>
9 #include <assert.h>
10 #include <libxml/parser.h>
11 #include <libxml/tree.h>
12 #include <libxml/xpath.h>
13
14 #include "noit_conf.h"
15 #include "utils/noit_hash.h"
16
17 /* tmp hash impl, replace this with something nice */
18 static noit_hash_table _tmp_config = NOIT_HASH_EMPTY;
19 static xmlDocPtr master_config = NULL;
20 static xmlXPathContextPtr xpath_ctxt = NULL;
21
22 static noit_hash_table _compiled_fallback = NOIT_HASH_EMPTY;
23 static struct {
24   const char *key;
25   const char *val;
26 } config_info[] = {
27   /*
28    * These are compile-time fallbacks to be used in the event
29    * that the current running config does not have values for
30    * these config paths.
31    *
32    * PLEASE: keep them alphabetically sorted.
33    */
34   { "/global/modules/directory", MODULES_DIR },
35
36   { NULL, NULL }
37 };
38
39
40 void noit_conf_init() {
41   int i;
42   for(i = 0; config_info[i].key != NULL; i++) {
43     noit_hash_store(&_compiled_fallback,
44                     strdup(config_info[i].key), strlen(config_info[i].key),
45                     (void *)strdup(config_info[i].val));
46   }
47   xmlInitParser();
48   xmlXPathInit();
49 }
50
51 int noit_conf_load(const char *path) {
52   xmlDocPtr new_config;
53   new_config = xmlParseFile(path);
54   if(new_config) {
55     if(master_config) xmlFreeDoc(master_config);
56     if(xpath_ctxt) xmlXPathFreeContext(xpath_ctxt);
57
58     master_config = new_config;
59     xpath_ctxt = xmlXPathNewContext(master_config);
60     return 0;
61   }
62   return -1;
63 }
64 int noit_conf_save(const char *path) {
65   return -1;
66 }
67
68 noit_conf_section_t noit_conf_get_section(noit_conf_section_t section,
69                                           const char *path) {
70   noit_conf_section_t subsection = NULL;
71   xmlXPathObjectPtr pobj;
72   xmlXPathContextPtr current_ctxt;
73   xmlNodePtr current_node = (xmlNodePtr)section;
74
75   current_ctxt = xpath_ctxt;
76   if(current_node) {
77     current_ctxt = xmlXPathNewContext(master_config);
78     current_ctxt->node = current_node;
79   }
80   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
81   if(!pobj) goto out;
82   if(pobj->type != XPATH_NODESET) goto out;
83   if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto out;
84   subsection = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
85  out:
86   if(current_ctxt && current_ctxt != xpath_ctxt)
87     xmlXPathFreeContext(current_ctxt);
88   return subsection;
89 }
90 noit_conf_section_t *noit_conf_get_sections(noit_conf_section_t section,
91                                             const char *path,
92                                             int *cnt) {
93   int i;
94   noit_conf_section_t *sections;
95   xmlXPathObjectPtr pobj;
96   xmlXPathContextPtr current_ctxt;
97   xmlNodePtr current_node = (xmlNodePtr)section;
98
99   *cnt = 0;
100   current_ctxt = xpath_ctxt;
101   if(current_node) {
102     current_ctxt = xmlXPathNewContext(master_config);
103     current_ctxt->node = current_node;
104   }
105   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
106   if(!pobj) goto out;
107   if(pobj->type != XPATH_NODESET) goto out;
108   if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) goto out;
109   *cnt = xmlXPathNodeSetGetLength(pobj->nodesetval);
110   sections = calloc(*cnt, sizeof(*sections));
111   for(i=0; i<*cnt; i++)
112     sections[i] = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i);
113  out:
114   if(current_ctxt && current_ctxt != xpath_ctxt)
115     xmlXPathFreeContext(current_ctxt);
116   return sections;
117 }
118 int _noit_conf_get_string(noit_conf_section_t section,
119                           const char *path, char **value) {
120   char *str;
121   int i;
122   xmlXPathObjectPtr pobj;
123   xmlXPathContextPtr current_ctxt;
124   xmlNodePtr current_node = (xmlNodePtr)section;
125
126   current_ctxt = xpath_ctxt;
127   if(current_node) {
128     current_ctxt = xmlXPathNewContext(master_config);
129     current_ctxt->node = current_node;
130   }
131   pobj = xmlXPathEval((xmlChar *)path, current_ctxt);
132   if(pobj) {
133     switch(pobj->type) {
134       case XPATH_NODESET:
135         if(xmlXPathNodeSetIsEmpty(pobj->nodesetval)) return 0;
136         i = xmlXPathNodeSetGetLength(pobj->nodesetval);
137         assert(i == 1);
138         *value = (char *)xmlXPathCastNodeSetToString(pobj->nodesetval);
139         break;
140       default:
141         *value = (char *)xmlXPathCastToString(pobj);
142     }
143     goto found;
144   }
145   if(noit_hash_retrieve(&_compiled_fallback,
146                         path, strlen(path), (void **)&str)) {
147     *value = str;
148     goto found;
149   }
150   return 0;
151  found:
152   if(current_ctxt && current_ctxt != xpath_ctxt)
153     xmlXPathFreeContext(current_ctxt);
154   return 1;
155 }
156 int noit_conf_get_string(noit_conf_section_t section,
157                          const char *path, char **value) {
158   char *str;
159   if(_noit_conf_get_string(section,path,&str)) {
160     *value = strdup(str);
161     return 1;
162   }
163   return 0;
164 }
165 int noit_conf_get_stringbuf(noit_conf_section_t section,
166                             const char *path, char *buf, int len) {
167   char *str;
168   if(_noit_conf_get_string(section,path,&str)) {
169     strlcpy(buf, str, len);
170     return 1;
171   }
172   return 0;
173 }
174 int noit_conf_set_string(noit_conf_section_t section,
175                          const char *path, const char *value) {
176   noit_hash_replace(&_tmp_config,
177                     strdup(path), strlen(path), (void *)strdup(value),
178                     free, free);
179   return 1;
180 }
181 int noit_conf_get_int(noit_conf_section_t section,
182                       const char *path, int *value) {
183   char *str;
184   long longval;
185   if(noit_conf_get_string(section,path,&str)) {
186     int base = 10;
187     if(str[0] == '0') {
188       if(str[1] == 'x') base = 16;
189       else base = 8;
190     }
191     longval = strtol(str, NULL, base);
192     free(str);
193     *value = (int)longval;
194     return 1;
195   }
196   return 0;
197 }
198 int noit_conf_set_int(noit_conf_section_t section,
199                       const char *path, int value) {
200   char buffer[32];
201   snprintf(buffer, 32, "%d", value);
202   return noit_conf_set_string(section,path,buffer);
203 }
204 int noit_conf_get_float(noit_conf_section_t section,
205                         const char *path, float *value) {
206   char *str;
207   if(noit_conf_get_string(section,path,&str)) {
208     *value = atof(str);
209     free(str);
210     return 1;
211   }
212   return 0;
213 }
214 int noit_conf_set_float(noit_conf_section_t section,
215                         const char *path, float value) {
216   char buffer[32];
217   snprintf(buffer, 32, "%f", value);
218   return noit_conf_set_string(section,path,buffer);
219 }
220 int noit_conf_get_boolean(noit_conf_section_t section,
221                           const char *path, noit_conf_boolean *value) {
222   char *str;
223   if(noit_conf_get_string(section,path,&str)) {
224     if(!strcasecmp(str, "true")) *value = noit_true;
225     else *value = noit_false;
226     free(str);
227     return 1;
228   }
229   return 0;
230 }
231 int noit_conf_set_boolean(noit_conf_section_t section,
232                           const char *path, noit_conf_boolean value) {
233   if(value == noit_true)
234     return noit_conf_set_string(section,path,"true");
235   return noit_conf_set_string(section,path,"false");
236 }
237
Note: See TracBrowser for help on using the browser.