Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/sh/arith_yylex.c
39478 views
1
/*-
2
* Copyright (c) 2002
3
* Herbert Xu.
4
* Copyright (c) 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Kenneth Almquist.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include <sys/cdefs.h>
36
#include <ctype.h>
37
#include <errno.h>
38
#include <inttypes.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include "shell.h"
42
#include "arith_yacc.h"
43
#include "expand.h"
44
#include "error.h"
45
#include "memalloc.h"
46
#include "parser.h"
47
#include "syntax.h"
48
49
#if ARITH_BOR + 11 != ARITH_BORASS || ARITH_ASS + 11 != ARITH_EQ
50
#error Arithmetic tokens are out of order.
51
#endif
52
53
arith_t
54
strtoarith_t(const char *restrict nptr, char **restrict endptr)
55
{
56
arith_t val;
57
58
while (isspace((unsigned char)*nptr))
59
nptr++;
60
switch (*nptr) {
61
case '-':
62
return strtoimax(nptr, endptr, 0);
63
case '0':
64
return (arith_t)strtoumax(nptr, endptr, 0);
65
default:
66
val = (arith_t)strtoumax(nptr, endptr, 0);
67
if (val >= 0)
68
return val;
69
else if (val == ARITH_MIN) {
70
errno = ERANGE;
71
return ARITH_MIN;
72
} else {
73
errno = ERANGE;
74
return ARITH_MAX;
75
}
76
}
77
}
78
79
int
80
yylex(void)
81
{
82
int value;
83
const char *buf = arith_buf;
84
char *end;
85
const char *p;
86
87
for (;;) {
88
value = *buf;
89
switch (value) {
90
case ' ':
91
case '\t':
92
case '\n':
93
buf++;
94
continue;
95
default:
96
return ARITH_BAD;
97
case '0':
98
case '1':
99
case '2':
100
case '3':
101
case '4':
102
case '5':
103
case '6':
104
case '7':
105
case '8':
106
case '9':
107
yylval.val = strtoarith_t(buf, &end);
108
arith_buf = end;
109
return ARITH_NUM;
110
case 'A':
111
case 'B':
112
case 'C':
113
case 'D':
114
case 'E':
115
case 'F':
116
case 'G':
117
case 'H':
118
case 'I':
119
case 'J':
120
case 'K':
121
case 'L':
122
case 'M':
123
case 'N':
124
case 'O':
125
case 'P':
126
case 'Q':
127
case 'R':
128
case 'S':
129
case 'T':
130
case 'U':
131
case 'V':
132
case 'W':
133
case 'X':
134
case 'Y':
135
case 'Z':
136
case '_':
137
case 'a':
138
case 'b':
139
case 'c':
140
case 'd':
141
case 'e':
142
case 'f':
143
case 'g':
144
case 'h':
145
case 'i':
146
case 'j':
147
case 'k':
148
case 'l':
149
case 'm':
150
case 'n':
151
case 'o':
152
case 'p':
153
case 'q':
154
case 'r':
155
case 's':
156
case 't':
157
case 'u':
158
case 'v':
159
case 'w':
160
case 'x':
161
case 'y':
162
case 'z':
163
p = buf;
164
while (buf++, is_in_name(*buf))
165
;
166
yylval.name = stalloc(buf - p + 1);
167
memcpy(yylval.name, p, buf - p);
168
yylval.name[buf - p] = '\0';
169
value = ARITH_VAR;
170
goto out;
171
case '=':
172
value += ARITH_ASS - '=';
173
checkeq:
174
buf++;
175
checkeqcur:
176
if (*buf != '=')
177
goto out;
178
value += 11;
179
break;
180
case '>':
181
switch (*++buf) {
182
case '=':
183
value += ARITH_GE - '>';
184
break;
185
case '>':
186
value += ARITH_RSHIFT - '>';
187
goto checkeq;
188
default:
189
value += ARITH_GT - '>';
190
goto out;
191
}
192
break;
193
case '<':
194
switch (*++buf) {
195
case '=':
196
value += ARITH_LE - '<';
197
break;
198
case '<':
199
value += ARITH_LSHIFT - '<';
200
goto checkeq;
201
default:
202
value += ARITH_LT - '<';
203
goto out;
204
}
205
break;
206
case '|':
207
if (*++buf != '|') {
208
value += ARITH_BOR - '|';
209
goto checkeqcur;
210
}
211
value += ARITH_OR - '|';
212
break;
213
case '&':
214
if (*++buf != '&') {
215
value += ARITH_BAND - '&';
216
goto checkeqcur;
217
}
218
value += ARITH_AND - '&';
219
break;
220
case '!':
221
if (*++buf != '=') {
222
value += ARITH_NOT - '!';
223
goto out;
224
}
225
value += ARITH_NE - '!';
226
break;
227
case 0:
228
goto out;
229
case '(':
230
value += ARITH_LPAREN - '(';
231
break;
232
case ')':
233
value += ARITH_RPAREN - ')';
234
break;
235
case '*':
236
value += ARITH_MUL - '*';
237
goto checkeq;
238
case '/':
239
value += ARITH_DIV - '/';
240
goto checkeq;
241
case '%':
242
value += ARITH_REM - '%';
243
goto checkeq;
244
case '+':
245
if (buf[1] == '+')
246
return ARITH_BAD;
247
value += ARITH_ADD - '+';
248
goto checkeq;
249
case '-':
250
if (buf[1] == '-')
251
return ARITH_BAD;
252
value += ARITH_SUB - '-';
253
goto checkeq;
254
case '~':
255
value += ARITH_BNOT - '~';
256
break;
257
case '^':
258
value += ARITH_BXOR - '^';
259
goto checkeq;
260
case '?':
261
value += ARITH_QMARK - '?';
262
break;
263
case ':':
264
value += ARITH_COLON - ':';
265
break;
266
}
267
break;
268
}
269
270
buf++;
271
out:
272
arith_buf = buf;
273
return value;
274
}
275
276