Mercurial > hg > octave-jordi > gnulib-hg
annotate lib/argp-parse.c @ 16201:8250f2777afc
maint: update all copyright year number ranges
Run "make update-copyright".
author | Jim Meyering <meyering@redhat.com> |
---|---|
date | Sun, 01 Jan 2012 10:04:58 +0100 |
parents | 3c249f388e46 |
children | 18a38c9615f0 |
rev | line source |
---|---|
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
1 /* Hierarchial argument parsing, layered over getopt |
16201
8250f2777afc
maint: update all copyright year number ranges
Jim Meyering <meyering@redhat.com>
parents:
15996
diff
changeset
|
2 Copyright (C) 1995-2000, 2002-2004, 2009-2012 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 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
157 __argp_error (state, dgettext (state->root_argp->argp_domain, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
158 "(PROGRAM ERROR) No version known!?")); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
159 if (! (state->flags & ARGP_NO_EXIT)) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
160 exit (0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
161 break; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
162 default: |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
163 return EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
164 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
165 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
166 } |
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 static const struct argp argp_version_argp = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
169 {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
|
170 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
171 /* 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
|
172 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
|
173 NAME will return the number of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
174 static int |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
175 find_long_option (struct option *long_options, const char *name) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
176 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
177 struct option *l = long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
178 while (l->name != NULL) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
179 if (name != NULL && strcmp (l->name, name) == 0) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
180 return l - long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
181 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
182 l++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
183 if (name == NULL) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
184 return l - long_options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
185 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
186 return -1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
187 } |
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 /* The state of a `group' during parsing. Each group corresponds to a |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
191 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
|
192 level argp passed to argp_parse. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
193 struct group |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
194 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
195 /* This group's parsing function. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
196 argp_parser_t parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
197 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
198 /* Which argp this group is from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
199 const struct argp *argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
200 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
201 /* 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
|
202 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
|
203 particular short options is from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
204 char *short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
205 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
206 /* The number of non-option args sucessfully handled by this parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
207 unsigned args_processed; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
208 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
209 /* This group's parser's parent's group. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
210 struct group *parent; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
211 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
|
212 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
213 /* 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
|
214 calling this group's parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
215 void *input, **child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
216 void *hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
217 }; |
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 /* 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
|
220 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
|
221 no parser, EBADKEY is returned. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
222 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
223 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
|
224 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
225 if (group->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
226 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
227 error_t err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
228 state->hook = group->hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
229 state->input = group->input; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
230 state->child_inputs = group->child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
231 state->arg_num = group->args_processed; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
232 err = (*group->parser)(key, arg, state); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
233 group->hook = state->hook; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
234 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
235 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
236 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
237 return EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
238 } |
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 struct parser |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
241 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
242 const struct argp *argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
243 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
244 /* 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
|
245 groups of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
246 char *short_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
247 /* 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
|
248 all the groups of options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
249 struct option *long_opts; |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
250 /* 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
|
251 struct _getopt_data opt_data; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
252 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
253 /* States of the various parsing groups. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
254 struct group *groups; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
255 /* The end of the GROUPS array. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
256 struct group *egroup; |
14774
70d101744577
maint: correct misuse of "a" and "an"
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
257 /* 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
|
258 void **child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
259 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
260 /* 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
|
261 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
|
262 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
|
263 moves the next argument pointer backwards. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
264 int try_getopt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
265 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
266 /* State block supplied to parsing routines. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
267 struct argp_state state; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
268 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
269 /* Memory used by this parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
270 void *storage; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
271 }; |
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 /* 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
|
274 convert_options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
275 struct parser_convert_state |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
276 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
277 struct parser *parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
278 char *short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
279 struct option *long_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
280 void **child_inputs_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
281 }; |
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 /* 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
|
284 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
|
285 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
|
286 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
|
287 static struct group * |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
288 convert_options (const struct argp *argp, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
289 struct group *parent, unsigned parent_index, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
290 struct group *group, struct parser_convert_state *cvt) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
291 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
292 /* REAL is the most recent non-alias value of OPT. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
293 const struct argp_option *real = argp->options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
294 const struct argp_child *children = argp->children; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
295 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
296 if (real || argp->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
297 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
298 const struct argp_option *opt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
299 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
300 if (real) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
301 for (opt = real; !__option_is_end (opt); opt++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
302 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
303 if (! (opt->flags & OPTION_ALIAS)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
304 /* 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
|
305 real = opt; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
306 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
307 if (! (real->flags & OPTION_DOC)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
308 /* A real option (not just documentation). */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
309 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
310 if (__option_is_short (opt)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
311 /* OPT can be used as a short option. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
312 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
313 *cvt->short_end++ = opt->key; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
314 if (real->arg) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
315 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
316 *cvt->short_end++ = ':'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
317 if (real->flags & OPTION_ARG_OPTIONAL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
318 *cvt->short_end++ = ':'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
319 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
320 *cvt->short_end = '\0'; /* keep 0 terminated */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
321 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
322 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
323 if (opt->name |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
324 && 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
|
325 /* OPT can be used as a long option. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
326 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
327 cvt->long_end->name = opt->name; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
328 cvt->long_end->has_arg = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
329 (real->arg |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
330 ? (real->flags & OPTION_ARG_OPTIONAL |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
331 ? optional_argument |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
332 : required_argument) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
333 : no_argument); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
334 cvt->long_end->flag = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
335 /* 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
|
336 values (which is removed before we actually call |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
337 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
|
338 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
|
339 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
|
340 however)... */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
341 cvt->long_end->val = |
12851
72c76b99f97b
Argp: fix recognition of short alias options.
Sergey Poznyakoff <gray@gnu.org.ua>
parents:
12559
diff
changeset
|
342 ((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
|
343 + (((group - cvt->parser->groups) + 1) << USER_BITS); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
344 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
345 /* Keep the LONG_OPTS list terminated. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
346 (++cvt->long_end)->name = NULL; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
347 } |
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 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
350 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
351 group->parser = argp->parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
352 group->argp = argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
353 group->short_end = cvt->short_end; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
354 group->args_processed = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
355 group->parent = parent; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
356 group->parent_index = parent_index; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
357 group->input = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
358 group->hook = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
359 group->child_inputs = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
360 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
361 if (children) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
362 /* 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
|
363 CVT->child_inputs_end.*/ |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
364 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
365 unsigned num_children = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
366 while (children[num_children].argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
367 num_children++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
368 group->child_inputs = cvt->child_inputs_end; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
369 cvt->child_inputs_end += num_children; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
370 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
371 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
372 parent = group++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
373 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
374 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
375 parent = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
376 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
377 if (children) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
378 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
379 unsigned index = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
380 while (children->argp) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
381 group = |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
382 convert_options (children++->argp, parent, index++, group, cvt); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
383 } |
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 return group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
386 } |
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 /* Find the merged set of getopt options, with keys appropiately prefixed. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
389 static void |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
390 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
|
391 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
392 struct parser_convert_state cvt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
393 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
394 cvt.parser = parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
395 cvt.short_end = parser->short_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
396 cvt.long_end = parser->long_opts; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
397 cvt.child_inputs_end = parser->child_inputs; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
398 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
399 if (flags & ARGP_IN_ORDER) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
400 *cvt.short_end++ = '-'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
401 else if (flags & ARGP_NO_ARGS) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
402 *cvt.short_end++ = '+'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
403 *cvt.short_end = '\0'; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
404 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
405 cvt.long_end->name = NULL; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
406 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
407 parser->argp = argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
408 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
409 if (argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
410 parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
411 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
412 parser->egroup = parser->groups; /* No parsers at all! */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
413 } |
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 /* Lengths of various parser fields which we will allocated. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
416 struct parser_sizes |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
417 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
418 size_t short_len; /* Getopt short options string. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
419 size_t long_len; /* Getopt long options vector. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
420 size_t num_groups; /* Group structures we allocate. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
421 size_t num_child_inputs; /* Child input slots. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
422 }; |
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 /* 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
|
425 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
|
426 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
|
427 long-options array, respectively. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
428 static void |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
429 calc_sizes (const struct argp *argp, struct parser_sizes *szs) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
430 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
431 const struct argp_child *child = argp->children; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
432 const struct argp_option *opt = argp->options; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
433 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
434 if (opt || argp->parser) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
435 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
436 szs->num_groups++; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
437 if (opt) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
438 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
439 int num_opts = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
440 while (!__option_is_end (opt++)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
441 num_opts++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
442 szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
443 szs->long_len += num_opts; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
444 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
445 } |
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 if (child) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
448 while (child->argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
449 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
450 calc_sizes ((child++)->argp, szs); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
451 szs->num_child_inputs++; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
452 } |
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 /* 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
|
456 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
457 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
|
458 int argc, char **argv, int flags, void *input) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
459 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
460 error_t err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
461 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
462 struct parser_sizes szs; |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
463 struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; |
5554 | 464 char *storage; |
465 size_t glen, gsum; | |
466 size_t clen, csum; | |
467 size_t llen, lsum; | |
468 size_t slen, ssum; | |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
469 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
470 szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
471 szs.long_len = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
472 szs.num_groups = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
473 szs.num_child_inputs = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
474 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
475 if (argp) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
476 calc_sizes (argp, &szs); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
477 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
478 /* Lengths of the various bits of storage used by PARSER. */ |
5554 | 479 glen = (szs.num_groups + 1) * sizeof (struct group); |
480 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
|
481 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
|
482 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
|
483 |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
484 /* 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
|
485 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
|
486 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
|
487 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
|
488 strictly as char. */ |
12b1a84e1247
(parser_init): Omit unnecessary alignments, and comment the alignments.
Paul Eggert <eggert@cs.ucla.edu>
parents:
5554
diff
changeset
|
489 gsum = glen; |
5554 | 490 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
|
491 lsum = csum + llen; |
5554 | 492 ssum = lsum + slen; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
493 |
5554 | 494 parser->storage = malloc (ssum); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
495 if (! parser->storage) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
496 return ENOMEM; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
497 |
5554 | 498 storage = parser->storage; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
499 parser->groups = parser->storage; |
5554 | 500 parser->child_inputs = (void **) (storage + gsum); |
501 parser->long_opts = (struct option *) (storage + csum); | |
502 parser->short_opts = storage + lsum; | |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
503 parser->opt_data = opt_data; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
504 |
5554 | 505 memset (parser->child_inputs, 0, clen); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
506 parser_convert (parser, argp, flags); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
507 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
508 memset (&parser->state, 0, sizeof (struct argp_state)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
509 parser->state.root_argp = parser->argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
510 parser->state.argc = argc; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
511 parser->state.argv = argv; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
512 parser->state.flags = flags; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
513 parser->state.err_stream = stderr; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
514 parser->state.out_stream = stdout; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
515 parser->state.next = 0; /* Tell getopt to initialize. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
516 parser->state.pstate = parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
517 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
518 parser->try_getopt = 1; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
519 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
520 /* 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
|
521 values to child parsers. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
522 if (parser->groups < parser->egroup) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
523 parser->groups->input = input; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
524 for (group = parser->groups; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
525 group < parser->egroup && (!err || err == EBADKEY); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
526 group++) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
527 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
528 if (group->parent) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
529 /* 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
|
530 group->input = group->parent->child_inputs[group->parent_index]; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
531 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
532 if (!group->parser |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
533 && group->argp->children && group->argp->children->argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
534 /* 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
|
535 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
|
536 makes very simple wrapper argps more convenient). */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
537 group->child_inputs[0] = group->input; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
538 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
539 err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
540 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
541 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
542 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
543 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
544 if (err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
545 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
546 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
547 if (parser->state.flags & ARGP_NO_ERRS) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
548 { |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
549 parser->opt_data.opterr = 0; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
550 if (parser->state.flags & ARGP_PARSE_ARGV0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
551 /* 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
|
552 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
|
553 parser->state.argv--, parser->state.argc++; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
554 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
555 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
556 parser->opt_data.opterr = 1; /* Print error messages. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
557 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
558 if (parser->state.argv == argv && argv[0]) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
559 /* 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
|
560 parser->state.name = __argp_base_name (argv[0]); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
561 else |
4767 | 562 parser->state.name = __argp_short_program_name (); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
563 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
564 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
565 } |
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 /* Free any storage consumed by PARSER (but not PARSER itself). */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
568 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
569 parser_finalize (struct parser *parser, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
570 error_t err, int arg_ebadkey, int *end_index) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
571 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
572 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
573 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
574 if (err == EBADKEY && arg_ebadkey) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
575 /* Suppress errors generated by unparsed arguments. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
576 err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
577 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
578 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
579 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
580 if (parser->state.next == parser->state.argc) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
581 /* 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
|
582 just a few more times... */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
583 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
584 for (group = parser->groups; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
585 group < parser->egroup && (!err || err==EBADKEY); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
586 group++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
587 if (group->args_processed == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
588 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
|
589 for (group = parser->egroup - 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
590 group >= parser->groups && (!err || err==EBADKEY); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
591 group--) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
592 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
|
593 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
594 if (err == EBADKEY) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
595 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
596 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
597 /* Tell the user that all arguments are parsed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
598 if (end_index) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
599 *end_index = parser->state.next; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
600 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
601 else if (end_index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
602 /* Return any remaining arguments to the user. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
603 *end_index = parser->state.next; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
604 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
605 /* 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
|
606 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
607 if (!(parser->state.flags & ARGP_NO_ERRS) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
608 && parser->state.err_stream) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
609 fprintf (parser->state.err_stream, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
610 dgettext (parser->argp->argp_domain, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
611 "%s: Too many arguments\n"), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
612 parser->state.name); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
613 err = EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
614 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
615 } |
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 /* 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
|
618 to indicate which one. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
619 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
620 if (err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
621 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
622 /* Maybe print an error message. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
623 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
624 /* 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
|
625 been printed earlier. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
626 __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
|
627 ARGP_HELP_STD_ERR); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
628 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
629 /* 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
|
630 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
|
631 group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
632 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
633 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
634 /* Notify parsers of success, and propagate back values from parsers. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
635 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
636 /* 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
|
637 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
|
638 the parent. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
639 for (group = parser->egroup - 1 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
640 ; group >= parser->groups && (!err || err == EBADKEY) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
641 ; group--) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
642 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
|
643 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
644 err = 0; /* Some parser didn't understand. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
645 } |
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 /* 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
|
648 for (group = parser->egroup - 1; group >= parser->groups; group--) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
649 group_parse (group, &parser->state, ARGP_KEY_FINI, 0); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
650 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
651 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
652 err = EINVAL; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
653 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
654 free (parser->storage); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
655 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
656 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
657 } |
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 /* 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
|
660 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
|
661 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
|
662 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
|
663 consumed. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
664 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
665 parser_parse_arg (struct parser *parser, char *val) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
666 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
667 /* 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
|
668 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
|
669 int index = --parser->state.next; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
670 error_t err = EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
671 struct group *group; |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
672 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
|
673 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
674 /* Try to parse the argument in each parser. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
675 for (group = parser->groups |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
676 ; group < parser->egroup && err == EBADKEY |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
677 ; group++) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
678 { |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
679 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
|
680 key = ARGP_KEY_ARG; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
681 err = group_parse (group, &parser->state, key, val); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
682 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
683 if (err == EBADKEY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
684 /* 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
|
685 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
686 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
|
687 key = ARGP_KEY_ARGS; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
688 err = group_parse (group, &parser->state, key, 0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
689 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
690 } |
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 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
693 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
694 if (key == ARGP_KEY_ARGS) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
695 /* 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
|
696 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
|
697 consumed. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
698 parser->state.next = parser->state.argc; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
699 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
700 if (parser->state.next > index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
701 /* Remember that we successfully processed a non-option |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
702 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
|
703 the clock back. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
704 (--group)->args_processed += (parser->state.next - index); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
705 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
706 /* 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
|
707 parser->try_getopt = 1; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
708 } |
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 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
711 } |
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 /* 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
|
714 current position, returning any error. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
715 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
716 parser_parse_opt (struct parser *parser, int opt, char *val) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
717 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
718 /* 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
|
719 group_number + 1 for long opts. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
720 int group_key = opt >> USER_BITS; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
721 error_t err = EBADKEY; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
722 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
723 if (group_key == 0) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
724 /* 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
|
725 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
|
726 determine which group OPT came from. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
727 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
728 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
729 char *short_index = strchr (parser->short_opts, opt); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
730 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
731 if (short_index) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
732 for (group = parser->groups; group < parser->egroup; group++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
733 if (group->short_end > short_index) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
734 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
735 err = group_parse (group, &parser->state, opt, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
736 parser->opt_data.optarg); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
737 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
738 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
739 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
740 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
741 /* 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
|
742 the user value in order to preserve the sign. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
743 err = |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
744 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
|
745 (opt << GROUP_BITS) >> GROUP_BITS, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
746 parser->opt_data.optarg); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
747 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
748 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
749 /* 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
|
750 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
|
751 with each option. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
752 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
753 static const char bad_key_err[] = |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
754 N_("(PROGRAM ERROR) Option should have been recognized!?"); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
755 if (group_key == 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
756 __argp_error (&parser->state, "-%c: %s", opt, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
757 dgettext (parser->argp->argp_domain, bad_key_err)); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
758 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
759 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
760 struct option *long_opt = parser->long_opts; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
761 while (long_opt->val != opt && long_opt->name) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
762 long_opt++; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
763 __argp_error (&parser->state, "--%s: %s", |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
764 long_opt->name ? long_opt->name : "???", |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
765 dgettext (parser->argp->argp_domain, bad_key_err)); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
766 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
767 } |
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 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
770 } |
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 /* 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
|
773 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
|
774 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
|
775 generally not fatal). */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
776 static error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
777 parser_parse_next (struct parser *parser, int *arg_ebadkey) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
778 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
779 int opt; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
780 error_t err = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
781 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
782 if (parser->state.quoted && parser->state.next < parser->state.quoted) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
783 /* The next argument pointer has been moved to before the quoted |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
784 region, so pretend we never saw the quoting `--', and give getopt |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
785 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
|
786 process it again. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
787 parser->state.quoted = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
788 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
789 if (parser->try_getopt && !parser->state.quoted) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
790 /* Give getopt a chance to parse this. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
791 { |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
792 /* 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
|
793 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
|
794 /* 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
|
795 parser->opt_data.optopt = KEY_END; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
796 if (parser->state.flags & ARGP_LONG_ONLY) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
797 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
|
798 parser->short_opts, parser->long_opts, 0, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
799 &parser->opt_data); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
800 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
801 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
|
802 parser->short_opts, parser->long_opts, 0, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
803 &parser->opt_data); |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
804 /* And see what getopt did. */ |
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
805 parser->state.next = parser->opt_data.optind; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
806 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
807 if (opt == KEY_END) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
808 /* 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
|
809 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
|
810 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
811 parser->try_getopt = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
812 if (parser->state.next > 1 |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
813 && 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
|
814 == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
815 /* Not only is this the end of the options, but it's a |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
816 `quoted' region, which may have args that *look* like |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
817 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
|
818 here, whatever happens. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
819 parser->state.quoted = parser->state.next; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
820 } |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
821 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
|
822 /* 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
|
823 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
|
824 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
|
825 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
826 *arg_ebadkey = 0; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
827 return EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
828 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
829 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
830 else |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
831 opt = KEY_END; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
832 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
833 if (opt == KEY_END) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
834 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
835 /* We're past what getopt considers the options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
836 if (parser->state.next >= parser->state.argc |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
837 || (parser->state.flags & ARGP_NO_ARGS)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
838 /* Indicate that we're done. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
839 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
840 *arg_ebadkey = 1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
841 return EBADKEY; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
842 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
843 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
844 /* 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
|
845 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
846 opt = KEY_ARG; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
847 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
|
848 } |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
849 } |
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 if (opt == KEY_ARG) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
852 /* 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
|
853 err = parser_parse_arg (parser, parser->opt_data.optarg); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
854 else |
4970
595e9138157c
Sync getopt and argp from libc CVS.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4888
diff
changeset
|
855 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
|
856 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
857 if (err == EBADKEY) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
858 *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
859 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
860 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
861 } |
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 /* 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
|
864 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
|
865 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
|
866 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
|
867 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
|
868 error_t |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
869 __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
|
870 int *end_index, void *input) |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
871 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
872 error_t err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
873 struct parser parser; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
874 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
875 /* 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
|
876 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
|
877 int arg_ebadkey = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
878 |
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
|
879 #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
|
880 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
|
881 { |
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 #ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME |
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
|
883 if (!program_invocation_name) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
884 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
|
885 #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
|
886 #ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME |
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
|
887 if (!program_invocation_short_name) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
888 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
|
889 #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
|
890 } |
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 #endif |
10095 | 892 |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
893 if (! (flags & ARGP_NO_HELP)) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
894 /* Add our own options. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
895 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
896 struct argp_child *child = alloca (4 * sizeof (struct argp_child)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
897 struct argp *top_argp = alloca (sizeof (struct argp)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
898 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
899 /* 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
|
900 argps. */ |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
901 memset (top_argp, 0, sizeof (*top_argp)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
902 top_argp->children = child; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
903 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
904 memset (child, 0, 4 * sizeof (struct argp_child)); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
905 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
906 if (argp) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
907 (child++)->argp = argp; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
908 (child++)->argp = &argp_default_argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
909 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
|
910 (child++)->argp = &argp_version_argp; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
911 child->argp = 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
912 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
913 argp = top_argp; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
914 } |
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 /* Construct a parser for these arguments. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
917 err = parser_init (&parser, argp, argc, argv, flags, input); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
918 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
919 if (! err) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
920 /* Parse! */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
921 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
922 while (! err) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
923 err = parser_parse_next (&parser, &arg_ebadkey); |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
924 err = parser_finalize (&parser, err, arg_ebadkey, end_index); |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
925 } |
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 return err; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
928 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
929 #ifdef weak_alias |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
930 weak_alias (__argp_parse, argp_parse) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
931 #endif |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
932 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
933 /* 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
|
934 by the help routines. */ |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
935 void * |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
936 __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
|
937 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
938 if (state) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
939 { |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
940 struct group *group; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
941 struct parser *parser = state->pstate; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
942 |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
943 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
|
944 if (group->argp == argp) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
10095
diff
changeset
|
945 return group->input; |
4385
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
946 } |
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 return 0; |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
949 } |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
950 #ifdef weak_alias |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
951 weak_alias (__argp_input, _argp_input) |
1c170fb33fa6
argp facility from glibc-20030610.
Bruno Haible <bruno@clisp.org>
parents:
diff
changeset
|
952 #endif |