- Rejects malformed or missing numbers
- Boolean switches must not have an = sign, others must have =
- Single-letter non-boolean can have optional = sign: -x=foo
- Single-letter boolean switches can be merged: -xyz
- Fixed addressing string[strlen+1]
- new parse_options_or_exit() prints help information for demo programs
- weston-eventdemo had '0' for single-letter switch
- weston-eventdemo log all events if no switches are given
---
 clients/eventdemo.c    |   23 +++++----
 clients/nested.c       |    4 +-
 clients/subsurfaces.c  |    4 +-
 clients/wscreensaver.c |    4 +-
 shared/config-parser.h |    4 ++
 shared/option-parser.c |  126 +++++++++++++++++++++++++++++++++++++-----------
 6 files changed, 121 insertions(+), 44 deletions(-)

diff --git a/clients/eventdemo.c b/clients/eventdemo.c
index 5ec6829..cebf6a0 100644
--- a/clients/eventdemo.c
+++ b/clients/eventdemo.c
@@ -373,13 +373,13 @@ static const struct weston_option eventdemo_options[] = {
        { WESTON_OPTION_INTEGER, "max-width", 0, &width_max },
        { WESTON_OPTION_INTEGER, "max-height", 0, &height_max },
        { WESTON_OPTION_BOOLEAN, "no-border", 'b', &noborder },
-       { WESTON_OPTION_BOOLEAN, "log-redraw", '0', &log_redraw },
-       { WESTON_OPTION_BOOLEAN, "log-resize", '0', &log_resize },
-       { WESTON_OPTION_BOOLEAN, "log-focus", '0', &log_focus },
-       { WESTON_OPTION_BOOLEAN, "log-key", '0', &log_key },
-       { WESTON_OPTION_BOOLEAN, "log-button", '0', &log_button },
-       { WESTON_OPTION_BOOLEAN, "log-axis", '0', &log_axis },
-       { WESTON_OPTION_BOOLEAN, "log-motion", '0', &log_motion },
+       { WESTON_OPTION_BOOLEAN, "log-redraw", 0, &log_redraw },
+       { WESTON_OPTION_BOOLEAN, "log-resize", 0, &log_resize },
+       { WESTON_OPTION_BOOLEAN, "log-focus", 0, &log_focus },
+       { WESTON_OPTION_BOOLEAN, "log-key", 0, &log_key },
+       { WESTON_OPTION_BOOLEAN, "log-button", 0, &log_button },
+       { WESTON_OPTION_BOOLEAN, "log-axis", 0, &log_axis },
+       { WESTON_OPTION_BOOLEAN, "log-motion", 0, &log_motion },
 };
 
 /**
@@ -392,8 +392,13 @@ main(int argc, char *argv[])
        struct display *d;
        struct eventdemo *e;
 
-       parse_options(eventdemo_options,
-                     ARRAY_LENGTH(eventdemo_options), &argc, argv);
+       parse_options_or_exit(eventdemo_options,
+                             ARRAY_LENGTH(eventdemo_options), &argc, argv);
+
+       if (!log_redraw && !log_resize && !log_focus && !log_key &&
+           !log_button && !log_axis && !log_motion)
+         log_redraw = log_resize = log_focus = log_key =
+           log_button = log_axis = log_motion = 1;
 
        /* Connect to the display and have the arguments parsed */
        d = display_create(&argc, argv);
diff --git a/clients/nested.c b/clients/nested.c
index 44389e4..0c5c7e9 100644
--- a/clients/nested.c
+++ b/clients/nested.c
@@ -1122,8 +1122,8 @@ main(int argc, char *argv[])
        struct display *display;
        struct nested *nested;
 
