All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0 of 2] xl: add helpers for option parsing
@ 2012-11-30 11:21 Ian Campbell
  2012-11-30 11:21 ` [PATCH 1 of 2] xl: allow def_getopt to handle long options Ian Campbell
  2012-11-30 11:21 ` [PATCH 2 of 2] xl: Introduce helper macro for option parsing Ian Campbell
  0 siblings, 2 replies; 7+ messages in thread
From: Ian Campbell @ 2012-11-30 11:21 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson

This is a repost of the last two patches of "xl shutdown compatibility
with xm" which were actually helpers for xl option parsing.

I've addresses Ian J's review comments on the second patch and rebased.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1 of 2] xl: allow def_getopt to handle long options
  2012-11-30 11:21 [PATCH 0 of 2] xl: add helpers for option parsing Ian Campbell
@ 2012-11-30 11:21 ` Ian Campbell
  2012-11-30 11:21 ` [PATCH 2 of 2] xl: Introduce helper macro for option parsing Ian Campbell
  1 sibling, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2012-11-30 11:21 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson

# HG changeset patch
# User Ian Campbell <ijc@hellion.org.uk>
# Date 1354274264 0
# Node ID b63fbacd5037e79bc4f40429453cb59816f94793
# Parent  7b2827b336543c854b15163aefcfe211fd89785d
xl: allow def_getopt to handle long options

Improves consistency of option parsing and error handling.

Consistently support --help for all options.

Many users of getopt_long were needlessly passing an option_index
pointer which was not used.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

diff -r 7b2827b33654 -r b63fbacd5037 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Fri Nov 30 11:17:15 2012 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Fri Nov 30 11:17:44 2012 +0000
@@ -2295,19 +2295,34 @@ static int64_t parse_mem_size_kb(const c
     return kbytes;
 }
 
