lib/strutils: extend parse_switch() to accept more options

* allow to specify more 0|1 pairs
* allow to specify error message

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2015-02-24 12:04:22 +01:00
parent e5cf147655
commit 30b294c491
3 changed files with 49 additions and 19 deletions

View file

@ -36,7 +36,7 @@ extern void strtotimeval_or_err(const char *str, struct timeval *tv,
extern int isdigit_string(const char *str); extern int isdigit_string(const char *str);
extern int parse_switch(const char *arg, const char *a, const char *b); extern int parse_switch(const char *arg, const char *errmesg, ...);
#ifndef HAVE_MEMPCPY #ifndef HAVE_MEMPCPY
extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n); extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);

View file

@ -181,13 +181,31 @@ int isdigit_string(const char *str)
return p && p > str && !*p; return p && p > str && !*p;
} }
int parse_switch(const char *arg, const char *a, const char *b) /*
* parse_switch(argv[i], "on", "off", "yes", "no", NULL);
*/
int parse_switch(const char *arg, const char *errmesg, ...)
{ {
if (strcmp(arg, a) == 0) const char *a, *b;
return 1; va_list ap;
else if (strcmp(arg, b) == 0)
return 0; va_start(ap, errmesg);
errx(STRTOXX_EXIT_CODE, _("argument error: %s"), arg); do {
a = va_arg(ap, char *);
if (!a)
break;
b = va_arg(ap, char *);
if (!b)
break;
if (strcmp(arg, a) == 0)
return 1;
else if (strcmp(arg, b) == 0)
return 0;
} while (1);
va_end(ap);
errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, arg);
} }
#ifndef HAVE_MEMPCPY #ifndef HAVE_MEMPCPY

View file

@ -542,19 +542,23 @@ static void parse_option(struct setterm_control *ctl, int argc, char **argv)
break; break;
case OPT_CURSOR: case OPT_CURSOR:
ctl->opt_cursor = set_opt_flag(ctl->opt_cursor); ctl->opt_cursor = set_opt_flag(ctl->opt_cursor);
ctl->opt_cu_on = parse_switch(optarg, "on", "off"); ctl->opt_cu_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_REPEAT: case OPT_REPEAT:
ctl->opt_repeat = set_opt_flag(ctl->opt_repeat); ctl->opt_repeat = set_opt_flag(ctl->opt_repeat);
ctl->opt_rep_on = parse_switch(optarg, "on", "off"); ctl->opt_rep_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_APPCURSORKEYS: case OPT_APPCURSORKEYS:
ctl->opt_appcursorkeys = set_opt_flag(ctl->opt_appcursorkeys); ctl->opt_appcursorkeys = set_opt_flag(ctl->opt_appcursorkeys);
ctl->opt_appck_on = parse_switch(optarg, "on", "off"); ctl->opt_appck_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_LINEWRAP: case OPT_LINEWRAP:
ctl->opt_linewrap = set_opt_flag(ctl->opt_linewrap); ctl->opt_linewrap = set_opt_flag(ctl->opt_linewrap);
ctl->opt_li_on = parse_switch(optarg, "on", "off"); ctl->opt_li_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_DEFAULT: case OPT_DEFAULT:
ctl->opt_default = set_opt_flag(ctl->opt_default); ctl->opt_default = set_opt_flag(ctl->opt_default);
@ -577,34 +581,41 @@ static void parse_option(struct setterm_control *ctl, int argc, char **argv)
break; break;
case OPT_INVERSESCREEN: case OPT_INVERSESCREEN:
ctl->opt_inversescreen = set_opt_flag(ctl->opt_inversescreen); ctl->opt_inversescreen = set_opt_flag(ctl->opt_inversescreen);
ctl->opt_invsc_on = parse_switch(optarg, "on", "off"); ctl->opt_invsc_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_BOLD: case OPT_BOLD:
ctl->opt_bold = set_opt_flag(ctl->opt_bold); ctl->opt_bold = set_opt_flag(ctl->opt_bold);
ctl->opt_bo_on = parse_switch(optarg, "on", "off"); ctl->opt_bo_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_HALF_BRIGHT: case OPT_HALF_BRIGHT:
ctl->opt_halfbright = set_opt_flag(ctl->opt_halfbright); ctl->opt_halfbright = set_opt_flag(ctl->opt_halfbright);
ctl->opt_hb_on = parse_switch(optarg, "on", "off"); ctl->opt_hb_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_BLINK: case OPT_BLINK:
ctl->opt_blink = set_opt_flag(ctl->opt_blink); ctl->opt_blink = set_opt_flag(ctl->opt_blink);
ctl->opt_bl_on = parse_switch(optarg, "on", "off"); ctl->opt_bl_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_REVERSE: case OPT_REVERSE:
ctl->opt_reverse = set_opt_flag(ctl->opt_reverse); ctl->opt_reverse = set_opt_flag(ctl->opt_reverse);
ctl->opt_re_on = parse_switch(optarg, "on", "off"); ctl->opt_re_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_UNDERLINE: case OPT_UNDERLINE:
ctl->opt_underline = set_opt_flag(ctl->opt_underline); ctl->opt_underline = set_opt_flag(ctl->opt_underline);
ctl->opt_un_on = parse_switch(optarg, "on", "off"); ctl->opt_un_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_STORE: case OPT_STORE:
ctl->opt_store = set_opt_flag(ctl->opt_store); ctl->opt_store = set_opt_flag(ctl->opt_store);
break; break;
case OPT_CLEAR: case OPT_CLEAR:
ctl->opt_clear = set_opt_flag(ctl->opt_clear); ctl->opt_clear = set_opt_flag(ctl->opt_clear);
ctl->opt_cl_all = parse_switch(optarg, "all", "reset"); ctl->opt_cl_all = parse_switch(optarg, _("argument error"),
"all", "reset", NULL);
break; break;
case OPT_TABS: case OPT_TABS:
ctl->opt_tabs = set_opt_flag(ctl->opt_tabs); ctl->opt_tabs = set_opt_flag(ctl->opt_tabs);
@ -636,7 +647,8 @@ static void parse_option(struct setterm_control *ctl, int argc, char **argv)
break; break;
case OPT_MSG: case OPT_MSG:
ctl->opt_msg = set_opt_flag(ctl->opt_msg); ctl->opt_msg = set_opt_flag(ctl->opt_msg);
ctl->opt_msg_on = parse_switch(optarg, "on", "off"); ctl->opt_msg_on = parse_switch(optarg, _("argument error"),
"on", "off", NULL);
break; break;
case OPT_MSGLEVEL: case OPT_MSGLEVEL:
ctl->opt_msglevel = set_opt_flag(ctl->opt_msglevel); ctl->opt_msglevel = set_opt_flag(ctl->opt_msglevel);