/src/hpn-ssh/openbsd-compat/getopt_long.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* $OpenBSD: getopt_long.c,v 1.25 2011/03/05 22:10:11 guenther Exp $ */ |
2 | | /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ |
3 | | |
4 | | /* |
5 | | * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> |
6 | | * |
7 | | * Permission to use, copy, modify, and distribute this software for any |
8 | | * purpose with or without fee is hereby granted, provided that the above |
9 | | * copyright notice and this permission notice appear in all copies. |
10 | | * |
11 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | | * |
19 | | * Sponsored in part by the Defense Advanced Research Projects |
20 | | * Agency (DARPA) and Air Force Research Laboratory, Air Force |
21 | | * Materiel Command, USAF, under agreement number F39502-99-1-0512. |
22 | | */ |
23 | | /*- |
24 | | * Copyright (c) 2000 The NetBSD Foundation, Inc. |
25 | | * All rights reserved. |
26 | | * |
27 | | * This code is derived from software contributed to The NetBSD Foundation |
28 | | * by Dieter Baron and Thomas Klausner. |
29 | | * |
30 | | * Redistribution and use in source and binary forms, with or without |
31 | | * modification, are permitted provided that the following conditions |
32 | | * are met: |
33 | | * 1. Redistributions of source code must retain the above copyright |
34 | | * notice, this list of conditions and the following disclaimer. |
35 | | * 2. Redistributions in binary form must reproduce the above copyright |
36 | | * notice, this list of conditions and the following disclaimer in the |
37 | | * documentation and/or other materials provided with the distribution. |
38 | | * |
39 | | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
40 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
41 | | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
42 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
43 | | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
44 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
45 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
46 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
47 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
48 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
49 | | * POSSIBILITY OF SUCH DAMAGE. |
50 | | */ |
51 | | |
52 | | /* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */ |
53 | | #include "includes.h" |
54 | | |
55 | | #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) |
56 | | |
57 | | /* |
58 | | * Some defines to make it easier to keep the code in sync with upstream. |
59 | | * getopt opterr optind optopt optreset optarg are all in defines.h which is |
60 | | * pulled in by includes.h. |
61 | | */ |
62 | 0 | #define warnx logit |
63 | | |
64 | | #if 0 |
65 | | #include <err.h> |
66 | | #include <getopt.h> |
67 | | #endif |
68 | | #include <errno.h> |
69 | | #include <stdlib.h> |
70 | | #include <string.h> |
71 | | #include <stdarg.h> |
72 | | |
73 | | #include "log.h" |
74 | | |
75 | | struct option { |
76 | | /* name of long option */ |
77 | | const char *name; |
78 | | /* |
79 | | * one of no_argument, required_argument, and optional_argument: |
80 | | * whether option takes an argument |
81 | | */ |
82 | | int has_arg; |
83 | | /* if not NULL, set *flag to val when option found */ |
84 | | int *flag; |
85 | | /* if flag not NULL, value to set *flag to; else return value */ |
86 | | int val; |
87 | | }; |
88 | | |
89 | | int opterr = 1; /* if error message should be printed */ |
90 | | int optind = 1; /* index into parent argv vector */ |
91 | | int optopt = '?'; /* character checked for validity */ |
92 | | int optreset; /* reset getopt */ |
93 | | char *optarg; /* argument associated with option */ |
94 | | |
95 | 0 | #define PRINT_ERROR ((opterr) && (*options != ':')) |
96 | | |
97 | 0 | #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ |
98 | 0 | #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ |
99 | 0 | #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ |
100 | | |
101 | | /* return values */ |
102 | 0 | #define BADCH (int)'?' |
103 | 0 | #define BADARG ((*options == ':') ? (int)':' : (int)'?') |
104 | 0 | #define INORDER (int)1 |
105 | | |
106 | 0 | #define EMSG "" |
107 | | |
108 | | static int getopt_internal(int, char * const *, const char *, |
109 | | const struct option *, int *, int); |
110 | | static int parse_long_options(char * const *, const char *, |
111 | | const struct option *, int *, int); |
112 | | static int gcd(int, int); |
113 | | static void permute_args(int, int, int, char * const *); |
114 | | |
115 | | static char *place = EMSG; /* option letter processing */ |
116 | | |
117 | | /* XXX: set optreset to 1 rather than these two */ |
118 | | static int nonopt_start = -1; /* first non option argument (for permute) */ |
119 | | static int nonopt_end = -1; /* first option after non options (for permute) */ |
120 | | |
121 | | /* Error messages */ |
122 | | static const char recargchar[] = "option requires an argument -- %c"; |
123 | | static const char recargstring[] = "option requires an argument -- %s"; |
124 | | static const char ambig[] = "ambiguous option -- %.*s"; |
125 | | static const char noarg[] = "option doesn't take an argument -- %.*s"; |
126 | | static const char illoptchar[] = "unknown option -- %c"; |
127 | | static const char illoptstring[] = "unknown option -- %s"; |
128 | | |
129 | | /* |
130 | | * Compute the greatest common divisor of a and b. |
131 | | */ |
132 | | static int |
133 | | gcd(int a, int b) |
134 | 0 | { |
135 | 0 | int c; |
136 | |
|
137 | 0 | c = a % b; |
138 | 0 | while (c != 0) { |
139 | 0 | a = b; |
140 | 0 | b = c; |
141 | 0 | c = a % b; |
142 | 0 | } |
143 | |
|
144 | 0 | return (b); |
145 | 0 | } |
146 | | |
147 | | /* |
148 | | * Exchange the block from nonopt_start to nonopt_end with the block |
149 | | * from nonopt_end to opt_end (keeping the same order of arguments |
150 | | * in each block). |
151 | | */ |
152 | | static void |
153 | | permute_args(int panonopt_start, int panonopt_end, int opt_end, |
154 | | char * const *nargv) |
155 | 0 | { |
156 | 0 | int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; |
157 | 0 | char *swap; |
158 | | |
159 | | /* |
160 | | * compute lengths of blocks and number and size of cycles |
161 | | */ |
162 | 0 | nnonopts = panonopt_end - panonopt_start; |
163 | 0 | nopts = opt_end - panonopt_end; |
164 | 0 | ncycle = gcd(nnonopts, nopts); |
165 | 0 | cyclelen = (opt_end - panonopt_start) / ncycle; |
166 | |
|
167 | 0 | for (i = 0; i < ncycle; i++) { |
168 | 0 | cstart = panonopt_end+i; |
169 | 0 | pos = cstart; |
170 | 0 | for (j = 0; j < cyclelen; j++) { |
171 | 0 | if (pos >= panonopt_end) |
172 | 0 | pos -= nnonopts; |
173 | 0 | else |
174 | 0 | pos += nopts; |
175 | 0 | swap = nargv[pos]; |
176 | | /* LINTED const cast */ |
177 | 0 | ((char **) nargv)[pos] = nargv[cstart]; |
178 | | /* LINTED const cast */ |
179 | 0 | ((char **)nargv)[cstart] = swap; |
180 | 0 | } |
181 | 0 | } |
182 | 0 | } |
183 | | |
184 | | /* |
185 | | * parse_long_options -- |
186 | | * Parse long options in argc/argv argument vector. |
187 | | * Returns -1 if short_too is set and the option does not match long_options. |
188 | | */ |
189 | | static int |
190 | | parse_long_options(char * const *nargv, const char *options, |
191 | | const struct option *long_options, int *idx, int short_too) |
192 | 0 | { |
193 | 0 | char *current_argv, *has_equal; |
194 | 0 | size_t current_argv_len; |
195 | 0 | int i, match; |
196 | |
|
197 | 0 | current_argv = place; |
198 | 0 | match = -1; |
199 | |
|
200 | 0 | optind++; |
201 | |
|
202 | 0 | if ((has_equal = strchr(current_argv, '=')) != NULL) { |
203 | | /* argument found (--option=arg) */ |
204 | 0 | current_argv_len = has_equal - current_argv; |
205 | 0 | has_equal++; |
206 | 0 | } else |
207 | 0 | current_argv_len = strlen(current_argv); |
208 | |
|
209 | 0 | for (i = 0; long_options[i].name; i++) { |
210 | | /* find matching long option */ |
211 | 0 | if (strncmp(current_argv, long_options[i].name, |
212 | 0 | current_argv_len)) |
213 | 0 | continue; |
214 | | |
215 | 0 | if (strlen(long_options[i].name) == current_argv_len) { |
216 | | /* exact match */ |
217 | 0 | match = i; |
218 | 0 | break; |
219 | 0 | } |
220 | | /* |
221 | | * If this is a known short option, don't allow |
222 | | * a partial match of a single character. |
223 | | */ |
224 | 0 | if (short_too && current_argv_len == 1) |
225 | 0 | continue; |
226 | | |
227 | 0 | if (match == -1) /* partial match */ |
228 | 0 | match = i; |
229 | 0 | else { |
230 | | /* ambiguous abbreviation */ |
231 | 0 | if (PRINT_ERROR) |
232 | 0 | warnx(ambig, (int)current_argv_len, |
233 | 0 | current_argv); |
234 | 0 | optopt = 0; |
235 | 0 | return (BADCH); |
236 | 0 | } |
237 | 0 | } |
238 | 0 | if (match != -1) { /* option found */ |
239 | 0 | if (long_options[match].has_arg == no_argument |
240 | 0 | && has_equal) { |
241 | 0 | if (PRINT_ERROR) |
242 | 0 | warnx(noarg, (int)current_argv_len, |
243 | 0 | current_argv); |
244 | | /* |
245 | | * XXX: GNU sets optopt to val regardless of flag |
246 | | */ |
247 | 0 | if (long_options[match].flag == NULL) |
248 | 0 | optopt = long_options[match].val; |
249 | 0 | else |
250 | 0 | optopt = 0; |
251 | 0 | return (BADARG); |
252 | 0 | } |
253 | 0 | if (long_options[match].has_arg == required_argument || |
254 | 0 | long_options[match].has_arg == optional_argument) { |
255 | 0 | if (has_equal) |
256 | 0 | optarg = has_equal; |
257 | 0 | else if (long_options[match].has_arg == |
258 | 0 | required_argument) { |
259 | | /* |
260 | | * optional argument doesn't use next nargv |
261 | | */ |
262 | 0 | optarg = nargv[optind++]; |
263 | 0 | } |
264 | 0 | } |
265 | 0 | if ((long_options[match].has_arg == required_argument) |
266 | 0 | && (optarg == NULL)) { |
267 | | /* |
268 | | * Missing argument; leading ':' indicates no error |
269 | | * should be generated. |
270 | | */ |
271 | 0 | if (PRINT_ERROR) |
272 | 0 | warnx(recargstring, |
273 | 0 | current_argv); |
274 | | /* |
275 | | * XXX: GNU sets optopt to val regardless of flag |
276 | | */ |
277 | 0 | if (long_options[match].flag == NULL) |
278 | 0 | optopt = long_options[match].val; |
279 | 0 | else |
280 | 0 | optopt = 0; |
281 | 0 | --optind; |
282 | 0 | return (BADARG); |
283 | 0 | } |
284 | 0 | } else { /* unknown option */ |
285 | 0 | if (short_too) { |
286 | 0 | --optind; |
287 | 0 | return (-1); |
288 | 0 | } |
289 | 0 | if (PRINT_ERROR) |
290 | 0 | warnx(illoptstring, current_argv); |
291 | 0 | optopt = 0; |
292 | 0 | return (BADCH); |
293 | 0 | } |
294 | 0 | if (idx) |
295 | 0 | *idx = match; |
296 | 0 | if (long_options[match].flag) { |
297 | 0 | *long_options[match].flag = long_options[match].val; |
298 | 0 | return (0); |
299 | 0 | } else |
300 | 0 | return (long_options[match].val); |
301 | 0 | } |
302 | | |
303 | | /* |
304 | | * getopt_internal -- |
305 | | * Parse argc/argv argument vector. Called by user level routines. |
306 | | */ |
307 | | static int |
308 | | getopt_internal(int nargc, char * const *nargv, const char *options, |
309 | | const struct option *long_options, int *idx, int flags) |
310 | 0 | { |
311 | 0 | char *oli; /* option letter list index */ |
312 | 0 | int optchar, short_too; |
313 | 0 | static int posixly_correct = -1; |
314 | |
|
315 | 0 | if (options == NULL) |
316 | 0 | return (-1); |
317 | | |
318 | | /* |
319 | | * XXX Some GNU programs (like cvs) set optind to 0 instead of |
320 | | * XXX using optreset. Work around this braindamage. |
321 | | */ |
322 | 0 | if (optind == 0) |
323 | 0 | optind = optreset = 1; |
324 | | |
325 | | /* |
326 | | * Disable GNU extensions if POSIXLY_CORRECT is set or options |
327 | | * string begins with a '+'. |
328 | | */ |
329 | 0 | if (posixly_correct == -1 || optreset) |
330 | 0 | posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); |
331 | 0 | if (*options == '-') |
332 | 0 | flags |= FLAG_ALLARGS; |
333 | 0 | else if (posixly_correct || *options == '+') |
334 | 0 | flags &= ~FLAG_PERMUTE; |
335 | 0 | if (*options == '+' || *options == '-') |
336 | 0 | options++; |
337 | |
|
338 | 0 | optarg = NULL; |
339 | 0 | if (optreset) |
340 | 0 | nonopt_start = nonopt_end = -1; |
341 | 0 | start: |
342 | 0 | if (optreset || !*place) { /* update scanning pointer */ |
343 | 0 | optreset = 0; |
344 | 0 | if (optind >= nargc) { /* end of argument vector */ |
345 | 0 | place = EMSG; |
346 | 0 | if (nonopt_end != -1) { |
347 | | /* do permutation, if we have to */ |
348 | 0 | permute_args(nonopt_start, nonopt_end, |
349 | 0 | optind, nargv); |
350 | 0 | optind -= nonopt_end - nonopt_start; |
351 | 0 | } |
352 | 0 | else if (nonopt_start != -1) { |
353 | | /* |
354 | | * If we skipped non-options, set optind |
355 | | * to the first of them. |
356 | | */ |
357 | 0 | optind = nonopt_start; |
358 | 0 | } |
359 | 0 | nonopt_start = nonopt_end = -1; |
360 | 0 | return (-1); |
361 | 0 | } |
362 | 0 | if (*(place = nargv[optind]) != '-' || |
363 | 0 | (place[1] == '\0' && strchr(options, '-') == NULL)) { |
364 | 0 | place = EMSG; /* found non-option */ |
365 | 0 | if (flags & FLAG_ALLARGS) { |
366 | | /* |
367 | | * GNU extension: |
368 | | * return non-option as argument to option 1 |
369 | | */ |
370 | 0 | optarg = nargv[optind++]; |
371 | 0 | return (INORDER); |
372 | 0 | } |
373 | 0 | if (!(flags & FLAG_PERMUTE)) { |
374 | | /* |
375 | | * If no permutation wanted, stop parsing |
376 | | * at first non-option. |
377 | | */ |
378 | 0 | return (-1); |
379 | 0 | } |
380 | | /* do permutation */ |
381 | 0 | if (nonopt_start == -1) |
382 | 0 | nonopt_start = optind; |
383 | 0 | else if (nonopt_end != -1) { |
384 | 0 | permute_args(nonopt_start, nonopt_end, |
385 | 0 | optind, nargv); |
386 | 0 | nonopt_start = optind - |
387 | 0 | (nonopt_end - nonopt_start); |
388 | 0 | nonopt_end = -1; |
389 | 0 | } |
390 | 0 | optind++; |
391 | | /* process next argument */ |
392 | 0 | goto start; |
393 | 0 | } |
394 | 0 | if (nonopt_start != -1 && nonopt_end == -1) |
395 | 0 | nonopt_end = optind; |
396 | | |
397 | | /* |
398 | | * If we have "-" do nothing, if "--" we are done. |
399 | | */ |
400 | 0 | if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { |
401 | 0 | optind++; |
402 | 0 | place = EMSG; |
403 | | /* |
404 | | * We found an option (--), so if we skipped |
405 | | * non-options, we have to permute. |
406 | | */ |
407 | 0 | if (nonopt_end != -1) { |
408 | 0 | permute_args(nonopt_start, nonopt_end, |
409 | 0 | optind, nargv); |
410 | 0 | optind -= nonopt_end - nonopt_start; |
411 | 0 | } |
412 | 0 | nonopt_start = nonopt_end = -1; |
413 | 0 | return (-1); |
414 | 0 | } |
415 | 0 | } |
416 | | |
417 | | /* |
418 | | * Check long options if: |
419 | | * 1) we were passed some |
420 | | * 2) the arg is not just "-" |
421 | | * 3) either the arg starts with -- we are getopt_long_only() |
422 | | */ |
423 | 0 | if (long_options != NULL && place != nargv[optind] && |
424 | 0 | (*place == '-' || (flags & FLAG_LONGONLY))) { |
425 | 0 | short_too = 0; |
426 | 0 | if (*place == '-') |
427 | 0 | place++; /* --foo long option */ |
428 | 0 | else if (*place != ':' && strchr(options, *place) != NULL) |
429 | 0 | short_too = 1; /* could be short option too */ |
430 | |
|
431 | 0 | optchar = parse_long_options(nargv, options, long_options, |
432 | 0 | idx, short_too); |
433 | 0 | if (optchar != -1) { |
434 | 0 | place = EMSG; |
435 | 0 | return (optchar); |
436 | 0 | } |
437 | 0 | } |
438 | | |
439 | 0 | if ((optchar = (int)*place++) == (int)':' || |
440 | 0 | (optchar == (int)'-' && *place != '\0') || |
441 | 0 | (oli = strchr(options, optchar)) == NULL) { |
442 | | /* |
443 | | * If the user specified "-" and '-' isn't listed in |
444 | | * options, return -1 (non-option) as per POSIX. |
445 | | * Otherwise, it is an unknown option character (or ':'). |
446 | | */ |
447 | 0 | if (optchar == (int)'-' && *place == '\0') |
448 | 0 | return (-1); |
449 | 0 | if (!*place) |
450 | 0 | ++optind; |
451 | 0 | if (PRINT_ERROR) |
452 | 0 | warnx(illoptchar, optchar); |
453 | 0 | optopt = optchar; |
454 | 0 | return (BADCH); |
455 | 0 | } |
456 | 0 | if (long_options != NULL && optchar == 'W' && oli[1] == ';') { |
457 | | /* -W long-option */ |
458 | 0 | if (*place) /* no space */ |
459 | 0 | /* NOTHING */; |
460 | 0 | else if (++optind >= nargc) { /* no arg */ |
461 | 0 | place = EMSG; |
462 | 0 | if (PRINT_ERROR) |
463 | 0 | warnx(recargchar, optchar); |
464 | 0 | optopt = optchar; |
465 | 0 | return (BADARG); |
466 | 0 | } else /* white space */ |
467 | 0 | place = nargv[optind]; |
468 | 0 | optchar = parse_long_options(nargv, options, long_options, |
469 | 0 | idx, 0); |
470 | 0 | place = EMSG; |
471 | 0 | return (optchar); |
472 | 0 | } |
473 | 0 | if (*++oli != ':') { /* doesn't take argument */ |
474 | 0 | if (!*place) |
475 | 0 | ++optind; |
476 | 0 | } else { /* takes (optional) argument */ |
477 | 0 | optarg = NULL; |
478 | 0 | if (*place) /* no white space */ |
479 | 0 | optarg = place; |
480 | 0 | else if (oli[1] != ':') { /* arg not optional */ |
481 | 0 | if (++optind >= nargc) { /* no arg */ |
482 | 0 | place = EMSG; |
483 | 0 | if (PRINT_ERROR) |
484 | 0 | warnx(recargchar, optchar); |
485 | 0 | optopt = optchar; |
486 | 0 | return (BADARG); |
487 | 0 | } else |
488 | 0 | optarg = nargv[optind]; |
489 | 0 | } |
490 | 0 | place = EMSG; |
491 | 0 | ++optind; |
492 | 0 | } |
493 | | /* dump back option letter */ |
494 | 0 | return (optchar); |
495 | 0 | } |
496 | | |
497 | | /* |
498 | | * getopt -- |
499 | | * Parse argc/argv argument vector. |
500 | | * |
501 | | * [eventually this will replace the BSD getopt] |
502 | | */ |
503 | | int |
504 | | getopt(int nargc, char * const *nargv, const char *options) |
505 | 0 | { |
506 | | |
507 | | /* |
508 | | * We don't pass FLAG_PERMUTE to getopt_internal() since |
509 | | * the BSD getopt(3) (unlike GNU) has never done this. |
510 | | * |
511 | | * Furthermore, since many privileged programs call getopt() |
512 | | * before dropping privileges it makes sense to keep things |
513 | | * as simple (and bug-free) as possible. |
514 | | */ |
515 | 0 | return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); |
516 | 0 | } |
517 | | |
518 | | #if 0 |
519 | | /* |
520 | | * getopt_long -- |
521 | | * Parse argc/argv argument vector. |
522 | | */ |
523 | | int |
524 | | getopt_long(int nargc, char * const *nargv, const char *options, |
525 | | const struct option *long_options, int *idx) |
526 | | { |
527 | | |
528 | | return (getopt_internal(nargc, nargv, options, long_options, idx, |
529 | | FLAG_PERMUTE)); |
530 | | } |
531 | | |
532 | | /* |
533 | | * getopt_long_only -- |
534 | | * Parse argc/argv argument vector. |
535 | | */ |
536 | | int |
537 | | getopt_long_only(int nargc, char * const *nargv, const char *options, |
538 | | const struct option *long_options, int *idx) |
539 | | { |
540 | | |
541 | | return (getopt_internal(nargc, nargv, options, long_options, idx, |
542 | | FLAG_PERMUTE|FLAG_LONGONLY)); |
543 | | } |
544 | | #endif |
545 | | |
546 | | #endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ |