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