]> granicus.if.org Git - postgresql/blob - src/port/getopt_long.c
Don't zero opfuncid when reading nodes.
[postgresql] / src / port / getopt_long.c
1 /*
2  * getopt_long() -- long options parser
3  *
4  * Portions Copyright (c) 1987, 1993, 1994
5  * The Regents of the University of California.  All rights reserved.
6  *
7  * Portions Copyright (c) 2003
8  * PostgreSQL Global Development Group
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *        notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *        notice, this list of conditions and the following disclaimer in the
17  *        documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *        may be used to endorse or promote products derived from this software
20  *        without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * src/port/getopt_long.c
35  */
36
37 #include "c.h"
38
39 #include "getopt_long.h"
40
41 #define BADCH   '?'
42 #define BADARG  ':'
43 #define EMSG    ""
44
45
46 /*
47  * getopt_long
48  *      Parse argc/argv argument vector, with long options.
49  *
50  * This implementation does not use optreset.  Instead, we guarantee that
51  * it can be restarted on a new argv array after a previous call returned -1,
52  * if the caller resets optind to 1 before the first call of the new series.
53  * (Internally, this means we must be sure to reset "place" to EMSG before
54  * returning -1.)
55  */
56 int
57 getopt_long(int argc, char *const argv[],
58                         const char *optstring,
59                         const struct option * longopts, int *longindex)
60 {
61         static char *place = EMSG;      /* option letter processing */
62         char       *oli;                        /* option letter list index */
63
64         if (!*place)
65         {                                                       /* update scanning pointer */
66                 if (optind >= argc)
67                 {
68                         place = EMSG;
69                         return -1;
70                 }
71
72                 place = argv[optind];
73
74                 if (place[0] != '-')
75                 {
76                         place = EMSG;
77                         return -1;
78                 }
79
80                 place++;
81
82                 if (place[0] && place[0] == '-' && place[1] == '\0')
83                 {                                               /* found "--" */
84                         ++optind;
85                         place = EMSG;
86                         return -1;
87                 }
88
89                 if (place[0] && place[0] == '-' && place[1])
90                 {
91                         /* long option */
92                         size_t          namelen;
93                         int                     i;
94
95                         place++;
96
97                         namelen = strcspn(place, "=");
98                         for (i = 0; longopts[i].name != NULL; i++)
99                         {
100                                 if (strlen(longopts[i].name) == namelen
101                                         && strncmp(place, longopts[i].name, namelen) == 0)
102                                 {
103                                         int                     has_arg = longopts[i].has_arg;
104
105                                         if (has_arg != no_argument)
106                                         {
107                                                 if (place[namelen] == '=')
108                                                         optarg = place + namelen + 1;
109                                                 else if (optind < argc - 1 &&
110                                                                  has_arg == required_argument)
111                                                 {
112                                                         optind++;
113                                                         optarg = argv[optind];
114                                                 }
115                                                 else
116                                                 {
117                                                         if (optstring[0] == ':')
118                                                                 return BADARG;
119
120                                                         if (opterr && has_arg == required_argument)
121                                                                 fprintf(stderr,
122                                                                    "%s: option requires an argument -- %s\n",
123                                                                                 argv[0], place);
124
125                                                         place = EMSG;
126                                                         optind++;
127
128                                                         if (has_arg == required_argument)
129                                                                 return BADCH;
130                                                         optarg = NULL;
131                                                 }
132                                         }
133                                         else
134                                         {
135                                                 optarg = NULL;
136                                                 if (place[namelen] != 0)
137                                                 {
138                                                         /* XXX error? */
139                                                 }
140                                         }
141
142                                         optind++;
143
144                                         if (longindex)
145                                                 *longindex = i;
146
147                                         place = EMSG;
148
149                                         if (longopts[i].flag == NULL)
150                                                 return longopts[i].val;
151                                         else
152                                         {
153                                                 *longopts[i].flag = longopts[i].val;
154                                                 return 0;
155                                         }
156                                 }
157                         }
158
159                         if (opterr && optstring[0] != ':')
160                                 fprintf(stderr,
161                                                 "%s: illegal option -- %s\n", argv[0], place);
162                         place = EMSG;
163                         optind++;
164                         return BADCH;
165                 }
166         }
167
168         /* short option */
169         optopt = (int) *place++;
170
171         oli = strchr(optstring, optopt);
172         if (!oli)
173         {
174                 if (!*place)
175                         ++optind;
176                 if (opterr && *optstring != ':')
177                         fprintf(stderr,
178                                         "%s: illegal option -- %c\n", argv[0], optopt);
179                 return BADCH;
180         }
181
182         if (oli[1] != ':')
183         {                                                       /* don't need argument */
184                 optarg = NULL;
185                 if (!*place)
186                         ++optind;
187         }
188         else
189         {                                                       /* need an argument */
190                 if (*place)                             /* no white space */
191                         optarg = place;
192                 else if (argc <= ++optind)
193                 {                                               /* no arg */
194                         place = EMSG;
195                         if (*optstring == ':')
196                                 return BADARG;
197                         if (opterr)
198                                 fprintf(stderr,
199                                                 "%s: option requires an argument -- %c\n",
200                                                 argv[0], optopt);
201                         return BADCH;
202                 }
203                 else
204                         /* white space */
205                         optarg = argv[optind];
206                 place = EMSG;
207                 ++optind;
208         }
209         return optopt;
210 }