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