Imported Upstream version 3.4
[debian/elilo] / getopt.c
1 /*
2  * Simplistic getopt() function for EFI
3  *
4  * This function provides the basic functionality of the POSIX getopt() function.
5  * No long options are supported.
6  *
7  * This code  is meant for EFI programs and therefore deals with Unicode characters.
8  *
9  * Copyright (C) 2000 Hewlett-Packard Co
10  * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
11  *
12  * ELILO is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * ELILO is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with ELILO; see the file COPYING.  If not, write to the Free
24  * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25  * 02111-1307, USA.
26  */
27
28
29 #include <efi.h>
30 #include <efilib.h>
31
32
33 #define DASH    (CHAR16)'-'
34 #define COLON   (CHAR16)':'
35 #define EOS     (CHAR16)'\0'
36 #define BADCH   (INTN)'?'
37 #define BADARG  (INTN)':'
38
39 extern CHAR16 * StrChr(IN const CHAR16 *s, INT16 c);
40
41 CHAR16 *Optarg;
42 INTN    Optind = 1;
43 INTN    Optopt;
44
45 /*
46  * This simple version of getopt supports:
47  *      - option with no argument (no :)
48  *      - option with REQUIRED argument (single :)
49  * it does not support:
50  *      - long options
51  *      - optional arguments to options
52  *      - optreset
53  */
54 INTN
55 Getopt(INTN argc, CHAR16 *const argv[], const CHAR16 *optstring)
56 {
57         static CHAR16 *cur_chr = NULL;
58         CHAR16 *opt;
59
60         if (Optind >= argc) { /* no option or end of argument list */
61                 cur_chr = NULL;
62                 return -1;
63         }
64         if (cur_chr == NULL || *cur_chr == EOS) {
65                 cur_chr = argv[Optind];
66                 if (*cur_chr++ != DASH) { /* missing DASH */
67                         cur_chr = NULL;
68                         return -1;
69                 }
70                 if (*cur_chr == DASH) {
71                         cur_chr = NULL;
72                         Optind++;
73                         return -1; /* -- case, we're done */
74                 }
75         }
76         Optopt = *cur_chr++;
77         opt = StrChr(optstring, Optopt);
78         if (!opt) {
79                 Print(L"%s: illegal option -- %c\n", argv[0], Optopt);
80                 if (*cur_chr == EOS) Optind++;
81                 return BADCH;
82         } 
83         if (*(opt+1) != COLON) {
84                 Optarg = NULL;
85                 if (*cur_chr == EOS) Optind++;
86         } else {
87                 if (*cur_chr) {
88                         Optarg = cur_chr;
89                 } else if ( ++Optind >= argc ) {
90                            Print(L"%s: option `%s' requires an argument\n", argv[0], argv[Optind-1]),
91                            cur_chr = NULL;
92                            return BADARG;
93                 } else {
94                         Optarg = argv[Optind];
95                 }
96                 Optind++;
97         }
98         return Optopt;
99 }