32 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
33 |
*/ |
*/ |
34 |
|
|
35 |
|
#include <inttypes.h> |
36 |
#include <stdlib.h> |
#include <stdlib.h> |
37 |
#include "arith.h" |
#include <string.h> |
38 |
|
#include "arith_yacc.h" |
39 |
#include "expand.h" |
#include "expand.h" |
40 |
#include "error.h" |
#include "error.h" |
41 |
|
#include "shell.h" |
42 |
|
#include "memalloc.h" |
43 |
|
#include "syntax.h" |
44 |
|
#include "system.h" |
45 |
|
|
46 |
extern int yylval; |
#if ARITH_BOR + 11 != ARITH_BORASS || ARITH_ASS + 11 != ARITH_EQ |
47 |
extern const char *arith_buf, *arith_startbuf; |
#error Arithmetic tokens are out of order. |
48 |
|
#endif |
49 |
|
|
50 |
|
extern const char *arith_buf; |
51 |
|
|
52 |
int |
int |
53 |
yylex() |
yylex() |
54 |
{ |
{ |
55 |
int value; |
int value; |
56 |
const char *buf = arith_buf; |
const char *buf = arith_buf; |
57 |
|
const char *p; |
58 |
|
|
59 |
for (;;) { |
for (;;) { |
60 |
switch (*buf) { |
value = *buf; |
61 |
|
switch (value) { |
62 |
case ' ': |
case ' ': |
63 |
case '\t': |
case '\t': |
64 |
case '\n': |
case '\n': |
65 |
buf++; |
buf++; |
66 |
continue; |
continue; |
67 |
default: |
default: |
68 |
err: |
return ARITH_BAD; |
|
sh_error("arith: syntax error: \"%s\"", arith_startbuf); |
|
|
/* NOTREACHED */ |
|
69 |
case '0': |
case '0': |
70 |
case '1': |
case '1': |
71 |
case '2': |
case '2': |
76 |
case '7': |
case '7': |
77 |
case '8': |
case '8': |
78 |
case '9': |
case '9': |
79 |
yylval = strtoll(buf, (char **) &arith_buf, 0); |
yylval.val = strtoimax(buf, (char **)&arith_buf, 0); |
80 |
return ARITH_NUM; |
return ARITH_NUM; |
81 |
|
case 'A': |
82 |
|
case 'B': |
83 |
|
case 'C': |
84 |
|
case 'D': |
85 |
|
case 'E': |
86 |
|
case 'F': |
87 |
|
case 'G': |
88 |
|
case 'H': |
89 |
|
case 'I': |
90 |
|
case 'J': |
91 |
|
case 'K': |
92 |
|
case 'L': |
93 |
|
case 'M': |
94 |
|
case 'N': |
95 |
|
case 'O': |
96 |
|
case 'P': |
97 |
|
case 'Q': |
98 |
|
case 'R': |
99 |
|
case 'S': |
100 |
|
case 'T': |
101 |
|
case 'U': |
102 |
|
case 'V': |
103 |
|
case 'W': |
104 |
|
case 'X': |
105 |
|
case 'Y': |
106 |
|
case 'Z': |
107 |
|
case '_': |
108 |
|
case 'a': |
109 |
|
case 'b': |
110 |
|
case 'c': |
111 |
|
case 'd': |
112 |
|
case 'e': |
113 |
|
case 'f': |
114 |
|
case 'g': |
115 |
|
case 'h': |
116 |
|
case 'i': |
117 |
|
case 'j': |
118 |
|
case 'k': |
119 |
|
case 'l': |
120 |
|
case 'm': |
121 |
|
case 'n': |
122 |
|
case 'o': |
123 |
|
case 'p': |
124 |
|
case 'q': |
125 |
|
case 'r': |
126 |
|
case 's': |
127 |
|
case 't': |
128 |
|
case 'u': |
129 |
|
case 'v': |
130 |
|
case 'w': |
131 |
|
case 'x': |
132 |
|
case 'y': |
133 |
|
case 'z': |
134 |
|
p = buf; |
135 |
|
while (buf++, is_in_name(*buf)) |
136 |
|
; |
137 |
|
yylval.name = stalloc(buf - p + 1); |
138 |
|
*(char *)mempcpy(yylval.name, p, buf - p) = 0; |
139 |
|
value = ARITH_VAR; |
140 |
|
goto out; |
141 |
case '=': |
case '=': |
142 |
if (*++buf != '=') { |
value += ARITH_ASS - '='; |
143 |
goto err; |
checkeq: |
144 |
} |
buf++; |
145 |
value = ARITH_EQ; |
checkeqcur: |
146 |
|
if (*buf != '=') |
147 |
|
goto out; |
148 |
|
value += 11; |
149 |
break; |
break; |
150 |
case '>': |
case '>': |
151 |
switch (*++buf) { |
switch (*++buf) { |
152 |
case '=': |
case '=': |
153 |
value = ARITH_GE; |
value += ARITH_GE - '>'; |
154 |
break; |
break; |
155 |
case '>': |
case '>': |
156 |
value = ARITH_RSHIFT; |
value += ARITH_RSHIFT - '>'; |
157 |
break; |
goto checkeq; |
158 |
default: |
default: |
159 |
value = ARITH_GT; |
value += ARITH_GT - '>'; |
160 |
goto out; |
goto out; |
161 |
} |
} |
162 |
break; |
break; |
163 |
case '<': |
case '<': |
164 |
switch (*++buf) { |
switch (*++buf) { |
165 |
case '=': |
case '=': |
166 |
value = ARITH_LE; |
value += ARITH_LE - '<'; |
167 |
break; |
break; |
168 |
case '<': |
case '<': |
169 |
value = ARITH_LSHIFT; |
value += ARITH_LSHIFT - '<'; |
170 |
break; |
goto checkeq; |
171 |
default: |
default: |
172 |
value = ARITH_LT; |
value += ARITH_LT - '<'; |
173 |
goto out; |
goto out; |
174 |
} |
} |
175 |
break; |
break; |
176 |
case '|': |
case '|': |
177 |
if (*++buf != '|') { |
if (*++buf != '|') { |
178 |
value = ARITH_BOR; |
value += ARITH_BOR - '|'; |
179 |
goto out; |
goto checkeqcur; |
180 |
} |
} |
181 |
value = ARITH_OR; |
value += ARITH_OR - '|'; |
182 |
break; |
break; |
183 |
case '&': |
case '&': |
184 |
if (*++buf != '&') { |
if (*++buf != '&') { |
185 |
value = ARITH_BAND; |
value += ARITH_BAND - '&'; |
186 |
goto out; |
goto checkeqcur; |
187 |
} |
} |
188 |
value = ARITH_AND; |
value += ARITH_AND - '&'; |
189 |
break; |
break; |
190 |
case '!': |
case '!': |
191 |
if (*++buf != '=') { |
if (*++buf != '=') { |
192 |
value = ARITH_NOT; |
value += ARITH_NOT - '!'; |
193 |
goto out; |
goto out; |
194 |
} |
} |
195 |
value = ARITH_NE; |
value += ARITH_NE - '!'; |
196 |
break; |
break; |
197 |
case 0: |
case 0: |
|
value = 0; |
|
198 |
goto out; |
goto out; |
199 |
case '(': |
case '(': |
200 |
value = ARITH_LPAREN; |
value += ARITH_LPAREN - '('; |
201 |
break; |
break; |
202 |
case ')': |
case ')': |
203 |
value = ARITH_RPAREN; |
value += ARITH_RPAREN - ')'; |
204 |
break; |
break; |
205 |
case '*': |
case '*': |
206 |
value = ARITH_MUL; |
value += ARITH_MUL - '*'; |
207 |
break; |
goto checkeq; |
208 |
case '/': |
case '/': |
209 |
value = ARITH_DIV; |
value += ARITH_DIV - '/'; |
210 |
break; |
goto checkeq; |
211 |
case '%': |
case '%': |
212 |
value = ARITH_REM; |
value += ARITH_REM - '%'; |
213 |
break; |
goto checkeq; |
214 |
case '+': |
case '+': |
215 |
value = ARITH_ADD; |
value += ARITH_ADD - '+'; |
216 |
break; |
goto checkeq; |
217 |
case '-': |
case '-': |
218 |
value = ARITH_SUB; |
value += ARITH_SUB - '-'; |
219 |
break; |
goto checkeq; |
220 |
case '~': |
case '~': |
221 |
value = ARITH_BNOT; |
value += ARITH_BNOT - '~'; |
222 |
break; |
break; |
223 |
case '^': |
case '^': |
224 |
value = ARITH_BXOR; |
value += ARITH_BXOR - '^'; |
225 |
|
goto checkeq; |
226 |
|
case '?': |
227 |
|
value += ARITH_QMARK - '?'; |
228 |
|
break; |
229 |
|
case ':': |
230 |
|
value += ARITH_COLON - ':'; |
231 |
break; |
break; |
232 |
} |
} |
233 |
break; |
break; |