comparison m_option.c @ 8164:487cfc28525d

New config system + cleanup of header inter dependency
author albeu
date Tue, 12 Nov 2002 01:56:42 +0000
parents
children ff6a98628e6c
comparison
equal deleted inserted replaced
8163:51e5033ee687 8164:487cfc28525d
1
2 #include "config.h"
3
4 #ifdef NEW_CONFIG
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include <math.h>
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <inttypes.h>
12
13 #include "m_option.h"
14 //#include "m_config.h"
15 #include "mp_msg.h"
16
17 // Default function that just do a memcpy
18
19 static void copy_opt(m_option_t* opt,void* dst,void* src) {
20 if(dst && src)
21 memcpy(dst,src,opt->type->size);
22 }
23
24 // Helper for the print funcs (from man printf)
25 static char* dup_printf(const char *fmt, ...) {
26 /* Guess we need no more than 50 bytes. */
27 int n, size = 50;
28 char *p;
29 va_list ap;
30 if ((p = malloc (size)) == NULL)
31 return NULL;
32 while (1) {
33 /* Try to print in the allocated space. */
34 va_start(ap, fmt);
35 n = vsnprintf (p, size, fmt, ap);
36 va_end(ap);
37 /* If that worked, return the string. */
38 if (n > -1 && n < size)
39 return p;
40 /* Else try again with more space. */
41 if (n > -1) /* glibc 2.1 */
42 size = n+1; /* precisely what is needed */
43 else /* glibc 2.0 */
44 size *= 2; /* twice the old size */
45 if ((p = realloc (p, size)) == NULL)
46 return NULL;
47 }
48 }
49
50
51 // Flag
52
53 #define VAL(x) (*(int*)(x))
54
55 static int parse_flag(m_option_t* opt,char *name, char *param, void* dst, int src) {
56 if (src == M_CONFIG_FILE) {
57 if (!strcasecmp(param, "yes") || /* any other language? */
58 !strcasecmp(param, "ja") ||
59 !strcasecmp(param, "si") ||
60 !strcasecmp(param, "igen") ||
61 !strcasecmp(param, "y") ||
62 !strcasecmp(param, "j") ||
63 !strcasecmp(param, "i") ||
64 !strcmp(param, "1")) {
65 if(dst) VAL(dst) = opt->max;
66 } else if (!strcasecmp(param, "no") ||
67 !strcasecmp(param, "nein") ||
68 !strcasecmp(param, "nicht") ||
69 !strcasecmp(param, "nem") ||
70 !strcasecmp(param, "n") ||
71 !strcmp(param, "0")) {
72 if(dst) VAL(dst) = opt->min;
73 } else {
74 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "invalid parameter for %s flag: %s\n",name, param);
75 return M_OPT_INVALID;
76 }
77 return 1;
78 } else {
79 if(dst) VAL(dst) = opt->max;
80 return 0;
81 }
82 }
83
84 static char* print_flag(m_option_t* opt, void* val) {
85 if(VAL(val) == opt->min)
86 return strdup("no");
87 else
88 return strdup("yes");
89 }
90
91 m_option_type_t m_option_type_flag = {
92 "Flag",
93 "need yes or no in config files",
94 sizeof(int),
95 0,
96 parse_flag,
97 print_flag,
98 copy_opt,
99 copy_opt,
100 NULL,
101 NULL
102 };
103
104 // Integer
105
106 static int parse_int(m_option_t* opt,char *name, char *param, void* dst, int src) {
107 long tmp_int;
108 char *endptr;
109 src = 0;
110
111 if (param == NULL)
112 return M_OPT_MISSING_PARAM;
113
114 tmp_int = strtol(param, &endptr, 0);
115 if (*endptr) {
116 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be an integer: %s\n",name, param);
117 return M_OPT_INVALID;
118 }
119
120 if ((opt->flags & M_OPT_MIN) && (tmp_int < opt->min)) {
121 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be >= %d: %s\n", name, (int) opt->min, param);
122 return M_OPT_OUT_OF_RANGE;
123 }
124
125 if ((opt->flags & M_OPT_MAX) && (tmp_int > opt->max)) {
126 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be <= %d: %s\n",name, (int) opt->max, param);
127 return M_OPT_OUT_OF_RANGE;
128 }
129
130 if(dst) VAL(dst) = tmp_int;
131
132 return 1;
133 }
134
135 static char* print_int(m_option_t* opt, void* val) {
136 opt = NULL;
137 return dup_printf("%d",VAL(val));
138 }
139
140 m_option_type_t m_option_type_int = {
141 "Integer",
142 "",
143 sizeof(int),
144 0,
145 parse_int,
146 print_int,
147 copy_opt,
148 copy_opt,
149 NULL,
150 NULL
151 };
152
153 // Float
154
155 #undef VAL
156 #define VAL(x) (*(float*)(x))
157
158 static int parse_float(m_option_t* opt,char *name, char *param, void* dst, int src) {
159 float tmp_float;
160 char* endptr;
161 src = 0;
162
163 if (param == NULL)
164 return M_OPT_MISSING_PARAM;
165
166 tmp_float = strtod(param, &endptr);
167
168 switch(*endptr) {
169 case ':':
170 case '/':
171 tmp_float /= strtod(endptr+1, &endptr);
172 break;
173 case '.':
174 case ',':
175 /* we also handle floats specified with
176 * non-locale decimal point ::atmos
177 */
178 if(tmp_float<0)
179 tmp_float -= 1.0/pow(10,strlen(endptr+1)) * strtod(endptr+1, &endptr);
180 else
181 tmp_float += 1.0/pow(10,strlen(endptr+1)) * strtod(endptr+1, &endptr);
182 break;
183 }
184
185 if (*endptr) {
186 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be a floating point "
187 "number or a ratio (numerator[:/]denominator): %s\n",name, param);
188 return M_OPT_INVALID;
189 }
190
191 if (opt->flags & M_OPT_MIN)
192 if (tmp_float < opt->min) {
193 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be >= %f: %s\n", name, opt->min, param);
194 return M_OPT_OUT_OF_RANGE;
195 }
196
197 if (opt->flags & M_OPT_MAX)
198 if (tmp_float > opt->max) {
199 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be <= %f: %s\n", name, opt->max, param);
200 return M_OPT_OUT_OF_RANGE;
201 }
202
203 if(dst) VAL(dst) = tmp_float;
204 return 1;
205 }
206
207 static char* print_float(m_option_t* opt, void* val) {
208 opt = NULL;
209 return dup_printf("%f",VAL(val));
210 }
211
212 m_option_type_t m_option_type_float = {
213 "Float",
214 "floating point number or ratio (numerator[:/]denominator)",
215 sizeof(float),
216 0,
217 parse_float,
218 print_float,
219 copy_opt,
220 copy_opt,
221 NULL,
222 NULL
223 };
224
225 ///////////// Position
226 #undef VAL
227 #define VAL(x) (*(off_t*)(x))
228
229 static int parse_position(m_option_t* opt,char *name, char *param, void* dst, int src) {
230 off_t tmp_off;
231 char dummy;
232
233 if (param == NULL)
234 return M_OPT_MISSING_PARAM;
235 if (sscanf(param, sizeof(off_t) == sizeof(int) ?
236 "%d%c" : "%lld%c", &tmp_off, &dummy) != 1) {
237 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "The %s option must be an integer: %s\n",opt->name,param);
238 return M_OPT_INVALID;
239 }
240
241 if (opt->flags & M_OPT_MIN)
242 if (tmp_off < opt->min) {
243 mp_msg(MSGT_CFGPARSER, MSGL_ERR,
244 (sizeof(off_t) == sizeof(int) ?
245 "The %s option must be >= %d: %s\n" :
246 "The %s option must be >= %lld: %s\n"),
247 (off_t) opt->min, param);
248 return M_OPT_OUT_OF_RANGE;
249 }
250
251 if (opt->flags & M_OPT_MAX)
252 if (tmp_off > opt->max) {
253 mp_msg(MSGT_CFGPARSER, MSGL_ERR,
254 (sizeof(off_t) == sizeof(int) ?
255 "The %s option must be <= %d: %s\n" :
256 "The %s option must be <= %lld: %s\n"),
257 (off_t) opt->max, param);
258 return M_OPT_OUT_OF_RANGE;
259 }
260
261 if(dst)
262 VAL(dst) = tmp_off;
263 return 1;
264 }
265
266 static char* print_position(m_option_t* opt, void* val) {
267 return dup_printf(sizeof(off_t) == sizeof(int) ? "%d" : "%lld",VAL(val));
268 }
269
270 m_option_type_t m_option_type_position = {
271 "Position",
272 "Integer (off_t)",
273 sizeof(off_t),
274 0,
275 parse_position,
276 print_position,
277 copy_opt,
278 copy_opt,
279 NULL,
280 NULL
281 };
282
283
284 ///////////// String
285
286 #undef VAL
287 #define VAL(x) (*(char**)(x))
288
289 static int parse_str(m_option_t* opt,char *name, char *param, void* dst, int src) {
290
291
292 if (param == NULL)
293 return M_OPT_MISSING_PARAM;
294
295 if ((opt->flags & M_OPT_MIN) && (strlen(param) < opt->min)) {
296 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "parameter must be >= %d chars: %s\n",
297 (int) opt->min, param);
298 return M_OPT_OUT_OF_RANGE;
299 }
300
301 if ((opt->flags & M_OPT_MAX) && (strlen(param) > opt->max)) {
302 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "parameter must be <= %d chars: %s\n",
303 (int) opt->max, param);
304 return M_OPT_OUT_OF_RANGE;
305 }
306
307 if(dst) {
308 if(VAL(dst))
309 free(VAL(dst));
310 VAL(dst) = strdup(param);
311 }
312
313 return 1;
314
315 }
316
317 static char* print_str(m_option_t* opt, void* val) {
318 return (val && VAL(val) && strlen(VAL(val)) > 0) ? strdup(VAL(val)) : strdup("(empty)");
319 }
320
321 static void copy_str(m_option_t* opt,void* dst, void* src) {
322 if(dst && src) {
323 if(VAL(dst)) free(VAL(dst));
324 VAL(dst) = VAL(src) ? strdup(VAL(src)) : NULL;
325 }
326 }
327
328 static void free_str(void* src) {
329 if(src && VAL(src)){
330 free(VAL(src));
331 VAL(src) = NULL;
332 }
333 }
334
335 m_option_type_t m_option_type_string = {
336 "String",
337 "",
338 sizeof(char*),
339 M_OPT_TYPE_DYNAMIC,
340 parse_str,
341 print_str,
342 copy_str,
343 copy_str,
344 copy_str,
345 free_str
346 };
347
348 //////////// String list
349
350 #define LIST_SEPARATOR ','
351 #undef VAL
352 #define VAL(x) (*(char***)(x))
353
354 #define OP_NONE 0
355 #define OP_ADD 1
356 #define OP_PRE 2
357 #define OP_DEL 3
358 #define OP_CLR 4
359
360 static void free_str_list(void* dst) {
361 char** d;
362 int i;
363
364 if(!dst || !VAL(dst)) return;
365 d = VAL(dst);
366
367
368 for(i = 0 ; d[i] != NULL ; i++)
369 free(d[i]);
370 free(d);
371 VAL(dst) = NULL;
372 }
373
374 static int str_list_add(char** add, int n,void* dst,int pre) {
375 char** lst = VAL(dst);
376 int ln;
377
378 if(!dst) return M_OPT_PARSER_ERR;
379 lst = VAL(dst);
380
381 for(ln = 0 ; lst && lst[ln] ; ln++)
382 /**/;
383
384 lst = realloc(lst,(n+ln+1)*sizeof(char*));
385
386 if(pre) {
387 memmove(&lst[n],lst,(ln+1)*sizeof(char*));
388 memcpy(lst,add,n*sizeof(char*));
389 } else
390 memcpy(&lst[ln],add,(n+1)*sizeof(char*));
391
392 free(add);
393
394 VAL(dst) = lst;
395
396 return 1;
397 }
398
399 static int str_list_del(char** del, int n,void* dst) {
400 char **lst,*ep,**d;
401 int i,ln,s;
402 long idx;
403
404 if(!dst) return M_OPT_PARSER_ERR;
405 lst = VAL(dst);
406
407 for(ln = 0 ; lst && lst[ln] ; ln++)
408 /**/;
409 s = ln;
410
411 for(i = 0 ; del[i] != NULL ; i++) {
412 idx = strtol(del[i], &ep, 0);
413 if(*ep) {
414 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid index: %s\n",del[i]);
415 free(del[i]);
416 continue;
417 }
418 free(del[i]);
419 if(idx < 0 || idx >= ln) {
420 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Index %d is out of range\n",idx);
421 continue;
422 } else if(!lst[idx])
423 continue;
424 free(lst[idx]);
425 lst[idx] = NULL;
426 s--;
427 }
428 free(del);
429
430 if(s == 0) {
431 if(lst) free(lst);
432 VAL(dst) = NULL;
433 return 1;
434 }
435
436 d = calloc(s+1,sizeof(char*));
437 for(i = 0, n = 0 ; i < ln ; i++) {
438 if(!lst[i]) continue;
439 d[n] = lst[i];
440 n++;
441 }
442 d[s] = NULL;
443
444 if(lst) free(lst);
445 VAL(dst) = d;
446
447 return 1;
448 }
449
450
451 static int parse_str_list(m_option_t* opt,char *name, char *param, void* dst, int src) {
452 int n = 0,len = strlen(opt->name);
453 char *ptr = param, *last_ptr, **res;
454 int op = OP_NONE;
455
456 if(opt->name[len-1] == '*' && ((int)strlen(name) > len - 1)) {
457 char* n = &name[len-1];
458 if(strcasecmp(n,"-add") == 0)
459 op = OP_ADD;
460 else if(strcasecmp(n,"-pre") == 0)
461 op = OP_PRE;
462 else if(strcasecmp(n,"-del") == 0)
463 op = OP_DEL;
464 else if(strcasecmp(n,"-clr") == 0)
465 op = OP_CLR;
466 else
467 return M_OPT_UNKNOW;
468 }
469
470 // Clear the list ??
471 if(op == OP_CLR) {
472 if(dst)
473 free_str_list(dst);
474 return 0;
475 }
476
477 // All other op need a param
478 if (param == NULL || strlen(param) == 0)
479 return M_OPT_MISSING_PARAM;
480
481
482 while(ptr[0] != '\0') {
483 last_ptr = ptr;
484 ptr = strchr(ptr,LIST_SEPARATOR);
485 if(!ptr) {
486 n++;
487 break;
488 }
489 ptr++;
490 n++;
491 }
492 if(n == 0)
493 return M_OPT_INVALID;
494 if( ((opt->flags & M_OPT_MIN) && (n < opt->min)) ||
495 ((opt->flags & M_OPT_MAX) && (n > opt->max)) )
496 return M_OPT_OUT_OF_RANGE;
497
498 if(!dst) return 1;
499
500 res = malloc((n+1)*sizeof(char*));
501 ptr = param;
502 n = 0;
503
504 while(1) {
505 last_ptr = ptr;
506 ptr = strchr(ptr,LIST_SEPARATOR);
507 if(!ptr) {
508 res[n] = strdup(last_ptr);
509 n++;
510 break;
511 }
512 len = ptr - last_ptr;
513 res[n] = (char*)malloc(len + 1);
514 if(len) strncpy(res[n],last_ptr,len);
515 res[n][len] = '\0';
516 ptr++;
517 n++;
518 }
519 res[n] = NULL;
520
521 switch(op) {
522 case OP_ADD:
523 return str_list_add(res,n,dst,0);
524 case OP_PRE:
525 return str_list_add(res,n,dst,1);
526 case OP_DEL:
527 return str_list_del(res,n,dst);
528 }
529
530 if(VAL(dst))
531 free_str_list(dst);
532 VAL(dst) = res;
533
534 return 1;
535 }
536
537 static void copy_str_list(m_option_t* opt,void* dst, void* src) {
538 int n;
539 char **d,**s;
540
541 if(!(dst && src)) return;
542 s = VAL(src);
543
544 if(VAL(dst))
545 free_str_list(dst);
546
547 if(!s) {
548 VAL(dst) = NULL;
549 return;
550 }
551
552 for(n = 0 ; s[n] != NULL ; n++)
553 /* NOTHING */;
554 d = (char**)malloc((n+1)*sizeof(char*));
555 for( ; n >= 0 ; n--)
556 d[n] = s[n] ? strdup(s[n]) : NULL;
557
558 VAL(dst) = d;
559 }
560
561 static char* print_str_list(m_option_t* opt, void* src) {
562 return strdup("TODO ;)");
563 }
564
565 m_option_type_t m_option_type_string_list = {
566 "String list",
567 "A list of string separated by ','\n"
568 "Option with name that finish by an * allow to use the following suffix : \n"
569 "\t-add : add the given parameters at the end of list\n"
570 "\t-pre : add the given parameters at the begining of list\n"
571 "\t-del : remove the entry at the given indexs\n"
572 "\t-clr : clear the list\n"
573 "e.g: -vop-add flip,mirror -vop-del 2,5\n",
574 sizeof(char**),
575 M_OPT_TYPE_DYNAMIC | M_OPT_TYPE_ALLOW_WILDCARD,
576 parse_str_list,
577 print_str_list,
578 copy_str_list,
579 copy_str_list,
580 copy_str_list,
581 free_str_list
582 };
583
584
585 /////////////////// Func based options
586
587 // A chained list to save the various calls for func_param and func_full
588 typedef struct m_func_save m_func_save_t;
589 struct m_func_save {
590 m_func_save_t* next;
591 char* name;
592 char* param;
593 };
594
595 #undef VAL
596 #define VAL(x) (*(m_func_save_t**)(x))
597
598 static void free_func_pf(void* src) {
599 m_func_save_t *s,*n;
600
601 if(!src) return;
602
603 s = VAL(src);
604
605 while(s) {
606 n = s->next;
607 free(s->name);
608 if(s->param) free(s->param);
609 free(s);
610 s = n;
611 }
612 VAL(src) = NULL;
613 }
614
615 // Parser for func_param and func_full
616 static int parse_func_pf(m_option_t* opt,char *name, char *param, void* dst, int src) {
617 m_func_save_t *s,*p;
618
619 if(!dst)
620 return 1;
621
622 s = (m_func_save_t*)calloc(1,sizeof(m_func_save_t));
623 s->name = strdup(name);
624 s->param = param ? strdup(param) : NULL;
625
626 p = VAL(dst);
627 if(p) {
628 for( ; p->next != NULL ; p = p->next)
629 /**/;
630 p->next = s;
631 } else
632 VAL(dst) = s;
633
634 return 1;
635 }
636
637 static void copy_func_pf(m_option_t* opt,void* dst, void* src) {
638 m_func_save_t *d = NULL, *s,* last = NULL;
639
640 if(!(dst && src)) return;
641 s = VAL(src);
642
643 if(VAL(dst))
644 free_func_pf(dst);
645
646 while(s) {
647 d = (m_func_save_t*)malloc(sizeof(m_func_save_t));
648 d->name = strdup(s->name);
649 d->param = s->param ? strdup(s->param) : NULL;
650 if(last)
651 last->next = d;
652 else
653 VAL(dst) = d;
654 last = d;
655 s = s->next;
656 }
657
658
659 }
660
661 /////////////////// Func_param
662
663 static void set_func_param(m_option_t* opt, void* dst, void* src) {
664 m_func_save_t* s;
665
666 if(!src) return;
667 s = VAL(src);
668
669 if(!s) return;
670
671 // Revert if needed
672 if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name);
673 for( ; s != NULL ; s = s->next)
674 ((m_opt_func_param_t) opt->p)(opt,s->param);
675 }
676
677 m_option_type_t m_option_type_func_param = {
678 "Func param",
679 "",
680 sizeof(m_func_save_t*),
681 M_OPT_TYPE_INDIRECT,
682 parse_func_pf,
683 NULL,
684 NULL, // Nothing to do on save
685 set_func_param,
686 copy_func_pf,
687 free_func_pf
688 };
689
690 /////////////////// Func_full
691
692 static void set_func_full(m_option_t* opt, void* dst, void* src) {
693 m_func_save_t* s;
694
695 if(!src) return;
696
697 for(s = VAL(src) ; s ; s = s->next) {
698 // Revert if needed
699 if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,s->name);
700 ((m_opt_func_full_t) opt->p)(opt,s->name,s->param);
701 }
702 }
703
704 m_option_type_t m_option_type_func_full = {
705 "Func full",
706 "",
707 sizeof(m_func_save_t*),
708 M_OPT_TYPE_ALLOW_WILDCARD|M_OPT_TYPE_INDIRECT,
709 parse_func_pf,
710 NULL,
711 NULL, // Nothing to do on save
712 set_func_full,
713 copy_func_pf,
714 free_func_pf
715 };
716
717 /////////////// Func
718
719 #undef VAL
720 #define VAL(x) (*(int*)(x))
721
722 static int parse_func(m_option_t* opt,char *name, char *param, void* dst, int src) {
723 if(dst)
724 VAL(dst) += 1;
725 return 0;
726 }
727
728 static void set_func(m_option_t* opt,void* dst, void* src) {
729 int i;
730 if(opt->priv) ((m_opt_default_func_t)opt->priv)(opt,opt->name);
731 for(i = 0 ; i < VAL(src) ; i++)
732 ((m_opt_func_t) opt->p)(opt);
733 }
734
735 m_option_type_t m_option_type_func = {
736 "Func",
737 "",
738 sizeof(int),
739 M_OPT_TYPE_INDIRECT,
740 parse_func,
741 NULL,
742 NULL, // Nothing to do on save
743 set_func,
744 NULL,
745 NULL
746 };
747
748 /////////////////// Print
749
750 static int parse_print(m_option_t* opt,char *name, char *param, void* dst, int src) {
751 mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s", (char *) opt->p);
752 if(opt->priv == NULL)
753 exit(1); // Call something else instead ??
754 return 1;
755 }
756
757 m_option_type_t m_option_type_print = {
758 "Print",
759 "",
760 0,
761 0,
762 parse_print,
763 NULL,
764 NULL,
765 NULL,
766 NULL,
767 NULL
768 };
769
770 /////////////////////// Subconfig
771 #undef VAL
772 #define VAL(x) (*(char***)(x))
773
774 static int parse_subconf(m_option_t* opt,char *name, char *param, void* dst, int src) {
775 char *subparam;
776 char *subopt;
777 int nr = 0;
778 m_option_t *subopts;
779 char *token;
780 char *p;
781 char** lst = NULL;
782
783 if (param == NULL || strlen(param) == 0)
784 return M_OPT_MISSING_PARAM;
785
786 subparam = malloc(strlen(param)+1);
787 subopt = malloc(strlen(param)+1);
788 p = strdup(param); // In case that param is a static string (cf man strtok)
789
790 subopts = opt->p;
791
792 token = strtok(p, (char *)&(":"));
793 while(token)
794 {
795 int sscanf_ret;
796 /* clear out */
797 subopt[0] = subparam[0] = 0;
798
799 sscanf_ret = sscanf(token, "%[^=]=%[^:]", subopt, subparam);
800
801 mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "token: '%s', subopt='%s', subparam='%s' (ret: %d)\n", token, subopt, subparam, sscanf_ret);
802 switch(sscanf_ret)
803 {
804 case 1:
805 subparam[0] = 0;
806 case 2:
807 if(dst) {
808 lst = (char**)realloc(lst,2 * (nr+2) * sizeof(char*));
809 lst[2*nr] = strdup(subopt);
810 lst[2*nr+1] = subparam[0] == 0 ? NULL : strdup(subparam);
811 memset(&lst[2*(nr+1)],0,2*sizeof(char*));
812 nr++;
813 }
814 break;
815 default:
816 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid subconfig argument! ('%s')\n", token);
817 return M_OPT_INVALID;
818 }
819 token = strtok(NULL, (char *)&(":"));
820 }
821
822 free(subparam);
823 free(subopt);
824 free(p);
825 VAL(dst) = lst;
826
827 return 1;
828 }
829
830 m_option_type_t m_option_type_subconfig = {
831 "Subconfig",
832 "The syntax is -option opt1=foo:flag:opt2=blah",
833 sizeof(int),
834 M_OPT_TYPE_HAS_CHILD,
835 parse_subconf,
836 NULL,
837 NULL,
838 NULL,
839 NULL,
840 NULL
841 };
842
843 #include "libmpcodecs/img_format.h"
844 // TODO : use an array so we parse/print easily
845
846 static int parse_imgfmt(m_option_t* opt,char *name, char *param, void* dst, int src) {
847 uint32_t fmt = 0;
848
849 if (param == NULL || strlen(param) == 0)
850 return M_OPT_MISSING_PARAM;
851
852 // From vf_format
853 if(!strcasecmp(param,"444p")) fmt=IMGFMT_444P; else
854 if(!strcasecmp(param,"422p")) fmt=IMGFMT_422P; else
855 if(!strcasecmp(param,"411p")) fmt=IMGFMT_411P; else
856 if(!strcasecmp(param,"yuy2")) fmt=IMGFMT_YUY2; else
857 if(!strcasecmp(param,"yv12")) fmt=IMGFMT_YV12; else
858 if(!strcasecmp(param,"i420")) fmt=IMGFMT_I420; else
859 if(!strcasecmp(param,"yvu9")) fmt=IMGFMT_YVU9; else
860 if(!strcasecmp(param,"if09")) fmt=IMGFMT_IF09; else
861 if(!strcasecmp(param,"iyuv")) fmt=IMGFMT_IYUV; else
862 if(!strcasecmp(param,"uyvy")) fmt=IMGFMT_UYVY; else
863 if(!strcasecmp(param,"bgr24")) fmt=IMGFMT_BGR24; else
864 if(!strcasecmp(param,"bgr32")) fmt=IMGFMT_BGR32; else
865 if(!strcasecmp(param,"bgr16")) fmt=IMGFMT_BGR16; else
866 if(!strcasecmp(param,"bgr15")) fmt=IMGFMT_BGR15; else
867 if(!strcasecmp(param,"bgr8")) fmt=IMGFMT_BGR8; else
868 if(!strcasecmp(param,"bgr4")) fmt=IMGFMT_BGR4; else
869 if(!strcasecmp(param,"bgr1")) fmt=IMGFMT_BGR1; else
870 if(!strcasecmp(param,"rgb24")) fmt=IMGFMT_RGB24; else
871 if(!strcasecmp(param,"rgb32")) fmt=IMGFMT_RGB32; else
872 if(!strcasecmp(param,"rgb16")) fmt=IMGFMT_RGB16; else
873 if(!strcasecmp(param,"rgb15")) fmt=IMGFMT_RGB15; else
874 if(!strcasecmp(param,"rgb8")) fmt=IMGFMT_RGB8; else
875 if(!strcasecmp(param,"rgb4")) fmt=IMGFMT_RGB4; else
876 if(!strcasecmp(param,"rgb1")) fmt=IMGFMT_RGB1; else {
877 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: unknown format name: '%s'\n",param);
878 return M_OPT_INVALID;
879 }
880
881 if(dst)
882 *((uint32_t*)dst) = fmt;
883
884 return 1;
885 }
886
887 m_option_type_t m_option_type_imgfmt = {
888 "Image format (aka colorspace)",
889 "Pls report any missing colorspace",
890 sizeof(uint32_t),
891 0,
892 parse_imgfmt,
893 NULL,
894 copy_opt,
895 copy_opt,
896 NULL,
897 NULL
898 };
899
900 /// Span stuff : Not finished
901 static int parse_play_pos(m_play_pos_t* pos,char* opt, char *s) {
902 char *ep;
903 long tmp;
904 int i;
905
906 memset(pos,0,sizeof(m_play_pos_t));
907
908 if(!s || s[0] == '\0')
909 return M_OPT_MISSING_PARAM;
910
911 // Track index
912 tmp = strtol(s, &ep, 0);
913 if(ep != s) {
914 if(tmp < 1) {
915 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Track/Chapter index must be > 0\n", opt);
916 return M_OPT_OUT_OF_RANGE;
917 }
918 pos->idx = tmp;
919 if(ep[0] == '\0')
920 return 1;
921 s = ep;
922 }
923
924 // Span
925 tmp = strlen(s);
926 if(s[0] != '[' || s[tmp-1] != ']') {
927 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid argument ?\n", opt);
928 return M_OPT_INVALID;
929 }
930 s[tmp-1] = '\0';
931 s++;
932
933 // hh:mm:ss
934 for( i = 2 ; i >= 0 && s[0] != 0 ; i--) {
935 if(s[0] == ':') {
936 tmp = 0;
937 s++;
938 } else {
939 tmp = strtol(s, &ep, 0);
940 if(tmp < 0 || (ep[0] != '\0' && ep[0] != (i > 0 ? ':' : '.') )) {
941 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid argument ?\n", opt);
942 return M_OPT_INVALID;
943 }
944 pos->seconds += tmp * pow(60,i);
945 s = ep;
946 if(s[0] != '\0')
947 s++;
948
949 }
950 }
951
952 // sectors
953 if(s[0]) {
954 tmp = strtol(s, &ep, 0);
955 if(tmp < 0 || ep[0] != '\0') {
956 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid argument ?\n", opt);
957 return M_OPT_INVALID;
958 }
959 pos->sectors = tmp;
960 }
961
962 return 1;
963 }
964
965
966 static int parse_span(m_option_t* opt,char *name, char *param, void* dst, int src) {
967 m_span_t* span = dst;
968 char *s = param,*e = NULL;
969 int r = M_OPT_INVALID;
970
971 if(param == NULL)
972 return M_OPT_MISSING_PARAM;
973
974 e = strchr(param,'-');
975 if(e) {
976 e[0] = '\0';
977 e++;
978 }
979
980 if(s[0] == '\0' && e[0] == '\0') {
981 mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid argument\n");
982 return M_OPT_INVALID;
983 }
984
985 if(s[0]) {
986 r = parse_play_pos(&span->start,name,s);
987 if(r < 0) return r;
988 }
989 if(e && e[0] != '\0')
990 r = parse_play_pos(&span->end,name,s);
991
992 return r;
993 }
994
995 m_option_type_t m_option_type_span = {
996 "Span",
997 "The syntax is 1[hh:mm:ss.zz]-5[hh:mm:ss.zz]",
998 sizeof(m_span_t),
999 0,
1000 parse_span,
1001 NULL,
1002 copy_opt,
1003 copy_opt,
1004 NULL,
1005 NULL
1006 };
1007
1008 #endif