Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / lib / libc / getopt / getopt.c
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12
13 /*
14  * includes
15  *******************************************************************************
16  */
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <getopt.h>
21
22 /*
23  * global variables, types & constants
24  * may be removed if already defined
25  *******************************************************************************
26  */
27 int opterr = 1;
28 int optopt = 0;
29 int optind = 1;
30 char *optarg = NULL;
31
32 /*
33  * internal values needed by getopt
34  * DO NOT CHANGE or REMOVE
35  */
36 enum {
37         OPTIONAL_ARG = 0,
38         MANDATORY_ARG = 1,
39         NO_ARG = 2
40 };
41
42 /*
43  * variables needed by getopt & getopt_long!
44  * DO NOT REMOVE
45  */
46 static char *optstart = NULL;
47
48 int
49 getopt(int argc, char **argv, const char *options)
50 {
51         char *optptr;
52         char *argptr;
53         int optman;
54         int idx;
55         int ret = 0;
56         int argpresent;
57
58         /*
59          * reset used global values
60          */
61         optopt = 0;
62         optarg = NULL;
63
64         /*
65          * reset getopt if a new argv pointer is passed
66          */
67         if (optstart != argv[0]) {
68                 optopt = 0;
69                 optind = 1;
70                 optarg = NULL;
71                 optstart = argv[0];
72         }
73
74         /*
75          * return if no more arguments are available
76          */
77         if (optind >= argc) {
78                 return -1;
79         }
80
81         /*
82          * start parsing argv[optind]
83          */
84         idx = 0;
85
86         /*
87          * return if the option does not begin with a '-' or has more than 2 characters
88          */
89         if (argv[optind][idx] != '-') {
90
91                 if (opterr != 0) {
92                         printf("unknown option \'%s\', expecting \'-\'\n",
93                                argv[optind]);
94                 }
95
96                 optopt = (int) argv[optind][idx];
97                 optind++;
98
99                 return '?';
100         }
101
102         /*
103          * continue to the next character in argv[optind]
104          */
105         idx++;
106
107         /*
108          * identify the option
109          * make sure if an option contains a ':' to invalidate the option
110          */
111         optptr = strchr(argv[optind], ':');
112
113         if (optptr == NULL) {
114                 optptr = strchr(options, (int) argv[optind][idx]);
115         } else {
116                 optptr = NULL;
117         }
118
119         /*
120          * check whether the option is present
121          */
122         if (optptr == NULL) {
123                 /*
124                  * unknown option detected
125                  */
126                 if (opterr != 0) {
127                         printf("unknown option \'%s\'\n", argv[optind]);
128                 }
129
130                 optopt = (int) argv[optind][idx];
131                 optind++;
132
133                 return '?';
134         }
135
136         /*
137          * the option is present in the option string
138          * setup return value
139          */
140         ret = (int) *optptr;
141
142         /*
143          * get option argument if needed
144          */
145         optptr++;
146
147         /*
148          * determine between mandatory and optional argument
149          */
150         optman = NO_ARG;
151
152         if (*optptr == ':') {
153                 optman--;       // now set to MANDATORY_ARG
154         }
155
156         if (optman == MANDATORY_ARG) {
157                 optptr++;
158
159                 if (*optptr == ':') {
160                         optman--;       // now set to OPTIONAL_ARG
161                 }
162
163         }
164
165         /*
166          * if strlen( argv[optind ) is greater than 2,
167          * the argument is in the same argv
168          */
169         if (strlen(argv[optind]) > 2) {
170                 argptr = &argv[optind][2];
171
172                 /*
173                  * do not allow '-' in an argument
174                  */
175                 if (strchr(argptr, '-') != NULL) {
176
177                         if (opterr != 0) {
178                                 printf
179                                     ("illegal argument value \'%s\' for option \'-%c\'\n",
180                                      argptr, ret);
181                         }
182
183                         optopt = ret;
184
185                         return '?';
186                 }
187
188         } else {
189                 /*
190                  * move on to the next argv
191                  * it now either contains an argument or the next option
192                  */
193                 optind++;
194
195                 /*
196                  * make sure not to overflow
197                  */
198                 if (optind < argc) {
199                         argptr = argv[optind];
200                 } else {
201                         argptr = NULL;
202                 }
203
204         }
205
206         /*
207          * do the needed actions for the argument state
208          */
209         switch (optman) {
210         case OPTIONAL_ARG:
211
212                 if (argptr == NULL) {
213                         break;
214                 }
215
216                 if (*argptr != '-') {
217                         /*
218                          * argument present
219                          */
220                         optarg = argptr;
221                         optind++;
222
223                 }
224
225
226                 break;
227
228         case MANDATORY_ARG:
229                 argpresent = (argptr != NULL);
230
231                 if (argpresent) {
232                         argpresent = (*argptr != '-');
233                 }
234
235                 if (argpresent) {
236                         /*
237                          * argument present
238                          */
239                         optarg = argptr;
240                         optind++;
241                 } else {
242                         /*
243                          * mandatory argument missing
244                          */
245                         if (opterr != 0) {
246                                 printf
247                                     ("missing argument for option \'-%c\'\n",
248                                      ret);
249                         }
250
251                         optopt = ret;
252
253                         /*
254                          * if the first character of options is a ':'
255                          * return a ':' instead of a '?' in case of
256                          * a missing argument
257                          */
258                         if (*options == ':') {
259                                 ret = ':';
260                         } else {
261                                 ret = '?';
262                         }
263
264                 }
265
266
267                 break;
268
269         case NO_ARG:
270
271                 if (strlen(argv[optind - 1]) > 2) {
272
273                         if (opterr != 0) {
274                                 printf
275                                     ("too many arguments for option \'-%c\'\n",
276                                      ret);
277                         }
278
279                         optopt = ret;
280                         ret = '?';
281                 }
282
283
284                 break;
285
286         }
287
288         return ret;
289 }
290
291 int
292 getopt_long(int argc, char **argv, const char *shortopts,
293             const struct option *longopts, int *indexptr)
294 {
295         struct option *optptr = (struct option *) longopts;
296         int optidx = 0;
297         int idx;
298         int ret = 0;
299         int argpresent;
300
301         /*
302          * reset used global values
303          */
304         optopt = 0;
305         optarg = NULL;
306
307         /*
308          * reset indexptr
309          */
310         *indexptr = -1;
311
312         /*
313          * reset getopt if a new argv pointer is passed
314          */
315         if (optstart != argv[0]) {
316                 optopt = 0;
317                 optind = 1;
318                 optarg = NULL;
319                 optstart = argv[0];
320         }
321
322         /*
323          * return if no more arguments are available
324          */
325         if (optind >= argc) {
326                 return -1;
327         }
328
329         /*
330          * start parsing argv[optind]
331          */
332         idx = 0;
333
334         /*
335          * return if the option does not begin with a '-'
336          */
337         if (argv[optind][idx] != '-') {
338                 printf("unknown option \'%s\', expecting \'-\'\n",
339                        argv[optind]);
340
341                 optind++;
342
343                 return '?';
344         }
345
346         /*
347          * move on to the next character in argv[optind]
348          */
349         idx++;
350
351         /*
352          * return getopt() in case of a short option
353          */
354         if (argv[optind][idx] != '-') {
355                 return getopt(argc, argv, shortopts);
356         }
357
358         /*
359          * handle a long option
360          */
361         idx++;
362
363         while (optptr->name != NULL) {
364
365                 if (strcmp(&argv[optind][idx], optptr->name) == 0) {
366                         break;
367                 }
368
369                 optptr++;
370                 optidx++;
371         }
372
373         /*
374          * no matching option found
375          */
376         if (optptr->name == NULL) {
377                 printf("unknown option \'%s\'\n", argv[optind]);
378
379                 optind++;
380
381                 return '?';
382         }
383
384         /*
385          * option was found, set up index pointer
386          */
387         *indexptr = optidx;
388
389         /*
390          * get argument
391          */
392         optind++;
393
394         switch (optptr->has_arg) {
395         case no_argument:
396                 /*
397                  * nothing to do
398                  */
399
400                 break;
401
402         case required_argument:
403                 argpresent = (optind != argc);
404
405                 if (argpresent) {
406                         argpresent = (argv[optind][0] != '-');
407                 }
408
409                 if (argpresent) {
410                         /*
411                          * argument present
412                          */
413                         optarg = argv[optind];
414                         optind++;
415                 } else {
416                         /*
417                          * mandatory argument missing
418                          */
419                         printf("missing argument for option \'%s\'\n",
420                                argv[optind - 1]);
421
422                         ret = '?';
423                 }
424
425
426                 break;
427
428         case optional_argument:
429
430                 if (optind == argc) {
431                         break;
432                 }
433
434                 if (argv[optind][0] != '-') {
435                         /*
436                          * argument present
437                          */
438                         optarg = argv[optind];
439                         optind++;
440                 }
441
442
443                 break;
444
445         default:
446                 printf("unknown argument option for option \'%s\'\n",
447                        argv[optind - 1]);
448
449                 ret = '?';
450
451                 break;
452
453         }
454
455         /*
456          * setup return values
457          */
458         if (ret != '?') {
459
460                 if (optptr->flag == NULL) {
461                         ret = optptr->val;
462                 } else {
463                         *optptr->flag = optptr->val;
464                         ret = 0;
465                 }
466
467         }
468
469         return ret;
470 }