getopt: return '?' if user wants an arg, but none is provided
[mirror/winof/.git] / etc / user / getopt.c
1 /*\r
2  * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  */\r
30 \r
31 #include <stdio.h>\r
32 #include <stdlib.h>\r
33 #include <string.h>\r
34 \r
35 #include "getopt.h"\r
36 \r
37 char *optarg;\r
38 int optind = 1;\r
39 int opterr = 1;\r
40 int optopt = '?';\r
41 \r
42 int getopt(int argc, char * const argv[], char const *opts)\r
43 {\r
44         char *loc;\r
45 \r
46         optarg = NULL;\r
47 \r
48         if (optind >= argc) {\r
49                 return EOF;\r
50         }\r
51 \r
52         if (argv[optind][0] != '-') {\r
53                 return EOF;\r
54         }\r
55 \r
56         if (!strcmp(argv[optind], "--")) {\r
57                 optind++;\r
58                 return '?';\r
59         }\r
60 \r
61         optopt = argv[optind][1];\r
62 \r
63         loc = strchr(opts, optopt);\r
64         if (loc == NULL) {\r
65                 return '?';\r
66         }\r
67 \r
68         if (loc[1] != ':') {\r
69                 goto out;\r
70         }\r
71 \r
72         if (argv[optind][2] != '\0') {\r
73                 optarg = &argv[optind][2];\r
74                 goto out;\r
75         }\r
76 \r
77         /* switch argument is optional (::) - be careful */\r
78         if (loc[2] == ':' && (argv[optind+1] && argv[optind+1][0] == '-'))\r
79                 goto out;\r
80  \r
81         optarg = argv[++optind];\r
82         if (!optarg || !(*optarg)) {\r
83                 return '?';\r
84         }\r
85 \r
86 out:\r
87         optind++;\r
88         return optopt;\r
89 }\r
90 \r
91 int getopt_long(int argc, char * const argv[], char const *opts,\r
92                                 const struct option *longopts, int *longindex)\r
93 {\r
94         char arg[256];\r
95         char *str;\r
96         int i;\r
97 \r
98         if (optind == argc) {\r
99                 return EOF;\r
100         }\r
101 \r
102         if (argv[optind][0] != '-') {\r
103                 return EOF;\r
104         }\r
105 \r
106         if (!strcmp(argv[optind], "--")) {\r
107                 optind++;\r
108                 return '?';\r
109         }\r
110 \r
111         if (argv[optind][1] != '-') {\r
112                 return getopt(argc, argv, opts);\r
113         }\r
114 \r
115         strcpy(arg, &argv[optind][2]);\r
116         str = strtok(arg, "=");\r
117 \r
118         for (i = 0; longopts[i].name; i++) {\r
119 \r
120                 if (strcmp(str, longopts[i].name)) {\r
121                         continue;\r
122                 }\r
123 \r
124                 if (longindex != NULL) {\r
125                         *longindex = i;\r
126                 }\r
127 \r
128                 if (longopts[i].flag != NULL) {\r
129                         *(longopts[i].flag) = longopts[i].val;\r
130                 }\r
131 \r
132                 switch (longopts[i].has_arg) {\r
133                 case required_argument:\r
134                         optarg = strtok(NULL, "=");\r
135                         if (optarg != NULL) {\r
136                                 break;\r
137                         }\r
138 \r
139                         if (++optind == argc || argv[optind][0] == '-') {\r
140                                 return '?';\r
141                         }\r
142 \r
143                         optarg = argv[optind];\r
144                         break;\r
145                 case optional_argument:\r
146                         optarg = strtok(NULL, "=");\r
147                         if (optarg != NULL) {\r
148                                 break;\r
149                         }\r
150 \r
151                         if (optind + 1 == argc || argv[optind + 1][0] == '-') {\r
152                                 break;\r
153                         }\r
154 \r
155                         optarg = argv[++optind];\r
156                         break;\r
157                 default:\r
158                         break;\r
159                 }\r
160 \r
161                 optind++;\r
162                 if (longopts[i].flag == 0) {\r
163                         return (longopts[i].val);\r
164                 } else {\r
165                         return 0;\r
166                 }\r
167         }\r
168         return '?';\r
169 }\r