menu: simplify usage for clients
[barebox-mini2440.git] / lib / getopt.c
blob64d6ac1e15d305580699265a8a0d38696cb00733
1 /*
2 * getopt.c - a simple getopt(3) implementation. See getopt.h for explanation.
4 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <common.h>
21 #include <module.h>
22 #include <getopt.h>
24 int opterr = 1;
25 int optind = 1;
26 int optopt;
27 char *optarg;
29 EXPORT_SYMBOL(optind);
30 EXPORT_SYMBOL(opterr);
31 EXPORT_SYMBOL(optopt);
32 EXPORT_SYMBOL(optarg);
34 static int optindex = 1; /* option index in the current argv[] element */
35 static int nonopts = 0; /* number of nonopts found */
37 void getopt_reset(void)
39 optind = opterr = optindex = 1;
40 nonopts = 0;
42 EXPORT_SYMBOL(getopt_reset);
44 int getopt(int argc, char *argv[], char *optstring)
46 char curopt; /* current option character */
47 char *curoptp; /* pointer to the current option in optstring */
49 while(1) {
50 // printf("optindex: %d nonopts: %d optind: %d\n", optindex, nonopts, optind);
52 /* first put nonopts to the end */
53 while (optind + nonopts < argc && *argv[optind] != '-') {
54 int i;
55 char *tmp;
57 nonopts++;
58 tmp = argv[optind];
59 for (i = optind; i + 1 < argc; i++)
60 argv[i] = argv[i + 1];
61 argv[argc - 1] = tmp;
64 if (optind + nonopts >= argc)
65 return -1;
67 /* We have found an option */
68 curopt = argv[optind][optindex];
69 if (curopt)
70 break;
71 /* no more options in current argv[] element. Start
72 * over with looking for nonopts
74 optind++;
75 optindex = 1;
78 /* look up current option in optstring */
79 curoptp = strchr(optstring, curopt);
81 if (!curoptp) {
82 if (opterr)
83 printf("%s: invalid option -- %c\n", argv[0], curopt);
84 optopt = curopt;
85 optindex++;
86 return '?';
89 if (*(curoptp + 1) != ':') {
90 /* option with no argument. Just return it */
91 optarg = NULL;
92 optindex++;
93 return curopt;
96 if (*(curoptp + 1) && *(curoptp + 2) == ':') {
97 /* optional argument */
98 if (argv[optind][optindex + 1]) {
99 /* optional argument with directly following optarg */
100 optarg = argv[optind] + optindex + 1;
101 optindex = 1;
102 optind++;
103 return curopt;
105 if (optind + nonopts + 1 == argc) {
106 /* We are at the last argv[] element */
107 optarg = NULL;
108 optind++;
109 return curopt;
111 if (*argv[optind + 1] != '-') {
112 /* optional argument with optarg in next argv[] element
114 optind++;
115 optarg = argv[optind];
116 optind++;
117 optindex = 1;
118 return curopt;
121 /* no optional argument found */
122 optarg = NULL;
123 optindex = 1;
124 optind++;
125 return curopt;
128 if (argv[optind][optindex + 1]) {
129 /* required argument with directly following optarg */
130 optarg = argv[optind] + optindex + 1;
131 optind++;
132 optindex = 1;
133 return curopt;
136 optind++;
137 optindex = 1;
139 if (optind + nonopts >= argc || argv[optind][0] == '-') {
140 if (opterr)
141 printf("option requires an argument -- %c\n",
142 curopt);
143 optopt = curopt;
144 return ':';
147 optarg = argv[optind];
148 optind++;
149 return curopt;
151 EXPORT_SYMBOL(getopt);