Mercurial > hg > octave-jordi > gnulib-hg
annotate lib/argp-parse.c @ 18070:d460ec17f09f
autoupdate
author | Karl Berry <karl@freefriends.org> |
---|---|
date | Tue, 28 Jul 2015 13:57:32 -0700 |
parents | ab58d4870664 |
children |
rev | line source |
---|---|
16358 | 1 /* Hierarchical argument parsing, layered over getopt |
17848 | 2 Copyright (C) 1995-2000, 2002-2004, 2009-2015 Free Software Foundation, Inc. |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
3 This file is part of the GNU C Library. |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
4 Written by Miles Bader <miles@gnu.ai.mit.edu>. |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
5 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7289
diff
changeset
|
6 This program is free software: you can redistribute it and/or modify |
4419
9b828c973b9d
Get lib/argp* from glibc.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4385
diff
changeset
|
7 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7289
diff
changeset
|
8 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7289
diff
changeset
|
9 (at your option) any later version. |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
10 |
4419
9b828c973b9d
Get lib/argp* from glibc.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4385
diff
changeset
|
11 This program is distributed in the hope that it will be useful, |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
4419
9b828c973b9d
Get lib/argp* from glibc.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4385
diff
changeset
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
9b828c973b9d
Get lib/argp* from glibc.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4385
diff
changeset
|
14 GNU General Public License for more details. |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
15 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7289
diff
changeset
|
16 You should have received a copy of the GNU General Public License |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
7289
diff
changeset
|
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
18 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
19 #ifdef HAVE_CONFIG_H |
6259
96c32553b4c6
Use a consistent style for including <config.h>.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5848
diff
changeset
|
20 # include <config.h> |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
21 #endif |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
22 |
5067
1407b63897fd
Simplify argp by assuming alloca module.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4970
diff
changeset
|
23 #include <alloca.h> |
15996 | 24 #include <stdalign.h> |
5554 | 25 #include <stddef.h> |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
26 #include <stdlib.h> |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
27 #include <string.h> |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
28 #include <unistd.h> |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
29 #include <limits.h> |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
30 #include <getopt.h> |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
31 #include <getopt_int.h> |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
32 |
5188
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
33 #ifdef _LIBC |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
34 # include <libintl.h> |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
35 # undef dgettext |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
36 # define dgettext(domain, msgid) \ |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
37 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
38 #else |
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
39 # include "gettext.h" |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
40 #endif |
5615
8cf397a43dd9
Removed braces around the expansion of N_()
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
5555
diff
changeset
|
41 #define N_(msgid) msgid |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
42 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
43 #include "argp.h" |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
44 #include "argp-namefrob.h" |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
45 |
5554 | 46 #define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) |
47 | |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
48 /* Getopt return values. */ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
49 #define KEY_END (-1) /* The end of the options. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
50 #define KEY_ARG 1 /* A non-option argument. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
51 #define KEY_ERR '?' /* An error parsing the options. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
52 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
53 /* The meta-argument used to prevent any further arguments being interpreted |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
54 as options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
55 #define QUOTE "--" |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
56 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
57 /* The number of bits we steal in a long-option value for our own use. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
58 #define GROUP_BITS CHAR_BIT |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
59 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
60 /* The number of bits available for the user value. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
61 #define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
62 #define USER_MASK ((1 << USER_BITS) - 1) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
63 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
64 /* EZ alias for ARGP_ERR_UNKNOWN. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
65 #define EBADKEY ARGP_ERR_UNKNOWN |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
66 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
67 /* Default options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
68 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
69 /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
70 for one second intervals, decrementing _ARGP_HANG until it's zero. Thus |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
71 you can force the program to continue by attaching a debugger and setting |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
72 it to 0 yourself. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
73 static volatile int _argp_hang; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
74 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
75 #define OPT_PROGNAME -2 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
76 #define OPT_USAGE -3 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
77 #define OPT_HANG -4 |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
78 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
79 static const struct argp_option argp_default_options[] = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
80 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
81 {"help", '?', 0, 0, N_("give this help list"), -1}, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
82 {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, |
6702
6d9001a44973
(argp_default_options): Consistently begin help messages with a lowercase letter.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6475
diff
changeset
|
83 {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
84 {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, |
6702
6d9001a44973
(argp_default_options): Consistently begin help messages with a lowercase letter.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6475
diff
changeset
|
85 N_("hang for SECS seconds (default 3600)"), 0}, |
5188
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
86 {NULL, 0, 0, 0, NULL, 0} |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
87 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
88 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
89 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
90 argp_default_parser (int key, char *arg, struct argp_state *state) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
91 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
92 switch (key) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
93 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
94 case '?': |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
95 __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
96 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
97 case OPT_USAGE: |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
98 __argp_state_help (state, state->out_stream, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
99 ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
100 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
101 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
102 case OPT_PROGNAME: /* Set the program name. */ |
4767 | 103 #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
104 program_invocation_name = arg; |
4767 | 105 #endif |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
106 /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
107 __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
108 to be that, so we have to be a bit careful here.] */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
109 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
110 /* Update what we use for messages. */ |
6475
7af794d77875
(argp_def): Use gettext wrappers
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6259
diff
changeset
|
111 state->name = __argp_base_name (arg); |
4767 | 112 |
113 #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME | |
114 program_invocation_short_name = state->name; | |
115 #endif | |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
116 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
117 if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
118 == ARGP_PARSE_ARGV0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
119 /* Update what getopt uses too. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
120 state->argv[0] = arg; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
121 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
122 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
123 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
124 case OPT_HANG: |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
125 _argp_hang = atoi (arg ? arg : "3600"); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
126 while (_argp_hang-- > 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
127 __sleep (1); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
128 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
129 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
130 default: |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
131 return EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
132 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
133 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
134 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
135 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
136 static const struct argp argp_default_argp = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
137 {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
138 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
139 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
140 static const struct argp_option argp_version_options[] = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
141 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
142 {"version", 'V', 0, 0, N_("print program version"), -1}, |
5188
e338f602ca07
Use "gettext.h" instead of its complicated substitute.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5067
diff
changeset
|
143 {NULL, 0, 0, 0, NULL, 0} |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
144 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
145 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
146 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
147 argp_version_parser (int key, char *arg, struct argp_state *state) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
148 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
149 switch (key) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
150 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
151 case 'V': |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
152 if (argp_program_version_hook) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
153 (*argp_program_version_hook) (state->out_stream, state); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
154 else if (argp_program_version) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
155 fprintf (state->out_stream, "%s\n", argp_program_version); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
156 else |
16241
76e0e719ee49
argp: Avoid crash if translator uses % characters in a translation.
Guillem Jover <guillem@hadrons.org>
parents:
16235
diff
changeset
|
157 __argp_error (state, "%s", |
76e0e719ee49
argp: Avoid crash if translator uses % characters in a translation.
Guillem Jover <guillem@hadrons.org>
parents:
16235
diff
changeset
|
158 dgettext (state->root_argp->argp_domain, |
76e0e719ee49
argp: Avoid crash if translator uses % characters in a translation.
Guillem Jover <guillem@hadrons.org>
parents:
16235
diff
changeset
|
159 "(PROGRAM ERROR) No version known!?")); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
160 if (! (state->flags & ARGP_NO_EXIT)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
161 exit (0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
162 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
163 default: |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
164 return EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
165 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
166 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
167 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
168 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
169 static const struct argp argp_version_argp = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
170 {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
171 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
172 /* Returns the offset into the getopt long options array LONG_OPTIONS of a |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
173 long option with called NAME, or -1 if none is found. Passing NULL as |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
174 NAME will return the number of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
175 static int |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
176 find_long_option (struct option *long_options, const char *name) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
177 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
178 struct option *l = long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
179 while (l->name != NULL) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
180 if (name != NULL && strcmp (l->name, name) == 0) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
181 return l - long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
182 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
183 l++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
184 if (name == NULL) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
185 return l - long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
186 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
187 return -1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
188 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
189 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
190 |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
191 /* The state of a "group" during parsing. Each group corresponds to a |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
192 particular argp structure from the tree of such descending from the top |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
193 level argp passed to argp_parse. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
194 struct group |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
195 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
196 /* This group's parsing function. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
197 argp_parser_t parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
198 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
199 /* Which argp this group is from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
200 const struct argp *argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
201 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
202 /* Points to the point in SHORT_OPTS corresponding to the end of the short |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
203 options for this group. We use it to determine from which group a |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
204 particular short options is from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
205 char *short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
206 |
16358 | 207 /* The number of non-option args successfully handled by this parser. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
208 unsigned args_processed; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
209 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
210 /* This group's parser's parent's group. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
211 struct group *parent; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
212 unsigned parent_index; /* And the our position in the parent. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
213 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
214 /* These fields are swapped into and out of the state structure when |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
215 calling this group's parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
216 void *input, **child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
217 void *hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
218 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
219 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
220 /* Call GROUP's parser with KEY and ARG, swapping any group-specific info |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
221 from STATE before calling, and back into state afterwards. If GROUP has |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
222 no parser, EBADKEY is returned. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
223 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
224 group_parse (struct group *group, struct argp_state *state, int key, char *arg) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
225 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
226 if (group->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
227 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
228 error_t err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
229 state->hook = group->hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
230 state->input = group->input; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
231 state->child_inputs = group->child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
232 state->arg_num = group->args_processed; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
233 err = (*group->parser)(key, arg, state); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
234 group->hook = state->hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
235 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
236 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
237 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
238 return EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
239 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
240 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
241 struct parser |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
242 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
243 const struct argp *argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
244 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
245 /* SHORT_OPTS is the getopt short options string for the union of all the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
246 groups of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
247 char *short_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
248 /* LONG_OPTS is the array of getop long option structures for the union of |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
249 all the groups of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
250 struct option *long_opts; |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
251 /* OPT_DATA is the getopt data used for the re-entrant getopt. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
252 struct _getopt_data opt_data; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
253 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
254 /* States of the various parsing groups. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
255 struct group *groups; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
256 /* The end of the GROUPS array. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
257 struct group *egroup; |
14774
70d101744577
maint: correct misuse of "a" and "an"
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
258 /* A vector containing storage for the CHILD_INPUTS field in all groups. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
259 void **child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
260 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
261 /* True if we think using getopt is still useful; if false, then |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
262 remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
263 cleared whenever getopt returns KEY_END, but may be set again if the user |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
264 moves the next argument pointer backwards. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
265 int try_getopt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
266 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
267 /* State block supplied to parsing routines. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
268 struct argp_state state; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
269 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
270 /* Memory used by this parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
271 void *storage; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
272 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
273 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
274 /* The next usable entries in the various parser tables being filled in by |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
275 convert_options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
276 struct parser_convert_state |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
277 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
278 struct parser *parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
279 char *short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
280 struct option *long_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
281 void **child_inputs_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
282 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
283 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
284 /* Converts all options in ARGP (which is put in GROUP) and ancestors |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
285 into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
286 CVT->LONG_END are the points at which new options are added. Returns the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
287 next unused group entry. CVT holds state used during the conversion. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
288 static struct group * |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
289 convert_options (const struct argp *argp, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
290 struct group *parent, unsigned parent_index, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
291 struct group *group, struct parser_convert_state *cvt) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
292 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
293 /* REAL is the most recent non-alias value of OPT. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
294 const struct argp_option *real = argp->options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
295 const struct argp_child *children = argp->children; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
296 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
297 if (real || argp->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
298 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
299 const struct argp_option *opt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
300 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
301 if (real) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
302 for (opt = real; !__option_is_end (opt); opt++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
303 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
304 if (! (opt->flags & OPTION_ALIAS)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
305 /* OPT isn't an alias, so we can use values from it. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
306 real = opt; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
307 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
308 if (! (real->flags & OPTION_DOC)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
309 /* A real option (not just documentation). */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
310 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
311 if (__option_is_short (opt)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
312 /* OPT can be used as a short option. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
313 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
314 *cvt->short_end++ = opt->key; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
315 if (real->arg) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
316 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
317 *cvt->short_end++ = ':'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
318 if (real->flags & OPTION_ARG_OPTIONAL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
319 *cvt->short_end++ = ':'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
320 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
321 *cvt->short_end = '\0'; /* keep 0 terminated */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
322 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
323 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
324 if (opt->name |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
325 && find_long_option (cvt->parser->long_opts, opt->name) < 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
326 /* OPT can be used as a long option. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
327 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
328 cvt->long_end->name = opt->name; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
329 cvt->long_end->has_arg = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
330 (real->arg |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
331 ? (real->flags & OPTION_ARG_OPTIONAL |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
332 ? optional_argument |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
333 : required_argument) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
334 : no_argument); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
335 cvt->long_end->flag = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
336 /* we add a disambiguating code to all the user's |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
337 values (which is removed before we actually call |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
338 the function to parse the value); this means that |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
339 the user loses use of the high 8 bits in all his |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
340 values (the sign of the lower bits is preserved |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
341 however)... */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
342 cvt->long_end->val = |
12851
72c76b99f97b
Argp: fix recognition of short alias options.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
12559
diff
changeset
|
343 ((opt->key ? opt->key : real->key) & USER_MASK) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
344 + (((group - cvt->parser->groups) + 1) << USER_BITS); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
345 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
346 /* Keep the LONG_OPTS list terminated. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
347 (++cvt->long_end)->name = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
348 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
349 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
350 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
351 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
352 group->parser = argp->parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
353 group->argp = argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
354 group->short_end = cvt->short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
355 group->args_processed = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
356 group->parent = parent; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
357 group->parent_index = parent_index; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
358 group->input = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
359 group->hook = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
360 group->child_inputs = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
361 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
362 if (children) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
363 /* Assign GROUP's CHILD_INPUTS field some space from |
4536
3358eb550c86
Leave whitespace alone when importing, undoing that part of yesterday's
Paul Eggert <eggert@cs.ucla.edu>
parents:
4533
diff
changeset
|
364 CVT->child_inputs_end.*/ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
365 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
366 unsigned num_children = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
367 while (children[num_children].argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
368 num_children++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
369 group->child_inputs = cvt->child_inputs_end; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
370 cvt->child_inputs_end += num_children; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
371 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
372 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
373 parent = group++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
374 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
375 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
376 parent = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
377 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
378 if (children) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
379 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
380 unsigned index = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
381 while (children->argp) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
382 group = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
383 convert_options (children++->argp, parent, index++, group, cvt); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
384 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
385 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
386 return group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
387 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
388 |
16358 | 389 /* Find the merged set of getopt options, with keys appropriately prefixed. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
390 static void |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
391 parser_convert (struct parser *parser, const struct argp *argp, int flags) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
392 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
393 struct parser_convert_state cvt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
394 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
395 cvt.parser = parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
396 cvt.short_end = parser->short_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
397 cvt.long_end = parser->long_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
398 cvt.child_inputs_end = parser->child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
399 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
400 if (flags & ARGP_IN_ORDER) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
401 *cvt.short_end++ = '-'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
402 else if (flags & ARGP_NO_ARGS) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
403 *cvt.short_end++ = '+'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
404 *cvt.short_end = '\0'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
405 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
406 cvt.long_end->name = NULL; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
407 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
408 parser->argp = argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
409 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
410 if (argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
411 parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
412 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
413 parser->egroup = parser->groups; /* No parsers at all! */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
414 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
415 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
416 /* Lengths of various parser fields which we will allocated. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
417 struct parser_sizes |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
418 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
419 size_t short_len; /* Getopt short options string. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
420 size_t long_len; /* Getopt long options vector. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
421 size_t num_groups; /* Group structures we allocate. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
422 size_t num_child_inputs; /* Child input slots. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
423 }; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
424 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
425 /* For ARGP, increments the NUM_GROUPS field in SZS by the total number of |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
426 argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
427 the maximum lengths of the resulting merged getopt short options string and |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
428 long-options array, respectively. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
429 static void |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
430 calc_sizes (const struct argp *argp, struct parser_sizes *szs) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
431 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
432 const struct argp_child *child = argp->children; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
433 const struct argp_option *opt = argp->options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
434 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
435 if (opt || argp->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
436 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
437 szs->num_groups++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
438 if (opt) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
439 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
440 int num_opts = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
441 while (!__option_is_end (opt++)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
442 num_opts++; |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
443 szs->short_len += num_opts * 3; /* opt + up to 2 ':'s */ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
444 szs->long_len += num_opts; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
445 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
446 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
447 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
448 if (child) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
449 while (child->argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
450 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
451 calc_sizes ((child++)->argp, szs); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
452 szs->num_child_inputs++; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
453 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
454 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
455 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
456 /* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
457 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
458 parser_init (struct parser *parser, const struct argp *argp, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
459 int argc, char **argv, int flags, void *input) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
460 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
461 error_t err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
462 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
463 struct parser_sizes szs; |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
464 struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; |
5554 | 465 char *storage; |
466 size_t glen, gsum; | |
467 size_t clen, csum; | |
468 size_t llen, lsum; | |
469 size_t slen, ssum; | |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
470 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
471 szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
472 szs.long_len = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
473 szs.num_groups = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
474 szs.num_child_inputs = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
475 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
476 if (argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
477 calc_sizes (argp, &szs); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
478 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
479 /* Lengths of the various bits of storage used by PARSER. */ |
5554 | 480 glen = (szs.num_groups + 1) * sizeof (struct group); |
481 clen = szs.num_child_inputs * sizeof (void *); | |
5555
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
482 llen = (szs.long_len + 1) * sizeof (struct option); |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
483 slen = szs.short_len + 1; |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
484 |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
485 /* Sums of previous lengths, properly aligned. There's no need to |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
486 align gsum, since struct group is aligned at least as strictly as |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
487 void * (since it contains a void * member). And there's no need |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
488 to align lsum, since struct option is aligned at least as |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
489 strictly as char. */ |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
490 gsum = glen; |
5554 | 491 csum = alignto (gsum + clen, alignof (struct option)); |
5555
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
492 lsum = csum + llen; |
5554 | 493 ssum = lsum + slen; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
494 |
5554 | 495 parser->storage = malloc (ssum); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
496 if (! parser->storage) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
497 return ENOMEM; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
498 |
5554 | 499 storage = parser->storage; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
500 parser->groups = parser->storage; |
5554 | 501 parser->child_inputs = (void **) (storage + gsum); |
502 parser->long_opts = (struct option *) (storage + csum); | |
503 parser->short_opts = storage + lsum; | |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
504 parser->opt_data = opt_data; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
505 |
5554 | 506 memset (parser->child_inputs, 0, clen); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
507 parser_convert (parser, argp, flags); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
508 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
509 memset (&parser->state, 0, sizeof (struct argp_state)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
510 parser->state.root_argp = parser->argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
511 parser->state.argc = argc; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
512 parser->state.argv = argv; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
513 parser->state.flags = flags; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
514 parser->state.err_stream = stderr; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
515 parser->state.out_stream = stdout; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
516 parser->state.next = 0; /* Tell getopt to initialize. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
517 parser->state.pstate = parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
518 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
519 parser->try_getopt = 1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
520 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
521 /* Call each parser for the first time, giving it a chance to propagate |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
522 values to child parsers. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
523 if (parser->groups < parser->egroup) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
524 parser->groups->input = input; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
525 for (group = parser->groups; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
526 group < parser->egroup && (!err || err == EBADKEY); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
527 group++) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
528 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
529 if (group->parent) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
530 /* If a child parser, get the initial input value from the parent. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
531 group->input = group->parent->child_inputs[group->parent_index]; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
532 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
533 if (!group->parser |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
534 && group->argp->children && group->argp->children->argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
535 /* For the special case where no parsing function is supplied for an |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
536 argp, propagate its input to its first child, if any (this just |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
537 makes very simple wrapper argps more convenient). */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
538 group->child_inputs[0] = group->input; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
539 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
540 err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
541 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
542 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
543 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
544 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
545 if (err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
546 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
547 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
548 if (parser->state.flags & ARGP_NO_ERRS) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
549 { |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
550 parser->opt_data.opterr = 0; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
551 if (parser->state.flags & ARGP_PARSE_ARGV0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
552 /* getopt always skips ARGV[0], so we have to fake it out. As long |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
553 as OPTERR is 0, then it shouldn't actually try to access it. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
554 parser->state.argv--, parser->state.argc++; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
555 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
556 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
557 parser->opt_data.opterr = 1; /* Print error messages. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
558 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
559 if (parser->state.argv == argv && argv[0]) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
560 /* There's an argv[0]; use it for messages. */ |
6475
7af794d77875
(argp_def): Use gettext wrappers
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6259
diff
changeset
|
561 parser->state.name = __argp_base_name (argv[0]); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
562 else |
4767 | 563 parser->state.name = __argp_short_program_name (); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
564 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
565 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
566 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
567 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
568 /* Free any storage consumed by PARSER (but not PARSER itself). */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
569 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
570 parser_finalize (struct parser *parser, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
571 error_t err, int arg_ebadkey, int *end_index) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
572 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
573 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
574 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
575 if (err == EBADKEY && arg_ebadkey) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
576 /* Suppress errors generated by unparsed arguments. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
577 err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
578 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
579 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
580 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
581 if (parser->state.next == parser->state.argc) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
582 /* We successfully parsed all arguments! Call all the parsers again, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
583 just a few more times... */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
584 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
585 for (group = parser->groups; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
586 group < parser->egroup && (!err || err==EBADKEY); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
587 group++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
588 if (group->args_processed == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
589 err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
590 for (group = parser->egroup - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
591 group >= parser->groups && (!err || err==EBADKEY); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
592 group--) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
593 err = group_parse (group, &parser->state, ARGP_KEY_END, 0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
594 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
595 if (err == EBADKEY) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
596 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
597 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
598 /* Tell the user that all arguments are parsed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
599 if (end_index) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
600 *end_index = parser->state.next; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
601 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
602 else if (end_index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
603 /* Return any remaining arguments to the user. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
604 *end_index = parser->state.next; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
605 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
606 /* No way to return the remaining arguments, they must be bogus. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
607 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
608 if (!(parser->state.flags & ARGP_NO_ERRS) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
609 && parser->state.err_stream) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
610 fprintf (parser->state.err_stream, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
611 dgettext (parser->argp->argp_domain, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
612 "%s: Too many arguments\n"), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
613 parser->state.name); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
614 err = EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
615 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
616 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
617 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
618 /* Okay, we're all done, with either an error or success; call the parsers |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
619 to indicate which one. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
620 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
621 if (err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
622 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
623 /* Maybe print an error message. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
624 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
625 /* An appropriate message describing what the error was should have |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
626 been printed earlier. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
627 __argp_state_help (&parser->state, parser->state.err_stream, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
628 ARGP_HELP_STD_ERR); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
629 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
630 /* Since we didn't exit, give each parser an error indication. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
631 for (group = parser->groups; group < parser->egroup; group++) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
632 group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
633 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
634 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
635 /* Notify parsers of success, and propagate back values from parsers. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
636 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
637 /* We pass over the groups in reverse order so that child groups are |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
638 given a chance to do there processing before passing back a value to |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
639 the parent. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
640 for (group = parser->egroup - 1 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
641 ; group >= parser->groups && (!err || err == EBADKEY) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
642 ; group--) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
643 err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
644 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
645 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
646 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
647 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
648 /* Call parsers once more, to do any final cleanup. Errors are ignored. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
649 for (group = parser->egroup - 1; group >= parser->groups; group--) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
650 group_parse (group, &parser->state, ARGP_KEY_FINI, 0); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
651 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
652 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
653 err = EINVAL; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
654 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
655 free (parser->storage); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
656 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
657 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
658 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
659 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
660 /* Call the user parsers to parse the non-option argument VAL, at the current |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
661 position, returning any error. The state NEXT pointer is assumed to have |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
662 been adjusted (by getopt) to point after this argument; this function will |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
663 adjust it correctly to reflect however many args actually end up being |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
664 consumed. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
665 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
666 parser_parse_arg (struct parser *parser, char *val) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
667 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
668 /* Save the starting value of NEXT, first adjusting it so that the arg |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
669 we're parsing is again the front of the arg vector. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
670 int index = --parser->state.next; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
671 error_t err = EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
672 struct group *group; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
673 int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
674 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
675 /* Try to parse the argument in each parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
676 for (group = parser->groups |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
677 ; group < parser->egroup && err == EBADKEY |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
678 ; group++) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
679 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
680 parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
681 key = ARGP_KEY_ARG; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
682 err = group_parse (group, &parser->state, key, val); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
683 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
684 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
685 /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
686 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
687 parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
688 key = ARGP_KEY_ARGS; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
689 err = group_parse (group, &parser->state, key, 0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
690 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
691 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
692 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
693 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
694 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
695 if (key == ARGP_KEY_ARGS) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
696 /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
697 changed by the user, *all* arguments should be considered |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
698 consumed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
699 parser->state.next = parser->state.argc; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
700 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
701 if (parser->state.next > index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
702 /* Remember that we successfully processed a non-option |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
703 argument -- but only if the user hasn't gotten tricky and set |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
704 the clock back. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
705 (--group)->args_processed += (parser->state.next - index); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
706 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
707 /* The user wants to reparse some args, give getopt another try. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
708 parser->try_getopt = 1; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
709 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
710 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
711 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
712 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
713 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
714 /* Call the user parsers to parse the option OPT, with argument VAL, at the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
715 current position, returning any error. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
716 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
717 parser_parse_opt (struct parser *parser, int opt, char *val) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
718 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
719 /* The group key encoded in the high bits; 0 for short opts or |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
720 group_number + 1 for long opts. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
721 int group_key = opt >> USER_BITS; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
722 error_t err = EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
723 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
724 if (group_key == 0) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
725 /* A short option. By comparing OPT's position in SHORT_OPTS to the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
726 various starting positions in each group's SHORT_END field, we can |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
727 determine which group OPT came from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
728 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
729 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
730 char *short_index = strchr (parser->short_opts, opt); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
731 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
732 if (short_index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
733 for (group = parser->groups; group < parser->egroup; group++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
734 if (group->short_end > short_index) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
735 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
736 err = group_parse (group, &parser->state, opt, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
737 parser->opt_data.optarg); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
738 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
739 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
740 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
741 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
742 /* A long option. We use shifts instead of masking for extracting |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
743 the user value in order to preserve the sign. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
744 err = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
745 group_parse (&parser->groups[group_key - 1], &parser->state, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
746 (opt << GROUP_BITS) >> GROUP_BITS, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
747 parser->opt_data.optarg); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
748 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
749 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
750 /* At least currently, an option not recognized is an error in the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
751 parser, because we pre-compute which parser is supposed to deal |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
752 with each option. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
753 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
754 static const char bad_key_err[] = |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
755 N_("(PROGRAM ERROR) Option should have been recognized!?"); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
756 if (group_key == 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
757 __argp_error (&parser->state, "-%c: %s", opt, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
758 dgettext (parser->argp->argp_domain, bad_key_err)); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
759 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
760 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
761 struct option *long_opt = parser->long_opts; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
762 while (long_opt->val != opt && long_opt->name) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
763 long_opt++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
764 __argp_error (&parser->state, "--%s: %s", |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
765 long_opt->name ? long_opt->name : "???", |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
766 dgettext (parser->argp->argp_domain, bad_key_err)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
767 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
768 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
769 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
770 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
771 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
772 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
773 /* Parse the next argument in PARSER (as indicated by PARSER->state.next). |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
774 Any error from the parsers is returned, and *ARGP_EBADKEY indicates |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
775 whether a value of EBADKEY is due to an unrecognized argument (which is |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
776 generally not fatal). */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
777 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
778 parser_parse_next (struct parser *parser, int *arg_ebadkey) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
779 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
780 int opt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
781 error_t err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
782 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
783 if (parser->state.quoted && parser->state.next < parser->state.quoted) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
784 /* The next argument pointer has been moved to before the quoted |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
785 region, so pretend we never saw the quoting "--", and give getopt |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
786 another chance. If the user hasn't removed it, getopt will just |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
787 process it again. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
788 parser->state.quoted = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
789 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
790 if (parser->try_getopt && !parser->state.quoted) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
791 /* Give getopt a chance to parse this. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
792 { |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
793 /* Put it back in OPTIND for getopt. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
794 parser->opt_data.optind = parser->state.next; |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
795 /* Distinguish KEY_ERR from a real option. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
796 parser->opt_data.optopt = KEY_END; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
797 if (parser->state.flags & ARGP_LONG_ONLY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
798 opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
799 parser->short_opts, parser->long_opts, 0, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
800 &parser->opt_data); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
801 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
802 opt = _getopt_long_r (parser->state.argc, parser->state.argv, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
803 parser->short_opts, parser->long_opts, 0, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
804 &parser->opt_data); |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
805 /* And see what getopt did. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
806 parser->state.next = parser->opt_data.optind; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
807 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
808 if (opt == KEY_END) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
809 /* Getopt says there are no more options, so stop using |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
810 getopt; we'll continue if necessary on our own. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
811 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
812 parser->try_getopt = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
813 if (parser->state.next > 1 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
814 && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
815 == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
816 /* Not only is this the end of the options, but it's a |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
817 "quoted" region, which may have args that *look* like |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
818 options, so we definitely shouldn't try to use getopt past |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
819 here, whatever happens. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
820 parser->state.quoted = parser->state.next; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
821 } |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
822 else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
823 /* KEY_ERR can have the same value as a valid user short |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
824 option, but in the case of a real error, getopt sets OPTOPT |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
825 to the offending character, which can never be KEY_END. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
826 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
827 *arg_ebadkey = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
828 return EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
829 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
830 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
831 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
832 opt = KEY_END; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
833 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
834 if (opt == KEY_END) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
835 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
836 /* We're past what getopt considers the options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
837 if (parser->state.next >= parser->state.argc |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
838 || (parser->state.flags & ARGP_NO_ARGS)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
839 /* Indicate that we're done. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
840 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
841 *arg_ebadkey = 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
842 return EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
843 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
844 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
845 /* A non-option arg; simulate what getopt might have done. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
846 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
847 opt = KEY_ARG; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
848 parser->opt_data.optarg = parser->state.argv[parser->state.next++]; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
849 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
850 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
851 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
852 if (opt == KEY_ARG) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
853 /* A non-option argument; try each parser in turn. */ |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
854 err = parser_parse_arg (parser, parser->opt_data.optarg); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
855 else |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
856 err = parser_parse_opt (parser, opt, parser->opt_data.optarg); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
857 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
858 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
859 *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
860 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
861 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
862 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
863 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
864 /* Parse the options strings in ARGC & ARGV according to the argp in ARGP. |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
865 FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
866 index in ARGV of the first unparsed option is returned in it. If an |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
867 unknown option is present, EINVAL is returned; if some parser routine |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
868 returned a non-zero value, it is returned; otherwise 0 is returned. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
869 error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
870 __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
871 int *end_index, void *input) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
872 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
873 error_t err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
874 struct parser parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
875 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
876 /* If true, then err == EBADKEY is a result of a non-option argument failing |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
877 to be parsed (which in some cases isn't actually an error). */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
878 int arg_ebadkey = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
879 |
7289
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
880 #ifndef _LIBC |
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
881 if (!(flags & ARGP_PARSE_ARGV0)) |
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
882 { |
16987
6bbf0e9974c9
argp: make HAVE_DECL usage consistent
Eric Blake <eblake@redhat.com>
parents:
16358
diff
changeset
|
883 #if HAVE_DECL_PROGRAM_INVOCATION_NAME |
7289
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
884 if (!program_invocation_name) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
885 program_invocation_name = argv[0]; |
7289
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
886 #endif |
16987
6bbf0e9974c9
argp: make HAVE_DECL usage consistent
Eric Blake <eblake@redhat.com>
parents:
16358
diff
changeset
|
887 #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME |
7289
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
888 if (!program_invocation_short_name) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
889 program_invocation_short_name = __argp_base_name (argv[0]); |
7289
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
890 #endif |
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
891 } |
ec5559fba282
(__argp_parse) [!_LIBC]: Make sure program_invocation_name and program_invocation_short_name are initialized.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
6702
diff
changeset
|
892 #endif |
10095 | 893 |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
894 if (! (flags & ARGP_NO_HELP)) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
895 /* Add our own options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
896 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
897 struct argp_child *child = alloca (4 * sizeof (struct argp_child)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
898 struct argp *top_argp = alloca (sizeof (struct argp)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
899 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
900 /* TOP_ARGP has no options, it just serves to group the user & default |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
901 argps. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
902 memset (top_argp, 0, sizeof (*top_argp)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
903 top_argp->children = child; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
904 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
905 memset (child, 0, 4 * sizeof (struct argp_child)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
906 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
907 if (argp) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
908 (child++)->argp = argp; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
909 (child++)->argp = &argp_default_argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
910 if (argp_program_version || argp_program_version_hook) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
911 (child++)->argp = &argp_version_argp; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
912 child->argp = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
913 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
914 argp = top_argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
915 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
916 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
917 /* Construct a parser for these arguments. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
918 err = parser_init (&parser, argp, argc, argv, flags, input); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
919 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
920 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
921 /* Parse! */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
922 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
923 while (! err) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
924 err = parser_parse_next (&parser, &arg_ebadkey); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
925 err = parser_finalize (&parser, err, arg_ebadkey, end_index); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
926 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
927 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
928 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
929 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
930 #ifdef weak_alias |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
931 weak_alias (__argp_parse, argp_parse) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
932 #endif |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
933 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
934 /* Return the input field for ARGP in the parser corresponding to STATE; used |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
935 by the help routines. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
936 void * |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
937 __argp_input (const struct argp *argp, const struct argp_state *state) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
938 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
939 if (state) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
940 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
941 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
942 struct parser *parser = state->pstate; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
943 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
944 for (group = parser->groups; group < parser->egroup; group++) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
945 if (group->argp == argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
946 return group->input; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
947 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
948 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
949 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
950 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
951 #ifdef weak_alias |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
952 weak_alias (__argp_input, _argp_input) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
953 #endif |