-       parse_options(nested_options,
-                     ARRAY_LENGTH(nested_options), &argc, argv);
+       parse_options_or_exit(nested_options,
+                             ARRAY_LENGTH(nested_options), &argc, argv);
 
        display = display_create(&argc, argv);
        if (display == NULL) {
diff --git a/clients/subsurfaces.c b/clients/subsurfaces.c
index 66a10f2..4ed0b78 100644
--- a/clients/subsurfaces.c
+++ b/clients/subsurfaces.c
@@ -775,8 +775,8 @@ main(int argc, char *argv[])
        struct display *display;
        struct demoapp *app;
 
-       parse_options(options, ARRAY_LENGTH(options), &argc, argv);
-       if (option_help) {
+       if (parse_options(options, ARRAY_LENGTH(options), &argc, argv)
+           || option_help) {
                printf(help_text, argv[0]);
                return 0;
        }
diff --git a/clients/wscreensaver.c b/clients/wscreensaver.c
index 47f6c8a..1de299a 100644
--- a/clients/wscreensaver.c
+++ b/clients/wscreensaver.c
@@ -310,8 +310,8 @@ int main(int argc, char *argv[])
 
        init_frand();
 
-       parse_options(wscreensaver_options,
-                     ARRAY_LENGTH(wscreensaver_options), &argc, argv);
+       parse_options_or_exit(wscreensaver_options,
+                             ARRAY_LENGTH(wscreensaver_options), &argc, argv);
 
        d = display_create(&argc, argv);
        if (d == NULL) {
diff --git a/shared/config-parser.h b/shared/config-parser.h
index 745562b..81baf76 100644
--- a/shared/config-parser.h
+++ b/shared/config-parser.h
@@ -65,6 +65,10 @@ int
 parse_options(const struct weston_option *options,
              int count, int *argc, char *argv[]);
 
+void
+parse_options_or_exit(const struct weston_option *options,
+                     int count, int *argc, char *argv[]);
+
 struct weston_config_section;
 struct weston_config;
 
diff --git a/shared/option-parser.c b/shared/option-parser.c
index c00349a..0ca9e52 100644
--- a/shared/option-parser.c
+++ b/shared/option-parser.c
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include <ctype.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -30,56 +31,123 @@
 
 #include "config-parser.h"
 
-static void
+static int
 handle_option(const struct weston_option *option, char *value)
 {
+       char* p;
        switch (option->type) {
        case WESTON_OPTION_INTEGER:
-               * (int32_t *) option->data = strtol(value, NULL, 0);
-               return;
+               * (int32_t *) option->data = strtol(value, &p, 0);
+               return p > value && !*p;
        case WESTON_OPTION_UNSIGNED_INTEGER:
-               * (uint32_t *) option->data = strtoul(value, NULL, 0);
-               return;
+               * (uint32_t *) option->data = strtoul(value, &p, 0);
+               return p > value && !*p;
        case WESTON_OPTION_STRING:
                * (char **) option->data = strdup(value);
-               return;
-       case WESTON_OPTION_BOOLEAN:
-               * (int32_t *) option->data = 1;
-               return;
+               return 1;
        default:
                assert(0);
        }
 }
 
+static int
+handle_long_option(const struct weston_option *options, int count, char* arg)
+{
+       int k, len;
+       for (k = 0; k < count; k++) {
+               if (! options[k].name) continue;
+               len = strlen(options[k].name);
+               if (strncmp(options[k].name, arg+2, len) != 0) continue;
+               if (options[k].type == WESTON_OPTION_BOOLEAN) {
+                       if (! arg[len+2]) {
+                               * (int32_t *) options[k].data = 1;
+                               return 1;
+                       }
+               } else if (arg[len+2] == '=') {
+                       return handle_option(options+k, arg+len+3);
+               }
+       }
+       return 0;
+}
+
+static int
+handle_short_option(const struct weston_option *options, int count, char* arg)
+{
+       int i, k;
+       for (i = 1; arg[i]; i++) {
+               for (k = 0; ; k++) {
+                       if (k >= count) return 0;
+                       if (options[k].short_name == arg[i]) break;
+               }
+               if (options[k].type == WESTON_OPTION_BOOLEAN)
+                       * (int32_t *) options[k].data = 1;
+               else if (arg[i+1] == '=')
+                       return handle_option(options+k, arg+i+2);
+               else
+                       return handle_option(options+k, arg+i+1);
+       }
+       return arg[1];
+}
+
+
 int
 parse_options(const struct weston_option *options,
              int count, int *argc, char *argv[])
 {
-       int i, j, k, len = 0;
+       int i, j;
 
        for (i = 1, j = 1; i < *argc; i++) {
-               for (k = 0; k < count; k++) {
-                       if (options[k].name)
-                               len = strlen(options[k].name);
-                       if (options[k].name &&
-                           argv[i][0] == '-' &&
-                           argv[i][1] == '-' &&
-                           strncmp(options[k].name, &argv[i][2], len) == 0 &&
-                           (argv[i][len + 2] == '=' || argv[i][len + 2] == 
'\0')) {
-                               handle_option(&options[k], &argv[i][len + 3]);
-                               break;
-                       } else if (options[k].short_name &&
-                                  argv[i][0] == '-' &&
-                                  options[k].short_name == argv[i][1]) {
-                               handle_option(&options[k], &argv[i][2]);
-                               break;
-                       }
+               if (argv[i][0] == '-') {
+                       if (argv[i][1] == '-') {
+                               if (handle_long_option(options, count, argv[i]))
+                                       continue;
+                       } else if (handle_short_option(options, count, argv[i]))
+                               continue;
                }
-               if (k == count)
-                       argv[j++] = argv[i];
+               argv[j++] = argv[i];
        }
+
        argv[j] = NULL;
        *argc = j;
 
-       return j;
+       return j - 1;
+}
+
+
+static void print_upper_case(const struct weston_option* option)
+{
+       const char* p;
+       if (option->name) {
+               for (p = option->name; *p; p++)
+                       if (isalpha(*p)) putchar(toupper(*p));
+       } else {
+               putchar(toupper(option->short_name));
+       }
+}
+
+
+void
+parse_options_or_exit(const struct weston_option *options,
+                     int count, int *argc, char *argv[])
+{
+       int k;
+       if (!parse_options(options, count, argc, argv)) return;
+       printf("Usage: %s [OPTIONS]\n\n", argv[0]);
+       for (k = 0; k < count; k++) {
+               if (options[k].name) {
+                       printf("  --%s", options[k].name);
+                       if (options[k].type != WESTON_OPTION_BOOLEAN) {
+                               putchar('=');
+                               print_upper_case(options+k);
+                       }
+                       putchar('\n');
+               }
+               if (options[k].short_name) {
+                       printf("  -%c", options[k].short_name);
+                       if (options[k].type != WESTON_OPTION_BOOLEAN)
+                               print_upper_case(options+k);
+                       putchar('\n');
+               }
+       }
+       exit(1);
 }
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to