Line data Source code
1 : /*
2 : * getopt_long() -- long options parser
3 : *
4 : * Portions Copyright (c) 1987, 1993, 1994
5 : * The Regents of the University of California. All rights reserved.
6 : *
7 : * Portions Copyright (c) 2003
8 : * PostgreSQL Global Development Group
9 : *
10 : * Simple conversion to C++ by Andrew Tridgell for ArduPilot. Based on
11 : * getopt_long.cpp from ccache
12 : *
13 : * Redistribution and use in source and binary forms, with or without
14 : * modification, are permitted provided that the following conditions
15 : * are met:
16 : * 1. Redistributions of source code must retain the above copyright
17 : * notice, this list of conditions and the following disclaimer.
18 : * 2. Redistributions in binary form must reproduce the above copyright
19 : * notice, this list of conditions and the following disclaimer in the
20 : * documentation and/or other materials provided with the distribution.
21 : * 3. Neither the name of the University nor the names of its contributors
22 : * may be used to endorse or promote products derived from this software
23 : * without specific prior written permission.
24 : *
25 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 : * SUCH DAMAGE.
36 : */
37 :
38 : #include <AP_HAL/AP_HAL.h>
39 :
40 : #include "getopt_cpp.h"
41 : #include <stdio.h>
42 : #include <string.h>
43 :
44 : #define GETOPT_ERROR(...) ::printf(__VA_ARGS__)
45 :
46 :
47 : /*
48 : constructor
49 : */
50 2128 : GetOptLong::GetOptLong(int _argc, char *const _argv[], const char *_optstring, const GetOptLong::option * _longopts) :
51 2128 : opterr(0),
52 2128 : optind(1),
53 2128 : optopt(0),
54 2128 : longindex(-1),
55 2128 : optarg(nullptr),
56 2128 : argc(_argc),
57 2128 : argv(_argv),
58 2128 : optstring(_optstring),
59 2128 : longopts(_longopts),
60 2128 : place("")
61 2128 : {}
62 :
63 : /*
64 : main parse code
65 : */
66 11200 : int GetOptLong::getoption(void)
67 : {
68 : const char *oli; /* option letter list index */
69 :
70 11200 : if (!*place)
71 : { /* update scanning pointer */
72 11198 : if (optind >= argc)
73 : {
74 2108 : place = "";
75 2108 : return -1;
76 : }
77 :
78 9090 : place = argv[optind];
79 :
80 9090 : if (place[0] != '-')
81 : {
82 4 : place = "";
83 4 : return -1;
84 : }
85 :
86 9086 : place++;
87 :
88 9086 : if (place[0] && place[0] == '-' && place[1] == '\0')
89 : { /* found "--" */
90 2 : ++optind;
91 2 : place = "";
92 2 : return -1;
93 : }
94 :
95 9084 : if (place[0] && place[0] == '-' && place[1])
96 : {
97 : /* long option */
98 : size_t namelen;
99 : int i;
100 :
101 8761 : place++;
102 :
103 8761 : namelen = strcspn(place, "=");
104 142696 : for (i = 0; longopts[i].name != nullptr; i++)
105 : {
106 142694 : if (strlen(longopts[i].name) == namelen
107 25497 : && strncmp(place, longopts[i].name, namelen) == 0)
108 : {
109 8759 : if (longopts[i].has_arg)
110 : {
111 8741 : if (place[namelen] == '=')
112 2398 : optarg = place + namelen + 1;
113 6343 : else if (optind < argc - 1)
114 : {
115 6339 : optind++;
116 6339 : optarg = argv[optind];
117 : }
118 : else
119 : {
120 4 : if (optstring[0] == ':')
121 2 : return BADARG;
122 2 : if (opterr) {
123 0 : GETOPT_ERROR("%s: option requires an argument -- %s\n",
124 : argv[0], place);
125 : }
126 2 : place = "";
127 2 : optind++;
128 2 : return BADCH;
129 : }
130 : }
131 : else
132 : {
133 18 : optarg = nullptr;
134 18 : if (place[namelen] != 0)
135 : {
136 : /* XXX error? */
137 : }
138 : }
139 :
140 8755 : optind++;
141 :
142 8755 : longindex = i;
143 :
144 8755 : place = "";
145 :
146 8755 : if (longopts[i].flag == nullptr)
147 8753 : return longopts[i].val;
148 : else
149 : {
150 2 : *longopts[i].flag = longopts[i].val;
151 2 : return 0;
152 : }
153 : }
154 : }
155 :
156 2 : if (opterr && optstring[0] != ':') {
157 0 : GETOPT_ERROR("%s: illegal option -- %s\n", argv[0], place);
158 : }
159 2 : place = "";
160 2 : optind++;
161 2 : return BADCH;
162 : }
163 : }
164 :
165 : /* short option */
166 325 : optopt = (int) *place++;
167 :
168 325 : oli = strchr(optstring, optopt);
169 325 : if (!oli)
170 : {
171 2 : if (!*place)
172 2 : ++optind;
173 2 : if (opterr && *optstring != ':') {
174 0 : GETOPT_ERROR("%s: illegal option -- %c\n", argv[0], optopt);
175 : }
176 2 : return BADCH;
177 : }
178 :
179 323 : if (oli[1] != ':')
180 : { /* don't need argument */
181 302 : optarg = nullptr;
182 302 : if (!*place)
183 300 : ++optind;
184 : }
185 : else
186 : { /* need an argument */
187 21 : if (*place) /* no white space */
188 2 : optarg = place;
189 19 : else if (argc <= ++optind)
190 : { /* no arg */
191 4 : place = "";
192 4 : if (*optstring == ':')
193 2 : return BADARG;
194 2 : if (opterr) {
195 0 : GETOPT_ERROR("%s: option requires an argument -- %c\n",
196 : argv[0], optopt);
197 : }
198 2 : return BADCH;
199 : }
200 : else
201 : /* white space */
202 15 : optarg = argv[optind];
203 17 : place = "";
204 17 : ++optind;
205 : }
206 319 : return optopt;
207 : }
208 :
|