2
NOTE: getopt is now part of the C library, so if you don't know what
3
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
6
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
7
Free Software Foundation, Inc.
9
This program is free software; you can redistribute it and/or modify it
10
under the terms of the GNU General Public License as published by the
11
Free Software Foundation; either version 2, or (at your zbx_option) any
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
28
long-named zbx_option. Because this is not POSIX.2 compliant, it is
30
/* #define GETOPT_COMPAT */
33
/* This version of `getopt' appears to the caller like standard Unix `getopt'
34
but it behaves differently for the user, since it allows the user
35
to intersperse the options with the other arguments.
37
As `getopt' works, it permutes the elements of ARGV so that,
38
when it is done, all the options precede everything else. Thus
39
all application programs are extended to handle flexible argument order.
41
Setting the environment variable POSIXLY_CORRECT disables permutation.
42
Then the behavior is completely standard.
44
GNU application programs can use a third alternative mode in which
45
they can distinguish the relative order of options and other arguments. */
47
#include "zbxgetopt.h"
51
/* For communication from `getopt' to the caller.
52
When `getopt' finds an zbx_option that takes an argument,
53
the argument value is returned here.
54
Also, when `ordering' is RETURN_IN_ORDER,
55
each non-zbx_option ARGV-element is returned here. */
57
char *zbx_optarg = NULL;
59
/* Index in ARGV of the next element to be scanned.
60
This is used for communication to and from the caller
61
and for communication between successive calls to `getopt'.
63
On entry to `getopt', zero means this is the first call; initialize.
65
When `getopt' returns EOF, this is the index of the first of the
66
non-zbx_option elements that the caller should itself scan.
68
Otherwise, `zbx_optind' communicates from one call to the next
69
how much of ARGV has been scanned so far. */
71
/* XXX 1003.2 says this must be 1 before any call. */
74
/* The next char to be scanned in the zbx_option-element
75
in which the last zbx_option character we returned was found.
76
This allows us to pick up the scan where we left off.
78
If this is zero, or a null string, it means resume the scan
79
by advancing to the next ARGV-element. */
81
static char *nextchar;
83
/* Callers store zero here to inhibit the error message
84
for unrecognized options. */
88
/* Set to an zbx_option character which was unrecognized.
89
This must be initialized on some systems to avoid linking in the
90
system's own getopt implementation. */
92
#define BAD_OPTION '\0'
93
int zbx_optopt = BAD_OPTION;
95
/* Describe how to deal with options that follow non-zbx_option ARGV-elements.
97
If the caller did not specify anything,
98
the default is REQUIRE_ORDER if the environment variable
99
POSIXLY_CORRECT is defined, PERMUTE otherwise.
101
REQUIRE_ORDER means don't recognize them as options;
102
stop zbx_option processing when the first non-zbx_option is seen.
103
This is what Unix does.
104
This mode of operation is selected by either setting the environment
105
variable POSIXLY_CORRECT, or using `+' as the first character
106
of the list of zbx_option characters.
108
PERMUTE is the default. We permute the contents of ARGV as we scan,
109
so that eventually all the non-options are at the end. This allows options
110
to be given in any order, even with programs that were not written to
113
RETURN_IN_ORDER is an zbx_option available to programs that were written
114
to expect options and other ARGV-elements in any order and that care about
115
the ordering of the two. We describe each non-zbx_option ARGV-element
116
as if it were the argument of an zbx_option with character code 1.
117
Using `-' as the first character of the list of zbx_option characters
118
selects this mode of operation.
120
The special argument `--' forces an end of zbx_option-scanning regardless
121
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
122
`--' can cause `getopt' to return EOF with `zbx_optind' != ARGC. */
126
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
129
/* Handle permutation of arguments. */
131
/* Describe the part of ARGV that contains non-options that have
132
been skipped. `first_nonopt' is the index in ARGV of the first of them;
133
`last_nonopt' is the index after the last of them. */
135
static int first_nonopt;
136
static int last_nonopt;
138
/* Exchange two adjacent subsequences of ARGV.
139
One subsequence is elements [first_nonopt,last_nonopt)
140
which contains all the non-options that have been skipped so far.
141
The other is elements [last_nonopt,zbx_optind), which contains all
142
the options processed since those non-options were skipped.
144
`first_nonopt' and `last_nonopt' are relocated so that they describe
145
the new indices of the non-options in ARGV after they are moved.
147
To perform the swap, we first reverse the order of all elements. So
148
all options now come before all non options, but they are in the
149
wrong order. So we put back the options and non options in original
150
order by reversing them again. For example:
151
original input: a b c -x -y
152
reverse all: -y -x c b a
153
reverse options: -x -y c b a
154
reverse non options: -x -y a b c
158
static void exchange (char **argv)
160
char *temp; char **first, **last;
162
/* Reverse all the elements [first_nonopt, zbx_optind) */
163
first = &argv[first_nonopt];
164
last = &argv[zbx_optind-1];
165
while (first < last) {
166
temp = *first; *first = *last; *last = temp; first++; last--;
168
/* Put back the options in order */
169
first = &argv[first_nonopt];
170
first_nonopt += (zbx_optind - last_nonopt);
171
last = &argv[first_nonopt - 1];
172
while (first < last) {
173
temp = *first; *first = *last; *last = temp; first++; last--;
176
/* Put back the non options in order */
177
first = &argv[first_nonopt];
178
last_nonopt = zbx_optind;
179
last = &argv[last_nonopt-1];
180
while (first < last) {
181
temp = *first; *first = *last; *last = temp; first++; last--;
185
/* Scan elements of ARGV (whose length is ARGC) for zbx_option characters
188
If an element of ARGV starts with '-', and is not exactly "-" or "--",
189
then it is an zbx_option element. The characters of this element
190
(aside from the initial '-') are zbx_option characters. If `getopt'
191
is called repeatedly, it returns successively each of the zbx_option characters
192
from each of the zbx_option elements.
194
If `getopt' finds another zbx_option character, it returns that character,
195
updating `zbx_optind' and `nextchar' so that the next call to `getopt' can
196
resume the scan with the following zbx_option character or ARGV-element.
198
If there are no more zbx_option characters, `getopt' returns `EOF'.
199
Then `zbx_optind' is the index in ARGV of the first ARGV-element
200
that is not an zbx_option. (The ARGV-elements have been permuted
201
so that those that are not options now come last.)
203
OPTSTRING is a string containing the legitimate zbx_option characters.
204
If an zbx_option character is seen that is not listed in OPTSTRING,
205
return BAD_OPTION after printing an error message. If you set `zbx_opterr' to
206
zero, the error message is suppressed but we still return BAD_OPTION.
208
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
209
so the following text in the same ARGV-element, or the text of the following
210
ARGV-element, is returned in `zbx_optarg'. Two colons mean an zbx_option that
211
wants an optional arg; if there is text in the current ARGV-element,
212
it is returned in `zbx_optarg', otherwise `zbx_optarg' is set to zero.
214
If OPTSTRING starts with `-' or `+', it requests different methods of
215
handling the non-zbx_option ARGV-elements.
216
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
218
Long-named options begin with `--' instead of `-'.
219
Their names may be abbreviated as long as the abbreviation is unique
220
or is an exact match for some defined zbx_option. If they have an
221
argument, it follows the zbx_option name in the same ARGV-element, separated
222
from the zbx_option name by a `=', or else the in next ARGV-element.
223
When `getopt' finds a long-named zbx_option, it returns 0 if that zbx_option's
224
`flag' field is nonzero, the value of the zbx_option's `val' field
225
if the `flag' field is zero.
227
LONGOPTS is a vector of `struct zbx_option' terminated by an
228
element containing a name which is zero.
230
LONGIND returns the index in LONGOPT of the long-named zbx_option found.
231
It is only valid when a long-named zbx_option has been found by the most
234
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
235
long-named options. */
237
static int zbx_getopt_internal (int argc, char **argv, const char *optstring,
238
const struct zbx_option *longopts, int *longind,
241
static char empty_string[1];
249
/* Initialize the internal data when the first call is made.
250
Start processing options with ARGV-element 1 (since ARGV-element 0
251
is the program name); the sequence of previously skipped
252
non-zbx_option ARGV-elements is empty. */
256
first_nonopt = last_nonopt = zbx_optind = 1;
260
/* Determine how to handle the ordering of options and nonoptions. */
262
if (optstring[0] == '-')
264
ordering = RETURN_IN_ORDER;
267
else if (optstring[0] == '+')
269
ordering = REQUIRE_ORDER;
273
else if (getenv ("POSIXLY_CORRECT") != NULL)
274
ordering = REQUIRE_ORDER;
280
if (nextchar == NULL || *nextchar == '\0')
282
if (ordering == PERMUTE)
284
/* If we have just processed some options following some non-options,
285
exchange them so that the options come first. */
287
if (first_nonopt != last_nonopt && last_nonopt != zbx_optind)
289
else if (last_nonopt != zbx_optind)
290
first_nonopt = zbx_optind;
292
/* Now skip any additional non-options
293
and extend the range of non-options previously skipped. */
295
while (zbx_optind < argc
296
&& (argv[zbx_optind][0] != '-' || argv[zbx_optind][1] == '\0')
299
|| argv[zbx_optind][0] != '+' || argv[zbx_optind][1] == '\0')
300
#endif /* GETOPT_COMPAT */
303
last_nonopt = zbx_optind;
306
/* Special ARGV-element `--' means premature end of options.
307
Skip it like a null zbx_option,
308
then exchange with previous non-options as if it were an zbx_option,
309
then skip everything else like a non-zbx_option. */
311
if (zbx_optind != argc && !strcmp (argv[zbx_optind], "--"))
315
if (first_nonopt != last_nonopt && last_nonopt != zbx_optind)
317
else if (first_nonopt == last_nonopt)
318
first_nonopt = zbx_optind;
324
/* If we have done all the ARGV-elements, stop the scan
325
and back over any non-options that we skipped and permuted. */
327
if (zbx_optind == argc)
329
/* Set the next-arg-index to point at the non-options
330
that we previously skipped, so the caller will digest them. */
331
if (first_nonopt != last_nonopt)
332
zbx_optind = first_nonopt;
336
/* If we have come to a non-zbx_option and did not permute it,
337
either stop the scan or describe it to the caller and pass it by. */
339
if ((argv[zbx_optind][0] != '-' || argv[zbx_optind][1] == '\0')
342
|| argv[zbx_optind][0] != '+' || argv[zbx_optind][1] == '\0')
343
#endif /* GETOPT_COMPAT */
346
if (ordering == REQUIRE_ORDER)
348
zbx_optarg = argv[zbx_optind++];
352
/* We have found another zbx_option-ARGV-element.
353
Start decoding its characters. */
355
nextchar = (argv[zbx_optind] + 1
356
+ (longopts != NULL && argv[zbx_optind][1] == '-'));
360
&& ((argv[zbx_optind][0] == '-'
361
&& (argv[zbx_optind][1] == '-' || long_only))
363
|| argv[zbx_optind][0] == '+'
364
#endif /* GETOPT_COMPAT */
367
const struct zbx_option *p;
371
const struct zbx_option *pfound = NULL;
376
/* allow `--zbx_option#value' because you cannout assign a '='
377
to an environment variable under DOS command.com */
378
while (*s && *s != '=' && * s != '#')
381
while (*s && *s != '=')
385
/* Test all options for either exact match or abbreviated matches. */
386
for (p = longopts, option_index = 0; p->name;
388
if (!strncmp (p->name, nextchar, (unsigned) (s - nextchar)))
390
if (p->has_arg & 0x10)
392
if ((unsigned) (s - nextchar) == strlen (p->name))
394
/* Exact match found. */
396
indfound = option_index;
400
else if (pfound == NULL)
402
/* First nonexact match found. */
404
indfound = option_index;
407
/* Second nonexact match found. */
411
/* don't allow nonexact longoptions */
412
if (needexact && !exact)
415
zbx_error("unrecognized zbx_option `%s'", argv[zbx_optind]);
417
nextchar += strlen (nextchar);
424
zbx_error("zbx_option `%s' is ambiguous", argv[zbx_optind]);
426
nextchar += strlen (nextchar);
433
int have_arg = (s[0] != '\0');
434
if (have_arg && (pfound->has_arg & 0xf))
435
have_arg = (s[1] != '\0');
436
option_index = indfound;
440
/* Don't test has_arg with >, because some C compilers don't
441
allow it to be used on enums. */
442
if (pfound->has_arg & 0xf)
448
if (argv[zbx_optind - 1][1] == '-')
450
zbx_error("zbx_option `--%s' doesn't allow an argument",pfound->name);
452
/* +zbx_option or -zbx_option */
453
zbx_error("zbx_option `%c%s' doesn't allow an argument", argv[zbx_optind - 1][0], pfound->name);
455
nextchar += strlen (nextchar);
459
else if ((pfound->has_arg & 0xf) == 1)
462
if (zbx_optind < argc)
464
if (zbx_optind < argc && (pfound->has_arg & 0x20) == 0)
466
zbx_optarg = argv[zbx_optind++];
470
zbx_error("zbx_option `--%s%s' requires an argument",
471
pfound->name, (pfound->has_arg & 0x20) ? "=" : "");
472
nextchar += strlen (nextchar);
473
return optstring[0] == ':' ? ':' : BAD_OPTION;
476
nextchar += strlen (nextchar);
478
*longind = option_index;
481
*(pfound->flag) = pfound->val;
486
/* Can't find it as a long zbx_option. If this is not getopt_long_only,
487
or the zbx_option starts with '--' or is not a valid short
488
zbx_option, then it's an error.
489
Otherwise interpret it as a short zbx_option. */
490
if (!long_only || argv[zbx_optind][1] == '-'
492
|| argv[zbx_optind][0] == '+'
493
#endif /* GETOPT_COMPAT */
494
|| strchr (optstring, *nextchar) == NULL)
498
if (argv[zbx_optind][1] == '-')
500
zbx_error("unrecognized zbx_option `--%s'", nextchar);
502
/* +zbx_option or -zbx_option */
503
zbx_error("unrecognized zbx_option `%c%s'", argv[zbx_optind][0], nextchar);
505
nextchar = empty_string;
509
(void) &ambig; /* UNUSED */
512
/* Look at and handle the next zbx_option-character. */
515
char c = *nextchar++;
516
const char *temp = strchr (optstring, c);
518
/* Increment `zbx_optind' when we start to process its last character. */
519
if (*nextchar == '\0')
522
if (temp == NULL || c == ':')
527
if (c < 040 || c >= 0177)
528
zbx_error("unrecognized zbx_option, character code 0%o", c);
530
zbx_error("unrecognized zbx_option `-%c'", c);
532
/* 1003.2 specifies the format of this message. */
533
zbx_error("illegal zbx_option -- %c", c);
543
/* This is an zbx_option that accepts an argument optionally. */
544
if (*nextchar != '\0')
546
zbx_optarg = nextchar;
555
/* This is an zbx_option that requires an argument. */
556
if (*nextchar != '\0')
558
zbx_optarg = nextchar;
559
/* If we end this ARGV-element by taking the rest as an arg,
560
we must advance to the next element now. */
563
else if (zbx_optind == argc)
568
zbx_error("zbx_option `-%c' requires an argument", c);
570
/* 1003.2 specifies the format of this message. */
571
zbx_error("zbx_option requires an argument -- %c", c);
575
if (optstring[0] == ':')
581
/* We already incremented `zbx_optind' once;
582
increment it again when taking next ARGV-elt as argument. */
583
zbx_optarg = argv[zbx_optind++];
591
int zbx_getopt(int argc, char **argv, const char *optstring)
593
return zbx_getopt_internal (argc, argv, optstring,
594
(const struct zbx_option *) 0,
599
int zbx_getopt_long(int argc, char **argv, const char *options,
600
const struct zbx_option *long_options, int *opt_index)
602
return zbx_getopt_internal (argc, argv, options, long_options, opt_index, 0);
608
/* Compile with -DTEST to make an executable for use in testing
609
the above definition of `getopt'. */
617
int digit_optind = 0;
621
int this_option_optind = zbx_optind ? zbx_optind : 1;
623
c = getopt (argc, argv, "abc:d:0123456789");
639
if (digit_optind != 0 && digit_optind != this_option_optind)
640
printf ("digits occur in two different argv-elements.\n");
641
digit_optind = this_option_optind;
642
printf ("zbx_option %c\n", c);
646
printf ("zbx_option a\n");
650
printf ("zbx_option b\n");
654
printf ("zbx_option c with value `%s'\n", zbx_optarg);
661
printf ("?? getopt returned character code 0%o ??\n", c);
665
if (zbx_optind < argc)
667
printf ("non-zbx_option ARGV-elements: ");
668
while (zbx_optind < argc)
669
printf ("%s ", argv[zbx_optind++]);