Mercurial > mplayer.hg
annotate m_config.c @ 9593:e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
Syntax is we decided, so you can give the nomes or not with both
vop and vf. vf take precedence over vop.
author | albeu |
---|---|
date | Sat, 15 Mar 2003 18:01:02 +0000 |
parents | d3da9b617aa8 |
children | 39444d65c4cb |
rev | line source |
---|---|
8164 | 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); | |
8892 | 217 if(!co){ |
8894 | 218 // mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Unknown option: %s\n",arg); |
8164 | 219 return M_OPT_UNKNOW; |
8892 | 220 } |
8164 | 221 |
222 #ifdef MP_DEBUG | |
223 // This is the only mandatory function | |
224 assert(co->opt->type->parse); | |
225 #endif | |
226 | |
227 // Check if this option isn't forbiden in the current mode | |
228 if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) { | |
8512 | 229 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used in a config file\n",arg); |
8164 | 230 return M_OPT_INVALID; |
231 } | |
232 if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) { | |
8512 | 233 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used on the command line\n",arg); |
8164 | 234 return M_OPT_INVALID; |
235 } | |
236 | |
237 // Option with childs are a bit different to parse | |
238 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
239 char** lst = NULL; | |
240 int i,sr; | |
241 // Parse the child options | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9222
diff
changeset
|
242 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 243 // Set them now |
8894 | 244 if(r >= 0) |
8164 | 245 for(i = 0 ; lst && lst[2*i] ; i++) { |
246 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
247 if(r >= 0) { | |
248 // Build the full name | |
249 char n[l]; | |
250 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
251 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 252 if(sr < 0){ |
253 if(sr == M_OPT_UNKNOW){ | |
254 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: option '%s' has no suboption '%s'\n",co->name,lst[2*i]); | |
255 r = M_OPT_INVALID; | |
256 } else | |
9222 | 257 if(sr == M_OPT_MISSING_PARAM){ |
258 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: suboption '%s' of '%s' must have a parameter!\n",lst[2*i],co->name); | |
259 r = M_OPT_INVALID; | |
260 } else | |
8894 | 261 r = sr; |
262 } | |
8164 | 263 } |
264 free(lst[2*i]); | |
265 free(lst[2*i+1]); | |
266 } | |
267 if(lst) free(lst); | |
268 } else | |
269 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
270 | |
271 // Parsing failed ? | |
272 if(r < 0) | |
273 return r; | |
274 // Set the option | |
275 if(set) { | |
276 m_option_set(co->opt,co->opt->p,co->slots->data); | |
277 co->flags = 1; | |
278 } | |
279 | |
280 return r; | |
281 } | |
282 | |
283 int | |
284 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
285 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
286 return m_config_parse_option(config,arg,param,1); | |
287 } | |
288 | |
289 int | |
290 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
9222 | 291 int r; |
8164 | 292 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 293 r=m_config_parse_option(config,arg,param,0); |
294 if(r==M_OPT_MISSING_PARAM){ | |
295 mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Error: option '%s' must have a parameter!\n",arg); | |
296 return M_OPT_INVALID; | |
297 } | |
298 return r; | |
8164 | 299 } |
300 | |
301 | |
302 m_option_t* | |
303 m_config_get_option(m_config_t *config, char* arg) { | |
304 m_config_option_t *co; | |
305 | |
306 #ifdef MP_DEBUG | |
307 assert(config != NULL); | |
308 assert(config->lvl > 0); | |
309 assert(arg != NULL); | |
310 #endif | |
311 | |
312 co = m_config_get_co(config,arg); | |
313 if(co) | |
314 return co->opt; | |
315 else | |
316 return NULL; | |
317 } | |
318 | |
319 void* | |
320 m_config_get_option_ptr(m_config_t *config, char* arg) { | |
321 m_option_t* conf; | |
322 | |
323 #ifdef MP_DEBUG | |
324 assert(config != NULL); | |
325 assert(arg != NULL); | |
326 #endif | |
327 | |
328 conf = m_config_get_option(config,arg); | |
329 if(!conf) return NULL; | |
330 return conf->p; | |
331 } | |
332 | |
333 void | |
334 m_config_print_option_list(m_config_t *config) { | |
335 char min[50],max[50]; | |
336 m_config_option_t* co; | |
337 int count = 0; | |
338 | |
339 if(!config->opts) return; | |
340 | |
341 printf("\n Name Type Min Max Global CL Cfg\n\n"); | |
342 for(co = config->opts ; co ; co = co->next) { | |
343 m_option_t* opt = co->opt; | |
344 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; | |
345 if(opt->flags & M_OPT_MIN) | |
346 sprintf(min,"%-8.0f",opt->min); | |
347 else | |
348 strcpy(min,"No"); | |
349 if(opt->flags & M_OPT_MAX) | |
350 sprintf(max,"%-8.0f",opt->max); | |
351 else | |
352 strcpy(max,"No"); | |
353 printf(" %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", | |
354 co->name, | |
355 co->opt->type->name, | |
356 min, | |
357 max, | |
358 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
359 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
360 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
361 count++; | |
362 } | |
363 printf("\nTotal: %d options\n",count); | |
364 } | |
365 | |
366 #endif // NEW_CONFIG |