PostgreSQL Source Code
git master
Loading...
Searching...
No Matches
getopt_long.c
Go to the documentation of this file.
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,
54
* "nonopt_start" to -1, and "force_nonopt" to false before returning -1.)
55
*
56
* Note that this routine reorders the pointers in argv (despite the const
57
* qualifier) so that all non-options will be at the end when -1 is returned.
58
*/
59
int
60
getopt_long
(
int
argc,
char
*
const
argv[],
61
const
char
*
optstring
,
62
const
struct
option
*
longopts
,
int
*
longindex
)
63
{
64
static
char
*
place
=
EMSG
;
/* option letter processing */
65
const
char
*
oli
;
/* option letter list index */
66
static
int
nonopt_start
= -1;
67
static
bool
force_nonopt
=
false
;
68
69
if
(!*
place
)
70
{
/* update scanning pointer */
71
char
**args = (
char
**) argv;
72
73
retry
:
74
75
/*
76
* If we are out of arguments or only non-options remain, return -1.
77
*/
78
if
(
optind
>= argc ||
optind
==
nonopt_start
)
79
{
80
place
=
EMSG
;
81
nonopt_start
= -1;
82
force_nonopt
=
false
;
83
return
-1;
84
}
85
86
place
= argv[
optind
];
87
88
/*
89
* An argument is a non-option if it meets any of the following
90
* criteria: it follows an argument that is equivalent to the string
91
* "--", it does not start with '-', or it is equivalent to the string
92
* "-". When we encounter a non-option, we move it to the end of argv
93
* (after shifting all remaining arguments over to make room), and
94
* then we try again with the next argument.
95
*/
96
if
(
force_nonopt
||
place
[0] !=
'-'
||
place
[1] ==
'\0'
)
97
{
98
for
(
int
i
=
optind
;
i
< argc - 1;
i
++)
99
args[
i
] = args[
i
+ 1];
100
args[argc - 1] =
place
;
101
102
if
(
nonopt_start
== -1)
103
nonopt_start
= argc - 1;
104
else
105
nonopt_start
--;
106
107
goto
retry
;
108
}
109
110
place
++;
111
112
if
(
place
[0] ==
'-'
&&
place
[1] ==
'\0'
)
113
{
114
/* found "--", treat it as end of options */
115
++
optind
;
116
force_nonopt
=
true
;
117
goto
retry
;
118
}
119
120
if
(
place
[0] ==
'-'
&&
place
[1])
121
{
122
/* long option */
123
size_t
namelen;
124
int
i
;
125
126
place
++;
127
128
namelen =
strcspn
(
place
,
"="
);
129
for
(
i
= 0;
longopts
[
i
].name !=
NULL
;
i
++)
130
{
131
if
(
strlen
(
longopts
[
i
].
name
) == namelen
132
&&
strncmp
(
place
,
longopts
[
i
].
name
, namelen) == 0)
133
{
134
int
has_arg =
longopts
[
i
].has_arg;
135
136
if
(has_arg !=
no_argument
)
137
{
138
if
(
place
[namelen] ==
'='
)
139
optarg
=
place
+ namelen + 1;
140
else
if
(
optind
< argc - 1 &&
141
has_arg ==
required_argument
)
142
{
143
optind
++;
144
optarg
= argv[
optind
];
145
}
146
else
147
{
148
if
(
optstring
[0] ==
':'
)
149
return
BADARG
;
150
151
if
(
opterr
&& has_arg ==
required_argument
)
152
fprintf
(
stderr
,
153
"%s: option requires an argument -- %s\n"
,
154
argv[0],
place
);
155
156
place
=
EMSG
;
157
optind
++;
158
159
if
(has_arg ==
required_argument
)
160
return
BADCH
;
161
optarg
=
NULL
;
162
}
163
}
164
else
165
{
166
optarg
=
NULL
;
167
if
(
place
[namelen] != 0)
168
{
169
/* XXX error? */
170
}
171
}
172
173
optind
++;
174
175
if
(
longindex
)
176
*
longindex
=
i
;
177
178
place
=
EMSG
;
179
180
if
(
longopts
[
i
].
flag
==
NULL
)
181
return
longopts
[
i
].val;
182
else
183
{
184
*
longopts
[
i
].flag =
longopts
[
i
].val;
185
return
0;
186
}
187
}
188
}
189
190
if
(
opterr
&&
optstring
[0] !=
':'
)
191
fprintf
(
stderr
,
192
"%s: illegal option -- %s\n"
, argv[0],
place
);
193
place
=
EMSG
;
194
optind
++;
195
return
BADCH
;
196
}
197
}
198
199
/* short option */
200
optopt
= (
int
) *
place
++;
201
202
oli
=
strchr
(
optstring
,
optopt
);
203
if
(!
oli
)
204
{
205
if
(!*
place
)
206
++
optind
;
207
if
(
opterr
&& *
optstring
!=
':'
)
208
fprintf
(
stderr
,
209
"%s: illegal option -- %c\n"
, argv[0],
optopt
);
210
return
BADCH
;
211
}
212
213
if
(
oli
[1] !=
':'
)
214
{
/* don't need argument */
215
optarg
=
NULL
;
216
if
(!*
place
)
217
++
optind
;
218
}
219
else
220
{
/* need an argument */
221
if
(*
place
)
/* no white space */
222
optarg
=
place
;
223
else
if
(argc <= ++
optind
)
224
{
/* no arg */
225
place
=
EMSG
;
226
if
(*
optstring
==
':'
)
227
return
BADARG
;
228
if
(
opterr
)
229
fprintf
(
stderr
,
230
"%s: option requires an argument -- %c\n"
,
231
argv[0],
optopt
);
232
return
BADCH
;
233
}
234
else
235
/* white space */
236
optarg
= argv[
optind
];
237
place
=
EMSG
;
238
++
optind
;
239
}
240
return
optopt
;
241
}
c.h
fprintf
#define fprintf(file, fmt, msg)
Definition
cubescan.l:21
getopt_long
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition
getopt_long.c:60
BADCH
#define BADCH
Definition
getopt_long.c:41
BADARG
#define BADARG
Definition
getopt_long.c:42
EMSG
#define EMSG
Definition
getopt_long.c:43
getopt_long.h
no_argument
#define no_argument
Definition
getopt_long.h:25
required_argument
#define required_argument
Definition
getopt_long.h:26
i
int i
Definition
isn.c:77
optind
PGDLLIMPORT int optind
Definition
getopt.c:51
optopt
PGDLLIMPORT int optopt
Definition
getopt.c:52
opterr
PGDLLIMPORT int opterr
Definition
getopt.c:50
optarg
PGDLLIMPORT char * optarg
Definition
getopt.c:53
fb
static int fb(int x)
Definition
preproc-init.c:92
option
Definition
getopt_long.h:18
flag
char * flag(int b)
Definition
test-ctype.c:33
name
const char * name
Definition
wait_event_funcs.c:28
src
port
getopt_long.c
Generated on Fri Jan 30 2026 06:13:18 for PostgreSQL Source Code by
1.9.8