parse_options: fail on more malformed options
[profile/ivi/weston-ivi-shell.git] / shared / option-parser.c
1 /*
2  * Copyright © 2012 Kristian Høgsberg
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <assert.h>
30
31 #include "config-parser.h"
32
33 static int
34 handle_option(const struct weston_option *option, char *value)
35 {
36         char* p;
37
38         switch (option->type) {
39         case WESTON_OPTION_INTEGER:
40                 * (int32_t *) option->data = strtol(value, &p, 0);
41                 return *value && !*p;
42         case WESTON_OPTION_UNSIGNED_INTEGER:
43                 * (uint32_t *) option->data = strtoul(value, &p, 0);
44                 return *value && !*p;
45         case WESTON_OPTION_STRING:
46                 * (char **) option->data = strdup(value);
47                 return 1;
48         default:
49                 assert(0);
50         }
51 }
52
53 static int
54 long_option(const struct weston_option *options, int count, char *arg)
55 {
56         int k, len;
57
58         for (k = 0; k < count; k++) {
59                 if (!options[k].name)
60                         continue;
61
62                 len = strlen(options[k].name);
63                 if (strncmp(options[k].name, arg + 2, len) != 0)
64                         continue;
65
66                 if (options[k].type == WESTON_OPTION_BOOLEAN) {
67                         if (!arg[len + 2]) {
68                                 * (int32_t *) options[k].data = 1;
69
70                                 return 1;
71                         }
72                 } else if (arg[len+2] == '=') {
73                         return handle_option(options + k, arg + len + 3);
74                 }
75         }
76
77         return 0;
78 }
79
80 static int
81 short_option(const struct weston_option *options, int count, char *arg)
82 {
83         int k;
84
85         if (!arg[1])
86                 return 0;
87
88         for (k = 0; k < count; k++) {
89                 if (options[k].short_name != arg[1])
90                         continue;
91
92                 if (options[k].type == WESTON_OPTION_BOOLEAN) {
93                         if (!arg[2]) {
94                                 * (int32_t *) options[k].data = 1;
95
96                                 return 1;
97                         }
98                 } else {
99                         return handle_option(options + k, arg + 2);
100                 }
101         }
102
103         return 0;
104 }
105
106 int
107 parse_options(const struct weston_option *options,
108               int count, int *argc, char *argv[])
109 {
110         int i, j;
111
112         for (i = 1, j = 1; i < *argc; i++) {
113                 if (argv[i][0] == '-') {
114                         if (argv[i][1] == '-') {
115                                 if (long_option(options, count, argv[i]))
116                                         continue;
117                         } else if (short_option(options, count, argv[i]))
118                                 continue;
119                 }
120                 argv[j++] = argv[i];
121         }
122         argv[j] = NULL;
123         *argc = j;
124
125         return j;
126 }