summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2015-02-24 12:04:22 +0100
committerKarel Zak2015-02-24 12:04:22 +0100
commit30b294c491b4577d5f0e5c94f17cf9e36a8ecb72 (patch)
tree087407622ab14e28164f8f6447e036eadcc2fb43
parentlib/strutils: move parse_switch() from setterm(1) to library (diff)
downloadkernel-qcow2-util-linux-30b294c491b4577d5f0e5c94f17cf9e36a8ecb72.tar.gz
kernel-qcow2-util-linux-30b294c491b4577d5f0e5c94f17cf9e36a8ecb72.tar.xz
kernel-qcow2-util-linux-30b294c491b4577d5f0e5c94f17cf9e36a8ecb72.zip
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>
-rw-r--r--include/strutils.h2
-rw-r--r--lib/strutils.c30
-rw-r--r--term-utils/setterm.c36
3 files changed, 49 insertions, 19 deletions
diff --git a/include/strutils.h b/include/strutils.h
index ee8c7cbda..847a4219f 100644
--- a/include/strutils.h
+++ b/include/strutils.h
@@ -36,7 +36,7 @@ extern void strtotimeval_or_err(const char *str, struct timeval *tv,
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
extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
diff --git a/lib/strutils.c b/lib/strutils.c
index f6154aaa4..dd776e7ab 100644
--- a/lib/strutils.c
+++ b/lib/strutils.c
@@ -181,13 +181,31 @@ int isdigit_string(const char *str)
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)
- return 1;
- else if (strcmp(arg, b) == 0)
- return 0;
- errx(STRTOXX_EXIT_CODE, _("argument error: %s"), arg);
+ const char *a, *b;
+ va_list ap;
+
+ va_start(ap, errmesg);
+ 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
diff --git a/term-utils/setterm.c b/term-utils/setterm.c
index fed25307c..db0edbb86 100644
--- a/term-utils/setterm.c
+++ b/term-utils/setterm.c
@@ -542,19 +542,23 @@ static void parse_option(struct setterm_control *ctl, int argc, char **argv)
break;
case 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;
case 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;
case 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;
case 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;
case 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;
case 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;
case 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;
case OPT_HALF_BRIGHT:
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;
case 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;
case 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;
case 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;
case OPT_STORE:
ctl->opt_store = set_opt_flag(ctl->opt_store);
break;
case 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;
case 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;
case 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;
case OPT_MSGLEVEL:
ctl->opt_msglevel = set_opt_flag(ctl->opt_msglevel);