Mercurial > mplayer.hg
annotate m_config.c @ 14802:63b1cc62fc9b
MEncoder multiple files patch by Oded Shimon (ods15)
Seems to work, or at least not to cause problems with existing
functionality (encoding single files).
Please test and report bugs, if there are any!
author | rfelker |
---|---|
date | Fri, 25 Feb 2005 02:32:29 +0000 |
parents | bad703951cf9 |
children | 63909962d3fc |
rev | line source |
---|---|
8164 | 1 #include "config.h" |
2 | |
3 #include <stdlib.h> | |
4 #include <stdio.h> | |
5 #include <errno.h> | |
6 #include <string.h> | |
7 #ifdef MP_DEBUG | |
8 #include <assert.h> | |
9 #endif | |
10 | |
11 #include "m_config.h" | |
12 #include "m_option.h" | |
13 #include "mp_msg.h" | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
14 #include "help_mp.h" |
8164 | 15 |
16 m_config_t* | |
17 m_config_new(void) { | |
18 m_config_t* config; | |
19 | |
20 config = (m_config_t*)calloc(1,sizeof(m_config_t)); | |
21 config->lvl = 1; // 0 Is the defaults | |
22 return config; | |
23 } | |
24 | |
25 void | |
26 m_config_free(m_config_t* config) { | |
27 m_config_option_t *i = config->opts, *ct; | |
28 m_config_save_slot_t *sl,*st; | |
29 | |
30 #ifdef MP_DEBUG | |
31 assert(config != NULL); | |
32 #endif | |
33 | |
34 while(i) { | |
13824 | 35 if (i->flags & M_CFG_OPT_ALIAS) |
36 sl = NULL; | |
37 else | |
38 sl = i->slots; | |
8164 | 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); | |
13824 | 49 i = ct; |
8164 | 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; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
71 if((co->opt->flags & M_OPT_OLD) && !(co->flags && M_CFG_OPT_SET)) |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
72 continue; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
73 if(co->flags & M_CFG_OPT_ALIAS) |
8164 | 74 continue; |
75 | |
76 // Update the current status | |
77 m_option_save(co->opt,co->slots->data,co->opt->p); | |
78 | |
79 // Allocate a new slot | |
80 slot = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); | |
81 slot->lvl = config->lvl; | |
82 slot->prev = co->slots; | |
83 co->slots = slot; | |
84 m_option_copy(co->opt,co->slots->data,co->slots->prev->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
85 // Reset our set flag |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
86 co->flags &= ~M_CFG_OPT_SET; |
8164 | 87 } |
88 | |
89 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl); | |
90 } | |
91 | |
92 void | |
93 m_config_pop(m_config_t* config) { | |
94 m_config_option_t *co; | |
95 m_config_save_slot_t *slot; | |
96 | |
97 #ifdef MP_DEBUG | |
98 assert(config != NULL); | |
99 assert(config->lvl > 1); | |
100 #endif | |
101 | |
102 for(co = config->opts ; co ; co = co->next ) { | |
103 int pop = 0; | |
104 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
105 continue; | |
106 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
107 continue; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
108 if(co->flags & M_CFG_OPT_ALIAS) |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
109 continue; |
8164 | 110 if(co->slots->lvl > config->lvl) |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
111 mp_msg(MSGT_CFGPARSER, MSGL_WARN,MSGTR_SaveSlotTooOld,config->lvl,co->slots->lvl); |
8164 | 112 |
113 while(co->slots->lvl >= config->lvl) { | |
114 m_option_free(co->opt,co->slots->data); | |
115 slot = co->slots; | |
116 co->slots = slot->prev; | |
117 free(slot); | |
118 pop++; | |
119 } | |
120 if(pop) // We removed some ctx -> set the previous value | |
121 m_option_set(co->opt,co->opt->p,co->slots->data); | |
122 } | |
123 | |
124 config->lvl--; | |
125 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl); | |
126 } | |
127 | |
128 static void | |
129 m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix) { | |
130 m_config_option_t *co; | |
131 m_config_save_slot_t* sl; | |
132 | |
133 #ifdef MP_DEBUG | |
134 assert(config != NULL); | |
135 assert(config->lvl > 0); | |
136 assert(arg != NULL); | |
137 #endif | |
138 | |
139 // Allocate a new entry for this option | |
140 co = (m_config_option_t*)calloc(1,sizeof(m_config_option_t) + arg->type->size); | |
141 co->opt = arg; | |
142 | |
143 // Fill in the full name | |
144 if(prefix && strlen(prefix) > 0) { | |
145 int l = strlen(prefix) + 1 + strlen(arg->name) + 1; | |
146 co->name = (char*) malloc(l); | |
147 sprintf(co->name,"%s:%s",prefix,arg->name); | |
148 } else | |
149 co->name = arg->name; | |
150 | |
151 // Option with childs -> add them | |
152 if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
153 m_option_t *ol = arg->p; | |
154 int i; | |
13824 | 155 co->slots = NULL; |
8164 | 156 for(i = 0 ; ol[i].name != NULL ; i++) |
157 m_config_add_option(config,&ol[i], co->name); | |
158 } else { | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
159 m_config_option_t *i; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
160 // Check if there is alredy an option pointing to this address |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
161 if(arg->p) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
162 for(i = config->opts ; i ; i = i->next ) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
163 if(i->opt->p == arg->p) { // So we don't save the same vars more than 1 time |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
164 co->slots = i->slots; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
165 co->flags |= M_CFG_OPT_ALIAS; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
166 break; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
167 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
168 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
169 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
170 if(!(co->flags & M_CFG_OPT_ALIAS)) { |
8164 | 171 // Allocate a slot for the defaults |
172 sl = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); | |
173 m_option_save(arg,sl->data,(void**)arg->p); | |
174 // Hack to avoid too much trouble with dynamicly allocated data : | |
175 // We always use a dynamic version | |
176 if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { | |
177 *(void**)arg->p = NULL; | |
178 m_option_set(arg,arg->p,sl->data); | |
179 } | |
180 sl->lvl = 0; | |
13824 | 181 sl->prev = NULL; |
8164 | 182 co->slots = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); |
183 co->slots->prev = sl; | |
184 co->slots->lvl = config->lvl; | |
185 m_option_copy(co->opt,co->slots->data,sl->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
186 } // !M_OPT_ALIAS |
8164 | 187 } |
188 co->next = config->opts; | |
189 config->opts = co; | |
190 } | |
191 | |
192 int | |
193 m_config_register_options(m_config_t *config, m_option_t *args) { | |
194 int i; | |
195 | |
196 #ifdef MP_DEBUG | |
197 assert(config != NULL); | |
198 assert(config->lvl > 0); | |
199 assert(args != NULL); | |
200 #endif | |
201 | |
202 for(i = 0 ; args[i].name != NULL ; i++) | |
203 m_config_add_option(config,&args[i],NULL); | |
204 | |
205 return 1; | |
206 } | |
207 | |
208 static m_config_option_t* | |
209 m_config_get_co(m_config_t *config, char* arg) { | |
210 m_config_option_t *co; | |
211 | |
212 for(co = config->opts ; co ; co = co->next ) { | |
213 int l = strlen(co->name) - 1; | |
214 if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && | |
215 (co->name[l] == '*')) { | |
216 if(strncasecmp(co->name,arg,l) == 0) | |
217 return co; | |
218 } else if(strcasecmp(co->name,arg) == 0) | |
219 return co; | |
220 } | |
221 return NULL; | |
222 } | |
223 | |
224 static int | |
225 m_config_parse_option(m_config_t *config, char* arg, char* param,int set) { | |
226 m_config_option_t *co; | |
227 int r = 0; | |
228 | |
229 #ifdef MP_DEBUG | |
230 assert(config != NULL); | |
231 assert(config->lvl > 0); | |
232 assert(arg != NULL); | |
233 #endif | |
234 | |
235 co = m_config_get_co(config,arg); | |
8892 | 236 if(!co){ |
8894 | 237 // mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Unknown option: %s\n",arg); |
10595
522afd56703c
100l to albeu for his english grammar, and 10l to me becouse I noticed that lately (my backward compatibilty macro uses M_OPT_UNKNOWN)
alex
parents:
10594
diff
changeset
|
238 return M_OPT_UNKNOWN; |
8892 | 239 } |
8164 | 240 |
241 #ifdef MP_DEBUG | |
242 // This is the only mandatory function | |
243 assert(co->opt->type->parse); | |
244 #endif | |
245 | |
246 // Check if this option isn't forbiden in the current mode | |
247 if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) { | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
248 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCfgfileOption,arg); |
8164 | 249 return M_OPT_INVALID; |
250 } | |
251 if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) { | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
252 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCmdlineOption,arg); |
8164 | 253 return M_OPT_INVALID; |
254 } | |
255 | |
256 // Option with childs are a bit different to parse | |
257 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { | |
258 char** lst = NULL; | |
259 int i,sr; | |
260 // 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
|
261 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 262 // Set them now |
8894 | 263 if(r >= 0) |
8164 | 264 for(i = 0 ; lst && lst[2*i] ; i++) { |
265 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
266 if(r >= 0) { | |
267 // Build the full name | |
268 char n[l]; | |
269 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
270 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 271 if(sr < 0){ |
10595
522afd56703c
100l to albeu for his english grammar, and 10l to me becouse I noticed that lately (my backward compatibilty macro uses M_OPT_UNKNOWN)
alex
parents:
10594
diff
changeset
|
272 if(sr == M_OPT_UNKNOWN){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
273 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidSuboption,co->name,lst[2*i]); |
8894 | 274 r = M_OPT_INVALID; |
275 } else | |
9222 | 276 if(sr == M_OPT_MISSING_PARAM){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
277 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingSuboptionParameter,lst[2*i],co->name); |
9222 | 278 r = M_OPT_INVALID; |
279 } else | |
8894 | 280 r = sr; |
281 } | |
8164 | 282 } |
283 free(lst[2*i]); | |
284 free(lst[2*i+1]); | |
285 } | |
286 if(lst) free(lst); | |
287 } else | |
288 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
289 | |
290 // Parsing failed ? | |
291 if(r < 0) | |
292 return r; | |
293 // Set the option | |
294 if(set) { | |
295 m_option_set(co->opt,co->opt->p,co->slots->data); | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
296 co->flags |= M_CFG_OPT_SET; |
8164 | 297 } |
298 | |
299 return r; | |
300 } | |
301 | |
302 int | |
303 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
304 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
305 return m_config_parse_option(config,arg,param,1); | |
306 } | |
307 | |
308 int | |
309 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
9222 | 310 int r; |
8164 | 311 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 312 r=m_config_parse_option(config,arg,param,0); |
313 if(r==M_OPT_MISSING_PARAM){ | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
314 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingOptionParameter,arg); |
9222 | 315 return M_OPT_INVALID; |
316 } | |
317 return r; | |
8164 | 318 } |
319 | |
320 | |
321 m_option_t* | |
322 m_config_get_option(m_config_t *config, char* arg) { | |
323 m_config_option_t *co; | |
324 | |
325 #ifdef MP_DEBUG | |
326 assert(config != NULL); | |
327 assert(config->lvl > 0); | |
328 assert(arg != NULL); | |
329 #endif | |
330 | |
331 co = m_config_get_co(config,arg); | |
332 if(co) | |
333 return co->opt; | |
334 else | |
335 return NULL; | |
336 } | |
337 | |
338 void* | |
339 m_config_get_option_ptr(m_config_t *config, char* arg) { | |
340 m_option_t* conf; | |
341 | |
342 #ifdef MP_DEBUG | |
343 assert(config != NULL); | |
344 assert(arg != NULL); | |
345 #endif | |
346 | |
347 conf = m_config_get_option(config,arg); | |
348 if(!conf) return NULL; | |
349 return conf->p; | |
350 } | |
351 | |
352 void | |
353 m_config_print_option_list(m_config_t *config) { | |
354 char min[50],max[50]; | |
355 m_config_option_t* co; | |
356 int count = 0; | |
357 | |
358 if(!config->opts) return; | |
359 | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
360 mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_OptionListHeader); |
8164 | 361 for(co = config->opts ; co ; co = co->next) { |
362 m_option_t* opt = co->opt; | |
363 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; | |
364 if(opt->flags & M_OPT_MIN) | |
365 sprintf(min,"%-8.0f",opt->min); | |
366 else | |
367 strcpy(min,"No"); | |
368 if(opt->flags & M_OPT_MAX) | |
369 sprintf(max,"%-8.0f",opt->max); | |
370 else | |
371 strcpy(max,"No"); | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
372 mp_msg(MSGT_FIXME, MSGL_FIXME, " %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", |
8164 | 373 co->name, |
374 co->opt->type->name, | |
375 min, | |
376 max, | |
377 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
378 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
379 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
380 count++; | |
381 } | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
382 mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_TotalOptions,count); |
8164 | 383 } |