Mercurial > mplayer.hg
annotate m_config.c @ 24992:5701e23ebcb4
Better handling of win32 GUI thread:
1. Use _beginthreadex to create the GUI thread to avoid possible memory leak
when linked to MS CRT.
2. Terminate the GUI thread in an cleaner way using PostThreadMessage()
rather than the unrecommended TerminateThread().
author | zuxy |
---|---|
date | Sun, 11 Nov 2007 08:14:57 +0000 |
parents | 09c2fe1e021d |
children | 51c23a18a17b |
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 | |
23 parse_profile(m_option_t* opt,char *name, char *param, void* dst, int src); | |
24 | |
25 static void | |
26 set_profile(m_option_t *opt, void* dst, void* src); | |
27 | |
28 static int | |
29 show_profile(m_option_t *opt, char* name, char *param); | |
30 | |
31 static void | |
32 m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix); | |
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; | |
17471 | 40 static int inited = 0; |
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 |
17471 | 52 if(!inited) { |
53 inited = 1; | |
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 | |
185 m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix) { | |
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) { |
209 m_option_t *ol = arg->p; | |
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 | |
249 m_config_register_options(m_config_t *config, m_option_t *args) { | |
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 } | |
311 | |
23868 | 312 // Option with children are a bit different to parse |
8164 | 313 if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) { |
314 char** lst = NULL; | |
315 int i,sr; | |
316 // 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
|
317 r = m_option_parse(co->opt,arg,param,&lst,M_COMMAND_LINE); |
8164 | 318 // Set them now |
8894 | 319 if(r >= 0) |
8164 | 320 for(i = 0 ; lst && lst[2*i] ; i++) { |
321 int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1; | |
322 if(r >= 0) { | |
323 // Build the full name | |
324 char n[l]; | |
325 sprintf(n,"%s:%s",co->name,lst[2*i]); | |
326 sr = m_config_parse_option(config,n,lst[2*i+1],set); | |
8894 | 327 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
|
328 if(sr == M_OPT_UNKNOWN){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
329 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_InvalidSuboption,co->name,lst[2*i]); |
8894 | 330 r = M_OPT_INVALID; |
331 } else | |
9222 | 332 if(sr == M_OPT_MISSING_PARAM){ |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
333 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingSuboptionParameter,lst[2*i],co->name); |
9222 | 334 r = M_OPT_INVALID; |
335 } else | |
8894 | 336 r = sr; |
337 } | |
8164 | 338 } |
339 free(lst[2*i]); | |
340 free(lst[2*i+1]); | |
341 } | |
342 if(lst) free(lst); | |
343 } else | |
344 r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode); | |
345 | |
346 // Parsing failed ? | |
347 if(r < 0) | |
348 return r; | |
349 // Set the option | |
350 if(set) { | |
351 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
|
352 co->flags |= M_CFG_OPT_SET; |
8164 | 353 } |
354 | |
355 return r; | |
356 } | |
357 | |
358 int | |
359 m_config_set_option(m_config_t *config, char* arg, char* param) { | |
360 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param); | |
361 return m_config_parse_option(config,arg,param,1); | |
362 } | |
363 | |
364 int | |
365 m_config_check_option(m_config_t *config, char* arg, char* param) { | |
9222 | 366 int r; |
8164 | 367 mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param); |
9222 | 368 r=m_config_parse_option(config,arg,param,0); |
369 if(r==M_OPT_MISSING_PARAM){ | |
13699
11b249ef87b0
printf --> mp_msg by the Wanderer <inverseparadox at comcast dot net>
diego
parents:
10595
diff
changeset
|
370 mp_msg(MSGT_CFGPARSER, MSGL_ERR,MSGTR_MissingOptionParameter,arg); |
9222 | 371 return M_OPT_INVALID; |
372 } | |
373 return r; | |
8164 | 374 } |
375 | |
376 | |
377 m_option_t* | |
378 m_config_get_option(m_config_t *config, char* arg) { | |
379 m_config_option_t *co; | |
380 | |
381 #ifdef MP_DEBUG | |
382 assert(config != NULL); | |
383 assert(config->lvl > 0); | |
384 assert(arg != NULL); | |
385 #endif | |
386 | |
387 co = m_config_get_co(config,arg); | |
388 if(co) | |
389 return co->opt; | |
390 else | |
391 return NULL; | |
392 } | |
393 | |
394 void* | |
395 m_config_get_option_ptr(m_config_t *config, char* arg) { | |
396 m_option_t* conf; | |
397 | |
398 #ifdef MP_DEBUG | |
399 assert(config != NULL); | |
400 assert(arg != NULL); | |
401 #endif | |
402 | |
403 conf = m_config_get_option(config,arg); | |
404 if(!conf) return NULL; | |
405 return conf->p; | |
406 } | |
407 | |
408 void | |
409 m_config_print_option_list(m_config_t *config) { | |
410 char min[50],max[50]; | |
411 m_config_option_t* co; | |
412 int count = 0; | |
413 | |
414 if(!config->opts) return; | |
415 | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
416 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_OptionListHeader); |
8164 | 417 for(co = config->opts ; co ; co = co->next) { |
418 m_option_t* opt = co->opt; | |
419 if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue; | |
420 if(opt->flags & M_OPT_MIN) | |
421 sprintf(min,"%-8.0f",opt->min); | |
422 else | |
423 strcpy(min,"No"); | |
424 if(opt->flags & M_OPT_MAX) | |
425 sprintf(max,"%-8.0f",opt->max); | |
426 else | |
427 strcpy(max,"No"); | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
428 mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s %-3.3s %-3.3s\n", |
8164 | 429 co->name, |
430 co->opt->type->name, | |
431 min, | |
432 max, | |
433 opt->flags & CONF_GLOBAL ? "Yes" : "No", | |
434 opt->flags & CONF_NOCMD ? "No" : "Yes", | |
435 opt->flags & CONF_NOCFG ? "No" : "Yes"); | |
436 count++; | |
437 } | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
438 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_TotalOptions,count); |
8164 | 439 } |
17471 | 440 |
441 m_profile_t* | |
442 m_config_get_profile(m_config_t* config, char* name) { | |
443 m_profile_t* p; | |
444 for(p = config->profiles ; p ; p = p->next) | |
445 if(!strcmp(p->name,name)) return p; | |
446 return NULL; | |
447 } | |
448 | |
449 m_profile_t* | |
450 m_config_add_profile(m_config_t* config, char* name) { | |
451 m_profile_t* p = m_config_get_profile(config,name); | |
452 if(p) return p; | |
453 p = calloc(1,sizeof(m_profile_t)); | |
454 p->name = strdup(name); | |
455 p->next = config->profiles; | |
456 config->profiles = p; | |
457 return p; | |
458 } | |
459 | |
460 void | |
461 m_profile_set_desc(m_profile_t* p, char* desc) { | |
462 if(p->desc) free(p->desc); | |
463 p->desc = desc ? strdup(desc) : NULL; | |
464 } | |
465 | |
466 int | |
467 m_config_set_profile_option(m_config_t* config, m_profile_t* p, | |
468 char* name, char* val) { | |
469 int i = m_config_check_option(config,name,val); | |
470 if(i < 0) return i; | |
471 if(p->opts) p->opts = realloc(p->opts,2*(p->num_opts+2)*sizeof(char*)); | |
472 else p->opts = malloc(2*(p->num_opts+2)*sizeof(char*)); | |
473 p->opts[p->num_opts*2] = strdup(name); | |
474 p->opts[p->num_opts*2+1] = val ? strdup(val) : NULL; | |
475 p->num_opts++; | |
476 p->opts[p->num_opts*2] = p->opts[p->num_opts*2+1] = NULL; | |
17856 | 477 return 1; |
17471 | 478 } |
479 | |
480 static void | |
481 m_config_set_profile(m_config_t* config, m_profile_t* p) { | |
482 int i; | |
483 if(config->profile_depth > MAX_PROFILE_DEPTH) { | |
18335 | 484 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_ProfileInclusionTooDeep); |
17471 | 485 return; |
486 } | |
487 config->profile_depth++; | |
488 for(i = 0 ; i < p->num_opts ; i++) | |
489 m_config_set_option(config,p->opts[2*i],p->opts[2*i+1]); | |
490 config->profile_depth--; | |
491 } | |
492 | |
493 static int | |
494 parse_profile(m_option_t* opt,char *name, char *param, void* dst, int src) { | |
495 m_config_t* config = opt->priv; | |
496 char** list = NULL; | |
497 int i,r; | |
498 if(param && !strcmp(param,"help")) { | |
499 m_profile_t* p; | |
500 if(!config->profiles) { | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
501 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_NoProfileDefined); |
17471 | 502 return M_OPT_EXIT-1; |
503 } | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
504 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_AvailableProfiles); |
17471 | 505 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
|
506 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\t%s\t%s\n",p->name, |
17471 | 507 p->desc ? p->desc : ""); |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
508 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); |
17471 | 509 return M_OPT_EXIT-1; |
510 } | |
511 | |
512 r = m_option_type_string_list.parse(opt,name,param,&list,src); | |
513 if(r < 0) return r; | |
514 if(!list || !list[0]) return M_OPT_INVALID; | |
515 for(i = 0 ; list[i] ; i++) | |
516 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
|
517 mp_msg(MSGT_CFGPARSER, MSGL_WARN, MSGTR_UnknownProfile, |
17471 | 518 list[i]); |
519 r = M_OPT_INVALID; | |
520 } | |
521 if(dst) | |
522 m_option_copy(opt,dst,&list); | |
523 else | |
524 m_option_free(opt,&list); | |
525 return r; | |
526 } | |
527 | |
528 static void | |
529 set_profile(m_option_t *opt, void* dst, void* src) { | |
530 m_config_t* config = opt->priv; | |
531 m_profile_t* p; | |
532 char** list = NULL; | |
533 int i; | |
534 if(!src || !*(char***)src) return; | |
535 m_option_copy(opt,&list,src); | |
536 for(i = 0 ; list[i] ; i++) { | |
537 p = m_config_get_profile(config,list[i]); | |
538 if(!p) continue; | |
539 m_config_set_profile(config,p); | |
540 } | |
541 m_option_free(opt,&list); | |
542 } | |
543 | |
544 static int | |
545 show_profile(m_option_t *opt, char* name, char *param) { | |
546 m_config_t* config = opt->priv; | |
547 m_profile_t* p; | |
548 int i,j; | |
549 if(!param) return M_OPT_MISSING_PARAM; | |
550 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
|
551 mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_UnknownProfile, param); |
17471 | 552 return M_OPT_EXIT-1; |
553 } | |
554 if(!config->profile_depth) | |
17481
99c0caec4677
Fix the MSG?_FIXME and make the profiles help translatable.
albeu
parents:
17472
diff
changeset
|
555 mp_msg(MSGT_CFGPARSER, MSGL_INFO, MSGTR_Profile, param, |
17471 | 556 p->desc ? p->desc : ""); |
557 config->profile_depth++; | |
558 for(i = 0 ; i < p->num_opts ; i++) { | |
559 char spc[config->profile_depth+1]; | |
560 for(j = 0 ; j < config->profile_depth ; j++) | |
561 spc[j] = ' '; | |
562 spc[config->profile_depth] = '\0'; | |
563 | |
564 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s%s=%s\n", spc, | |
565 p->opts[2*i], p->opts[2*i+1]); | |
566 | |
567 | |
568 if(config->profile_depth < MAX_PROFILE_DEPTH && | |
569 !strcmp(p->opts[2*i],"profile")) { | |
570 char* e,*list = p->opts[2*i+1]; | |
571 while((e = strchr(list,','))) { | |
572 int l = e-list; | |
573 char tmp[l+1]; | |
574 if(!l) continue; | |
575 memcpy(tmp,list,l); | |
576 tmp[l] = '\0'; | |
577 show_profile(opt,name,tmp); | |
578 list = e+1; | |
579 } | |
580 if(list[0] != '\0') | |
581 show_profile(opt,name,list); | |
582 } | |
583 } | |
584 config->profile_depth--; | |
585 if(!config->profile_depth) mp_msg(MSGT_CFGPARSER, MSGL_INFO, "\n"); | |
586 return M_OPT_EXIT-1; | |
587 } | |
17472
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
588 |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
589 static int |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
590 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
|
591 m_config_t* config = opt->priv; |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
592 m_config_print_option_list(config); |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
593 return M_OPT_EXIT; |
526abfe30498
Make -list-options work in both MPlayer and MEncoder.
albeu
parents:
17471
diff
changeset
|
594 } |