~ubuntu-branches/ubuntu/warty/bash/warty

« back to all changes in this revision

Viewing changes to builtins/bashgetopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2002-04-08 20:51:41 UTC
  • Revision ID: james.westby@ubuntu.com-20020408205141-qovkhu3a90201hf2
Tags: upstream-2.05a
ImportĀ upstreamĀ versionĀ 2.05a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* bashgetopt.c -- `getopt' for use by the builtins. */
 
2
 
 
3
/* Copyright (C) 1992 Free Software Foundation, Inc.
 
4
 
 
5
This file is part of GNU Bash, the Bourne Again SHell.
 
6
 
 
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
 
10
version.
 
11
 
 
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
 
15
for more details.
 
16
 
 
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. */
 
20
 
 
21
#include <config.h>
 
22
 
 
23
#if defined (HAVE_UNISTD_H)
 
24
#  include <unistd.h>
 
25
#endif
 
26
 
 
27
#include "../bashansi.h"
 
28
#include <chartypes.h>
 
29
#include <errno.h>
 
30
 
 
31
#include "../shell.h"
 
32
#include "common.h"
 
33
 
 
34
#define ERR(S, C)       builtin_error("%s%c", (S), (C))
 
35
 
 
36
static int      sp;
 
37
 
 
38
char    *list_optarg;
 
39
int     list_optopt;
 
40
 
 
41
static WORD_LIST *lhead = (WORD_LIST *)NULL;
 
42
WORD_LIST       *lcurrent = (WORD_LIST *)NULL;
 
43
WORD_LIST       *loptend;       /* Points to the first non-option argument in the list */
 
44
 
 
45
int
 
46
internal_getopt(list, opts)
 
47
WORD_LIST       *list;
 
48
char            *opts;
 
49
{
 
50
        register int c;
 
51
        register char *cp;
 
52
        int     plus;   /* nonzero means to handle +option */
 
53
 
 
54
        if (*opts == '+') {
 
55
                plus = 1;
 
56
                opts++;
 
57
        } else
 
58
                plus = 0;
 
59
 
 
60
        if (list == 0) {
 
61
                list_optarg = (char *)NULL;
 
62
                loptend = (WORD_LIST *)NULL;    /* No non-option arguments */
 
63
                return -1;
 
64
        }
 
65
 
 
66
        if (list != lhead || lhead == 0) {
 
67
                /* Hmmm.... called with a different word list.  Reset. */
 
68
                sp = 1;
 
69
                lcurrent = lhead = list;
 
70
                loptend = (WORD_LIST *)NULL;
 
71
        }
 
72
 
 
73
        if (sp == 1) {
 
74
                if (lcurrent == 0 ||
 
75
                    (lcurrent->word->word[0] != '-' || lcurrent->word->word[1] == '\0')) {
 
76
                        lhead = (WORD_LIST *)NULL;
 
77
                        loptend = lcurrent;
 
78
                        return(-1);
 
79
                } else if (lcurrent->word->word[0] == '-' &&
 
80
                           lcurrent->word->word[1] == '-' &&
 
81
                           lcurrent->word->word[2] == 0) {
 
82
                        lhead = (WORD_LIST *)NULL;
 
83
                        loptend = lcurrent->next;
 
84
                        return(-1);
 
85
                }
 
86
        }
 
87
 
 
88
        list_optopt = c = lcurrent->word->word[sp];
 
89
 
 
90
        if (c == ':' || (cp = strchr(opts, c)) == NULL) {
 
91
                ERR("illegal option: -", c);
 
92
                if (lcurrent->word->word[++sp] == '\0') {
 
93
                        lcurrent = lcurrent->next;
 
94
                        sp = 1;
 
95
                }
 
96
                list_optarg = NULL;
 
97
                if (lcurrent)
 
98
                        loptend = lcurrent->next;
 
99
                return('?');
 
100
        }
 
101
 
 
102
        if (*++cp == ':' || *cp == ';') {
 
103
                /* `:': Option requires an argument. */
 
104
                /* `;': option argument may be missing */
 
105
                /* We allow -l2 as equivalent to -l 2 */
 
106
                if (lcurrent->word->word[sp+1]) {
 
107
                        list_optarg = lcurrent->word->word + sp + 1;
 
108
                        lcurrent = lcurrent->next;
 
109
                /* If the specifier is `;', don't set optarg if the next
 
110
                   argument looks like another option. */
 
111
                } else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) {
 
112
                        lcurrent = lcurrent->next;
 
113
                        list_optarg = lcurrent->word->word;
 
114
                        lcurrent = lcurrent->next;
 
115
                } else if (*cp == ';') {
 
116
                        list_optarg = (char *)NULL;
 
117
                        lcurrent = lcurrent->next;
 
118
                } else {        /* lcurrent->next == NULL */
 
119
                        ERR("option requires an argument: -", c);
 
120
                        sp = 1;
 
121
                        list_optarg = (char *)NULL;
 
122
                        return('?');
 
123
                }
 
124
                sp = 1;
 
125
        } else if (*cp == '#') {
 
126
                /* optional numeric argument */
 
127
                if (lcurrent->word->word[sp+1]) {
 
128
                        if (DIGIT(lcurrent->word->word[sp+1])) {
 
129
                                list_optarg = lcurrent->word->word + sp + 1;
 
130
                                lcurrent = lcurrent->next;
 
131
                        } else
 
132
                                list_optarg = (char *)NULL;
 
133
                } else {
 
134
                        if (lcurrent->next && legal_number(lcurrent->next->word->word, (long *)0)) {
 
135
                                lcurrent = lcurrent->next;
 
136
                                list_optarg = lcurrent->word->word;
 
137
                                lcurrent = lcurrent->next;
 
138
                        } else
 
139
                                list_optarg = (char *)NULL;
 
140
                }
 
141
 
 
142
        } else {
 
143
                /* No argument, just return the option. */
 
144
                if (lcurrent->word->word[++sp] == '\0') {
 
145
                        sp = 1;
 
146
                        lcurrent = lcurrent->next;
 
147
                }
 
148
                list_optarg = (char *)NULL;
 
149
        }
 
150
 
 
151
        return(c);
 
152
}
 
153
 
 
154
/*
 
155
 * reset_internal_getopt -- force the in[ft]ernal getopt to reset
 
156
 */
 
157
 
 
158
void
 
159
reset_internal_getopt ()
 
160
{
 
161
        lhead = lcurrent = loptend = (WORD_LIST *)NULL;
 
162
        sp = 1;
 
163
}
 
164
 
 
165
#ifdef INCLUDE_UNUSED
 
166
void
 
167
report_bad_option ()
 
168
{
 
169
        char s[3];
 
170
 
 
171
        s[0] = '-';
 
172
        s[1] = list_optopt;
 
173
        s[2] = '\0';
 
174
        bad_option (s);
 
175
}
 
176
#endif