From 4767835aca9860a30da8300254e036f2f7e9a080 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 11 Nov 2011 20:30:18 +0100 Subject: [PATCH] isl_arg_parse: support string list arguments Signed-off-by: Sven Verdoolaege --- include/isl/arg.h | 13 +++++++++ isl_arg.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/include/isl/arg.h b/include/isl/arg.h index 68284929..4ae3374b 100644 --- a/include/isl/arg.h +++ b/include/isl/arg.h @@ -42,6 +42,7 @@ enum isl_arg_type { isl_arg_long, isl_arg_ulong, isl_arg_str, + isl_arg_str_list, isl_arg_version }; @@ -88,6 +89,9 @@ struct isl_arg { const char *default_value; } str; struct { + size_t offset_n; + } str_list; + struct { struct isl_args *child; } child; struct { @@ -229,6 +233,15 @@ struct isl_args { }, #define ISL_ARG_STR(st,f,s,l,a,d,h) \ ISL_ARG_STR_F(st,f,s,l,a,d,h,0) +#define ISL_ARG_STR_LIST(st,f_n,f_l,s,l,a,h) { \ + .type = isl_arg_str_list, \ + .short_name = s, \ + .long_name = l, \ + .argument_name = a, \ + .offset = offsetof(st, f_l), \ + .help_msg = h, \ + .u = { .str_list = { .offset_n = offsetof(st, f_n) } } \ +}, #define _ISL_ARG_CHILD(o,l,c,h,fl) { \ .type = isl_arg_child, \ .long_name = l, \ diff --git a/isl_arg.c b/isl_arg.c index ce0dcce6..6961a078 100644 --- a/isl_arg.c +++ b/isl_arg.c @@ -78,6 +78,12 @@ static void set_default_str(struct isl_arg *arg, void *opt) *(const char **)(((char *)opt) + arg->offset) = str; } +static void set_default_str_list(struct isl_arg *arg, void *opt) +{ + *(const char ***)(((char *) opt) + arg->offset) = NULL; + *(int *)(((char *) opt) + arg->u.str_list.offset_n) = 0; +} + void isl_args_set_defaults(struct isl_args *args, void *opt) { int i; @@ -112,6 +118,9 @@ void isl_args_set_defaults(struct isl_args *args, void *opt) case isl_arg_str: set_default_str(&args->args[i], opt); break; + case isl_arg_str_list: + set_default_str_list(&args->args[i], opt); + break; case isl_arg_alias: case isl_arg_footer: case isl_arg_version: @@ -121,6 +130,17 @@ void isl_args_set_defaults(struct isl_args *args, void *opt) } } +static void free_str_list(struct isl_arg *arg, void *opt) +{ + int i; + int n = *(int *)(((char *) opt) + arg->u.str_list.offset_n); + char **list = *(char ***)(((char *) opt) + arg->offset); + + for (i = 0; i < n; ++i) + free(list[i]); + free(list); +} + static void free_args(struct isl_arg *arg, void *opt) { int i; @@ -138,6 +158,9 @@ static void free_args(struct isl_arg *arg, void *opt) case isl_arg_str: free(*(char **)(((char *)opt) + arg[i].offset)); break; + case isl_arg_str_list: + free_str_list(&arg[i], opt); + break; case isl_arg_user: if (arg[i].u.user.clear) arg[i].u.user.clear(((char *)opt) + arg[i].offset); @@ -470,6 +493,16 @@ static void print_str_help(struct isl_arg *decl, const char *prefix, void *opt) printf("\n"); } +static void print_str_list_help(struct isl_arg *decl, const char *prefix) +{ + int pos; + const char *a = decl->argument_name ? decl->argument_name : "string"; + pos = print_arg_help(decl, prefix, 0); + pos = print_argument_name(decl, a, pos); + pos = print_help_msg(decl, pos); + printf("\n"); +} + static void print_help(struct isl_arg *arg, const char *prefix, void *opt) { int i; @@ -507,6 +540,10 @@ static void print_help(struct isl_arg *arg, const char *prefix, void *opt) print_str_help(&arg[i], prefix, opt); any = 1; break; + case isl_arg_str_list: + print_str_list_help(&arg[i], prefix); + any = 1; + break; case isl_arg_alias: case isl_arg_version: case isl_arg_arg: @@ -848,6 +885,44 @@ static int parse_str_option(struct isl_arg *decl, char **arg, return 0; } +static int isl_arg_str_list_append(struct isl_arg *decl, void *opt, + const char *s) +{ + int *n = (int *)(((char *) opt) + decl->u.str_list.offset_n); + char **list = *(char ***)(((char *) opt) + decl->offset); + + list = realloc(list, (*n + 1) * sizeof(char *)); + if (!list) + return -1; + *(char ***)(((char *) opt) + decl->offset) = list; + list[*n] = strdup(s); + (*n)++; + return 0; +} + +static int parse_str_list_option(struct isl_arg *decl, char **arg, + const char *prefix, void *opt) +{ + int has_argument; + const char *s; + + s = skip_name(decl, arg[0], prefix, 0, &has_argument); + if (!s) + return 0; + + if (has_argument) { + isl_arg_str_list_append(decl, opt, s); + return 1; + } + + if (arg[1]) { + isl_arg_str_list_append(decl, opt, arg[1]); + return 2; + } + + return 0; +} + static int parse_int_option(struct isl_arg *decl, char **arg, const char *prefix, void *opt) { @@ -993,6 +1068,10 @@ static int parse_option(struct isl_arg *decl, char **arg, case isl_arg_str: parsed = parse_str_option(&decl[i], arg, prefix, opt); break; + case isl_arg_str_list: + parsed = parse_str_list_option(&decl[i], arg, prefix, + opt); + break; case isl_arg_child: parsed = parse_child_option(&decl[i], arg, prefix, opt); break; -- 2.11.4.GIT