diff --git a/cmdutils.c b/cmdutils.c index 1eed404647..6c64d47d01 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -207,6 +207,7 @@ int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef { const OptionDef *po; int bool_val = 1; + int *dstcount; void *dst; po = find_option(options, opt); @@ -231,7 +232,17 @@ unknown_opt: /* new-style options contain an offset into optctx, old-style address of * a global var*/ - dst = po->flags & (OPT_OFFSET) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; + dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr; + + if (po->flags & OPT_SPEC) { + SpecifierOpt **so = dst; + char *p = strchr(opt, ':'); + + dstcount = (int*)(so + 1); + *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1); + (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : ""); + dst = &(*so)[*dstcount - 1].u; + } if (po->flags & OPT_STRING) { char *str; diff --git a/cmdutils.h b/cmdutils.h index f0c9079647..003c928fc6 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -108,6 +108,16 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do */ int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration); +typedef struct SpecifierOpt { + char *specifier; /**< stream/chapter/program/... specifier */ + union { + uint8_t *str; + int i; + int64_t i64; + float f; + } u; +} SpecifierOpt; + typedef struct { const char *name; int flags; @@ -126,6 +136,9 @@ typedef struct { #define OPT_DATA 0x1000 #define OPT_FUNC2 0x2000 #define OPT_OFFSET 0x4000 /* option is specified as an offset in a passed optctx */ +#define OPT_SPEC 0x8000 /* option is to be stored in an array of SpecifierOpt. + Implies OPT_OFFSET. Next element after the offset is + an int containing element count in the array. */ union { void *dst_ptr; int (*func_arg)(const char *, const char *);