]> git.ipfire.org Git - thirdparty/ccache.git/blob - getopt_long.c
Improve description on how to fix bad object files in the cache
[thirdparty/ccache.git] / 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
35 #include "config.h"
36
37 #ifndef HAVE_GETOPT_LONG
38
39 #include "getopt_long.h"
40
41 #include <stdio.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 #define BADCH '?'
46 #define BADARG ':'
47 #define EMSG ""
48
49 int
50 getopt_long(int argc, char *const argv[],
51 const char *optstring,
52 const struct option * longopts, int *longindex)
53 {
54 static char *place = EMSG; /* option letter processing */
55 char *oli; /* option letter list index */
56
57 if (!*place)
58 { /* update scanning pointer */
59 if (optind >= argc)
60 {
61 place = EMSG;
62 return -1;
63 }
64
65 place = argv[optind];
66
67 if (place[0] != '-')
68 {
69 place = EMSG;
70 return -1;
71 }
72
73 place++;
74
75 if (place[0] && place[0] == '-' && place[1] == '\0')
76 { /* found "--" */
77 ++optind;
78 place = EMSG;
79 return -1;
80 }
81
82 if (place[0] && place[0] == '-' && place[1])
83 {
84 /* long option */
85 size_t namelen;
86 int i;
87
88 place++;
89
90 namelen = strcspn(place, "=");
91 for (i = 0; longopts[i].name != NULL; i++)
92 {
93 if (strlen(longopts[i].name) == namelen
94 && strncmp(place, longopts[i].name, namelen) == 0)
95 {
96 if (longopts[i].has_arg)
97 {
98 if (place[namelen] == '=')
99 optarg = place + namelen + 1;
100 else if (optind < argc - 1)
101 {
102 optind++;
103 optarg = argv[optind];
104 }
105 else
106 {
107 if (optstring[0] == ':')
108 return BADARG;
109 if (opterr)
110 fprintf(stderr,
111 "%s: option requires an argument -- %s\n",
112 argv[0], place);
113 place = EMSG;
114 optind++;
115 return BADCH;
116 }
117 }
118 else
119 {
120 optarg = NULL;
121 if (place[namelen] != 0)
122 {
123 /* XXX error? */
124 }
125 }
126
127 optind++;
128
129 if (longindex)
130 *longindex = i;
131
132 place = EMSG;
133
134 if (longopts[i].flag == NULL)
135 return longopts[i].val;
136 else
137 {
138 *longopts[i].flag = longopts[i].val;
139 return 0;
140 }
141 }
142 }
143
144 if (opterr && optstring[0] != ':')
145 fprintf(stderr,
146 "%s: illegal option -- %s\n", argv[0], place);
147 place = EMSG;
148 optind++;
149 return BADCH;
150 }
151 }
152
153 /* short option */
154 optopt = (int) *place++;
155
156 oli = strchr(optstring, optopt);
157 if (!oli)
158 {
159 if (!*place)
160 ++optind;
161 if (opterr && *optstring != ':')
162 fprintf(stderr,
163 "%s: illegal option -- %c\n", argv[0], optopt);
164 return BADCH;
165 }
166
167 if (oli[1] != ':')
168 { /* don't need argument */
169 optarg = NULL;
170 if (!*place)
171 ++optind;
172 }
173 else
174 { /* need an argument */
175 if (*place) /* no white space */
176 optarg = place;
177 else if (argc <= ++optind)
178 { /* no arg */
179 place = EMSG;
180 if (*optstring == ':')
181 return BADARG;
182 if (opterr)
183 fprintf(stderr,
184 "%s: option requires an argument -- %c\n",
185 argv[0], optopt);
186 return BADCH;
187 }
188 else
189 /* white space */
190 optarg = argv[optind];
191 place = EMSG;
192 ++optind;
193 }
194 return optopt;
195 }
196
197 #endif /* HAVE_GETOPT_LONG */