1 |
/* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */ |
2 |
|
3 |
/* |
4 |
* Copyright (c) 1987, 1993, 1994 |
5 |
* The Regents of the University of California. All rights reserved. |
6 |
* |
7 |
* Redistribution and use in source and binary forms, with or without |
8 |
* modification, are permitted provided that the following conditions |
9 |
* are met: |
10 |
* 1. Redistributions of source code must retain the above copyright |
11 |
* notice, this list of conditions and the following disclaimer. |
12 |
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
* notice, this list of conditions and the following disclaimer in the |
14 |
* documentation and/or other materials provided with the distribution. |
15 |
* 3. Neither the name of the University nor the names of its contributors |
16 |
* may be used to endorse or promote products derived from this software |
17 |
* without specific prior written permission. |
18 |
* |
19 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
20 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
23 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
25 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
26 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 |
* SUCH DAMAGE. |
30 |
*/ |
31 |
|
32 |
#ifdef HAVE_CONFIG_H |
33 |
# include "config.h" |
34 |
#endif |
35 |
#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT) |
36 |
#include <sys/cdefs.h> |
37 |
|
38 |
#include <stdio.h> |
39 |
#include <stdlib.h> |
40 |
#include <string.h> |
41 |
|
42 |
|
43 |
#define BADCH (int)'?' |
44 |
#define BADARG (int)':' |
45 |
#define EMSG "" |
46 |
|
47 |
int opterr = 1, /* if error message should be printed */ |
48 |
optind = 1, /* index into parent argv vector */ |
49 |
optopt = BADCH, /* character checked for validity */ |
50 |
optreset; /* reset getopt */ |
51 |
char *optarg; /* argument associated with option */ |
52 |
|
53 |
/* |
54 |
* getopt -- |
55 |
* Parse argc/argv argument vector. |
56 |
*/ |
57 |
int |
58 |
getopt(int nargc, char * const nargv[], const char *ostr) |
59 |
{ |
60 |
extern char *__progname; |
61 |
static const char *place = EMSG; /* option letter processing */ |
62 |
char *oli; /* option letter list index */ |
63 |
|
64 |
#ifndef BSD4_4 |
65 |
if (!__progname) { |
66 |
if (__progname = strrchr(nargv[0], '/')) |
67 |
++__progname; |
68 |
else |
69 |
__progname = nargv[0]; |
70 |
} |
71 |
#endif |
72 |
|
73 |
if (optreset || *place == 0) { /* update scanning pointer */ |
74 |
optreset = 0; |
75 |
place = nargv[optind]; |
76 |
if (optind >= nargc || *place++ != '-') { |
77 |
/* Argument is absent or is not an option */ |
78 |
place = EMSG; |
79 |
return (-1); |
80 |
} |
81 |
optopt = *place++; |
82 |
if (optopt == '-' && *place == 0) { |
83 |
/* "--" => end of options */ |
84 |
++optind; |
85 |
place = EMSG; |
86 |
return (-1); |
87 |
} |
88 |
if (optopt == 0) { |
89 |
/* Solitary '-', treat as a '-' option |
90 |
if the program (eg su) is looking for it. */ |
91 |
place = EMSG; |
92 |
if (strchr(ostr, '-') == NULL) |
93 |
return -1; |
94 |
optopt = '-'; |
95 |
} |
96 |
} else |
97 |
optopt = *place++; |
98 |
|
99 |
/* See if option letter is one the caller wanted... */ |
100 |
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { |
101 |
if (*place == 0) |
102 |
++optind; |
103 |
if (opterr && *ostr != ':') |
104 |
(void)fprintf(stderr, |
105 |
"%s: unknown option -- %c\n", __progname, optopt); |
106 |
return (BADCH); |
107 |
} |
108 |
|
109 |
/* Does this option need an argument? */ |
110 |
if (oli[1] != ':') { |
111 |
/* don't need argument */ |
112 |
optarg = NULL; |
113 |
if (*place == 0) |
114 |
++optind; |
115 |
} else { |
116 |
/* Option-argument is either the rest of this argument or the |
117 |
entire next argument. */ |
118 |
if (*place) |
119 |
optarg = __UNCONST(place); |
120 |
else if (oli[2] == ':') |
121 |
/* |
122 |
* GNU Extension, for optional arguments if the rest of |
123 |
* the argument is empty, we return NULL |
124 |
*/ |
125 |
optarg = NULL; |
126 |
else if (nargc > ++optind) |
127 |
optarg = nargv[optind]; |
128 |
else { |
129 |
/* option-argument absent */ |
130 |
place = EMSG; |
131 |
if (*ostr == ':') |
132 |
return (BADARG); |
133 |
if (opterr) |
134 |
(void)fprintf(stderr, |
135 |
"%s: option requires an argument -- %c\n", |
136 |
__progname, optopt); |
137 |
return (BADCH); |
138 |
} |
139 |
place = EMSG; |
140 |
++optind; |
141 |
} |
142 |
return (optopt); /* return option letter */ |
143 |
} |
144 |
#endif |
145 |
#ifdef MAIN |
146 |
#ifndef BSD4_4 |
147 |
char *__progname; |
148 |
#endif |
149 |
|
150 |
int |
151 |
main(argc, argv) |
152 |
int argc; |
153 |
char *argv[]; |
154 |
{ |
155 |
int c; |
156 |
char *opts = argv[1]; |
157 |
|
158 |
--argc; |
159 |
++argv; |
160 |
|
161 |
while ((c = getopt(argc, argv, opts)) != EOF) { |
162 |
switch (c) { |
163 |
case '-': |
164 |
if (optarg) |
165 |
printf("--%s ", optarg); |
166 |
break; |
167 |
case '?': |
168 |
exit(1); |
169 |
break; |
170 |
default: |
171 |
if (optarg) |
172 |
printf("-%c %s ", c, optarg); |
173 |
else |
174 |
printf("-%c ", c); |
175 |
break; |
176 |
} |
177 |
} |
178 |
|
179 |
if (optind < argc) { |
180 |
printf("-- "); |
181 |
for (; optind < argc; ++optind) { |
182 |
printf("%s ", argv[optind]); |
183 |
} |
184 |
} |
185 |
printf("\n"); |
186 |
exit(0); |
187 |
} |
188 |
#endif |