libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
GetOpt.cc
Go to the documentation of this file.
1/*
2Getopt for GNU.
3Copyright (C) 1987, 1989 Free Software Foundation, Inc.
4
5(Modified by Douglas C. Schmidt for use with GNU G++.)
6This file is part of the GNU C++ Library. This library is free
7software; you can redistribute it and/or modify it under the terms of
8the GNU Library General Public License as published by the Free
9Software Foundation; either version 2 of the License, or (at your
10option) any later version. This library is distributed in the hope
11that it will be useful, but WITHOUT ANY WARRANTY; without even the
12implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13PURPOSE. See the GNU Library General Public License for more details.
14You should have received a copy of the GNU Library General Public
15License along with this library; if not, write to the Free Software
16Foundation, 59 Temple Place - Fifth Floor, Boston, MA 02110-1301, USA.
17*/
18
19#include "config.h"
20
21/* AIX requires the alloca decl to be the first thing in the file. */
22#ifdef __GNUC__
23#define alloca __builtin_alloca
24#elif defined(sparc)
25#include <alloca.h>
26#elif defined(_AIX)
27#pragma alloca
28#elif defined(WIN32)
29#include <malloc.h>
30#else
31char *alloca();
32#endif
33
34#include <vector>
35
36#ifdef HAVE_UNISTD_H
37#include <unistd.h>
38#endif
39#include <cstdio>
40#include <cstdlib>
41#include <cstring> // Added these. 10/20/98 jhrg
42
43#include "GetOpt.h"
44
45// #include <string.h>
46
47char *GetOpt::nextchar = 0;
48int GetOpt::first_nonopt = 0;
49int GetOpt::last_nonopt = 0;
50
51GetOpt::GetOpt(int argc, char **argv, const char *optstring)
52 : opterr(1), nargc(argc), nargv(argv), noptstring(optstring) {
53 /* Initialize the internal data when the first call is made.
54 Start processing options with ARGV-element 1 (since ARGV-element 0
55 is the program name); the sequence of previously skipped
56 non-option ARGV-elements is empty. */
57
58 first_nonopt = last_nonopt = optind = 1;
59 optarg = nextchar = 0;
60
61 /* Determine how to handle the ordering of options and nonoptions. */
62
63 if (optstring[0] == '-')
64 ordering = RETURN_IN_ORDER;
65 else if (getenv("_POSIX_OPTION_ORDER") != 0)
66 ordering = REQUIRE_ORDER;
67 else
68 ordering = PERMUTE;
69}
70
71void GetOpt::exchange(char **argv) {
72 int nonopts_size = (last_nonopt - first_nonopt) * sizeof(char *);
73 /* char **temp = (char **) alloca (nonopts_size); */
74 /* char **temp = (char **)malloc(nonopts_size); */
75 std::vector<char> temp(nonopts_size);
76
77 /* Interchange the two blocks of data in argv. */
78
79 memcpy(temp.data(), &argv[first_nonopt], nonopts_size);
80
81 /* valgrind complains about this because in some cases the memory areas
82 overlap. I switched to memmove. See the memcpy & memmove man pages.
83 02/12/04 jhrg */
84#if 0
85 memcpy (&argv[first_nonopt], &argv[last_nonopt],
86 (optind - last_nonopt) * sizeof (char *));
87#endif
88 memmove(&argv[first_nonopt], &argv[last_nonopt], (optind - last_nonopt) * sizeof(char *));
89
90 memcpy(&argv[first_nonopt + optind - last_nonopt], temp.data(), nonopts_size);
91
92 /* Update records for the slots the non-options now occupy. */
93
94 first_nonopt += (optind - last_nonopt);
95 last_nonopt = optind;
96
97 // free(temp);
98}
99
100/* Scan elements of ARGV (whose length is ARGC) for option characters
101 given in OPTSTRING.
102
103 If an element of ARGV starts with '-', and is not exactly "-" or "--",
104 then it is an option element. The characters of this element
105 (aside from the initial '-') are option characters. If `getopt'
106 is called repeatedly, it returns successively each of theoption characters
107 from each of the option elements.
108
109 If `getopt' finds another option character, it returns that character,
110 updating `optind' and `nextchar' so that the next call to `getopt' can
111 resume the scan with the following option character or ARGV-element.
112
113 If there are no more option characters, `getopt' returns `EOF'.
114 Then `optind' is the index in ARGV of the first ARGV-element
115 that is not an option. (The ARGV-elements have been permuted
116 so that those that are not options now come last.)
117
118 OPTSTRING is a string containing the legitimate option characters.
119 A colon in OPTSTRING means that the previous character is an option
120 that wants an argument. The argument is taken from the rest of the
121 current ARGV-element, or from the following ARGV-element,
122 and returned in `optarg'.
123
124 If an option character is seen that is not listed in OPTSTRING,
125 return '?' after printing an error message. If you set `opterr' to
126 zero, the error message is suppressed but we still return '?'.
127
128 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
129 so the following text in the same ARGV-element, or the text of the following
130 ARGV-element, is returned in `optarg. Two colons mean an option that
131 wants an optional arg; if there is text in the current ARGV-element,
132 it is returned in `optarg'.
133
134 If OPTSTRING starts with `-', it requests a different method of handling the
135 non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above. */
136
138 if (nextchar == 0 || *nextchar == 0) {
139 if (ordering == PERMUTE) {
140 /* If we have just processed some options following some non-options,
141 exchange them so that the options come first. */
142
143 if (first_nonopt != last_nonopt && last_nonopt != optind)
144 exchange(nargv);
145 else if (last_nonopt != optind)
146 first_nonopt = optind;
147
148 /* Now skip any additional non-options
149 and extend the range of non-options previously skipped. */
150
151 while (optind < nargc && (nargv[optind][0] != '-' || nargv[optind][1] == 0))
152 optind++;
153 last_nonopt = optind;
154 }
155
156 /* Special ARGV-element `--' means premature end of options.
157 Skip it like a null option,
158 then exchange with previous non-options as if it were an option,
159 then skip everything else like a non-option. */
160
161 if (optind != nargc && !strcmp(nargv[optind], "--")) {
162 optind++;
163
164 if (first_nonopt != last_nonopt && last_nonopt != optind)
165 exchange(nargv);
166 else if (first_nonopt == last_nonopt)
167 first_nonopt = optind;
168 last_nonopt = nargc;
169
170 optind = nargc;
171 }
172
173 /* If we have done all the ARGV-elements, stop the scan
174 and back over any non-options that we skipped and permuted. */
175
176 if (optind == nargc) {
177 /* Set the next-arg-index to point at the non-options
178 that we previously skipped, so the caller will digest them. */
179 if (first_nonopt != last_nonopt)
180 optind = first_nonopt;
181 return EOF;
182 }
183
184 /* If we have come to a non-option and did not permute it,
185 either stop the scan or describe it to the caller and pass it by. */
186
187 if (nargv[optind][0] != '-' || nargv[optind][1] == 0) {
188 if (ordering == REQUIRE_ORDER)
189 return EOF;
190 optarg = nargv[optind++];
191 return 0;
192 }
193
194 /* We have found another option-ARGV-element.
195 Start decoding its characters. */
196
197 nextchar = nargv[optind] + 1;
198 }
199
200 /* Look at and handle the next option-character. */
201
202 {
203 char c = *nextchar++;
204 char *temp = (char *)strchr(noptstring, c);
205
206 /* Increment `optind' when we start to process its last character. */
207 if (*nextchar == 0)
208 optind++;
209
210 if (temp == 0 || c == ':') {
211 if (opterr != 0) {
212 if (c < 040 || c >= 0177)
213 fprintf(stderr, "%s: unrecognized option, character code 0%o\n", nargv[0], c);
214 else
215 fprintf(stderr, "%s: unrecognized option `-%c'\n", nargv[0], c);
216 }
217 return '?';
218 }
219 if (temp[1] == ':') {
220 if (temp[2] == ':') {
221 /* This is an option that accepts an argument optionally. */
222 if (*nextchar != 0) {
223 optarg = nextchar;
224 optind++;
225 } else
226 optarg = 0;
227 nextchar = 0;
228 } else {
229 /* This is an option that requires an argument. */
230 if (*nextchar != 0) {
231 optarg = nextchar;
232 /* If we end this ARGV-element by taking the rest as an arg,
233 we must advance to the next element now. */
234 optind++;
235 } else if (optind == nargc) {
236 if (opterr != 0)
237 fprintf(stderr, "%s: no argument for `-%c' option\n", nargv[0], c);
238 c = '?';
239 } else
240 /* We already incremented `optind' once;
241 increment it again when taking next ARGV-elt as argument. */
242 optarg = nargv[optind++];
243 nextchar = 0;
244 }
245 }
246 return c;
247 }
248}
char * alloca()
int nargc
Definition GetOpt.h:115
int opterr
Definition GetOpt.h:113
GetOpt(int argc, char **argv, const char *optstring)
Definition GetOpt.cc:51
const char * noptstring
Definition GetOpt.h:117
int operator()(void)
Definition GetOpt.cc:137
char * optarg
Definition GetOpt.h:95
int optind
Definition GetOpt.h:108
char ** nargv
Definition GetOpt.h:116