Mercurial > mplayer.hg
comparison m_config.c @ 8164:487cfc28525d
New config system + cleanup of header inter dependency
author | albeu |
---|---|
date | Tue, 12 Nov 2002 01:56:42 +0000 |
parents | |
children | 9c784bd027ad |
comparison
equal
deleted
inserted
replaced
8163:51e5033ee687 | 8164:487cfc28525d |
---|---|
1 | |
2 #include "config.h" | |
3 | |
4 #ifdef NEW_CONFIG | |
5 | |
6 #include <stdlib.h> | |
7 #include <stdio.h> | |
8 #include <errno.h> | |
9 #include <string.h> | |
10 #ifdef MP_DEBUG | |
11 #include <assert.h> | |
12 #endif | |
13 | |
14 | |
15 #include "m_config.h" | |
16 #include "m_option.h" | |
17 #include "mp_msg.h" | |
18 | |
19 m_config_t* | |
20 m_config_new(void) { | |
21 m_config_t* config; | |
22 | |
23 config = (m_config_t*)calloc(1,sizeof(m_config_t)); | |
24 config->lvl = 1; // 0 Is the defaults | |
25 return config; | |
26 } | |
27 | |
28 void | |
29 m_config_free(m_config_t* config) { | |
30 m_config_option_t *i = config->opts, *ct; | |
31 m_config_save_slot_t *sl,*st; | |
32 | |
33 #ifdef MP_DEBUG | |
34 assert(config != NULL); | |
35 #endif | |
36 | |
37 while(i) { | |
38 sl = i->slots; | |
39 while(sl) { | |
40 m_option_free(i->opt,sl->data); | |
41 st = sl->prev; | |
42 free(sl); | |
43 sl = st; | |
44 } | |
45 if(i->name != i->opt->name) | |
46 free(i->name); | |
47 ct = i->next; | |
48 free(i); | |
49 ct = i; | |
50 } | |
51 free(config); | |
52 } | |
53 | |
54 void | |
55 m_config_push(m_config_t* config) { | |
56 m_config_option_t *co; | |
57 m_config_save_slot_t *slot; | |
58 | |
59 #ifdef MP_DEBUG | |
60 assert(config != NULL); | |
61 assert(config->lvl > 0); | |
62 #endif | |
63 | |
64 config->lvl++; | |
65 | |
66 for(co = config->opts ; co ; co = co->next ) { | |
67 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
68 continue; | |
69 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
70 continue; | |
71 if((co->opt->flags & M_OPT_OLD) && !co->flags) | |
72 continue; | |
73 | |
74 // Update the current status | |
75 m_option_save(co->opt,co->slots->data,co->opt->p); | |
76 | |
77 // Allocate a new slot | |
78 slot = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); | |
79 slot->lvl = config->lvl; | |
80 slot->prev = co->slots; | |
81 co->slots = slot; | |
82 m_option_copy(co->opt,co->slots->data,co->slots->prev->data); | |
83 // Reset our flags | |
84 co->flags=0; | |
85 } | |
86 | |
87 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl); | |
88 } | |
89 | |
90 void | |
91 m_config_pop(m_config_t* config) { | |
92 m_config_option_t *co; | |
93 m_config_save_slot_t *slot; | |
94 | |
95 #ifdef MP_DEBUG | |
96 assert(config != NULL); | |
97 assert(config->lvl > 1); | |
98 #endif | |
99 | |
100 for(co = config->opts ; co ; co = co->next ) { | |
101 int pop = 0; | |
102 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
103 continue; | |
104 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
105 continue; | |
106 if(co->slots->lvl > config->lvl) | |
107 mp_msg(MSGT_CFGPARSER, MSGL_WARN,"Too old save slot found from lvl %d : %d !!!\n",config->lvl,co->slots->lvl); | |
108 | |
109 while(co->slots->lvl >= config->lvl) { | |
110 m_option_free(co->opt,co->slots->data); | |
111 slot = co->slots; | |
112 co->slots = slot->prev; | |
113 free(slot); | |
114 pop++; | |
115 } | |
116 if(pop) // We removed some ctx -> set the previous value | |
117 m_option_set(co->opt,co->opt->p,co->slots->data); | |
118 } | |
119 | |
120 config->lvl--; | |
121 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl); | |
122 } | |
123 | |
124 static void | |
125 m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix) { | |
126 m_config_option_t *co; | |
127 m_config_save_slot_t* sl; | |
128 | |
129 #ifdef MP_DEBUG | |
130 assert(config != NULL); | |
131 assert(config->lvl > 0); | |
132 assert(arg != NULL); | |
133 #endif | |
134 | |
135 // Allocate a new entry for this option | |
136 co = (m_config_option_t*)calloc(1,sizeof(m_config_option_t) + arg->type->size); | |
137 co->opt = arg; | |
138 | |
139 // Fill in the full name | |
140 if(prefix && strlen(prefix) > 0) { | |
141 int l = strlen(prefix) + 1 + strlen(arg->name) + 1; | |
142 co->name = (char*) malloc(l); | |
143 sprintf(co->name,"%s:%s",prefix,arg->name); | |
144 } else | |
145 co->name = arg->name; | |
146 | |
147 // Option with childs -> add them | |
148 if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
149 m_option_t *ol = arg->p; | |
150 int i; | |
151 for(i = 0 ; ol[i].name != NULL ; i++) | |
152 m_config_add_option(config,&ol[i], co->name); | |
153 } else { | |
154 // Allocate a slot for the defaults | |
155 sl = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); | |
156 m_option_save(arg,sl->data,(void**)arg->p); | |
157 // Hack to avoid too much trouble with dynamicly allocated data : | |
158 // We always use a dynamic version | |
159 if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { | |
160 *(void**)arg->p = NULL; | |
161 m_option_set(arg,arg->p,sl->data); | |
162 } | |
163 sl->lvl = 0; | |
164 co->slots = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); | |
165 co->slots->prev = sl; | |
166 co->slots->lvl = config->lvl; | |
167 m_option_copy(co->opt,co->slots->data,sl->data); | |
168 } | |
169 co->next = config->opts; | |
170 config->opts = co; | |
171 } | |
172 | |
173 int | |
174 m_config_register_options(m_config_t *config, m_option_t *args) { | |
175 int i; | |
176 | |
177 #ifdef MP_DEBUG | |
178 assert(config != NULL); | |
179 assert(config->lvl > 0); | |
180 assert(args != NULL); | |
181 #endif | |
182 | |
183 for(i = 0 ; args[i].name != NULL ; i++) | |
184 m_config_add_option(config,&args[i],NULL); | |
185 | |
186 return 1; | |
187 } | |
188 | |
189 static m_config_option_t* | |
190 m_config_get_co(m_config_t *config, char* arg) { | |
191 m_config_option_t *co; | |
192 | |
193 for(co = config->opts ; co ; co = co->next ) { | |
194 int l = strlen(co->name) - 1; | |
195 if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && | |
196 (co->name[l] == '*')) { | |
197 if(strncasecmp(co->name,arg,l) == 0) | |
198 return co; | |
199 } else if(strcasecmp(co->name,arg) == 0) | |
200 return co; | |
201 } | |
202 return NULL; | |
203 } | |
204 | |
205 static int | |
206 m_config_parse_option(m_config_t *config, char* arg, char* param,int set) { | |
207 m_config_option_t *co; | |
208 int r = 0; | |
209 | |
210 #ifdef MP_DEBUG | |
211 assert(config != NULL); | |
212 assert(config->lvl > 0); | |
213 assert(arg != NULL); | |
214 #endif | |
215 | |
216 co = m_config_get_co(config,arg); | |
217 if(!co) | |
218 return M_OPT_UNKNOW; | |
219 | |
220 #ifdef MP_DEBUG | |
221 // This is the only mandatory function | |
222 assert(co->opt->type->parse); | |
223 #endif | |
224 | |
225 // Check if this option isn't forbiden in the current mode | |
226 if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) { | |
227 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used in a config file\n",config->lvl); | |
228 return M_OPT_INVALID; | |
229 } | |
230 if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) { | |
231 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used on the command line\n",config->lvl); | |
232 return M_OPT_INVALID; | |
233 } | |
234 | |
235 // Option with childs are a bit different to parse | |
236 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
237 char** lst = NULL; | |
238 int i,sr; | |
239 // Parse the child options | |
240 r = m_option_parse(co->opt,arg,param,&lst,config->mode); | |
241 // Set them now | |
242 for(i = 0 ; lst && lst[2*i] ; i++) { | |
243 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
244 if(r >= 0) { | |
245 // Build the full name | |
246 char n[l]; | |
247 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
248 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
249 if(sr < 0) r = sr; | |
250 } | |
251 free(lst[2*i]); | |
252 free(lst[2*i+1]); | |
253 } | |
254 if(lst) free(lst); | |
255 } else | |
256 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
257 | |
258 // Parsing failed ? | |
259 if(r < 0) | |
260 return r; | |
261 // Set the option | |
262 if(set) { | |
263 m_option_set(co->opt,co->opt->p,co->slots->data); | |
264 co->flags = 1; | |
265 } | |
266 | |
267 return r; | |
268 } | |
269 | |
270 int | |
271 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
272 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
273 return m_config_parse_option(config,arg,param,1); | |
274 } | |
275 | |
276 int | |
277 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
278 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); | |
279 return m_config_parse_option(config,arg,param,0); | |
280 } | |
281 | |
282 | |
283 m_option_t* | |
284 m_config_get_option(m_config_t *config, char* arg) { | |
285 m_config_option_t *co; | |
286 | |
287 #ifdef MP_DEBUG | |
288 assert(config != NULL); | |
289 assert(config->lvl > 0); | |
290 assert(arg != NULL); | |
291 #endif | |
292 | |
293 co = m_config_get_co(config,arg); | |
294 if(co) | |
295 return co->opt; | |
296 else | |
297 return NULL; | |
298 } | |
299 | |
300 void* | |
301 m_config_get_option_ptr(m_config_t *config, char* arg) { | |
302 m_option_t* conf; | |
303 | |
304 #ifdef MP_DEBUG | |
305 assert(config != NULL); | |
306 assert(arg != NULL); | |
307 #endif | |
308 | |
309 conf = m_config_get_option(config,arg); | |
310 if(!conf) return NULL; | |
311 return conf->p; | |
312 } | |
313 | |
314 void | |
315 m_config_print_option_list(m_config_t *config) { | |
316 char min[50],max[50]; | |
317 m_config_option_t* co; | |
318 int count = 0; | |
319 | |
320 if(!config->opts) return; | |
321 | |
322 printf("\n Name Type Min Max Global CL Cfg\n\n"); | |
323 for(co = config->opts ; co ; co = co->next) { | |
324 m_option_t* opt = co->opt; | |
325 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; | |
326 if(opt->flags & M_OPT_MIN) | |
327 sprintf(min,"%-8.0f",opt->min); | |
328 else | |
329 strcpy(min,"No"); | |
330 if(opt->flags & M_OPT_MAX) | |
331 sprintf(max,"%-8.0f",opt->max); | |
332 else | |
333 strcpy(max,"No"); | |
334 printf(" %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", | |
335 co->name, | |
336 co->opt->type->name, | |
337 min, | |
338 max, | |
339 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
340 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
341 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
342 count++; | |
343 } | |
344 printf("\nTotal: %d options\n",count); | |
345 } | |
346 | |
347 #endif // NEW_CONFIG |