-static int def_getopt(int argc, char * const argv[], const char *optstring,
+#define COMMON_LONG_OPTS {"help", 0, 0, 'h'}
+
+static int def_getopt(int argc, char * const argv[],
+                      const char *optstring,
+                      const struct option *longopts,
                       const char* helpstr, int reqargs)
 {
     int opt;
+    const struct option def_options[] = {
+        COMMON_LONG_OPTS,
+        {0, 0, 0, 0}
+    };
+
+    if (!longopts)
+        longopts = def_options;
 
     opterr = 0;
-    while ((opt = getopt(argc, argv, optstring)) == '?') {
+    while ((opt = getopt_long(argc, argv, optstring, longopts, NULL)) == '?') {
         if (optopt == 'h') {
             help(helpstr);
             return 0;
         }
         fprintf(stderr, "option `%c' not supported.\n", optopt);
     }
+    if (opt == 'h') {
+        help(helpstr);
+        return 0;
+    }
     if (opt != -1)
         return opt;
 
@@ -2343,7 +2358,7 @@ int main_memmax(int argc, char **argv)
     char *mem;
     int rc;
 
-    if ((opt = def_getopt(argc, argv, "", "mem-max", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "mem-max", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2377,7 +2392,7 @@ int main_memset(int argc, char **argv)
     int opt = 0;
     const char *mem;
 
-    if ((opt = def_getopt(argc, argv, "", "mem-set", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "mem-set", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2416,7 +2431,7 @@ int main_cd_eject(int argc, char **argv)
     int opt = 0;
     const char *virtdev;
 
-    if ((opt = def_getopt(argc, argv, "", "cd-eject", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cd-eject", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2433,7 +2448,7 @@ int main_cd_insert(int argc, char **argv
     const char *virtdev;
     char *file = NULL; /* modified by cd_insert tokenising it */
 
-    if ((opt = def_getopt(argc, argv, "", "cd-insert", 3)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cd-insert", 3)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2450,7 +2465,7 @@ int main_console(int argc, char **argv)
     int opt = 0, num = 0;
     libxl_console_type type = 0;
 
-    while ((opt = def_getopt(argc, argv, "n:t:", "console", 1)) != -1) {
+    while ((opt = def_getopt(argc, argv, "n:t:", NULL, "console", 1)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -2481,36 +2496,23 @@ int main_console(int argc, char **argv)
 
 int main_vncviewer(int argc, char **argv)
 {
-    static const struct option long_options[] = {
+    static const struct option opts[] = {
         {"autopass", 0, 0, 'a'},
         {"vncviewer-autopass", 0, 0, 'a'},
-        {"help", 0, 0, 'h'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
     uint32_t domid;
     int opt, autopass = 0;
 
-    while (1) {
-        opt = getopt_long(argc, argv, "ah", long_options, NULL);
-        if (opt == -1)
-            break;
-
+    while ((opt = def_getopt(argc, argv, "ah", opts, "vncviewer", 1)) != -1) {
         switch (opt) {
+        case 0: case 2:
+            return opt;
         case 'a':
             autopass = 1;
             break;
-        case 'h':
-            help("vncviewer");
-            return 0;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
-        }
-    }
-
-    if (argc - optind != 1) {
-        help("vncviewer");
-        return 2;
+        }
     }
 
     domid = find_domain(argv[optind]);
@@ -2543,7 +2545,7 @@ int main_pcilist(int argc, char **argv)
     uint32_t domid;
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "pci-list", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "pci-list", 1)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2582,7 +2584,7 @@ int main_pcidetach(int argc, char **argv
     int force = 0;
     const char *bdf = NULL;
 
-    while ((opt = def_getopt(argc, argv, "f", "pci-detach", 2)) != -1) {
+    while ((opt = def_getopt(argc, argv, "f", NULL, "pci-detach", 2)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -2624,7 +2626,7 @@ int main_pciattach(int argc, char **argv
     int opt;
     const char *bdf = NULL, *vs = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", "pci-attach", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "pci-attach", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -2658,7 +2660,7 @@ int main_pciassignable_list(int argc, ch
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "pci-assignable-list", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-list", 0)) != -1)
         return opt;
 
     pciassignable_list();
@@ -2690,7 +2692,7 @@ int main_pciassignable_add(int argc, cha
     int opt;
     const char *bdf = NULL;
 
-    while ((opt = def_getopt(argc, argv, "", "pci-assignable-add", 1)) != -1) {
+    while ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-add", 1)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -2729,7 +2731,7 @@ int main_pciassignable_remove(int argc, 
     const char *bdf = NULL;
     int rebind = 0;
 
-    while ((opt = def_getopt(argc, argv, "r", "pci-assignable-remove", 1)) != -1) {
+    while ((opt = def_getopt(argc, argv, "r", NULL, "pci-assignable-remove", 1)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -3540,24 +3542,18 @@ int main_restore(int argc, char **argv)
     int paused = 0, debug = 0, daemonize = 1, monitor = 1,
         console_autoconnect = 0, vnc = 0, vncautopass = 0;
     int opt, rc;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"vncviewer", 0, 0, 'V'},
         {"vncviewer-autopass", 0, 0, 'A'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    while (1) {
-        opt = getopt_long(argc, argv, "FhcpdeVA", long_options, &option_index);
-        if (opt == -1)
-            break;
-
+    while ((opt = def_getopt(argc, argv, "FhcpdeVA",
+                             opts, "restore", 1)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
-        case 'h':
-            help("restore");
-            return 2;
         case 'c':
             console_autoconnect = 1;
             break;
@@ -3617,7 +3613,7 @@ int main_migrate_receive(int argc, char 
     int debug = 0, daemonize = 1, monitor = 1, remus = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "Fedr", "migrate-receive", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "Fedr", NULL, "migrate-receive", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -3656,7 +3652,7 @@ int main_save(int argc, char **argv)
     int checkpoint = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "c", "save", 2)) != -1) {
+    while ((opt = def_getopt(argc, argv, "c", NULL, "save", 2)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -3689,7 +3685,7 @@ int main_migrate(int argc, char **argv)
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0;
 
-    while ((opt = def_getopt(argc, argv, "FC:s:ed", "migrate", 2)) != -1) {
+    while ((opt = def_getopt(argc, argv, "FC:s:ed", NULL, "migrate", 2)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -3733,7 +3729,7 @@ int main_dump_core(int argc, char **argv
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "dump-core", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "dump-core", 2)) != -1)
         return opt;
 
     core_dump_domain(find_domain(argv[optind]), argv[optind + 1]);
@@ -3744,7 +3740,7 @@ int main_pause(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "pause", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "pause", 1)) != -1)
         return opt;
 
     pause_domain(find_domain(argv[optind]));
@@ -3756,7 +3752,7 @@ int main_unpause(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "unpause", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "unpause", 1)) != -1)
         return opt;
 
     unpause_domain(find_domain(argv[optind]));
@@ -3768,7 +3764,7 @@ int main_destroy(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "destroy", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "destroy", 1)) != -1)
         return opt;
 
     destroy_domain(find_domain(argv[optind]));
@@ -3777,19 +3773,21 @@ int main_destroy(int argc, char **argv)
 
 static int main_shutdown_or_reboot(int do_reboot, int argc, char **argv)
 {
+    const char *what = do_reboot ? "reboot" : "shutdown";
     void (*fn)(uint32_t domid,
                libxl_evgen_domain_death **, libxl_ev_user, int) =
         do_reboot ? &reboot_domain : &shutdown_domain;
     int opt, i, nb_domain;
     int wait_for_it = 0, all =0;
     int fallback_trigger = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"all", 0, 0, 'a'},
         {"wait", 0, 0, 'w'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    while ((opt = getopt_long(argc, argv, "awF", long_options, NULL)) != -1) {
+    while ((opt = def_getopt(argc, argv, "awF", opts, what, 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -3861,12 +3859,11 @@ int main_list(int argc, char **argv)
     int opt, verbose = 0;
     int context = 0;
     int details = 0;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"long", 0, 0, 'l'},
-        {"help", 0, 0, 'h'},
         {"verbose", 0, 0, 'v'},
         {"context", 0, 0, 'Z'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
@@ -3874,12 +3871,10 @@ int main_list(int argc, char **argv)
     libxl_dominfo *info, *info_free=0;
     int nb_domain, rc;
 
-    while (1) {
-        opt = getopt_long(argc, argv, "lvhZ", long_options, &option_index);
-        if (opt == -1)
-            break;
-
+    while ((opt = def_getopt(argc, argv, "lvhZ", opts, "list", 0)) != -1) {
         switch (opt) {
+        case 0: case 2:
+            return opt;
         case 'l':
             details = 1;
             break;
@@ -3892,9 +3887,6 @@ int main_list(int argc, char **argv)
         case 'Z':
             context = 1;
             break;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
         }
     }
 
@@ -3941,7 +3933,7 @@ int main_vm_list(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "vm-list", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vm-list", 0)) != -1)
         return opt;
 
     list_vm();
@@ -3957,14 +3949,13 @@ int main_create(int argc, char **argv)
     int paused = 0, debug = 0, daemonize = 1, console_autoconnect = 0,
         quiet = 0, monitor = 1, vnc = 0, vncautopass = 0;
     int opt, rc;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"dryrun", 0, 0, 'n'},
         {"quiet", 0, 0, 'q'},
-        {"help", 0, 0, 'h'},
         {"defconfig", 1, 0, 'f'},
         {"vncviewer", 0, 0, 'V'},
         {"vncviewer-autopass", 0, 0, 'A'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
@@ -3973,12 +3964,10 @@ int main_create(int argc, char **argv)
         argc--; argv++;
     }
 
-    while (1) {
-        opt = getopt_long(argc, argv, "Fhnqf:pcdeVA", long_options, &option_index);
-        if (opt == -1)
-            break;
-
+    while ((opt = def_getopt(argc, argv, "Fhnqf:pcdeVA", opts, "create", 0)) != -1) {
         switch (opt) {
+        case 0: case 2:
+            return opt;
         case 'f':
             filename = optarg;
             break;
@@ -4013,9 +4002,6 @@ int main_create(int argc, char **argv)
         case 'A':
             vnc = vncautopass = 1;
             break;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
         }
     }
 
@@ -4063,11 +4049,10 @@ int main_config_update(int argc, char **
     int config_len = 0;
     libxl_domain_config d_config;
     int opt, rc;
-    int option_index = 0;
     int debug = 0;
-    static struct option long_options[] = {
-        {"help", 0, 0, 'h'},
+    static struct option opts[] = {
         {"defconfig", 1, 0, 'f'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
@@ -4085,24 +4070,16 @@ int main_config_update(int argc, char **
         argc--; argv++;
     }
 
-    while (1) {
-        opt = getopt_long(argc, argv, "dhqf:", long_options, &option_index);
-        if (opt == -1)
-            break;
-
+    while ((opt = def_getopt(argc, argv, "dhqf:", opts, "config_update", 0)) != -1) {
         switch (opt) {
+        case 0: case 2:
+            return opt;
         case 'd':
             debug = 1;
             break;
         case 'f':
             filename = optarg;
             break;
-        case 'h':
-            help("create");
-            return 0;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
         }
     }
 
@@ -4191,7 +4168,7 @@ int main_button_press(int argc, char **a
     fprintf(stderr, "WARNING: \"button-press\" is deprecated. "
             "Please use \"trigger\"\n");
 
-    if ((opt = def_getopt(argc, argv, "", "button-press", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "button-press", 2)) != -1)
         return opt;
 
     button_press(find_domain(argv[optind]), argv[optind + 1]);
@@ -4332,7 +4309,7 @@ int main_vcpulist(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "cpu-list", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpu-list", 0)) != -1)
         return opt;
 
     vcpulist(argc - optind, argv + optind);
@@ -4393,7 +4370,7 @@ int main_vcpupin(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "vcpu-pin", 3)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-pin", 3)) != -1)
         return opt;
 
     vcpupin(find_domain(argv[optind]), argv[optind+1] , argv[optind+2]);
@@ -4429,7 +4406,7 @@ int main_vcpuset(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "vcpu-set", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-set", 2)) != -1)
         return opt;
 
     vcpuset(find_domain(argv[optind]), argv[optind+1]);
@@ -4605,25 +4582,20 @@ static void print_info(int numa)
 int main_info(int argc, char **argv)
 {
     int opt;
-    int option_index = 0;
-    static struct option long_options[] = {
-        {"help", 0, 0, 'h'},
+    static struct option opts[] = {
         {"numa", 0, 0, 'n'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
     int numa = 0;
 
-    while ((opt = getopt_long(argc, argv, "hn", long_options, &option_index)) != -1) {
+    while ((opt = def_getopt(argc, argv, "hn", opts, "info", 0)) != -1) {
         switch (opt) {
-        case 'h':
-            help("info");
-            return 0;
+        case 0: case 2:
+            return opt;
         case 'n':
             numa = 1;
             break;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
         }
     }
 
@@ -4658,7 +4630,7 @@ int main_sharing(int argc, char **argv)
     libxl_dominfo *info, *info_free = NULL;
     int nb_domain, rc;
 
-    if ((opt = def_getopt(argc, argv, "", "sharing", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "sharing", 0)) != -1)
         return opt;
 
     if (optind >= argc) {
@@ -4927,8 +4899,7 @@ int main_sched_credit(int argc, char **a
     int opt_s = 0;
     int tslice = 0, opt_t = 0, ratelimit = 0, opt_r = 0;
     int opt, rc;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"domain", 1, 0, 'd'},
         {"weight", 1, 0, 'w'},
         {"cap", 1, 0, 'c'},
@@ -4936,15 +4907,11 @@ int main_sched_credit(int argc, char **a
         {"tslice_ms", 1, 0, 't'},
         {"ratelimit_us", 1, 0, 'r'},
         {"cpupool", 1, 0, 'p'},
-        {"help", 0, 0, 'h'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    while (1) {
-        opt = getopt_long(argc, argv, "d:w:c:p:t:r:hs", long_options,
-                          &option_index);
-        if (opt == -1)
-            break;
+    while ((opt = def_getopt(argc, argv, "d:w:c:p:t:r:hs", opts, "sched-credit", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -4973,9 +4940,6 @@ int main_sched_credit(int argc, char **a
         case 'p':
             cpupool = optarg;
             break;
-        case 'h':
-            help("sched-credit");
-            return 0;
         }
     }
 
@@ -5058,19 +5022,15 @@ int main_sched_credit2(int argc, char **
     const char *cpupool = NULL;
     int weight = 256, opt_w = 0;
     int opt, rc;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"domain", 1, 0, 'd'},
         {"weight", 1, 0, 'w'},
         {"cpupool", 1, 0, 'p'},
-        {"help", 0, 0, 'h'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    while (1) {
-        opt = getopt_long(argc, argv, "d:w:p:h", long_options, &option_index);
-        if (opt == -1)
-            break;
+    while ((opt = def_getopt(argc, argv, "d:w:p:h", opts, "sched-credit2", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -5084,9 +5044,6 @@ int main_sched_credit2(int argc, char **
         case 'p':
             cpupool = optarg;
             break;
-        case 'h':
-            help("sched-credit");
-            return 0;
         }
     }
 
@@ -5137,23 +5094,18 @@ int main_sched_sedf(int argc, char **arg
     int extra = 0, opt_e = 0;
     int weight = 0, opt_w = 0;
     int opt, rc;
-    int option_index = 0;
-    static struct option long_options[] = {
+    static struct option opts[] = {
         {"period", 1, 0, 'p'},
         {"slice", 1, 0, 's'},
         {"latency", 1, 0, 'l'},
         {"extra", 1, 0, 'e'},
         {"weight", 1, 0, 'w'},
         {"cpupool", 1, 0, 'c'},
-        {"help", 0, 0, 'h'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
 
-    while (1) {
-        opt = getopt_long(argc, argv, "d:p:s:l:e:w:c:h", long_options,
-                          &option_index);
-        if (opt == -1)
-            break;
+    while ((opt = def_getopt(argc, argv, "d:p:s:l:e:w:c:h", opts, "sched-sedf", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -5183,9 +5135,6 @@ int main_sched_sedf(int argc, char **arg
         case 'c':
             cpupool = optarg;
             break;
-        case 'h':
-            help("sched-sedf");
-            return 0;
         }
     }
 
@@ -5253,7 +5202,7 @@ int main_domid(int argc, char **argv)
     int opt;
     const char *domname = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", "domid", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "domid", 1)) != -1)
         return opt;
 
     domname = argv[optind];
@@ -5275,7 +5224,7 @@ int main_domname(int argc, char **argv)
     char *domname = NULL;
     char *endptr = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", "domname", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "domname", 1)) != -1)
         return opt;
 
     domid = strtol(argv[optind], &endptr, 10);
@@ -5303,7 +5252,7 @@ int main_rename(int argc, char **argv)
     int opt;
     const char *dom, *new_name;
 
-    if ((opt = def_getopt(argc, argv, "", "rename", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "rename", 2)) != -1)
         return opt;
 
     dom = argv[optind++];
@@ -5327,7 +5276,7 @@ int main_trigger(int argc, char **argv)
     const char *trigger_name = NULL;
     libxl_trigger trigger;
 
-    if ((opt = def_getopt(argc, argv, "", "trigger", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "trigger", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind++]);
@@ -5357,7 +5306,7 @@ int main_sysrq(int argc, char **argv)
     int opt;
     const char *sysrq = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", "sysrq", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "sysrq", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind++]);
@@ -5380,7 +5329,7 @@ int main_debug_keys(int argc, char **arg
     int opt;
     char *keys;
 
-    if ((opt = def_getopt(argc, argv, "", "debug-keys", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "debug-keys", 1)) != -1)
         return opt;
 
     keys = argv[optind];
@@ -5400,7 +5349,7 @@ int main_dmesg(int argc, char **argv)
     char *line;
     int opt, ret = 1;
 
-    while ((opt = def_getopt(argc, argv, "c", "dmesg", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "c", NULL, "dmesg", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -5426,7 +5375,7 @@ int main_top(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", "top", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "top", 0)) != -1)
         return opt;
 
     return system("xentop");
@@ -5443,7 +5392,7 @@ int main_networkattach(int argc, char **
     int i;
     unsigned int val;
 
-    if ((opt = def_getopt(argc, argv, "", "network-attach", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "network-attach", 1)) != -1)
         return opt;
 
     if (argc-optind > 11) {
@@ -5530,7 +5479,7 @@ int main_networklist(int argc, char **ar
     libxl_nicinfo nicinfo;
     int nb, i;
 
-    if ((opt = def_getopt(argc, argv, "", "network-list", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "network-list", 1)) != -1)
         return opt;
 
     /*      Idx  BE   MAC   Hdl  Sta  evch txr/rxr  BE-path */
@@ -5567,7 +5516,7 @@ int main_networkdetach(int argc, char **
     int opt;
     libxl_device_nic nic;
 
-    if ((opt = def_getopt(argc, argv, "", "network-detach", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "network-detach", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -5598,7 +5547,7 @@ int main_blockattach(int argc, char **ar
     libxl_device_disk disk = { 0 };
     XLU_Config *config = 0;
 
-    if ((opt = def_getopt(argc, argv, "", "block-attach", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "block-attach", 2)) != -1)
         return opt;
 
     if (domain_qualifier_to_domid(argv[optind], &fe_domid, 0) < 0) {
@@ -5633,7 +5582,7 @@ int main_blocklist(int argc, char **argv
     libxl_device_disk *disks;
     libxl_diskinfo diskinfo;
 
-    if ((opt = def_getopt(argc, argv, "", "block-list", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "block-list", 1)) != -1)
         return opt;
 
     printf("%-5s %-3s %-6s %-5s %-6s %-8s %-30s\n",
@@ -5669,7 +5618,7 @@ int main_blockdetach(int argc, char **ar
     int opt, rc = 0;
     libxl_device_disk disk;
 
-    if ((opt = def_getopt(argc, argv, "", "block-detach", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "block-detach", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -5694,7 +5643,7 @@ int main_vtpmattach(int argc, char **arg
     unsigned int val;
     uint32_t domid;
 
-    if ((opt = def_getopt(argc, argv, "", "vtpm-attach", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-attach", 1)) != -1)
         return opt;
 
     if (domain_qualifier_to_domid(argv[optind], &domid, 0) < 0) {
@@ -5747,7 +5696,7 @@ int main_vtpmlist(int argc, char **argv)
     libxl_vtpminfo vtpminfo;
     int nb, i;
 
-    if ((opt = def_getopt(argc, argv, "", "vtpm-list", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-list", 1)) != -1)
         return opt;
 
     /*      Idx  BE   UUID   Hdl  Sta  evch rref  BE-path */
@@ -5787,7 +5736,7 @@ int main_vtpmdetach(int argc, char **arg
     libxl_device_vtpm vtpm;
     libxl_uuid uuid;
 
-    if ((opt = def_getopt(argc, argv, "", "vtpm-detach", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-detach", 2)) != -1)
         return opt;
 
     domid = find_domain(argv[optind]);
@@ -5979,7 +5928,7 @@ int main_uptime(int argc, char **argv)
     int nb_doms = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "s", "uptime", 1)) != -1) {
+    while ((opt = def_getopt(argc, argv, "s", NULL, "uptime", 1)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6006,7 +5955,7 @@ int main_tmem_list(int argc, char **argv
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "al", "tmem-list", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "al", NULL, "tmem-list", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6047,7 +5996,7 @@ int main_tmem_freeze(int argc, char **ar
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "a", "tmem-freeze", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-freeze", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6080,7 +6029,7 @@ int main_tmem_thaw(int argc, char **argv
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "a", "tmem-thaw", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-thaw", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6115,7 +6064,7 @@ int main_tmem_set(int argc, char **argv)
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "aw:c:p:", "tmem-set", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "aw:c:p:", NULL, "tmem-set", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6176,7 +6125,7 @@ int main_tmem_shared_auth(int argc, char
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "au:A:", "tmem-shared-auth", 0)) != -1) {
+    while ((opt = def_getopt(argc, argv, "au:A:", NULL, "tmem-shared-auth", 0)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;
@@ -6226,7 +6175,7 @@ int main_tmem_freeable(int argc, char **
     int opt;
     int mb;
 
-    if ((opt = def_getopt(argc, argv, "", "tmem-freeable", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "tmem-freeable", 0)) != -1)
         return opt;
 
     mb = libxl_tmem_freeable(ctx);
@@ -6243,11 +6192,10 @@ int main_cpupoolcreate(int argc, char **
     const char *p;
     char extra_config[1024];
     int opt;
-    int option_index = 0;
-    static struct option long_options[] = {
-        {"help", 0, 0, 'h'},
+    static struct option opts[] = {
         {"defconfig", 1, 0, 'f'},
         {"dryrun", 0, 0, 'n'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
     int ret;
@@ -6265,26 +6213,18 @@ int main_cpupoolcreate(int argc, char **
     libxl_bitmap cpumap;
     libxl_uuid uuid;
     libxl_cputopology *topology;
-    int rc = -ERROR_FAIL; 
-
-    while (1) {
-        opt = getopt_long(argc, argv, "hnf:", long_options, &option_index);
-        if (opt == -1)
-            break;
-
+    int rc = -ERROR_FAIL;
+
+    while ((opt = def_getopt(argc, argv, "hnf:", opts, "cpupool-create", 0)) != -1) {
         switch (opt) {
+        case 0: case 2:
+            return opt;
         case 'f':
             filename = optarg;
             break;
-        case 'h':
-            help("cpupool-create");
-            return 0;
         case 'n':
             dryrun_only = 1;
             break;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
         }
     }
 
@@ -6447,10 +6387,9 @@ out:
 int main_cpupoollist(int argc, char **argv)
 {
     int opt;
-    int option_index = 0;
-    static struct option long_options[] = {
-        {"help", 0, 0, 'h'},
+    static struct option opts[] = {
         {"cpus", 0, 0, 'c'},
+        COMMON_LONG_OPTS,
         {0, 0, 0, 0}
     };
     int opt_cpus = 0;
@@ -6461,28 +6400,16 @@ int main_cpupoollist(int argc, char **ar
     char *name;
     int ret = 0;
 
-    while (1) {
-        opt = getopt_long(argc, argv, "hc", long_options, &option_index);
-        if (opt == -1)
+    while ((opt = def_getopt(argc, argv, "hc", opts, "cpupool-list", 1)) != -1) {
+        switch (opt) {
+        case 0: case 2:
             break;
-
-        switch (opt) {
-        case 'h':
-            help("cpupool-list");
-            return 0;
         case 'c':
             opt_cpus = 1;
             break;
-        default:
-            fprintf(stderr, "option `%c' not supported.\n", optopt);
-            break;
-        }
-    }
-
-    if ((optind + 1) < argc) {
-        help("cpupool-list");
-        return -ERROR_FAIL;
-    }
+        }
+    }
+
     if (optind < argc) {
         pool = argv[optind];
         if (libxl_name_to_cpupoolid(ctx, pool, &poolid)) {
@@ -6540,7 +6467,7 @@ int main_cpupooldestroy(int argc, char *
     const char *pool;
     uint32_t poolid;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-destroy", 1)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-destroy", 1)) != -1)
         return opt;
 
     pool = argv[optind];
@@ -6561,7 +6488,7 @@ int main_cpupoolrename(int argc, char **
     const char *new_name;
     uint32_t poolid;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-rename", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-rename", 2)) != -1)
         return opt;
 
     pool = argv[optind++];
@@ -6591,7 +6518,7 @@ int main_cpupoolcpuadd(int argc, char **
     int node;
     int n;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-cpu-add", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-add", 2)) != -1)
         return opt;
 
     pool = argv[optind++];
@@ -6635,7 +6562,7 @@ int main_cpupoolcpuremove(int argc, char
     int node;
     int n;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-cpu-remove", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-remove", 2)) != -1)
         return opt;
 
     pool = argv[optind++];
@@ -6678,7 +6605,7 @@ int main_cpupoolmigrate(int argc, char *
     const char *dom;
     uint32_t domid;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-migrate", 2)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-migrate", 2)) != -1)
         return opt;
 
     dom = argv[optind++];
@@ -6718,7 +6645,7 @@ int main_cpupoolnumasplit(int argc, char
     libxl_cputopology *topology;
     libxl_dominfo info;
 
-    if ((opt = def_getopt(argc, argv, "", "cpupool-numa-split", 0)) != -1)
+    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-numa-split", 0)) != -1)
         return opt;
     ret = 0;
 
@@ -6971,7 +6898,7 @@ int main_remus(int argc, char **argv)
     r_info.blackhole = 0;
     r_info.compression = 1;
 
-    while ((opt = def_getopt(argc, argv, "bui:s:e", "remus", 2)) != -1) {
+    while ((opt = def_getopt(argc, argv, "bui:s:e", NULL, "remus", 2)) != -1) {
         switch (opt) {
         case 0: case 2:
             return opt;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2 of 2] xl: Introduce helper macro for option parsing
  2012-11-30 11:21 [PATCH 0 of 2] xl: add helpers for option parsing Ian Campbell
  2012-11-30 11:21 ` [PATCH 1 of 2] xl: allow def_getopt to handle long options Ian Campbell
@ 2012-11-30 11:21 ` Ian Campbell
  2012-12-13 10:22   ` Ian Campbell
  2012-12-13 15:05   ` Ian Jackson
  1 sibling, 2 replies; 7+ messages in thread
From: Ian Campbell @ 2012-11-30 11:21 UTC (permalink / raw)
  To: xen-devel; +Cc: ian.jackson

# HG changeset patch
# User Ian Campbell <ijc@hellion.org.uk>
# Date 1354274264 0
# Node ID d4cc790b47d8735ae3f2b0c4707bfa58f90a2cd3
# Parent  b63fbacd5037e79bc4f40429453cb59816f94793
xl: Introduce helper macro for option parsing.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
v2:
- s/FOREACH_OPT/SWITCH_FOREACH_OPT/
- Document the macro

diff -r b63fbacd5037 -r d4cc790b47d8 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c	Fri Nov 30 11:17:44 2012 +0000
+++ b/tools/libxl/xl_cmdimpl.c	Fri Nov 30 11:17:44 2012 +0000
@@ -2297,6 +2297,10 @@ static int64_t parse_mem_size_kb(const c
 
 #define COMMON_LONG_OPTS {"help", 0, 0, 'h'}
 
+/*
+ * Callers should use SWITCH_FOREACH_OPT in preference to calling this
+ * directly.
+ */
 static int def_getopt(int argc, char * const argv[],
                       const char *optstring,
                       const struct option *longopts,
@@ -2335,6 +2339,57 @@ static int def_getopt(int argc, char * c
     return -1;
 }
 
+/*
+ * Wraps def_getopt into a convenient loop+switch to process all arguments.
+ *
+ * _opt:        an int variable, holds the current option during processing.
+ * _opts:       short options, as per getopt_long(3)'s optstring argument.
+ * _lopts:      long options, as per getopt_long(3)'s longopts argument. May
+ *              be null.
+ * _help:       name of this command, for usage string.
+ * _req:        number of non-option command line parameters which are required.
+ *
+ * In addition the calling context is expected to contain variables
+ * "argc" and "argv" in the conventional C-style:
+ *   main(int argc, char **argv)
+ * manner.
+ *
+ * Callers should treat SWITCH_FOREACH_OPT as they would a switch
+ * statement over the value of _opt. Each option given in _opts (or
+ * _lopts) should be handled by a case statement as if it were inside
+ * a switch statement.
+ *
+ * In addition to the options provided in _opts callers must handle
+ * two additional pseudo options:
+ *  0 -- generated if the user passes a -h option. help will be printed,
+ *       caller should return 0.
+ *  2 -- generated if the user does not provided _req non-option arguments,
+ *       caller should return 2.
+ *
+ * Example:
+ *
+ * int main_foo(int argc, char **argv) {
+ *     int opt;
+ *
+ *     SWITCH_FOREACH_OPT(opt, "blah", NULL, "foo", 0) {
+ *     case 0: case2:
+ *          return opt;
+ *      case 'b':
+ *          ... handle b option...
+ *          break;
+ *      case 'l':
+ *          ... handle l option ...
+ *          break;
+ *      case etc etc...
+ *      }
+ *      ... do something useful with the options ...
+ * }
+ */
+#define SWITCH_FOREACH_OPT(_opt, _opts, _lopts, _help, _req)    \
+    while (((_opt) = def_getopt(argc, argv, (_opts), (_lopts),  \
+                                (_help), (_req))) != -1)        \
+        switch (opt)
+
 static int set_memory_max(uint32_t domid, const char *mem)
 {
     int64_t memorykb;
@@ -2358,8 +2413,10 @@ int main_memmax(int argc, char **argv)
     char *mem;
     int rc;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "mem-max", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "mem-max", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
     mem = argv[optind + 1];
@@ -2392,8 +2449,10 @@ int main_memset(int argc, char **argv)
     int opt = 0;
     const char *mem;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "mem-set", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "mem-set", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
     mem = argv[optind + 1];
@@ -2431,8 +2490,10 @@ int main_cd_eject(int argc, char **argv)
     int opt = 0;
     const char *virtdev;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cd-eject", 2)) != -1)
-        return opt;
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cd-eject", 2) {
+        case 0: case 2:
+            return opt;
+    }
 
     domid = find_domain(argv[optind]);
     virtdev = argv[optind + 1];
@@ -2448,8 +2509,10 @@ int main_cd_insert(int argc, char **argv
     const char *virtdev;
     char *file = NULL; /* modified by cd_insert tokenising it */
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cd-insert", 3)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cd-insert", 3) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
     virtdev = argv[optind + 1];
@@ -2465,24 +2528,22 @@ int main_console(int argc, char **argv)
     int opt = 0, num = 0;
     libxl_console_type type = 0;
 
-    while ((opt = def_getopt(argc, argv, "n:t:", NULL, "console", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 't':
-            if (!strcmp(optarg, "pv"))
-                type = LIBXL_CONSOLE_TYPE_PV;
-            else if (!strcmp(optarg, "serial"))
-                type = LIBXL_CONSOLE_TYPE_SERIAL;
-            else {
-                fprintf(stderr, "console type supported are: pv, serial\n");
-                return 2;
-            }
-            break;
-        case 'n':
-            num = atoi(optarg);
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "n:t:", NULL, "console", 1) {
+    case 0: case 2:
+        return opt;
+    case 't':
+        if (!strcmp(optarg, "pv"))
+            type = LIBXL_CONSOLE_TYPE_PV;
+        else if (!strcmp(optarg, "serial"))
+            type = LIBXL_CONSOLE_TYPE_SERIAL;
+        else {
+            fprintf(stderr, "console type supported are: pv, serial\n");
+            return 2;
+        }
+        break;
+    case 'n':
+        num = atoi(optarg);
+        break;
     }
 
     domid = find_domain(argv[optind]);
@@ -2505,14 +2566,12 @@ int main_vncviewer(int argc, char **argv
     uint32_t domid;
     int opt, autopass = 0;
 
-    while ((opt = def_getopt(argc, argv, "ah", opts, "vncviewer", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            autopass = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "ah", opts, "vncviewer", 1) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        autopass = 1;
+        break;
     }
 
     domid = find_domain(argv[optind]);
@@ -2545,8 +2604,10 @@ int main_pcilist(int argc, char **argv)
     uint32_t domid;
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "pci-list", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-list", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
 
@@ -2584,14 +2645,12 @@ int main_pcidetach(int argc, char **argv
     int force = 0;
     const char *bdf = NULL;
 
-    while ((opt = def_getopt(argc, argv, "f", NULL, "pci-detach", 2)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'f':
-            force = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
+    case 0: case 2:
+        return opt;
+    case 'f':
+        force = 1;
+        break;
     }
 
     domid = find_domain(argv[optind]);
@@ -2626,8 +2685,10 @@ int main_pciattach(int argc, char **argv
     int opt;
     const char *bdf = NULL, *vs = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "pci-attach", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
     bdf = argv[optind + 1];
@@ -2660,8 +2721,10 @@ int main_pciassignable_list(int argc, ch
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-list", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     pciassignable_list();
     return 0;
@@ -2692,11 +2755,9 @@ int main_pciassignable_add(int argc, cha
     int opt;
     const char *bdf = NULL;
 
-    while ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-add", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        }
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
+    case 0: case 2:
+        return opt;
     }
 
     bdf = argv[optind];
@@ -2731,14 +2792,12 @@ int main_pciassignable_remove(int argc, 
     const char *bdf = NULL;
     int rebind = 0;
 
-    while ((opt = def_getopt(argc, argv, "r", NULL, "pci-assignable-remove", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'r':
-            rebind=1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
+    case 0: case 2:
+        return opt;
+    case 'r':
+        rebind=1;
+        break;
     }
 
     bdf = argv[optind];
@@ -3549,34 +3608,31 @@ int main_restore(int argc, char **argv)
         {0, 0, 0, 0}
     };
 
-    while ((opt = def_getopt(argc, argv, "FhcpdeVA",
-                             opts, "restore", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'c':
-            console_autoconnect = 1;
-            break;
-        case 'p':
-            paused = 1;
-            break;
-        case 'd':
-            debug = 1;
-            break;
-        case 'F':
-            daemonize = 0;
-            break;
-        case 'e':
-            daemonize = 0;
-            monitor = 0;
-            break;
-        case 'V':
-            vnc = 1;
-            break;
-        case 'A':
-            vnc = vncautopass = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "FhcpdeVA", opts, "restore", 1) {
+    case 0: case 2:
+        return opt;
+    case 'c':
+        console_autoconnect = 1;
+        break;
+    case 'p':
+        paused = 1;
+        break;
+    case 'd':
+        debug = 1;
+        break;
+    case 'F':
+        daemonize = 0;
+        break;
+    case 'e':
+        daemonize = 0;
+        monitor = 0;
+        break;
+    case 'V':
+        vnc = 1;
+        break;
+    case 'A':
+        vnc = vncautopass = 1;
+        break;
     }
 
     if (argc-optind == 1) {
@@ -3613,24 +3669,22 @@ int main_migrate_receive(int argc, char 
     int debug = 0, daemonize = 1, monitor = 1, remus = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "Fedr", NULL, "migrate-receive", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'F':
-            daemonize = 0;
-            break;
-        case 'e':
-            daemonize = 0;
-            monitor = 0;
-            break;
-        case 'd':
-            debug = 1;
-            break;
-        case 'r':
-            remus = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "Fedr", NULL, "migrate-receive", 0) {
+    case 0: case 2:
+        return opt;
+    case 'F':
+        daemonize = 0;
+        break;
+    case 'e':
+        daemonize = 0;
+        monitor = 0;
+        break;
+    case 'd':
+        debug = 1;
+        break;
+    case 'r':
+        remus = 1;
+        break;
     }
 
     if (argc-optind != 0) {
@@ -3652,14 +3706,12 @@ int main_save(int argc, char **argv)
     int checkpoint = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "c", NULL, "save", 2)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'c':
-            checkpoint = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "c", NULL, "save", 2) {
+    case 0: case 2:
+        return opt;
+    case 'c':
+        checkpoint = 1;
+        break;
     }
 
     if (argc-optind > 3) {
@@ -3685,27 +3737,25 @@ int main_migrate(int argc, char **argv)
     char *host;
     int opt, daemonize = 1, monitor = 1, debug = 0;
 
-    while ((opt = def_getopt(argc, argv, "FC:s:ed", NULL, "migrate", 2)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'C':
-            config_filename = optarg;
-            break;
-        case 's':
-            ssh_command = optarg;
-            break;
-        case 'F':
-            daemonize = 0;
-            break;
-        case 'e':
-            daemonize = 0;
-            monitor = 0;
-            break;
-        case 'd':
-            debug = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "FC:s:ed", NULL, "migrate", 2) {
+    case 0: case 2:
+        return opt;
+    case 'C':
+        config_filename = optarg;
+        break;
+    case 's':
+        ssh_command = optarg;
+        break;
+    case 'F':
+        daemonize = 0;
+        break;
+    case 'e':
+        daemonize = 0;
+        monitor = 0;
+        break;
+    case 'd':
+        debug = 1;
+        break;
     }
 
     domid = find_domain(argv[optind]);
@@ -3729,8 +3779,10 @@ int main_dump_core(int argc, char **argv
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "dump-core", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "dump-core", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     core_dump_domain(find_domain(argv[optind]), argv[optind + 1]);
     return 0;
@@ -3740,8 +3792,10 @@ int main_pause(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "pause", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "pause", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     pause_domain(find_domain(argv[optind]));
 
@@ -3752,8 +3806,10 @@ int main_unpause(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "unpause", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "unpause", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     unpause_domain(find_domain(argv[optind]));
 
@@ -3764,8 +3820,10 @@ int main_destroy(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "destroy", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "destroy", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     destroy_domain(find_domain(argv[optind]));
     return 0;
@@ -3787,20 +3845,18 @@ static int main_shutdown_or_reboot(int d
         {0, 0, 0, 0}
     };
 
-    while ((opt = def_getopt(argc, argv, "awF", opts, what, 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            all = 1;
-            break;
-        case 'w':
-            wait_for_it = 1;
-            break;
-        case 'F':
-            fallback_trigger = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "awF", opts, what, 0) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        all = 1;
+        break;
+    case 'w':
+        wait_for_it = 1;
+        break;
+    case 'F':
+        fallback_trigger = 1;
+        break;
     }
 
     if (!argv[optind] && !all) {
@@ -3871,23 +3927,18 @@ int main_list(int argc, char **argv)
     libxl_dominfo *info, *info_free=0;
     int nb_domain, rc;
 
-    while ((opt = def_getopt(argc, argv, "lvhZ", opts, "list", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'l':
-            details = 1;
-            break;
-        case 'h':
-            help("list");
-            return 0;
-        case 'v':
-            verbose = 1;
-            break;
-        case 'Z':
-            context = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "lvhZ", opts, "list", 0) {
+    case 0: case 2:
+        return opt;
+    case 'l':
+        details = 1;
+        break;
+    case 'v':
+        verbose = 1;
+        break;
+    case 'Z':
+        context = 1;
+        break;
     }
 
     if (optind >= argc) {
@@ -3933,8 +3984,10 @@ int main_vm_list(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vm-list", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vm-list", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     list_vm();
     return 0;
@@ -3964,45 +4017,40 @@ int main_create(int argc, char **argv)
         argc--; argv++;
     }
 
-    while ((opt = def_getopt(argc, argv, "Fhnqf:pcdeVA", opts, "create", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'f':
-            filename = optarg;
-            break;
-        case 'p':
-            paused = 1;
-            break;
-        case 'c':
-            console_autoconnect = 1;
-            break;
-        case 'd':
-            debug = 1;
-            break;
-        case 'F':
-            daemonize = 0;
-            break;
-        case 'e':
-            daemonize = 0;
-            monitor = 0;
-            break;
-        case 'h':
-            help("create");
-            return 0;
-        case 'n':
-            dryrun_only = 1;
-            break;
-        case 'q':
-            quiet = 1;
-            break;
-        case 'V':
-            vnc = 1;
-            break;
-        case 'A':
-            vnc = vncautopass = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "Fhnqf:pcdeVA", opts, "create", 0) {
+    case 0: case 2:
+        return opt;
+    case 'f':
+        filename = optarg;
+        break;
+    case 'p':
+        paused = 1;
+        break;
+    case 'c':
+        console_autoconnect = 1;
+        break;
+    case 'd':
+        debug = 1;
+        break;
+    case 'F':
+        daemonize = 0;
+        break;
+    case 'e':
+        daemonize = 0;
+        monitor = 0;
+        break;
+    case 'n':
+        dryrun_only = 1;
+        break;
+    case 'q':
+        quiet = 1;
+        break;
+    case 'V':
+        vnc = 1;
+        break;
+    case 'A':
+        vnc = vncautopass = 1;
+        break;
     }
 
     extra_config[0] = '\0';
@@ -4070,17 +4118,15 @@ int main_config_update(int argc, char **
         argc--; argv++;
     }
 
-    while ((opt = def_getopt(argc, argv, "dhqf:", opts, "config_update", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'd':
-            debug = 1;
-            break;
-        case 'f':
-            filename = optarg;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "dhqf:", opts, "config_update", 0) {
+    case 0: case 2:
+        return opt;
+    case 'd':
+        debug = 1;
+        break;
+    case 'f':
+        filename = optarg;
+        break;
     }
 
     extra_config[0] = '\0';
@@ -4168,8 +4214,11 @@ int main_button_press(int argc, char **a
     fprintf(stderr, "WARNING: \"button-press\" is deprecated. "
             "Please use \"trigger\"\n");
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "button-press", 2)) != -1)
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "button-press", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     button_press(find_domain(argv[optind]), argv[optind + 1]);
 
@@ -4309,8 +4358,10 @@ int main_vcpulist(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpu-list", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpu-list", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     vcpulist(argc - optind, argv + optind);
     return 0;
@@ -4370,8 +4421,10 @@ int main_vcpupin(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-pin", 3)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vcpu-pin", 3) {
+    case 0: case 2:
         return opt;
+    }
 
     vcpupin(find_domain(argv[optind]), argv[optind+1] , argv[optind+2]);
     return 0;
@@ -4406,8 +4459,10 @@ int main_vcpuset(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-set", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vcpu-set", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     vcpuset(find_domain(argv[optind]), argv[optind+1]);
     return 0;
@@ -4589,14 +4644,12 @@ int main_info(int argc, char **argv)
     };
     int numa = 0;
 
-    while ((opt = def_getopt(argc, argv, "hn", opts, "info", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'n':
-            numa = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "hn", opts, "info", 0) {
+    case 0: case 2:
+        return opt;
+    case 'n':
+        numa = 1;
+        break;
     }
 
     print_info(numa);
@@ -4630,8 +4683,10 @@ int main_sharing(int argc, char **argv)
     libxl_dominfo *info, *info_free = NULL;
     int nb_domain, rc;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "sharing", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "sharing", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     if (optind >= argc) {
         info = libxl_list_domain(ctx, &nb_domain);
@@ -4911,36 +4966,34 @@ int main_sched_credit(int argc, char **a
         {0, 0, 0, 0}
     };
 
-    while ((opt = def_getopt(argc, argv, "d:w:c:p:t:r:hs", opts, "sched-credit", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'd':
-            dom = optarg;
-            break;
-        case 'w':
-            weight = strtol(optarg, NULL, 10);
-            opt_w = 1;
-            break;
-        case 'c':
-            cap = strtol(optarg, NULL, 10);
-            opt_c = 1;
-            break;
-        case 't':
-            tslice = strtol(optarg, NULL, 10);
-            opt_t = 1;
-            break;
-        case 'r':
-            ratelimit = strtol(optarg, NULL, 10);
-            opt_r = 1;
-            break;
-        case 's':
-            opt_s = 1;
-            break;
-        case 'p':
-            cpupool = optarg;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:hs", opts, "sched-credit", 0) {
+    case 0: case 2:
+        return opt;
+    case 'd':
+        dom = optarg;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = 1;
+        break;
+    case 'c':
+        cap = strtol(optarg, NULL, 10);
+        opt_c = 1;
+        break;
+    case 't':
+        tslice = strtol(optarg, NULL, 10);
+        opt_t = 1;
+        break;
+    case 'r':
+        ratelimit = strtol(optarg, NULL, 10);
+        opt_r = 1;
+        break;
+    case 's':
+        opt_s = 1;
+        break;
+    case 'p':
+        cpupool = optarg;
+        break;
     }
 
     if ((cpupool || opt_s) && (dom || opt_w || opt_c)) {
@@ -5030,21 +5083,19 @@ int main_sched_credit2(int argc, char **
         {0, 0, 0, 0}
     };
 
-    while ((opt = def_getopt(argc, argv, "d:w:p:h", opts, "sched-credit2", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'd':
-            dom = optarg;
-            break;
-        case 'w':
-            weight = strtol(optarg, NULL, 10);
-            opt_w = 1;
-            break;
-        case 'p':
-            cpupool = optarg;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "d:w:p:h", opts, "sched-credit2", 0) {
+    case 0: case 2:
+        return opt;
+    case 'd':
+        dom = optarg;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = 1;
+        break;
+    case 'p':
+        cpupool = optarg;
+        break;
     }
 
     if (cpupool && (dom || opt_w)) {
@@ -5105,37 +5156,35 @@ int main_sched_sedf(int argc, char **arg
         {0, 0, 0, 0}
     };
 
-    while ((opt = def_getopt(argc, argv, "d:p:s:l:e:w:c:h", opts, "sched-sedf", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'd':
-            dom = optarg;
-            break;
-        case 'p':
-            period = strtol(optarg, NULL, 10);
-            opt_p = 1;
-            break;
-        case 's':
-            slice = strtol(optarg, NULL, 10);
-            opt_s = 1;
-            break;
-        case 'l':
-            latency = strtol(optarg, NULL, 10);
-            opt_l = 1;
-            break;
-        case 'e':
-            extra = strtol(optarg, NULL, 10);
-            opt_e = 1;
-            break;
-        case 'w':
-            weight = strtol(optarg, NULL, 10);
-            opt_w = 1;
-            break;
-        case 'c':
-            cpupool = optarg;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "d:p:s:l:e:w:c:h", opts, "sched-sedf", 0) {
+    case 0: case 2:
+        return opt;
+    case 'd':
+        dom = optarg;
+        break;
+    case 'p':
+        period = strtol(optarg, NULL, 10);
+        opt_p = 1;
+        break;
+    case 's':
+        slice = strtol(optarg, NULL, 10);
+        opt_s = 1;
+        break;
+    case 'l':
+        latency = strtol(optarg, NULL, 10);
+        opt_l = 1;
+        break;
+    case 'e':
+        extra = strtol(optarg, NULL, 10);
+        opt_e = 1;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = 1;
+        break;
+    case 'c':
+        cpupool = optarg;
+        break;
     }
 
     if (cpupool && (dom || opt_p || opt_s || opt_l || opt_e || opt_w)) {
@@ -5202,8 +5251,10 @@ int main_domid(int argc, char **argv)
     int opt;
     const char *domname = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "domid", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "domid", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     domname = argv[optind];
 
@@ -5224,8 +5275,10 @@ int main_domname(int argc, char **argv)
     char *domname = NULL;
     char *endptr = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "domname", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "domname", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = strtol(argv[optind], &endptr, 10);
     if (domid == 0 && !strcmp(endptr, argv[optind])) {
@@ -5252,8 +5305,10 @@ int main_rename(int argc, char **argv)
     int opt;
     const char *dom, *new_name;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "rename", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "rename", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     dom = argv[optind++];
     new_name = argv[optind];
@@ -5276,8 +5331,10 @@ int main_trigger(int argc, char **argv)
     const char *trigger_name = NULL;
     libxl_trigger trigger;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "trigger", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "trigger", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind++]);
 
@@ -5306,8 +5363,10 @@ int main_sysrq(int argc, char **argv)
     int opt;
     const char *sysrq = NULL;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "sysrq", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "sysrq", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind++]);
 
@@ -5329,8 +5388,10 @@ int main_debug_keys(int argc, char **arg
     int opt;
     char *keys;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "debug-keys", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "debug-keys", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     keys = argv[optind];
 
@@ -5349,14 +5410,12 @@ int main_dmesg(int argc, char **argv)
     char *line;
     int opt, ret = 1;
 
-    while ((opt = def_getopt(argc, argv, "c", NULL, "dmesg", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'c':
-            clear = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "c", NULL, "dmesg", 0) {
+    case 0: case 2:
+        return opt;
+    case 'c':
+        clear = 1;
+        break;
     }
 
     cr = libxl_xen_console_read_start(ctx, clear);
@@ -5375,8 +5434,10 @@ int main_top(int argc, char **argv)
 {
     int opt;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "top", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "top", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     return system("xentop");
 }
@@ -5392,8 +5453,10 @@ int main_networkattach(int argc, char **
     int i;
     unsigned int val;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "network-attach", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "network-attach", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     if (argc-optind > 11) {
         help("network-attach");
@@ -5479,8 +5542,10 @@ int main_networklist(int argc, char **ar
     libxl_nicinfo nicinfo;
     int nb, i;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "network-list", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "network-list", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     /*      Idx  BE   MAC   Hdl  Sta  evch txr/rxr  BE-path */
     printf("%-3s %-2s %-17s %-6s %-5s %-6s %5s/%-5s %-30s\n",
@@ -5516,8 +5581,10 @@ int main_networkdetach(int argc, char **
     int opt;
     libxl_device_nic nic;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "network-detach", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "network-detach", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
 
@@ -5547,8 +5614,10 @@ int main_blockattach(int argc, char **ar
     libxl_device_disk disk = { 0 };
     XLU_Config *config = 0;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "block-attach", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "block-attach", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     if (domain_qualifier_to_domid(argv[optind], &fe_domid, 0) < 0) {
         fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
@@ -5582,8 +5651,10 @@ int main_blocklist(int argc, char **argv
     libxl_device_disk *disks;
     libxl_diskinfo diskinfo;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "block-list", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "block-list", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     printf("%-5s %-3s %-6s %-5s %-6s %-8s %-30s\n",
            "Vdev", "BE", "handle", "state", "evt-ch", "ring-ref", "BE-path");
@@ -5618,8 +5689,10 @@ int main_blockdetach(int argc, char **ar
     int opt, rc = 0;
     libxl_device_disk disk;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "block-detach", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "block-detach", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
 
@@ -5643,8 +5716,10 @@ int main_vtpmattach(int argc, char **arg
     unsigned int val;
     uint32_t domid;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-attach", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-attach", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     if (domain_qualifier_to_domid(argv[optind], &domid, 0) < 0) {
         fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
@@ -5696,8 +5771,10 @@ int main_vtpmlist(int argc, char **argv)
     libxl_vtpminfo vtpminfo;
     int nb, i;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-list", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-list", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     /*      Idx  BE   UUID   Hdl  Sta  evch rref  BE-path */
     printf("%-3s %-2s %-36s %-6s %-5s %-6s %-5s %-10s\n",
@@ -5736,8 +5813,10 @@ int main_vtpmdetach(int argc, char **arg
     libxl_device_vtpm vtpm;
     libxl_uuid uuid;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-detach", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-detach", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     domid = find_domain(argv[optind]);
 
@@ -5928,14 +6007,12 @@ int main_uptime(int argc, char **argv)
     int nb_doms = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "s", NULL, "uptime", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 's':
-            short_mode = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "s", NULL, "uptime", 1) {
+    case 0: case 2:
+        return opt;
+    case 's':
+        short_mode = 1;
+        break;
     }
 
     for (;(dom = argv[optind]) != NULL; nb_doms++,optind++)
@@ -5955,17 +6032,15 @@ int main_tmem_list(int argc, char **argv
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "al", NULL, "tmem-list", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'l':
-            use_long = 1;
-            break;
-        case 'a':
-            all = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "al", NULL, "tmem-list", 0) {
+    case 0: case 2:
+        return opt;
+    case 'l':
+        use_long = 1;
+        break;
+    case 'a':
+        all = 1;
+        break;
     }
 
     dom = argv[optind];
@@ -5996,14 +6071,12 @@ int main_tmem_freeze(int argc, char **ar
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-freeze", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            all = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "a", NULL, "tmem-freeze", 0) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        all = 1;
+        break;
     }
 
     dom = argv[optind];
@@ -6029,14 +6102,12 @@ int main_tmem_thaw(int argc, char **argv
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-thaw", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            all = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "a", NULL, "tmem-thaw", 0) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        all = 1;
+        break;
     }
 
     dom = argv[optind];
@@ -6064,26 +6135,24 @@ int main_tmem_set(int argc, char **argv)
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "aw:c:p:", NULL, "tmem-set", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            all = 1;
-            break;
-        case 'w':
-            weight = strtol(optarg, NULL, 10);
-            opt_w = 1;
-            break;
-        case 'c':
-            cap = strtol(optarg, NULL, 10);
-            opt_c = 1;
-            break;
-        case 'p':
-            compress = strtol(optarg, NULL, 10);
-            opt_p = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "aw:c:p:", NULL, "tmem-set", 0) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        all = 1;
+        break;
+    case 'w':
+        weight = strtol(optarg, NULL, 10);
+        opt_w = 1;
+        break;
+    case 'c':
+        cap = strtol(optarg, NULL, 10);
+        opt_c = 1;
+        break;
+    case 'p':
+        compress = strtol(optarg, NULL, 10);
+        opt_p = 1;
+        break;
     }
 
     dom = argv[optind];
@@ -6125,20 +6194,18 @@ int main_tmem_shared_auth(int argc, char
     int all = 0;
     int opt;
 
-    while ((opt = def_getopt(argc, argv, "au:A:", NULL, "tmem-shared-auth", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'a':
-            all = 1;
-            break;
-        case 'u':
-            uuid = optarg;
-            break;
-        case 'A':
-            autharg = optarg;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "au:A:", NULL, "tmem-shared-auth", 0) {
+    case 0: case 2:
+        return opt;
+    case 'a':
+        all = 1;
+        break;
+    case 'u':
+        uuid = optarg;
+        break;
+    case 'A':
+        autharg = optarg;
+        break;
     }
 
     dom = argv[optind];
@@ -6175,8 +6242,10 @@ int main_tmem_freeable(int argc, char **
     int opt;
     int mb;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "tmem-freeable", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "tmem-freeale", 0) {
+    case 0: case 2:
         return opt;
+    }
 
     mb = libxl_tmem_freeable(ctx);
     if (mb == -1)
@@ -6215,17 +6284,15 @@ int main_cpupoolcreate(int argc, char **
     libxl_cputopology *topology;
     int rc = -ERROR_FAIL;
 
-    while ((opt = def_getopt(argc, argv, "hnf:", opts, "cpupool-create", 0)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-        case 'f':
-            filename = optarg;
-            break;
-        case 'n':
-            dryrun_only = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "hnf:", opts, "cpupool-create", 0) {
+    case 0: case 2:
+        return opt;
+    case 'f':
+        filename = optarg;
+        break;
+    case 'n':
+        dryrun_only = 1;
+        break;
     }
 
     memset(extra_config, 0, sizeof(extra_config));
@@ -6400,14 +6467,12 @@ int main_cpupoollist(int argc, char **ar
     char *name;
     int ret = 0;
 
-    while ((opt = def_getopt(argc, argv, "hc", opts, "cpupool-list", 1)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            break;
-        case 'c':
-            opt_cpus = 1;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "hc", opts, "cpupool-list", 1) {
+    case 0: case 2:
+        break;
+    case 'c':
+        opt_cpus = 1;
+        break;
     }
 
     if (optind < argc) {
@@ -6467,8 +6532,10 @@ int main_cpupooldestroy(int argc, char *
     const char *pool;
     uint32_t poolid;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-destroy", 1)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-destroy", 1) {
+    case 0: case 2:
         return opt;
+    }
 
     pool = argv[optind];
 
@@ -6488,8 +6555,10 @@ int main_cpupoolrename(int argc, char **
     const char *new_name;
     uint32_t poolid;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-rename", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-rename", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     pool = argv[optind++];
 
@@ -6518,8 +6587,10 @@ int main_cpupoolcpuadd(int argc, char **
     int node;
     int n;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-add", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-cpu-add", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     pool = argv[optind++];
     node = -1;
@@ -6562,8 +6633,10 @@ int main_cpupoolcpuremove(int argc, char
     int node;
     int n;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-remove", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-cpu-remove", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     pool = argv[optind++];
     node = -1;
@@ -6605,8 +6678,10 @@ int main_cpupoolmigrate(int argc, char *
     const char *dom;
     uint32_t domid;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-migrate", 2)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-migrate", 2) {
+    case 0: case 2:
         return opt;
+    }
 
     dom = argv[optind++];
     pool = argv[optind];
@@ -6645,8 +6720,11 @@ int main_cpupoolnumasplit(int argc, char
     libxl_cputopology *topology;
     libxl_dominfo info;
 
-    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-numa-split", 0)) != -1)
+    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-numa-split", 0) {
+    case 0: case 2:
         return opt;
+    }
+
     ret = 0;
 
     poolinfo = libxl_list_cpupool(ctx, &n_pools);
@@ -6898,27 +6976,24 @@ int main_remus(int argc, char **argv)
     r_info.blackhole = 0;
     r_info.compression = 1;
 
-    while ((opt = def_getopt(argc, argv, "bui:s:e", NULL, "remus", 2)) != -1) {
-        switch (opt) {
-        case 0: case 2:
-            return opt;
-
-        case 'i':
-	    r_info.interval = atoi(optarg);
-            break;
-        case 'b':
-            r_info.blackhole = 1;
-            break;
-        case 'u':
-	    r_info.compression = 0;
-            break;
-        case 's':
-            ssh_command = optarg;
-            break;
-        case 'e':
-            daemonize = 0;
-            break;
-        }
+    SWITCH_FOREACH_OPT(opt, "bui:s:e", NULL, "remus", 2) {
+    case 0: case 2:
+        return opt;
+    case 'i':
+        r_info.interval = atoi(optarg);
+        break;
+    case 'b':
+        r_info.blackhole = 1;
+        break;
+    case 'u':
+        r_info.compression = 0;
+        break;
+    case 's':
+        ssh_command = optarg;
+        break;
+    case 'e':
+        daemonize = 0;
+        break;
     }
 
     domid = find_domain(argv[optind]);

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2 of 2] xl: Introduce helper macro for option parsing
  2012-11-30 11:21 ` [PATCH 2 of 2] xl: Introduce helper macro for option parsing Ian Campbell
@ 2012-12-13 10:22   ` Ian Campbell
  2012-12-13 15:05   ` Ian Jackson
  1 sibling, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2012-12-13 10:22 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Jackson

ping?

On Fri, 2012-11-30 at 11:21 +0000, Ian Campbell wrote:
> # HG changeset patch
> # User Ian Campbell <ijc@hellion.org.uk>
> # Date 1354274264 0
> # Node ID d4cc790b47d8735ae3f2b0c4707bfa58f90a2cd3
> # Parent  b63fbacd5037e79bc4f40429453cb59816f94793
> xl: Introduce helper macro for option parsing.
> 
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
> v2:
> - s/FOREACH_OPT/SWITCH_FOREACH_OPT/
> - Document the macro
> 
> diff -r b63fbacd5037 -r d4cc790b47d8 tools/libxl/xl_cmdimpl.c
> --- a/tools/libxl/xl_cmdimpl.c  Fri Nov 30 11:17:44 2012 +0000
> +++ b/tools/libxl/xl_cmdimpl.c  Fri Nov 30 11:17:44 2012 +0000
> @@ -2297,6 +2297,10 @@ static int64_t parse_mem_size_kb(const c
> 
>  #define COMMON_LONG_OPTS {"help", 0, 0, 'h'}
> 
> +/*
> + * Callers should use SWITCH_FOREACH_OPT in preference to calling this
> + * directly.
> + */
>  static int def_getopt(int argc, char * const argv[],
>                        const char *optstring,
>                        const struct option *longopts,
> @@ -2335,6 +2339,57 @@ static int def_getopt(int argc, char * c
>      return -1;
>  }
> 
> +/*
> + * Wraps def_getopt into a convenient loop+switch to process all arguments.
> + *
> + * _opt:        an int variable, holds the current option during processing.
> + * _opts:       short options, as per getopt_long(3)'s optstring argument.
> + * _lopts:      long options, as per getopt_long(3)'s longopts argument. May
> + *              be null.
> + * _help:       name of this command, for usage string.
> + * _req:        number of non-option command line parameters which are required.
> + *
> + * In addition the calling context is expected to contain variables
> + * "argc" and "argv" in the conventional C-style:
> + *   main(int argc, char **argv)
> + * manner.
> + *
> + * Callers should treat SWITCH_FOREACH_OPT as they would a switch
> + * statement over the value of _opt. Each option given in _opts (or
> + * _lopts) should be handled by a case statement as if it were inside
> + * a switch statement.
> + *
> + * In addition to the options provided in _opts callers must handle
> + * two additional pseudo options:
> + *  0 -- generated if the user passes a -h option. help will be printed,
> + *       caller should return 0.
> + *  2 -- generated if the user does not provided _req non-option arguments,
> + *       caller should return 2.
> + *
> + * Example:
> + *
> + * int main_foo(int argc, char **argv) {
> + *     int opt;
> + *
> + *     SWITCH_FOREACH_OPT(opt, "blah", NULL, "foo", 0) {
> + *     case 0: case2:
> + *          return opt;
> + *      case 'b':
> + *          ... handle b option...
> + *          break;
> + *      case 'l':
> + *          ... handle l option ...
> + *          break;
> + *      case etc etc...
> + *      }
> + *      ... do something useful with the options ...
> + * }
> + */
> +#define SWITCH_FOREACH_OPT(_opt, _opts, _lopts, _help, _req)    \
> +    while (((_opt) = def_getopt(argc, argv, (_opts), (_lopts),  \
> +                                (_help), (_req))) != -1)        \
> +        switch (opt)
> +
>  static int set_memory_max(uint32_t domid, const char *mem)
>  {
>      int64_t memorykb;
> @@ -2358,8 +2413,10 @@ int main_memmax(int argc, char **argv)
>      char *mem;
>      int rc;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "mem-max", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "mem-max", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
>      mem = argv[optind + 1];
> @@ -2392,8 +2449,10 @@ int main_memset(int argc, char **argv)
>      int opt = 0;
>      const char *mem;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "mem-set", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "mem-set", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
>      mem = argv[optind + 1];
> @@ -2431,8 +2490,10 @@ int main_cd_eject(int argc, char **argv)
>      int opt = 0;
>      const char *virtdev;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cd-eject", 2)) != -1)
> -        return opt;
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cd-eject", 2) {
> +        case 0: case 2:
> +            return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
>      virtdev = argv[optind + 1];
> @@ -2448,8 +2509,10 @@ int main_cd_insert(int argc, char **argv
>      const char *virtdev;
>      char *file = NULL; /* modified by cd_insert tokenising it */
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cd-insert", 3)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cd-insert", 3) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
>      virtdev = argv[optind + 1];
> @@ -2465,24 +2528,22 @@ int main_console(int argc, char **argv)
>      int opt = 0, num = 0;
>      libxl_console_type type = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "n:t:", NULL, "console", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 't':
> -            if (!strcmp(optarg, "pv"))
> -                type = LIBXL_CONSOLE_TYPE_PV;
> -            else if (!strcmp(optarg, "serial"))
> -                type = LIBXL_CONSOLE_TYPE_SERIAL;
> -            else {
> -                fprintf(stderr, "console type supported are: pv, serial\n");
> -                return 2;
> -            }
> -            break;
> -        case 'n':
> -            num = atoi(optarg);
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "n:t:", NULL, "console", 1) {
> +    case 0: case 2:
> +        return opt;
> +    case 't':
> +        if (!strcmp(optarg, "pv"))
> +            type = LIBXL_CONSOLE_TYPE_PV;
> +        else if (!strcmp(optarg, "serial"))
> +            type = LIBXL_CONSOLE_TYPE_SERIAL;
> +        else {
> +            fprintf(stderr, "console type supported are: pv, serial\n");
> +            return 2;
> +        }
> +        break;
> +    case 'n':
> +        num = atoi(optarg);
> +        break;
>      }
> 
>      domid = find_domain(argv[optind]);
> @@ -2505,14 +2566,12 @@ int main_vncviewer(int argc, char **argv
>      uint32_t domid;
>      int opt, autopass = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "ah", opts, "vncviewer", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            autopass = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "ah", opts, "vncviewer", 1) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        autopass = 1;
> +        break;
>      }
> 
>      domid = find_domain(argv[optind]);
> @@ -2545,8 +2604,10 @@ int main_pcilist(int argc, char **argv)
>      uint32_t domid;
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "pci-list", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-list", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
> 
> @@ -2584,14 +2645,12 @@ int main_pcidetach(int argc, char **argv
>      int force = 0;
>      const char *bdf = NULL;
> 
> -    while ((opt = def_getopt(argc, argv, "f", NULL, "pci-detach", 2)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'f':
> -            force = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "f", NULL, "pci-detach", 2) {
> +    case 0: case 2:
> +        return opt;
> +    case 'f':
> +        force = 1;
> +        break;
>      }
> 
>      domid = find_domain(argv[optind]);
> @@ -2626,8 +2685,10 @@ int main_pciattach(int argc, char **argv
>      int opt;
>      const char *bdf = NULL, *vs = NULL;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "pci-attach", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-attach", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
>      bdf = argv[optind + 1];
> @@ -2660,8 +2721,10 @@ int main_pciassignable_list(int argc, ch
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-list", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-list", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pciassignable_list();
>      return 0;
> @@ -2692,11 +2755,9 @@ int main_pciassignable_add(int argc, cha
>      int opt;
>      const char *bdf = NULL;
> 
> -    while ((opt = def_getopt(argc, argv, "", NULL, "pci-assignable-add", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "pci-assignable-add", 1) {
> +    case 0: case 2:
> +        return opt;
>      }
> 
>      bdf = argv[optind];
> @@ -2731,14 +2792,12 @@ int main_pciassignable_remove(int argc,
>      const char *bdf = NULL;
>      int rebind = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "r", NULL, "pci-assignable-remove", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'r':
> -            rebind=1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "r", NULL, "pci-assignable-remove", 1) {
> +    case 0: case 2:
> +        return opt;
> +    case 'r':
> +        rebind=1;
> +        break;
>      }
> 
>      bdf = argv[optind];
> @@ -3549,34 +3608,31 @@ int main_restore(int argc, char **argv)
>          {0, 0, 0, 0}
>      };
> 
> -    while ((opt = def_getopt(argc, argv, "FhcpdeVA",
> -                             opts, "restore", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'c':
> -            console_autoconnect = 1;
> -            break;
> -        case 'p':
> -            paused = 1;
> -            break;
> -        case 'd':
> -            debug = 1;
> -            break;
> -        case 'F':
> -            daemonize = 0;
> -            break;
> -        case 'e':
> -            daemonize = 0;
> -            monitor = 0;
> -            break;
> -        case 'V':
> -            vnc = 1;
> -            break;
> -        case 'A':
> -            vnc = vncautopass = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "FhcpdeVA", opts, "restore", 1) {
> +    case 0: case 2:
> +        return opt;
> +    case 'c':
> +        console_autoconnect = 1;
> +        break;
> +    case 'p':
> +        paused = 1;
> +        break;
> +    case 'd':
> +        debug = 1;
> +        break;
> +    case 'F':
> +        daemonize = 0;
> +        break;
> +    case 'e':
> +        daemonize = 0;
> +        monitor = 0;
> +        break;
> +    case 'V':
> +        vnc = 1;
> +        break;
> +    case 'A':
> +        vnc = vncautopass = 1;
> +        break;
>      }
> 
>      if (argc-optind == 1) {
> @@ -3613,24 +3669,22 @@ int main_migrate_receive(int argc, char
>      int debug = 0, daemonize = 1, monitor = 1, remus = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "Fedr", NULL, "migrate-receive", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'F':
> -            daemonize = 0;
> -            break;
> -        case 'e':
> -            daemonize = 0;
> -            monitor = 0;
> -            break;
> -        case 'd':
> -            debug = 1;
> -            break;
> -        case 'r':
> -            remus = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "Fedr", NULL, "migrate-receive", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'F':
> +        daemonize = 0;
> +        break;
> +    case 'e':
> +        daemonize = 0;
> +        monitor = 0;
> +        break;
> +    case 'd':
> +        debug = 1;
> +        break;
> +    case 'r':
> +        remus = 1;
> +        break;
>      }
> 
>      if (argc-optind != 0) {
> @@ -3652,14 +3706,12 @@ int main_save(int argc, char **argv)
>      int checkpoint = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "c", NULL, "save", 2)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'c':
> -            checkpoint = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "c", NULL, "save", 2) {
> +    case 0: case 2:
> +        return opt;
> +    case 'c':
> +        checkpoint = 1;
> +        break;
>      }
> 
>      if (argc-optind > 3) {
> @@ -3685,27 +3737,25 @@ int main_migrate(int argc, char **argv)
>      char *host;
>      int opt, daemonize = 1, monitor = 1, debug = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "FC:s:ed", NULL, "migrate", 2)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'C':
> -            config_filename = optarg;
> -            break;
> -        case 's':
> -            ssh_command = optarg;
> -            break;
> -        case 'F':
> -            daemonize = 0;
> -            break;
> -        case 'e':
> -            daemonize = 0;
> -            monitor = 0;
> -            break;
> -        case 'd':
> -            debug = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "FC:s:ed", NULL, "migrate", 2) {
> +    case 0: case 2:
> +        return opt;
> +    case 'C':
> +        config_filename = optarg;
> +        break;
> +    case 's':
> +        ssh_command = optarg;
> +        break;
> +    case 'F':
> +        daemonize = 0;
> +        break;
> +    case 'e':
> +        daemonize = 0;
> +        monitor = 0;
> +        break;
> +    case 'd':
> +        debug = 1;
> +        break;
>      }
> 
>      domid = find_domain(argv[optind]);
> @@ -3729,8 +3779,10 @@ int main_dump_core(int argc, char **argv
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "dump-core", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "dump-core", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      core_dump_domain(find_domain(argv[optind]), argv[optind + 1]);
>      return 0;
> @@ -3740,8 +3792,10 @@ int main_pause(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "pause", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "pause", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pause_domain(find_domain(argv[optind]));
> 
> @@ -3752,8 +3806,10 @@ int main_unpause(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "unpause", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "unpause", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      unpause_domain(find_domain(argv[optind]));
> 
> @@ -3764,8 +3820,10 @@ int main_destroy(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "destroy", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "destroy", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      destroy_domain(find_domain(argv[optind]));
>      return 0;
> @@ -3787,20 +3845,18 @@ static int main_shutdown_or_reboot(int d
>          {0, 0, 0, 0}
>      };
> 
> -    while ((opt = def_getopt(argc, argv, "awF", opts, what, 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            all = 1;
> -            break;
> -        case 'w':
> -            wait_for_it = 1;
> -            break;
> -        case 'F':
> -            fallback_trigger = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "awF", opts, what, 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        all = 1;
> +        break;
> +    case 'w':
> +        wait_for_it = 1;
> +        break;
> +    case 'F':
> +        fallback_trigger = 1;
> +        break;
>      }
> 
>      if (!argv[optind] && !all) {
> @@ -3871,23 +3927,18 @@ int main_list(int argc, char **argv)
>      libxl_dominfo *info, *info_free=0;
>      int nb_domain, rc;
> 
> -    while ((opt = def_getopt(argc, argv, "lvhZ", opts, "list", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'l':
> -            details = 1;
> -            break;
> -        case 'h':
> -            help("list");
> -            return 0;
> -        case 'v':
> -            verbose = 1;
> -            break;
> -        case 'Z':
> -            context = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "lvhZ", opts, "list", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'l':
> +        details = 1;
> +        break;
> +    case 'v':
> +        verbose = 1;
> +        break;
> +    case 'Z':
> +        context = 1;
> +        break;
>      }
> 
>      if (optind >= argc) {
> @@ -3933,8 +3984,10 @@ int main_vm_list(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vm-list", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vm-list", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      list_vm();
>      return 0;
> @@ -3964,45 +4017,40 @@ int main_create(int argc, char **argv)
>          argc--; argv++;
>      }
> 
> -    while ((opt = def_getopt(argc, argv, "Fhnqf:pcdeVA", opts, "create", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'f':
> -            filename = optarg;
> -            break;
> -        case 'p':
> -            paused = 1;
> -            break;
> -        case 'c':
> -            console_autoconnect = 1;
> -            break;
> -        case 'd':
> -            debug = 1;
> -            break;
> -        case 'F':
> -            daemonize = 0;
> -            break;
> -        case 'e':
> -            daemonize = 0;
> -            monitor = 0;
> -            break;
> -        case 'h':
> -            help("create");
> -            return 0;
> -        case 'n':
> -            dryrun_only = 1;
> -            break;
> -        case 'q':
> -            quiet = 1;
> -            break;
> -        case 'V':
> -            vnc = 1;
> -            break;
> -        case 'A':
> -            vnc = vncautopass = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "Fhnqf:pcdeVA", opts, "create", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'f':
> +        filename = optarg;
> +        break;
> +    case 'p':
> +        paused = 1;
> +        break;
> +    case 'c':
> +        console_autoconnect = 1;
> +        break;
> +    case 'd':
> +        debug = 1;
> +        break;
> +    case 'F':
> +        daemonize = 0;
> +        break;
> +    case 'e':
> +        daemonize = 0;
> +        monitor = 0;
> +        break;
> +    case 'n':
> +        dryrun_only = 1;
> +        break;
> +    case 'q':
> +        quiet = 1;
> +        break;
> +    case 'V':
> +        vnc = 1;
> +        break;
> +    case 'A':
> +        vnc = vncautopass = 1;
> +        break;
>      }
> 
>      extra_config[0] = '\0';
> @@ -4070,17 +4118,15 @@ int main_config_update(int argc, char **
>          argc--; argv++;
>      }
> 
> -    while ((opt = def_getopt(argc, argv, "dhqf:", opts, "config_update", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'd':
> -            debug = 1;
> -            break;
> -        case 'f':
> -            filename = optarg;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "dhqf:", opts, "config_update", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'd':
> +        debug = 1;
> +        break;
> +    case 'f':
> +        filename = optarg;
> +        break;
>      }
> 
>      extra_config[0] = '\0';
> @@ -4168,8 +4214,11 @@ int main_button_press(int argc, char **a
>      fprintf(stderr, "WARNING: \"button-press\" is deprecated. "
>              "Please use \"trigger\"\n");
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "button-press", 2)) != -1)
> +
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "button-press", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      button_press(find_domain(argv[optind]), argv[optind + 1]);
> 
> @@ -4309,8 +4358,10 @@ int main_vcpulist(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpu-list", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpu-list", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      vcpulist(argc - optind, argv + optind);
>      return 0;
> @@ -4370,8 +4421,10 @@ int main_vcpupin(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-pin", 3)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vcpu-pin", 3) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      vcpupin(find_domain(argv[optind]), argv[optind+1] , argv[optind+2]);
>      return 0;
> @@ -4406,8 +4459,10 @@ int main_vcpuset(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vcpu-set", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vcpu-set", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      vcpuset(find_domain(argv[optind]), argv[optind+1]);
>      return 0;
> @@ -4589,14 +4644,12 @@ int main_info(int argc, char **argv)
>      };
>      int numa = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "hn", opts, "info", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'n':
> -            numa = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "hn", opts, "info", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'n':
> +        numa = 1;
> +        break;
>      }
> 
>      print_info(numa);
> @@ -4630,8 +4683,10 @@ int main_sharing(int argc, char **argv)
>      libxl_dominfo *info, *info_free = NULL;
>      int nb_domain, rc;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "sharing", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "sharing", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      if (optind >= argc) {
>          info = libxl_list_domain(ctx, &nb_domain);
> @@ -4911,36 +4966,34 @@ int main_sched_credit(int argc, char **a
>          {0, 0, 0, 0}
>      };
> 
> -    while ((opt = def_getopt(argc, argv, "d:w:c:p:t:r:hs", opts, "sched-credit", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'd':
> -            dom = optarg;
> -            break;
> -        case 'w':
> -            weight = strtol(optarg, NULL, 10);
> -            opt_w = 1;
> -            break;
> -        case 'c':
> -            cap = strtol(optarg, NULL, 10);
> -            opt_c = 1;
> -            break;
> -        case 't':
> -            tslice = strtol(optarg, NULL, 10);
> -            opt_t = 1;
> -            break;
> -        case 'r':
> -            ratelimit = strtol(optarg, NULL, 10);
> -            opt_r = 1;
> -            break;
> -        case 's':
> -            opt_s = 1;
> -            break;
> -        case 'p':
> -            cpupool = optarg;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "d:w:c:p:t:r:hs", opts, "sched-credit", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'd':
> +        dom = optarg;
> +        break;
> +    case 'w':
> +        weight = strtol(optarg, NULL, 10);
> +        opt_w = 1;
> +        break;
> +    case 'c':
> +        cap = strtol(optarg, NULL, 10);
> +        opt_c = 1;
> +        break;
> +    case 't':
> +        tslice = strtol(optarg, NULL, 10);
> +        opt_t = 1;
> +        break;
> +    case 'r':
> +        ratelimit = strtol(optarg, NULL, 10);
> +        opt_r = 1;
> +        break;
> +    case 's':
> +        opt_s = 1;
> +        break;
> +    case 'p':
> +        cpupool = optarg;
> +        break;
>      }
> 
>      if ((cpupool || opt_s) && (dom || opt_w || opt_c)) {
> @@ -5030,21 +5083,19 @@ int main_sched_credit2(int argc, char **
>          {0, 0, 0, 0}
>      };
> 
> -    while ((opt = def_getopt(argc, argv, "d:w:p:h", opts, "sched-credit2", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'd':
> -            dom = optarg;
> -            break;
> -        case 'w':
> -            weight = strtol(optarg, NULL, 10);
> -            opt_w = 1;
> -            break;
> -        case 'p':
> -            cpupool = optarg;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "d:w:p:h", opts, "sched-credit2", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'd':
> +        dom = optarg;
> +        break;
> +    case 'w':
> +        weight = strtol(optarg, NULL, 10);
> +        opt_w = 1;
> +        break;
> +    case 'p':
> +        cpupool = optarg;
> +        break;
>      }
> 
>      if (cpupool && (dom || opt_w)) {
> @@ -5105,37 +5156,35 @@ int main_sched_sedf(int argc, char **arg
>          {0, 0, 0, 0}
>      };
> 
> -    while ((opt = def_getopt(argc, argv, "d:p:s:l:e:w:c:h", opts, "sched-sedf", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'd':
> -            dom = optarg;
> -            break;
> -        case 'p':
> -            period = strtol(optarg, NULL, 10);
> -            opt_p = 1;
> -            break;
> -        case 's':
> -            slice = strtol(optarg, NULL, 10);
> -            opt_s = 1;
> -            break;
> -        case 'l':
> -            latency = strtol(optarg, NULL, 10);
> -            opt_l = 1;
> -            break;
> -        case 'e':
> -            extra = strtol(optarg, NULL, 10);
> -            opt_e = 1;
> -            break;
> -        case 'w':
> -            weight = strtol(optarg, NULL, 10);
> -            opt_w = 1;
> -            break;
> -        case 'c':
> -            cpupool = optarg;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "d:p:s:l:e:w:c:h", opts, "sched-sedf", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'd':
> +        dom = optarg;
> +        break;
> +    case 'p':
> +        period = strtol(optarg, NULL, 10);
> +        opt_p = 1;
> +        break;
> +    case 's':
> +        slice = strtol(optarg, NULL, 10);
> +        opt_s = 1;
> +        break;
> +    case 'l':
> +        latency = strtol(optarg, NULL, 10);
> +        opt_l = 1;
> +        break;
> +    case 'e':
> +        extra = strtol(optarg, NULL, 10);
> +        opt_e = 1;
> +        break;
> +    case 'w':
> +        weight = strtol(optarg, NULL, 10);
> +        opt_w = 1;
> +        break;
> +    case 'c':
> +        cpupool = optarg;
> +        break;
>      }
> 
>      if (cpupool && (dom || opt_p || opt_s || opt_l || opt_e || opt_w)) {
> @@ -5202,8 +5251,10 @@ int main_domid(int argc, char **argv)
>      int opt;
>      const char *domname = NULL;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "domid", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "domid", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domname = argv[optind];
> 
> @@ -5224,8 +5275,10 @@ int main_domname(int argc, char **argv)
>      char *domname = NULL;
>      char *endptr = NULL;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "domname", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "domname", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = strtol(argv[optind], &endptr, 10);
>      if (domid == 0 && !strcmp(endptr, argv[optind])) {
> @@ -5252,8 +5305,10 @@ int main_rename(int argc, char **argv)
>      int opt;
>      const char *dom, *new_name;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "rename", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "rename", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      dom = argv[optind++];
>      new_name = argv[optind];
> @@ -5276,8 +5331,10 @@ int main_trigger(int argc, char **argv)
>      const char *trigger_name = NULL;
>      libxl_trigger trigger;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "trigger", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "trigger", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind++]);
> 
> @@ -5306,8 +5363,10 @@ int main_sysrq(int argc, char **argv)
>      int opt;
>      const char *sysrq = NULL;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "sysrq", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "sysrq", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind++]);
> 
> @@ -5329,8 +5388,10 @@ int main_debug_keys(int argc, char **arg
>      int opt;
>      char *keys;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "debug-keys", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "debug-keys", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      keys = argv[optind];
> 
> @@ -5349,14 +5410,12 @@ int main_dmesg(int argc, char **argv)
>      char *line;
>      int opt, ret = 1;
> 
> -    while ((opt = def_getopt(argc, argv, "c", NULL, "dmesg", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'c':
> -            clear = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "c", NULL, "dmesg", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'c':
> +        clear = 1;
> +        break;
>      }
> 
>      cr = libxl_xen_console_read_start(ctx, clear);
> @@ -5375,8 +5434,10 @@ int main_top(int argc, char **argv)
>  {
>      int opt;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "top", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "top", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      return system("xentop");
>  }
> @@ -5392,8 +5453,10 @@ int main_networkattach(int argc, char **
>      int i;
>      unsigned int val;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "network-attach", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "network-attach", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      if (argc-optind > 11) {
>          help("network-attach");
> @@ -5479,8 +5542,10 @@ int main_networklist(int argc, char **ar
>      libxl_nicinfo nicinfo;
>      int nb, i;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "network-list", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "network-list", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      /*      Idx  BE   MAC   Hdl  Sta  evch txr/rxr  BE-path */
>      printf("%-3s %-2s %-17s %-6s %-5s %-6s %5s/%-5s %-30s\n",
> @@ -5516,8 +5581,10 @@ int main_networkdetach(int argc, char **
>      int opt;
>      libxl_device_nic nic;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "network-detach", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "network-detach", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
> 
> @@ -5547,8 +5614,10 @@ int main_blockattach(int argc, char **ar
>      libxl_device_disk disk = { 0 };
>      XLU_Config *config = 0;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "block-attach", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "block-attach", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      if (domain_qualifier_to_domid(argv[optind], &fe_domid, 0) < 0) {
>          fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
> @@ -5582,8 +5651,10 @@ int main_blocklist(int argc, char **argv
>      libxl_device_disk *disks;
>      libxl_diskinfo diskinfo;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "block-list", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "block-list", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      printf("%-5s %-3s %-6s %-5s %-6s %-8s %-30s\n",
>             "Vdev", "BE", "handle", "state", "evt-ch", "ring-ref", "BE-path");
> @@ -5618,8 +5689,10 @@ int main_blockdetach(int argc, char **ar
>      int opt, rc = 0;
>      libxl_device_disk disk;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "block-detach", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "block-detach", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
> 
> @@ -5643,8 +5716,10 @@ int main_vtpmattach(int argc, char **arg
>      unsigned int val;
>      uint32_t domid;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-attach", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-attach", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      if (domain_qualifier_to_domid(argv[optind], &domid, 0) < 0) {
>          fprintf(stderr, "%s is an invalid domain identifier\n", argv[optind]);
> @@ -5696,8 +5771,10 @@ int main_vtpmlist(int argc, char **argv)
>      libxl_vtpminfo vtpminfo;
>      int nb, i;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-list", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-list", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      /*      Idx  BE   UUID   Hdl  Sta  evch rref  BE-path */
>      printf("%-3s %-2s %-36s %-6s %-5s %-6s %-5s %-10s\n",
> @@ -5736,8 +5813,10 @@ int main_vtpmdetach(int argc, char **arg
>      libxl_device_vtpm vtpm;
>      libxl_uuid uuid;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "vtpm-detach", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "vtpm-detach", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      domid = find_domain(argv[optind]);
> 
> @@ -5928,14 +6007,12 @@ int main_uptime(int argc, char **argv)
>      int nb_doms = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "s", NULL, "uptime", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 's':
> -            short_mode = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "s", NULL, "uptime", 1) {
> +    case 0: case 2:
> +        return opt;
> +    case 's':
> +        short_mode = 1;
> +        break;
>      }
> 
>      for (;(dom = argv[optind]) != NULL; nb_doms++,optind++)
> @@ -5955,17 +6032,15 @@ int main_tmem_list(int argc, char **argv
>      int all = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "al", NULL, "tmem-list", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'l':
> -            use_long = 1;
> -            break;
> -        case 'a':
> -            all = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "al", NULL, "tmem-list", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'l':
> +        use_long = 1;
> +        break;
> +    case 'a':
> +        all = 1;
> +        break;
>      }
> 
>      dom = argv[optind];
> @@ -5996,14 +6071,12 @@ int main_tmem_freeze(int argc, char **ar
>      int all = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-freeze", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            all = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "a", NULL, "tmem-freeze", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        all = 1;
> +        break;
>      }
> 
>      dom = argv[optind];
> @@ -6029,14 +6102,12 @@ int main_tmem_thaw(int argc, char **argv
>      int all = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "a", NULL, "tmem-thaw", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            all = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "a", NULL, "tmem-thaw", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        all = 1;
> +        break;
>      }
> 
>      dom = argv[optind];
> @@ -6064,26 +6135,24 @@ int main_tmem_set(int argc, char **argv)
>      int all = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "aw:c:p:", NULL, "tmem-set", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            all = 1;
> -            break;
> -        case 'w':
> -            weight = strtol(optarg, NULL, 10);
> -            opt_w = 1;
> -            break;
> -        case 'c':
> -            cap = strtol(optarg, NULL, 10);
> -            opt_c = 1;
> -            break;
> -        case 'p':
> -            compress = strtol(optarg, NULL, 10);
> -            opt_p = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "aw:c:p:", NULL, "tmem-set", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        all = 1;
> +        break;
> +    case 'w':
> +        weight = strtol(optarg, NULL, 10);
> +        opt_w = 1;
> +        break;
> +    case 'c':
> +        cap = strtol(optarg, NULL, 10);
> +        opt_c = 1;
> +        break;
> +    case 'p':
> +        compress = strtol(optarg, NULL, 10);
> +        opt_p = 1;
> +        break;
>      }
> 
>      dom = argv[optind];
> @@ -6125,20 +6194,18 @@ int main_tmem_shared_auth(int argc, char
>      int all = 0;
>      int opt;
> 
> -    while ((opt = def_getopt(argc, argv, "au:A:", NULL, "tmem-shared-auth", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'a':
> -            all = 1;
> -            break;
> -        case 'u':
> -            uuid = optarg;
> -            break;
> -        case 'A':
> -            autharg = optarg;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "au:A:", NULL, "tmem-shared-auth", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'a':
> +        all = 1;
> +        break;
> +    case 'u':
> +        uuid = optarg;
> +        break;
> +    case 'A':
> +        autharg = optarg;
> +        break;
>      }
> 
>      dom = argv[optind];
> @@ -6175,8 +6242,10 @@ int main_tmem_freeable(int argc, char **
>      int opt;
>      int mb;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "tmem-freeable", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "tmem-freeale", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      mb = libxl_tmem_freeable(ctx);
>      if (mb == -1)
> @@ -6215,17 +6284,15 @@ int main_cpupoolcreate(int argc, char **
>      libxl_cputopology *topology;
>      int rc = -ERROR_FAIL;
> 
> -    while ((opt = def_getopt(argc, argv, "hnf:", opts, "cpupool-create", 0)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -        case 'f':
> -            filename = optarg;
> -            break;
> -        case 'n':
> -            dryrun_only = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "hnf:", opts, "cpupool-create", 0) {
> +    case 0: case 2:
> +        return opt;
> +    case 'f':
> +        filename = optarg;
> +        break;
> +    case 'n':
> +        dryrun_only = 1;
> +        break;
>      }
> 
>      memset(extra_config, 0, sizeof(extra_config));
> @@ -6400,14 +6467,12 @@ int main_cpupoollist(int argc, char **ar
>      char *name;
>      int ret = 0;
> 
> -    while ((opt = def_getopt(argc, argv, "hc", opts, "cpupool-list", 1)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            break;
> -        case 'c':
> -            opt_cpus = 1;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "hc", opts, "cpupool-list", 1) {
> +    case 0: case 2:
> +        break;
> +    case 'c':
> +        opt_cpus = 1;
> +        break;
>      }
> 
>      if (optind < argc) {
> @@ -6467,8 +6532,10 @@ int main_cpupooldestroy(int argc, char *
>      const char *pool;
>      uint32_t poolid;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-destroy", 1)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-destroy", 1) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pool = argv[optind];
> 
> @@ -6488,8 +6555,10 @@ int main_cpupoolrename(int argc, char **
>      const char *new_name;
>      uint32_t poolid;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-rename", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-rename", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pool = argv[optind++];
> 
> @@ -6518,8 +6587,10 @@ int main_cpupoolcpuadd(int argc, char **
>      int node;
>      int n;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-add", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-cpu-add", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pool = argv[optind++];
>      node = -1;
> @@ -6562,8 +6633,10 @@ int main_cpupoolcpuremove(int argc, char
>      int node;
>      int n;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-cpu-remove", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-cpu-remove", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      pool = argv[optind++];
>      node = -1;
> @@ -6605,8 +6678,10 @@ int main_cpupoolmigrate(int argc, char *
>      const char *dom;
>      uint32_t domid;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-migrate", 2)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-migrate", 2) {
> +    case 0: case 2:
>          return opt;
> +    }
> 
>      dom = argv[optind++];
>      pool = argv[optind];
> @@ -6645,8 +6720,11 @@ int main_cpupoolnumasplit(int argc, char
>      libxl_cputopology *topology;
>      libxl_dominfo info;
> 
> -    if ((opt = def_getopt(argc, argv, "", NULL, "cpupool-numa-split", 0)) != -1)
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "cpupool-numa-split", 0) {
> +    case 0: case 2:
>          return opt;
> +    }
> +
>      ret = 0;
> 
>      poolinfo = libxl_list_cpupool(ctx, &n_pools);
> @@ -6898,27 +6976,24 @@ int main_remus(int argc, char **argv)
>      r_info.blackhole = 0;
>      r_info.compression = 1;
> 
> -    while ((opt = def_getopt(argc, argv, "bui:s:e", NULL, "remus", 2)) != -1) {
> -        switch (opt) {
> -        case 0: case 2:
> -            return opt;
> -
> -        case 'i':
> -           r_info.interval = atoi(optarg);
> -            break;
> -        case 'b':
> -            r_info.blackhole = 1;
> -            break;
> -        case 'u':
> -           r_info.compression = 0;
> -            break;
> -        case 's':
> -            ssh_command = optarg;
> -            break;
> -        case 'e':
> -            daemonize = 0;
> -            break;
> -        }
> +    SWITCH_FOREACH_OPT(opt, "bui:s:e", NULL, "remus", 2) {
> +    case 0: case 2:
> +        return opt;
> +    case 'i':
> +        r_info.interval = atoi(optarg);
> +        break;
> +    case 'b':
> +        r_info.blackhole = 1;
> +        break;
> +    case 'u':
> +        r_info.compression = 0;
> +        break;
> +    case 's':
> +        ssh_command = optarg;
> +        break;
> +    case 'e':
> +        daemonize = 0;
> +        break;
>      }
> 
>      domid = find_domain(argv[optind]);
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2 of 2] xl: Introduce helper macro for option parsing
  2012-11-30 11:21 ` [PATCH 2 of 2] xl: Introduce helper macro for option parsing Ian Campbell
  2012-12-13 10:22   ` Ian Campbell
@ 2012-12-13 15:05   ` Ian Jackson
  2012-12-18 14:38     ` Ian Campbell
  1 sibling, 1 reply; 7+ messages in thread
From: Ian Jackson @ 2012-12-13 15:05 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

Ian Campbell writes ("[PATCH 2 of 2] xl: Introduce helper macro for option parsing"):
> - s/FOREACH_OPT/SWITCH_FOREACH_OPT/
> - Document the macro

Thanks.

> +/*
> + * Wraps def_getopt into a convenient loop+switch to process all arguments.
> + *
> + * _opt:        an int variable, holds the current option during processing.
> + * _opts:       short options, as per getopt_long(3)'s optstring argument.
> + * _lopts:      long options, as per getopt_long(3)'s longopts argument. May
> + *              be null.
> + * _help:       name of this command, for usage string.
> + * _req:        number of non-option command line parameters which are required.

Can we have a pseudo-prototype for this ?  Eg

    *   SWITCH_FOREACH_OPT(int &opt, const char *opts,
    *                      const struct option *longopts,
    *                      const char *commandname,
    *                      int num_opts_req) { ...
    *    case ...

Also, there is no need to prefix macro formal arguments with _.  Why
do you do that ?  We don't do it elsewhere in libxl...

> + * Callers should treat SWITCH_FOREACH_OPT as they would a switch
> + * statement over the value of _opt. Each option given in _opts (or
> + * _lopts) should be handled by a case statement as if it were inside
> + * a switch statement.
> + *
> + * In addition to the options provided in _opts callers must handle
> + * two additional pseudo options:
> + *  0 -- generated if the user passes a -h option. help will be printed,
> + *       caller should return 0.
> + *  2 -- generated if the user does not provided _req non-option arguments,
> + *       caller should return 2.

I don't think you can mean "caller should return".  Your description
of the macro doesn't specify anything in particular about the calling
function so it can't possibly intend for you to return particular
values from it.

Did you mean "cause the program to exit" ?  And if so why not have the
macro (or the function) do that ?

I haven't gone through your call sites to review them...

Ian.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2 of 2] xl: Introduce helper macro for option parsing
  2012-12-13 15:05   ` Ian Jackson
@ 2012-12-18 14:38     ` Ian Campbell
  2012-12-18 15:16       ` Ian Campbell
  0 siblings, 1 reply; 7+ messages in thread
From: Ian Campbell @ 2012-12-18 14:38 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Thu, 2012-12-13 at 15:05 +0000, Ian Jackson wrote:
> Ian Campbell writes ("[PATCH 2 of 2] xl: Introduce helper macro for option parsing"):
> > - s/FOREACH_OPT/SWITCH_FOREACH_OPT/
> > - Document the macro
> 
> Thanks.
> 
> > +/*
> > + * Wraps def_getopt into a convenient loop+switch to process all arguments.
> > + *
> > + * _opt:        an int variable, holds the current option during processing.
> > + * _opts:       short options, as per getopt_long(3)'s optstring argument.
> > + * _lopts:      long options, as per getopt_long(3)'s longopts argument. May
> > + *              be null.
> > + * _help:       name of this command, for usage string.
> > + * _req:        number of non-option command line parameters which are required.
> 
> Can we have a pseudo-prototype for this ?  Eg
> 
>     *   SWITCH_FOREACH_OPT(int &opt, const char *opts,
>     *                      const struct option *longopts,
>     *                      const char *commandname,
>     *                      int num_opts_req) { ...
>     *    case ...

Will do.

> Also, there is no need to prefix macro formal arguments with _.  Why
> do you do that ?  We don't do it elsewhere in libxl...

Not sure why I did that, will remove them.

> > + * Callers should treat SWITCH_FOREACH_OPT as they would a switch
> > + * statement over the value of _opt. Each option given in _opts (or
> > + * _lopts) should be handled by a case statement as if it were inside
> > + * a switch statement.
> > + *
> > + * In addition to the options provided in _opts callers must handle
> > + * two additional pseudo options:
> > + *  0 -- generated if the user passes a -h option. help will be printed,
> > + *       caller should return 0.
> > + *  2 -- generated if the user does not provided _req non-option arguments,
> > + *       caller should return 2.
> 
> I don't think you can mean "caller should return".  Your description
> of the macro doesn't specify anything in particular about the calling
> function so it can't possibly intend for you to return particular
> values from it.
> 
> Did you mean "cause the program to exit" ?

The existing (somewhat inferred, but it seems to be reasonably
consistent) semantics of xl's main_foo() dispatchers is to return 2,
causing the xl's main to exit under these circumstances. Why 2? I've no
idea.

Rather than trying to treat this as some sort of generic helper I'd be
more inclined to just document that it is to be called only by xl
main_foo() functions, since its main purpose is to make main_foo() more
consistent in their argument handling.

I originally preferred return from main_foo() over exit(2) so that we
could have a chance to free the xl context etc (mostly for the benefit
of people using valgrind). We have an atexit hook now so perhaps that
concern is no longer valid.

> And if so why not have the macro (or the function) do that ?

I don't like returns in macros.

> I haven't gone through your call sites to review them...
> 
> Ian.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2 of 2] xl: Introduce helper macro for option parsing
  2012-12-18 14:38     ` Ian Campbell
@ 2012-12-18 15:16       ` Ian Campbell
  0 siblings, 0 replies; 7+ messages in thread
From: Ian Campbell @ 2012-12-18 15:16 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Tue, 2012-12-18 at 14:38 +0000, Ian Campbell wrote:
> 
> I originally preferred return from main_foo() over exit(2) so that we
> could have a chance to free the xl context etc (mostly for the benefit
> of people using valgrind). We have an atexit hook now so perhaps that
> concern is no longer valid.
> 
> > And if so why not have the macro (or the function) do that ?
> 
> I don't like returns in macros. 

I implemented this as a third patch in the series, so we can decide what
we think.

Ian.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-12-18 15:16 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-30 11:21 [PATCH 0 of 2] xl: add helpers for option parsing Ian Campbell
2012-11-30 11:21 ` [PATCH 1 of 2] xl: allow def_getopt to handle long options Ian Campbell
2012-11-30 11:21 ` [PATCH 2 of 2] xl: Introduce helper macro for option parsing Ian Campbell
2012-12-13 10:22   ` Ian Campbell
2012-12-13 15:05   ` Ian Jackson
2012-12-18 14:38     ` Ian Campbell
2012-12-18 15:16       ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.