summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libc/stdlib/getopt_long.c89
1 files changed, 61 insertions, 28 deletions
diff --git a/src/lib/libc/stdlib/getopt_long.c b/src/lib/libc/stdlib/getopt_long.c
index bcbd53cf44..7674d4a1e4 100644
--- a/src/lib/libc/stdlib/getopt_long.c
+++ b/src/lib/libc/stdlib/getopt_long.c
@@ -1,6 +1,32 @@
1/* $OpenBSD: getopt_long.c,v 1.4 2002/12/05 22:26:04 millert Exp $ */ 1/* $OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 millert Exp $ */
2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 2/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
3 3
4/*
5 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
4/*- 30/*-
5 * Copyright (c) 2000 The NetBSD Foundation, Inc. 31 * Copyright (c) 2000 The NetBSD Foundation, Inc.
6 * All rights reserved. 32 * All rights reserved.
@@ -38,7 +64,7 @@
38 */ 64 */
39 65
40#if defined(LIBC_SCCS) && !defined(lint) 66#if defined(LIBC_SCCS) && !defined(lint)
41static char *rcsid = "$OpenBSD: getopt_long.c,v 1.4 2002/12/05 22:26:04 millert Exp $"; 67static char *rcsid = "$OpenBSD: getopt_long.c,v 1.5 2002/12/06 16:03:29 millert Exp $";
42#endif /* LIBC_SCCS and not lint */ 68#endif /* LIBC_SCCS and not lint */
43 69
44#include <err.h> 70#include <err.h>
@@ -70,7 +96,7 @@ char *optarg; /* argument associated with option */
70 96
71static int getopt_internal(int, char * const *, const char *, 97static int getopt_internal(int, char * const *, const char *,
72 const struct option *, int *, int); 98 const struct option *, int *, int);
73static int parse_long_options(int, char * const *, const char *, 99static int parse_long_options(char * const *, const char *,
74 const struct option *, int *, int); 100 const struct option *, int *, int);
75static int gcd(int, int); 101static int gcd(int, int);
76static void permute_args(int, int, int, char * const *); 102static void permute_args(int, int, int, char * const *);
@@ -103,7 +129,7 @@ gcd(int a, int b)
103 b = c; 129 b = c;
104 c = a % b; 130 c = a % b;
105 } 131 }
106 132
107 return (b); 133 return (b);
108} 134}
109 135
@@ -147,11 +173,11 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end,
147/* 173/*
148 * parse_long_options -- 174 * parse_long_options --
149 * Parse long options in argc/argv argument vector. 175 * Parse long options in argc/argv argument vector.
150 * Returns -2 if long_only is set and the current option could be a short 176 * Returns -1 if long_only is set and the current option could be a short
151 * (single character) option instead. 177 * (single character) option instead.
152 */ 178 */
153static int 179static int
154parse_long_options(int nargc, char * const *nargv, const char *options, 180parse_long_options(char * const *nargv, const char *options,
155 const struct option *long_options, int *idx, int long_only) 181 const struct option *long_options, int *idx, int long_only)
156{ 182{
157 char *current_argv, *has_equal; 183 char *current_argv, *has_equal;
@@ -249,7 +275,7 @@ parse_long_options(int nargc, char * const *nargv, const char *options,
249 } else { /* unknown option */ 275 } else { /* unknown option */
250 if (long_only) { 276 if (long_only) {
251 --optind; 277 --optind;
252 return (-2); 278 return (-1);
253 } 279 }
254 if (PRINT_ERROR) 280 if (PRINT_ERROR)
255 warnx(illoptstring, current_argv); 281 warnx(illoptstring, current_argv);
@@ -261,7 +287,7 @@ parse_long_options(int nargc, char * const *nargv, const char *options,
261 if (long_options[match].flag) { 287 if (long_options[match].flag) {
262 *long_options[match].flag = long_options[match].val; 288 *long_options[match].flag = long_options[match].val;
263 return (0); 289 return (0);
264 } else 290 } else
265 return (long_options[match].val); 291 return (long_options[match].val);
266} 292}
267 293
@@ -275,6 +301,7 @@ getopt_internal(int nargc, char * const *nargv, const char *options,
275{ 301{
276 char *oli; /* option letter list index */ 302 char *oli; /* option letter list index */
277 int optchar; 303 int optchar;
304 int long_only;
278 static int posixly_correct = -1; 305 static int posixly_correct = -1;
279 306
280 optarg = NULL; 307 optarg = NULL;
@@ -328,7 +355,7 @@ start:
328 place = EMSG; 355 place = EMSG;
329 if (flags & FLAG_ALLARGS) { 356 if (flags & FLAG_ALLARGS) {
330 /* 357 /*
331 * GNU extension: 358 * GNU extension:
332 * return non-option as argument to option 1 359 * return non-option as argument to option 1
333 */ 360 */
334 optarg = nargv[optind++]; 361 optarg = nargv[optind++];
@@ -373,31 +400,37 @@ start:
373 return (-1); 400 return (-1);
374 } 401 }
375 place++; 402 place++;
403 }
376 404
377 /* Check long options if we have any */ 405 /* Check long options if we have any */
378 if (long_options != NULL) { 406 long_only = 0;
379 int long_only = 0; 407 if (long_options != NULL) {
380 408 if (*place == '-' ||
381 if (*place == '-' || 409 (long_only = (flags & FLAG_LONGONLY))) {
382 (long_only = (flags & FLAG_LONGONLY))) { 410 if (!long_only)
383 if (!long_only) 411 place++;
384 place++; 412 optchar = parse_long_options(nargv, options,
385 optchar = parse_long_options(nargc, nargv, 413 long_options, idx, long_only);
386 options, long_options, idx, long_only); 414 if (optchar != -1) {
387 if (optchar != -2) { 415 place = EMSG;
388 place = EMSG; 416 return (optchar);
389 return (optchar);
390 }
391 } 417 }
392 } 418 }
393 } 419 }
394 if ((optchar = (int)*place++) == (int)':' || 420 if ((optchar = (int)*place++) == (int)':' ||
395 (oli = strchr(options, optchar)) == NULL) { 421 (oli = strchr(options, optchar)) == NULL) {
396 /* option letter unknown or ':' */ 422 /* option letter unknown or ':' */
397 if (!*place) 423 if (PRINT_ERROR) {
424 if (long_only)
425 warnx(illoptstring, place - 1);
426 else
427 warnx(illoptchar, optchar);
428 }
429 if (!*place || long_only) {
398 ++optind; 430 ++optind;
399 if (PRINT_ERROR) 431 if (*place)
400 warnx(illoptchar, optchar); 432 place = EMSG;
433 }
401 optopt = optchar; 434 optopt = optchar;
402 return (BADCH); 435 return (BADCH);
403 } 436 }
@@ -413,8 +446,8 @@ start:
413 return (BADARG); 446 return (BADARG);
414 } else /* white space */ 447 } else /* white space */
415 place = nargv[optind]; 448 place = nargv[optind];
416 optchar = parse_long_options(nargc, nargv, options, 449 optchar = parse_long_options(nargv, options, long_options,
417 long_options, idx, 0); 450 idx, 0);
418 place = EMSG; 451 place = EMSG;
419 return (optchar); 452 return (optchar);
420 } 453 }