Print this page
5218 posix definition of NULL
correct unistd.h and iso/stddef_iso.h
update gate source affected
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libc/port/gen/getopt.c
+++ new/usr/src/lib/libc/port/gen/getopt.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /* Copyright (c) 1988 AT&T */
28 28 /* All Rights Reserved */
29 29
30 30 #pragma ident "%Z%%M% %I% %E% SMI"
31 31
32 32 /*
33 33 * See getopt(3C) and SUS/XPG getopt() for function definition and
34 34 * requirements.
35 35 *
36 36 * This actual implementation is a bit looser than the specification
37 37 * as it allows any character other than ':' and '(' to be used as
38 38 * a short option character - The specification only guarantees the
39 39 * alnum characters ([a-z][A-Z][0-9]).
40 40 */
41 41
42 42 #pragma weak _getopt = getopt
43 43
44 44 #include "lint.h"
45 45 #include "_libc_gettext.h"
46 46
47 47 #include <unistd.h>
48 48 #include <string.h>
49 49 #include <stdio.h>
50 50
51 51 /*
52 52 * Generalized error processing macro. The parameter i is a pointer to
53 53 * the failed option string. If it is NULL, the character in c is converted
54 54 * to a string and displayed instead. s is the error text.
55 55 *
56 56 * This could be / should be a static function if it is used more, but
57 57 * that would require moving the 'optstring[0]' test outside of the
58 58 * function.
59 59 */
60 60 #define ERR(s, c, i) if (opterr && optstring[0] != ':') { \
61 61 char errbuf[256]; \
62 62 char cbuf[2]; \
63 63 cbuf[0] = c; \
64 64 cbuf[1] = '\0'; \
65 65 (void) snprintf(errbuf, sizeof (errbuf), s, argv[0], \
66 66 (i ? argv[i]+2 : cbuf)); \
67 67 (void) write(2, errbuf, strlen(errbuf)); }
68 68
69 69 /*
70 70 * _sp is required to keep state between successive calls to getopt() while
71 71 * extracting aggregated short-options (ie: -abcd). Hence, getopt() is not
72 72 * thread safe or reentrant, but it really doesn't matter.
73 73 *
74 74 * So, why isn't this "static" you ask? Because the historical Bourne
75 75 * shell has actually latched on to this little piece of private data.
76 76 */
77 77 int _sp = 1;
78 78
79 79 /*
80 80 * Determine if the specified character (c) is present in the string
81 81 * (optstring) as a regular, single character option. If the option is found,
82 82 * return a pointer into optstring pointing at the short-option character,
83 83 * otherwise return null. The characters ':' and '(' are not allowed.
84 84 */
85 85 static char *
86 86 parseshort(const char *optstring, const char c)
87 87 {
88 88 char *cp = (char *)optstring;
89 89
90 90 if (c == ':' || c == '(')
91 91 return (NULL);
92 92 do {
93 93 if (*cp == c)
94 94 return (cp);
95 95 while (*cp == '(')
96 96 while (*cp != '\0' && *cp != ')')
97 97 cp++;
98 98 } while (*cp++ != '\0');
99 99 return (NULL);
100 100 }
101 101
102 102 /*
103 103 * Determine if the specified string (opt) is present in the string
104 104 * (optstring) as a long-option contained within parenthesis. If the
105 105 * long-option specifies option-argument, return a pointer to it in
106 106 * longoptarg. Otherwise set longoptarg to null. If the option is found,
107 107 * return a pointer into optstring pointing at the short-option character
108 108 * associated with this long-option; otherwise return null.
109 109 *
110 110 * optstring The entire optstring passed to getopt() by the caller
111 111 *
112 112 * opt The long option read from the command line
113 113 *
114 114 * longoptarg The argument to the option is returned in this parameter,
115 115 * if an option exists. Possible return values in longoptarg
116 116 * are:
117 117 * NULL No argument was found
118 118 * empty string ("") Argument was explicitly left empty
119 119 * by the user (e.g., --option= )
120 120 * valid string Argument found on the command line
121 121 *
122 122 * returns Pointer to equivalent short-option in optstring, null
123 123 * if option not found in optstring.
124 124 *
125 125 * ASSUMES: No parameters are NULL
126 126 *
127 127 */
128 128 static char *
129 129 parselong(const char *optstring, const char *opt, char **longoptarg)
130 130 {
131 131 char *cp; /* ptr into optstring, beginning of one option spec. */
132 132 char *ip; /* ptr into optstring, traverses every char */
133 133 char *op; /* pointer into opt */
134 134 int match; /* nonzero if opt is matching part of optstring */
135 135
136 136 cp = ip = (char *)optstring;
137 137 do {
138 138 if (*ip != '(' && *++ip == '\0')
139 139 break;
140 140 if (*ip == ':' && *++ip == '\0')
141 141 break;
142 142 while (*ip == '(') {
143 143 if (*++ip == '\0')
144 144 break;
145 145 op = (char *)opt;
146 146 match = 1;
147 147 while (*ip != ')' && *ip != '\0' && *op != '\0')
148 148 match = (*ip++ == *op++ && match);
149 149 if (match && *ip == ')' &&
150 150 (*op == '\0' || *op == '=')) {
151 151 if ((*op) == '=') {
152 152 /* may be an empty string - OK */
153 153 (*longoptarg) = op + 1;
154 154 } else {
155 155 (*longoptarg) = NULL;
156 156 }
157 157 return (cp);
158 158 }
159 159 if (*ip == ')' && *++ip == '\0')
160 160 break;
161 161 }
162 162 cp = ip;
163 163 /*
164 164 * Handle double-colon in optstring ("a::(longa)")
165 165 * The old getopt() accepts it and treats it as a
166 166 * required argument.
167 167 */
168 168 while ((cp > optstring) && ((*cp) == ':')) {
169 169 --cp;
170 170 }
171 171 } while (*cp != '\0');
172 172 return (NULL);
173 173 } /* parselong() */
174 174
175 175 /*
176 176 * External function entry point.
177 177 */
178 178 int
179 179 getopt(int argc, char *const *argv, const char *optstring)
180 180 {
181 181 char c;
182 182 char *cp;
183 183 int longopt;
184 184 char *longoptarg;
185 185
186 186 /*
187 187 * Has the end of the options been encountered? The following
188 188 * implements the SUS requirements:
189 189 *
190 190 * If, when getopt() is called:
191 191 * argv[optind] is a null pointer
↓ open down ↓ |
191 lines elided |
↑ open up ↑ |
192 192 * *argv[optind] is not the character '-'
193 193 * argv[optind] points to the string "-"
194 194 * getopt() returns -1 without changing optind. If
195 195 * argv[optind] points to the string "--"
196 196 * getopt() returns -1 after incrementing optind.
197 197 */
198 198 if (_sp == 1) {
199 199 if (optind >= argc || argv[optind][0] != '-' ||
200 200 argv[optind] == NULL || argv[optind][1] == '\0')
201 201 return (EOF);
202 - else if (strcmp(argv[optind], "--") == NULL) {
202 + else if (strcmp(argv[optind], "--") == 0) {
203 203 optind++;
204 204 return (EOF);
205 205 }
206 206 }
207 207
208 208 /*
209 209 * Getting this far indicates that an option has been encountered.
210 210 * Note that the syntax of optstring applies special meanings to
211 211 * the characters ':' and '(', so they are not permissible as
212 212 * option letters. A special meaning is also applied to the ')'
213 213 * character, but its meaning can be determined from context.
214 214 * Note that the specification only requires that the alnum
215 215 * characters be accepted.
216 216 *
217 217 * If the second character of the argument is a '-' this must be
218 218 * a long-option, otherwise it must be a short option. Scan for
219 219 * the option in optstring by the appropriate algorithm. Either
220 220 * scan will return a pointer to the short-option character in
221 221 * optstring if the option is found and NULL otherwise.
222 222 *
223 223 * For an unrecognized long-option, optopt will equal 0, but
224 224 * since long-options can't aggregate the failing option can
225 225 * be identified by argv[optind-1].
226 226 */
227 227 optopt = c = (unsigned char)argv[optind][_sp];
228 228 optarg = NULL;
229 229 longopt = (_sp == 1 && c == '-');
230 230 if (!(longopt ?
231 231 ((cp = parselong(optstring, argv[optind]+2, &longoptarg)) != NULL) :
232 232 ((cp = parseshort(optstring, c)) != NULL))) {
233 233 ERR(_libc_gettext("%s: illegal option -- %s\n"),
234 234 c, (longopt ? optind : 0));
235 235 /*
236 236 * Note: When the long option is unrecognized, optopt
237 237 * will be '-' here, which matches the specification.
238 238 */
239 239 if (argv[optind][++_sp] == '\0' || longopt) {
240 240 optind++;
241 241 _sp = 1;
242 242 }
243 243 return ('?');
244 244 }
245 245 optopt = c = *cp;
246 246
247 247 /*
248 248 * A valid option has been identified. If it should have an
249 249 * option-argument, process that now. SUS defines the setting
250 250 * of optarg as follows:
251 251 *
252 252 * 1. If the option was the last character in the string pointed to
253 253 * by an element of argv, then optarg contains the next element
254 254 * of argv, and optind is incremented by 2. If the resulting
255 255 * value of optind is not less than argc, this indicates a
256 256 * missing option-argument, and getopt() returns an error
257 257 * indication.
258 258 *
259 259 * 2. Otherwise, optarg points to the string following the option
260 260 * character in that element of argv, and optind is incremented
261 261 * by 1.
262 262 *
263 263 * The second clause allows -abcd (where b requires an option-argument)
264 264 * to be interpreted as "-a -b cd".
265 265 *
266 266 * Note that the option-argument can legally be an empty string,
267 267 * such as:
268 268 * command --option= operand
269 269 * which explicitly sets the value of --option to nil
270 270 */
271 271 if (*(cp + 1) == ':') {
272 272 /* The option takes an argument */
273 273 if (!longopt && argv[optind][_sp+1] != '\0') {
274 274 optarg = &argv[optind++][_sp+1];
275 275 } else if (longopt && longoptarg) {
276 276 /*
277 277 * The option argument was explicitly set to
278 278 * the empty string on the command line (--option=)
279 279 */
280 280 optind++;
281 281 optarg = longoptarg;
282 282 } else if (++optind >= argc) {
283 283 ERR(_libc_gettext("%s: option requires an argument" \
284 284 " -- %s\n"), c, (longopt ? optind - 1 : 0));
285 285 _sp = 1;
286 286 optarg = NULL;
287 287 return (optstring[0] == ':' ? ':' : '?');
288 288 } else
289 289 optarg = argv[optind++];
290 290 _sp = 1;
291 291 } else {
292 292 /* The option does NOT take an argument */
293 293 if (longopt && (longoptarg != NULL)) {
294 294 /* User supplied an arg to an option that takes none */
295 295 ERR(_libc_gettext(
296 296 "%s: option doesn't take an argument -- %s\n"),
297 297 0, (longopt ? optind : 0));
298 298 optarg = longoptarg = NULL;
299 299 c = '?';
300 300 }
301 301
302 302 if (longopt || argv[optind][++_sp] == '\0') {
303 303 _sp = 1;
304 304 optind++;
305 305 }
306 306 optarg = NULL;
307 307 }
308 308 return (c);
309 309 } /* getopt() */
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX