1 /* bashgetopt.c -- `getopt' for use by the builtins. */
3 /* Copyright (C) 1992 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #if defined (HAVE_UNISTD_H)
27 #include "../bashansi.h"
33 #define ERR(S, C) builtin_error("%s%c", (S), (C))
40 static WORD_LIST *lhead = (WORD_LIST *)NULL;
41 WORD_LIST *lcurrent = (WORD_LIST *)NULL;
42 WORD_LIST *loptend; /* Points to the first non-option argument in the list */
45 internal_getopt(list, opts)
51 int plus; /* nonzero means to handle +option */
60 list_optarg = (char *)NULL;
61 loptend = (WORD_LIST *)NULL; /* No non-option arguments */
65 if (list != lhead || lhead == 0) {
66 /* Hmmm.... called with a different word list. Reset. */
68 lcurrent = lhead = list;
69 loptend = (WORD_LIST *)NULL;
74 (lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
75 lhead = (WORD_LIST *)NULL;
78 } else if (lcurrent->word->word[0] == '-' &&
79 lcurrent->word->word[1] == '-' &&
80 lcurrent->word->word[2] == 0) {
81 lhead = (WORD_LIST *)NULL;
82 loptend = lcurrent->next;
87 list_optopt = c = lcurrent->word->word[sp];
89 if (c == ':' || (cp = strchr(opts, c)) == NULL) {
90 ERR("illegal option: -", c);
91 if (lcurrent->word->word[++sp] == '\0') {
92 lcurrent = lcurrent->next;
97 loptend = lcurrent->next;
101 if (*++cp == ':' || *cp == ';') {
102 /* `:': Option requires an argument. */
103 /* `;': option argument may be missing */
104 /* We allow -l2 as equivalent to -l 2 */
105 if (lcurrent->word->word[sp+1]) {
106 list_optarg = lcurrent->word->word + sp + 1;
107 lcurrent = lcurrent->next;
108 /* If the specifier is `;', don't set optarg if the next
109 argument looks like another option. */
110 } else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) {
111 lcurrent = lcurrent->next;
112 list_optarg = lcurrent->word->word;
113 lcurrent = lcurrent->next;
114 } else if (*cp == ';') {
115 list_optarg = (char *)NULL;
116 lcurrent = lcurrent->next;
117 } else { /* lcurrent->next == NULL */
118 ERR("option requires an argument: -", c);
120 list_optarg = (char *)NULL;
124 } else if (*cp == '#') {
125 /* optional numeric argument */
126 if (lcurrent->word->word[sp+1]) {
127 if (digit(lcurrent->word->word[sp+1])) {
128 list_optarg = lcurrent->word->word + sp + 1;
129 lcurrent = lcurrent->next;
131 list_optarg = (char *)NULL;
133 if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) {
134 lcurrent = lcurrent->next;
135 list_optarg = lcurrent->word->word;
136 lcurrent = lcurrent->next;
138 list_optarg = (char *)NULL;
142 /* No argument, just return the option. */
143 if (lcurrent->word->word[++sp] == '\0') {
145 lcurrent = lcurrent->next;
147 list_optarg = (char *)NULL;
154 * reset_internal_getopt -- force the in[ft]ernal getopt to reset
158 reset_internal_getopt ()
160 lhead = lcurrent = loptend = (WORD_LIST *)NULL;
164 #ifdef INCLUDE_UNUSED