Mercurial > mplayer.hg
annotate m_config.c @ 28677:cd9aa9b2533a
ffvc1vdpau and ffwmv3vdpau should be marked as buggy in the same
way as the software decoders, otherwise they will be preferred over
the software decoders which just breaks things when using e.g. xv vo.
author | reimar |
---|---|
date | Mon, 23 Feb 2009 11:48:45 +0000 |
parents | 7a36d5941fd8 |
children | 0f1b5b68af32 |
rev | line source |
---|---|
18258 | 1 |
2 /// \file | |
3 /// \ingroup Config | |
4 | |
8164 | 5 #include "config.h" |
6 | |
7 #include <stdlib.h> | |
8 #include <stdio.h> | |
9 #include <errno.h> | |
10 #include <string.h> | |
11 #ifdef MP_DEBUG | |
12 #include <assert.h> | |
13 #endif | |
14 | |
15 #include "m_config.h" | |
16 #include "m_option.h" | |
17 #include "mp_msg.h" | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
18 #include "help_mp.h" |
8164 | 19 |
17471 | 20 #define MAX_PROFILE_DEPTH 20 |
21 | |
22 static int | |
26288 | 23 parse_profile(const m_option_t *opt, const char *name, char *param, void *dst, int src); |
17471 | 24 |
25 static void | |
26288 | 26 set_profile(const m_option_t *opt, void* dst, void* src); |
17471 | 27 |
28 static int | |
29 show_profile(m_option_t *opt, char* name, char *param); | |
30 | |
31 static void | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
32 m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefix); |
17471 | 33 |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
34 static int |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
35 list_options(m_option_t *opt, char* name, char *param); |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
36 |
8164 | 37 m_config_t* |
38 m_config_new(void) { | |
39 m_config_t* config; | |
25962 | 40 static int initialized = 0; |
17471 | 41 static m_option_type_t profile_opt_type; |
42 static m_option_t ref_opts[] = { | |
43 { "profile", NULL, &profile_opt_type, CONF_NOSAVE, 0, 0, NULL }, | |
44 { "show-profile", show_profile, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, | |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
45 { "list-options", list_options, CONF_TYPE_PRINT_FUNC, CONF_NOCFG, 0, 0, NULL }, |
17471 | 46 { NULL, NULL, NULL, 0, 0, 0, NULL } |
47 }; | |
48 int i; | |
8164 | 49 |
18879 | 50 config = calloc(1,sizeof(m_config_t)); |
8164 | 51 config->lvl = 1; // 0 Is the defaults |
25962 | 52 if(!initialized) { |
53 initialized = 1; | |
17471 | 54 profile_opt_type = m_option_type_string_list; |
55 profile_opt_type.parse = parse_profile; | |
56 profile_opt_type.set = set_profile; | |
57 } | |
58 config->self_opts = malloc(sizeof(ref_opts)); | |
59 memcpy(config->self_opts,ref_opts,sizeof(ref_opts)); | |
60 for(i = 0 ; config->self_opts[i].name ; i++) | |
61 config->self_opts[i].priv = config; | |
62 m_config_register_options(config,config->self_opts); | |
63 | |
8164 | 64 return config; |
65 } | |
66 | |
67 void | |
68 m_config_free(m_config_t* config) { | |
69 m_config_option_t *i = config->opts, *ct; | |
70 m_config_save_slot_t *sl,*st; | |
17471 | 71 m_profile_t *p,*pn; |
72 int j; | |
8164 | 73 |
74 #ifdef MP_DEBUG | |
75 assert(config != NULL); | |
76 #endif | |
77 | |
78 while(i) { | |
13824 | 79 if (i->flags & M_CFG_OPT_ALIAS) |
80 sl = NULL; | |
81 else | |
82 sl = i->slots; | |
8164 | 83 while(sl) { |
84 m_option_free(i->opt,sl->data); | |
85 st = sl->prev; | |
86 free(sl); | |
87 sl = st; | |
88 } | |
89 if(i->name != i->opt->name) | |
90 free(i->name); | |
91 ct = i->next; | |
92 free(i); | |
13824 | 93 i = ct; |
8164 | 94 } |
17471 | 95 for(p = config->profiles ; p ; p = pn) { |
96 pn = p->next; | |
97 free(p->name); | |
98 if(p->desc) free(p->desc); | |
99 for(j = 0 ; j < p->num_opts ; j++) { | |
100 free(p->opts[2*j]); | |
101 if(p->opts[2*j+1]) free(p->opts[2*j+1]); | |
102 } | |
103 free(p->opts); | |
104 free(p); | |
105 } | |
106 free(config->self_opts); | |
8164 | 107 free(config); |
108 } | |
109 | |
110 void | |
111 m_config_push(m_config_t* config) { | |
112 m_config_option_t *co; | |
113 m_config_save_slot_t *slot; | |
114 | |
115 #ifdef MP_DEBUG | |
116 assert(config != NULL); | |
117 assert(config->lvl > 0); | |
118 #endif | |
119 | |
120 config->lvl++; | |
121 | |
122 for(co = config->opts ; co ; co = co->next ) { | |
123 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
124 continue; | |
125 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
126 continue; | |
21054
7d5035aafcc6
Fix obvious typo, although the exact effect is still unclear to me, see also bug #593.
reimar
parents:
18879
diff
changeset
|
127 if((co->opt->flags & M_OPT_OLD) && !(co->flags & M_CFG_OPT_SET)) |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
128 continue; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
129 if(co->flags & M_CFG_OPT_ALIAS) |
8164 | 130 continue; |
131 | |
132 // Update the current status | |
133 m_option_save(co->opt,co->slots->data,co->opt->p); | |
134 | |
135 // Allocate a new slot | |
18879 | 136 slot = calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size); |
8164 | 137 slot->lvl = config->lvl; |
138 slot->prev = co->slots; | |
139 co->slots = slot; | |
140 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
|
141 // Reset our set flag |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
142 co->flags &= ~M_CFG_OPT_SET; |
8164 | 143 } |
144 | |
145 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl); | |
146 } | |
147 | |
148 void | |
149 m_config_pop(m_config_t* config) { | |
150 m_config_option_t *co; | |
151 m_config_save_slot_t *slot; | |
152 | |
153 #ifdef MP_DEBUG | |
154 assert(config != NULL); | |
155 assert(config->lvl > 1); | |
156 #endif | |
157 | |
158 for(co = config->opts ; co ; co = co->next ) { | |
159 int pop = 0; | |
160 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) | |
161 continue; | |
162 if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE)) | |
163 continue; | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
164 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
|
165 continue; |
8164 | 166 if(co->slots->lvl > config->lvl) |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
167 mp_msg(MSGT_CFGPARSER, MSGL_WARN,MSGTR_SaveSlotTooOld,config->lvl,co->slots->lvl); |
8164 | 168 |
169 while(co->slots->lvl >= config->lvl) { | |
170 m_option_free(co->opt,co->slots->data); | |
171 slot = co->slots; | |
172 co->slots = slot->prev; | |
173 free(slot); | |
174 pop++; | |
175 } | |
176 if(pop) // We removed some ctx -> set the previous value | |
177 m_option_set(co->opt,co->opt->p,co->slots->data); | |
178 } | |
179 | |
180 config->lvl--; | |
181 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl); | |
182 } | |
183 | |
184 static void | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
185 m_config_add_option(m_config_t *config, const m_option_t *arg, const char* prefix) { |
8164 | 186 m_config_option_t *co; |
187 m_config_save_slot_t* sl; | |
188 | |
189 #ifdef MP_DEBUG | |
190 assert(config != NULL); | |
191 assert(config->lvl > 0); | |
192 assert(arg != NULL); | |
193 #endif | |
194 | |
195 // Allocate a new entry for this option | |
18879 | 196 co = calloc(1,sizeof(m_config_option_t) + arg->type->size); |
8164 | 197 co->opt = arg; |
198 | |
199 // Fill in the full name | |
200 if(prefix && strlen(prefix) > 0) { | |
201 int l = strlen(prefix) + 1 + strlen(arg->name) + 1; | |
23806 | 202 co->name = malloc(l); |
8164 | 203 sprintf(co->name,"%s:%s",prefix,arg->name); |
204 } else | |
205 co->name = arg->name; | |
206 | |
23868 | 207 // Option with children -> add them |
8164 | 208 if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) { |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
209 const m_option_t *ol = arg->p; |
8164 | 210 int i; |
13824 | 211 co->slots = NULL; |
8164 | 212 for(i = 0 ; ol[i].name != NULL ; i++) |
213 m_config_add_option(config,&ol[i], co->name); | |
214 } else { | |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
215 m_config_option_t *i; |
23868 | 216 // Check if there is already an option pointing to this address |
9912
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
217 if(arg->p) { |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
218 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
|
219 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
|
220 co->slots = i->slots; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
221 co->flags |= M_CFG_OPT_ALIAS; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
222 break; |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
223 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
224 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
225 } |
39444d65c4cb
Don't save restore all options wich point to the same variable.
albeu
parents:
9593
diff
changeset
|
226 if(!(co->flags & M_CFG_OPT_ALIAS)) { |
8164 | 227 // Allocate a slot for the defaults |
18879 | 228 sl = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); |
8164 | 229 m_option_save(arg,sl->data,(void**)arg->p); |
23868 | 230 // Hack to avoid too much trouble with dynamically allocated data : |
8164 | 231 // We always use a dynamic version |
232 if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) { | |
233 *(void**)arg->p = NULL; | |
234 m_option_set(arg,arg->p,sl->data); | |
235 } | |
236 sl->lvl = 0; | |
13824 | 237 sl->prev = NULL; |
18879 | 238 co->slots = calloc(1,sizeof(m_config_save_slot_t) + arg->type->size); |
8164 | 239 co->slots->prev = sl; |
240 co->slots->lvl = config->lvl; | |
241 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
|
242 } // !M_OPT_ALIAS |
8164 | 243 } |
244 co->next = config->opts; | |
245 config->opts = co; | |
246 } | |
247 | |
248 int | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
249 m_config_register_options(m_config_t *config, const m_option_t *args) { |
8164 | 250 int i; |
251 | |
252 #ifdef MP_DEBUG | |
253 assert(config != NULL); | |
254 assert(config->lvl > 0); | |
255 assert(args != NULL); | |
256 #endif | |
257 | |
258 for(i = 0 ; args[i].name != NULL ; i++) | |
259 m_config_add_option(config,&args[i],NULL); | |
260 | |
261 return 1; | |
262 } | |
263 | |
264 static m_config_option_t* | |
265 m_config_get_co(m_config_t *config, char* arg) { | |
266 m_config_option_t *co; | |
267 | |
268 for(co = config->opts ; co ; co = co->next ) { | |
269 int l = strlen(co->name) - 1; | |
270 if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && | |
271 (co->name[l] == '*')) { | |
272 if(strncasecmp(co->name,arg,l) == 0) | |
273 return co; | |
274 } else if(strcasecmp(co->name,arg) == 0) | |
275 return co; | |
276 } | |
277 return NULL; | |
278 } | |
279 | |
280 static int | |
281 m_config_parse_option(m_config_t *config, char* arg, char* param,int set) { | |
282 m_config_option_t *co; | |
283 int r = 0; | |
284 | |
285 #ifdef MP_DEBUG | |
286 assert(config != NULL); | |
287 assert(config->lvl > 0); | |
288 assert(arg != NULL); | |
289 #endif | |
290 | |
291 co = m_config_get_co(config,arg); | |
8892 | 292 if(!co){ |
8894 | 293 // 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
|
294 return M_OPT_UNKNOWN; |
8892 | 295 } |
8164 | 296 |
297 #ifdef MP_DEBUG | |
298 // This is the only mandatory function | |
299 assert(co->opt->type->parse); | |
300 #endif | |
301 | |
23868 | 302 // Check if this option isn't forbidden in the current mode |
8164 | 303 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
|
304 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCfgfileOption,arg); |
8164 | 305 return M_OPT_INVALID; |
306 } | |
307 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
|
308 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidCmdlineOption,arg); |
8164 | 309 return M_OPT_INVALID; |
310 } | |
26408
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
311 // During command line preparse set only pre-parse options |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
312 // Otherwise only set pre-parse option if they were not already set. |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
313 if(((config->mode == M_COMMAND_LINE_PRE_PARSE) && |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
314 !(co->opt->flags & M_OPT_PRE_PARSE)) || |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
315 ((config->mode != M_COMMAND_LINE_PRE_PARSE) && |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
316 (co->opt->flags & M_OPT_PRE_PARSE) && (co->flags & M_CFG_OPT_SET))) |
7a36d5941fd8
Replace the trivial command line preparser with a more robust version
albeu
parents:
26288
diff
changeset
|
317 set = 0; |
8164 | 318 |
23868 | 319 // Option with children are a bit different to parse |
8164 | 320 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { |
321 char** lst = NULL; | |
322 int i,sr; | |
323 // 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
|
324 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 325 // Set them now |
8894 | 326 if(r >= 0) |
8164 | 327 for(i = 0 ; lst && lst[2*i] ; i++) { |
328 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
329 if(r >= 0) { | |
330 // Build the full name | |
331 char n[l]; | |
332 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
333 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 334 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
|
335 if(sr == M_OPT_UNKNOWN){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
336 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidSuboption,co->name,lst[2*i]); |
8894 | 337 r = M_OPT_INVALID; |
338 } else | |
9222 | 339 if(sr == M_OPT_MISSING_PARAM){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
340 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingSuboptionParameter,lst[2*i],co->name); |
9222 | 341 r = M_OPT_INVALID; |
342 } else | |
8894 | 343 r = sr; |
344 } | |
8164 | 345 } |
346 free(lst[2*i]); | |
347 free(lst[2*i+1]); | |
348 } | |
349 if(lst) free(lst); | |
350 } else | |
351 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
352 | |
353 // Parsing failed ? | |
354 if(r < 0) | |
355 return r; | |
356 // Set the option | |
357 if(set) { | |
358 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
|
359 co->flags |= M_CFG_OPT_SET; |
8164 | 360 } |
361 | |
362 return r; | |
363 } | |
364 | |
365 int | |
366 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
367 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
368 return m_config_parse_option(config,arg,param,1); | |
369 } | |
370 | |
371 int | |
372 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
9222 | 373 int r; |
8164 | 374 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 375 r=m_config_parse_option(config,arg,param,0); |
376 if(r==M_OPT_MISSING_PARAM){ | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
377 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingOptionParameter,arg); |
9222 | 378 return M_OPT_INVALID; |
379 } | |
380 return r; | |
8164 | 381 } |
382 | |
383 | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
384 const m_option_t* |
8164 | 385 m_config_get_option(m_config_t *config, char* arg) { |
386 m_config_option_t *co; | |
387 | |
388 #ifdef MP_DEBUG | |
389 assert(config != NULL); | |
390 assert(config->lvl > 0); | |
391 assert(arg != NULL); | |
392 #endif | |
393 | |
394 co = m_config_get_co(config,arg); | |
395 if(co) | |
396 return co->opt; | |
397 else | |
398 return NULL; | |
399 } | |
400 | |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
401 const void* |
8164 | 402 m_config_get_option_ptr(m_config_t *config, char* arg) { |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
403 const m_option_t* conf; |
8164 | 404 |
405 #ifdef MP_DEBUG | |
406 assert(config != NULL); | |
407 assert(arg != NULL); | |
408 #endif | |
409 | |
410 conf = m_config_get_option(config,arg); | |
411 if(!conf) return NULL; | |
412 return conf->p; | |
413 } | |
414 | |
415 void | |
416 m_config_print_option_list(m_config_t *config) { | |
417 char min[50],max[50]; | |
418 m_config_option_t* co; | |
419 int count = 0; | |
420 | |
421 if(!config->opts) return; | |
422 | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
423 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_OptionListHeader); |
8164 | 424 for(co = config->opts ; co ; co = co->next) { |
25225
51c23a18a17b
First try to mark some things in m_config correctly as const
reimar
parents:
23868
diff
changeset
|
425 const m_option_t* opt = co->opt; |
8164 | 426 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; |
427 if(opt->flags & M_OPT_MIN) | |
428 sprintf(min,"%-8.0f",opt->min); | |
429 else | |
430 strcpy(min,"No"); | |
431 if(opt->flags & M_OPT_MAX) | |
432 sprintf(max,"%-8.0f",opt->max); | |
433 else | |
434 strcpy(max,"No"); | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
435 mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", |
8164 | 436 co->name, |
437 co->opt->type->name, | |
438 min, | |
439 max, | |
440 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
441 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
442 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
443 count++; | |
444 } | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
445 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_TotalOptions,count); |
8164 | 446 } |
17471 | 447 |
448 m_profile_t* | |
449 m_config_get_profile(m_config_t* config, char* name) { | |
450 m_profile_t* p; | |
451 for(p = config->profiles ; p ; p = p->next) | |
452 if(!strcmp(p->name,name)) return p; | |
453 return NULL; | |
454 } | |
455 | |
456 m_profile_t* | |
457 m_config_add_profile(m_config_t* config, char* name) { | |
458 m_profile_t* p = m_config_get_profile(config,name); | |
459 if(p) return p; | |
460 p = calloc(1,sizeof(m_profile_t)); | |
461 p->name = strdup(name); | |
462 p->next = config->profiles; | |
463 config->profiles = p; | |
464 return p; | |
465 } | |
466 | |
467 void | |
468 m_profile_set_desc(m_profile_t* p, char* desc) { | |
469 if(p->desc) free(p->desc); | |
470 p->desc = desc ? strdup(desc) : NULL; | |
471 } | |
472 | |
473 int | |
474 m_config_set_profile_option(m_config_t* config, m_profile_t* p, | |
475 char* name, char* val) { | |
476 int i = m_config_check_option(config,name,val); | |
477 if(i < 0) return i; | |
478 if(p->opts) p->opts = realloc(p->opts,2*(p->num_opts+2)*sizeof(char*)); | |
479 else p->opts = malloc(2*(p->num_opts+2)*sizeof(char*)); | |
480 p->opts[p->num_opts*2] = strdup(name); | |
481 p->opts[p->num_opts*2+1] = val ? strdup(val) : NULL; | |
482 p->num_opts++; | |
483 p->opts[p->num_opts*2] = p->opts[p->num_opts*2+1] = NULL; | |
17856 | 484 return 1; |
17471 | 485 } |
486 | |
25634 | 487 void |
17471 | 488 m_config_set_profile(m_config_t* config, m_profile_t* p) { |
489 int i; | |
490 if(config->profile_depth > MAX_PROFILE_DEPTH) { | |
18335 | 491 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_ProfileInclusionTooDeep); |
17471 | 492 return; |
493 } | |
494 config->profile_depth++; | |
495 for(i = 0 ; i < p->num_opts ; i++) | |
496 m_config_set_option(config,p->opts[2*i],p->opts[2*i+1]); | |
497 config->profile_depth--; | |
498 } | |
499 | |
500 static int | |
26288 | 501 parse_profile(const m_option_t *opt, const char *name, char *param, void *dst, int src) |
502 { | |
17471 | 503 m_config_t* config = opt->priv; |
504 char** list = NULL; | |
505 int i,r; | |
506 if(param && !strcmp(param,"help")) { | |
507 m_profile_t* p; | |
508 if(!config->profiles) { | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
509 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_NoProfileDefined); |
17471 | 510 return M_OPT_EXIT-1; |
511 } | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
512 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_AvailableProfiles); |
17471 | 513 for(p = config->profiles ; p ; p = p->next) |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
514 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\t%s\t%s\n",p->name, |
17471 | 515 p->desc ? p->desc : ""); |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
516 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); |
17471 | 517 return M_OPT_EXIT-1; |
518 } | |
519 | |
520 r = m_option_type_string_list.parse(opt,name,param,&list,src); | |
521 if(r < 0) return r; | |
522 if(!list || !list[0]) return M_OPT_INVALID; | |
523 for(i = 0 ; list[i] ; i++) | |
524 if(!m_config_get_profile(config,list[i])) { | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
525 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_UnknownProfile, |
17471 | 526 list[i]); |
527 r = M_OPT_INVALID; | |
528 } | |
529 if(dst) | |
530 m_option_copy(opt,dst,&list); | |
531 else | |
532 m_option_free(opt,&list); | |
533 return r; | |
534 } | |
535 | |
536 static void | |
26288 | 537 set_profile(const m_option_t *opt, void *dst, void *src) { |
17471 | 538 m_config_t* config = opt->priv; |
539 m_profile_t* p; | |
540 char** list = NULL; | |
541 int i; | |
542 if(!src || !*(char***)src) return; | |
543 m_option_copy(opt,&list,src); | |
544 for(i = 0 ; list[i] ; i++) { | |
545 p = m_config_get_profile(config,list[i]); | |
546 if(!p) continue; | |
547 m_config_set_profile(config,p); | |
548 } | |
549 m_option_free(opt,&list); | |
550 } | |
551 | |
552 static int | |
553 show_profile(m_option_t *opt, char* name, char *param) { | |
554 m_config_t* config = opt->priv; | |
555 m_profile_t* p; | |
556 int i,j; | |
557 if(!param) return M_OPT_MISSING_PARAM; | |
558 if(!(p = m_config_get_profile(config,param))) { | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
559 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_UnknownProfile, param); |
17471 | 560 return M_OPT_EXIT-1; |
561 } | |
562 if(!config->profile_depth) | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
563 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_Profile, param, |
17471 | 564 p->desc ? p->desc : ""); |
565 config->profile_depth++; | |
566 for(i = 0 ; i < p->num_opts ; i++) { | |
567 char spc[config->profile_depth+1]; | |
568 for(j = 0 ; j < config->profile_depth ; j++) | |
569 spc[j] = ' '; | |
570 spc[config->profile_depth] = '\0'; | |
571 | |
572 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s%s=%s\n", spc, | |
573 p->opts[2*i], p->opts[2*i+1]); | |
574 | |
575 | |
576 if(config->profile_depth < MAX_PROFILE_DEPTH && | |
577 !strcmp(p->opts[2*i],"profile")) { | |
578 char* e,*list = p->opts[2*i+1]; | |
579 while((e = strchr(list,','))) { | |
580 int l = e-list; | |
581 char tmp[l+1]; | |
582 if(!l) continue; | |
583 memcpy(tmp,list,l); | |
584 tmp[l] = '\0'; | |
585 show_profile(opt,name,tmp); | |
586 list = e+1; | |
587 } | |
588 if(list[0] != '\0') | |
589 show_profile(opt,name,list); | |
590 } | |
591 } | |
592 config->profile_depth--; | |
593 if(!config->profile_depth) mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); | |
594 return M_OPT_EXIT-1; | |
595 } | |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
596 |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
597 static int |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
598 list_options(m_option_t *opt, char* name, char *param) { |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
599 m_config_t* config = opt->priv; |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
600 m_config_print_option_list(config); |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
601 return M_OPT_EXIT; |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
602 } |