Mercurial > mplayer.hg
annotate m_config.c @ 26981:f3f553c03044
No need to set LC_ALL=C for individual shell commands,
it is already set from config.mak.
author | diego |
---|---|
date | Sat, 07 Jun 2008 12:01:29 +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 } |