1218466Sjilles/*-
2218466Sjilles * Copyright (c) 2002
3218466Sjilles *	Herbert Xu.
4218466Sjilles * Copyright (c) 1993
5218466Sjilles *	The Regents of the University of California.  All rights reserved.
6218466Sjilles *
7218466Sjilles * This code is derived from software contributed to Berkeley by
8218466Sjilles * Kenneth Almquist.
9218466Sjilles *
10218466Sjilles * Redistribution and use in source and binary forms, with or without
11218466Sjilles * modification, are permitted provided that the following conditions
12218466Sjilles * are met:
13218466Sjilles * 1. Redistributions of source code must retain the above copyright
14218466Sjilles *    notice, this list of conditions and the following disclaimer.
15218466Sjilles * 2. Redistributions in binary form must reproduce the above copyright
16218466Sjilles *    notice, this list of conditions and the following disclaimer in the
17218466Sjilles *    documentation and/or other materials provided with the distribution.
18218466Sjilles * 3. Neither the name of the University nor the names of its contributors
19218466Sjilles *    may be used to endorse or promote products derived from this software
20218466Sjilles *    without specific prior written permission.
21218466Sjilles *
22218466Sjilles * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23218466Sjilles * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24218466Sjilles * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25218466Sjilles * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26218466Sjilles * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27218466Sjilles * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28218466Sjilles * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29218466Sjilles * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30218466Sjilles * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31218466Sjilles * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32218466Sjilles * SUCH DAMAGE.
33218466Sjilles */
34218466Sjilles
35218466Sjilles#include <sys/cdefs.h>
36218466Sjilles__FBSDID("$FreeBSD$");
37218466Sjilles
38218466Sjilles#include <inttypes.h>
39218466Sjilles#include <stdlib.h>
40218466Sjilles#include <string.h>
41218466Sjilles#include "shell.h"
42218466Sjilles#include "arith_yacc.h"
43218466Sjilles#include "expand.h"
44218466Sjilles#include "error.h"
45218466Sjilles#include "memalloc.h"
46218466Sjilles#include "parser.h"
47218466Sjilles#include "syntax.h"
48218466Sjilles
49218466Sjilles#if ARITH_BOR + 11 != ARITH_BORASS || ARITH_ASS + 11 != ARITH_EQ
50218466Sjilles#error Arithmetic tokens are out of order.
51218466Sjilles#endif
52218466Sjilles
53218466Sjillesextern const char *arith_buf;
54218466Sjilles
55218466Sjillesint
56218466Sjillesyylex()
57218466Sjilles{
58218466Sjilles	int value;
59218466Sjilles	const char *buf = arith_buf;
60219306Sjilles	char *end;
61218466Sjilles	const char *p;
62218466Sjilles
63218466Sjilles	for (;;) {
64218466Sjilles		value = *buf;
65218466Sjilles		switch (value) {
66218466Sjilles		case ' ':
67218466Sjilles		case '\t':
68218466Sjilles		case '\n':
69218466Sjilles			buf++;
70218466Sjilles			continue;
71218466Sjilles		default:
72218466Sjilles			return ARITH_BAD;
73218466Sjilles		case '0':
74218466Sjilles		case '1':
75218466Sjilles		case '2':
76218466Sjilles		case '3':
77218466Sjilles		case '4':
78218466Sjilles		case '5':
79218466Sjilles		case '6':
80218466Sjilles		case '7':
81218466Sjilles		case '8':
82218466Sjilles		case '9':
83219363Sstefanf			yylval.val = strtoarith_t(buf, &end, 0);
84219306Sjilles			arith_buf = end;
85218466Sjilles			return ARITH_NUM;
86218466Sjilles		case 'A':
87218466Sjilles		case 'B':
88218466Sjilles		case 'C':
89218466Sjilles		case 'D':
90218466Sjilles		case 'E':
91218466Sjilles		case 'F':
92218466Sjilles		case 'G':
93218466Sjilles		case 'H':
94218466Sjilles		case 'I':
95218466Sjilles		case 'J':
96218466Sjilles		case 'K':
97218466Sjilles		case 'L':
98218466Sjilles		case 'M':
99218466Sjilles		case 'N':
100218466Sjilles		case 'O':
101218466Sjilles		case 'P':
102218466Sjilles		case 'Q':
103218466Sjilles		case 'R':
104218466Sjilles		case 'S':
105218466Sjilles		case 'T':
106218466Sjilles		case 'U':
107218466Sjilles		case 'V':
108218466Sjilles		case 'W':
109218466Sjilles		case 'X':
110218466Sjilles		case 'Y':
111218466Sjilles		case 'Z':
112218466Sjilles		case '_':
113218466Sjilles		case 'a':
114218466Sjilles		case 'b':
115218466Sjilles		case 'c':
116218466Sjilles		case 'd':
117218466Sjilles		case 'e':
118218466Sjilles		case 'f':
119218466Sjilles		case 'g':
120218466Sjilles		case 'h':
121218466Sjilles		case 'i':
122218466Sjilles		case 'j':
123218466Sjilles		case 'k':
124218466Sjilles		case 'l':
125218466Sjilles		case 'm':
126218466Sjilles		case 'n':
127218466Sjilles		case 'o':
128218466Sjilles		case 'p':
129218466Sjilles		case 'q':
130218466Sjilles		case 'r':
131218466Sjilles		case 's':
132218466Sjilles		case 't':
133218466Sjilles		case 'u':
134218466Sjilles		case 'v':
135218466Sjilles		case 'w':
136218466Sjilles		case 'x':
137218466Sjilles		case 'y':
138218466Sjilles		case 'z':
139218466Sjilles			p = buf;
140218466Sjilles			while (buf++, is_in_name(*buf))
141218466Sjilles				;
142218466Sjilles			yylval.name = stalloc(buf - p + 1);
143218466Sjilles			memcpy(yylval.name, p, buf - p);
144218466Sjilles			yylval.name[buf - p] = '\0';
145218466Sjilles			value = ARITH_VAR;
146218466Sjilles			goto out;
147218466Sjilles		case '=':
148218466Sjilles			value += ARITH_ASS - '=';
149218466Sjillescheckeq:
150218466Sjilles			buf++;
151218466Sjillescheckeqcur:
152218466Sjilles			if (*buf != '=')
153218466Sjilles				goto out;
154218466Sjilles			value += 11;
155218466Sjilles			break;
156218466Sjilles		case '>':
157218466Sjilles			switch (*++buf) {
158218466Sjilles			case '=':
159218466Sjilles				value += ARITH_GE - '>';
160218466Sjilles				break;
161218466Sjilles			case '>':
162218466Sjilles				value += ARITH_RSHIFT - '>';
163218466Sjilles				goto checkeq;
164218466Sjilles			default:
165218466Sjilles				value += ARITH_GT - '>';
166218466Sjilles				goto out;
167218466Sjilles			}
168218466Sjilles			break;
169218466Sjilles		case '<':
170218466Sjilles			switch (*++buf) {
171218466Sjilles			case '=':
172218466Sjilles				value += ARITH_LE - '<';
173218466Sjilles				break;
174218466Sjilles			case '<':
175218466Sjilles				value += ARITH_LSHIFT - '<';
176218466Sjilles				goto checkeq;
177218466Sjilles			default:
178218466Sjilles				value += ARITH_LT - '<';
179218466Sjilles				goto out;
180218466Sjilles			}
181218466Sjilles			break;
182218466Sjilles		case '|':
183218466Sjilles			if (*++buf != '|') {
184218466Sjilles				value += ARITH_BOR - '|';
185218466Sjilles				goto checkeqcur;
186218466Sjilles			}
187218466Sjilles			value += ARITH_OR - '|';
188218466Sjilles			break;
189218466Sjilles		case '&':
190218466Sjilles			if (*++buf != '&') {
191218466Sjilles				value += ARITH_BAND - '&';
192218466Sjilles				goto checkeqcur;
193218466Sjilles			}
194218466Sjilles			value += ARITH_AND - '&';
195218466Sjilles			break;
196218466Sjilles		case '!':
197218466Sjilles			if (*++buf != '=') {
198218466Sjilles				value += ARITH_NOT - '!';
199218466Sjilles				goto out;
200218466Sjilles			}
201218466Sjilles			value += ARITH_NE - '!';
202218466Sjilles			break;
203218466Sjilles		case 0:
204218466Sjilles			goto out;
205218466Sjilles		case '(':
206218466Sjilles			value += ARITH_LPAREN - '(';
207218466Sjilles			break;
208218466Sjilles		case ')':
209218466Sjilles			value += ARITH_RPAREN - ')';
210218466Sjilles			break;
211218466Sjilles		case '*':
212218466Sjilles			value += ARITH_MUL - '*';
213218466Sjilles			goto checkeq;
214218466Sjilles		case '/':
215218466Sjilles			value += ARITH_DIV - '/';
216218466Sjilles			goto checkeq;
217218466Sjilles		case '%':
218218466Sjilles			value += ARITH_REM - '%';
219218466Sjilles			goto checkeq;
220218466Sjilles		case '+':
221218466Sjilles			value += ARITH_ADD - '+';
222218466Sjilles			goto checkeq;
223218466Sjilles		case '-':
224218466Sjilles			value += ARITH_SUB - '-';
225218466Sjilles			goto checkeq;
226218466Sjilles		case '~':
227218466Sjilles			value += ARITH_BNOT - '~';
228218466Sjilles			break;
229218466Sjilles		case '^':
230218466Sjilles			value += ARITH_BXOR - '^';
231218466Sjilles			goto checkeq;
232218466Sjilles		case '?':
233218466Sjilles			value += ARITH_QMARK - '?';
234218466Sjilles			break;
235218466Sjilles		case ':':
236218466Sjilles			value += ARITH_COLON - ':';
237218466Sjilles			break;
238218466Sjilles		}
239218466Sjilles		break;
240218466Sjilles	}
241218466Sjilles
242218466Sjilles	buf++;
243218466Sjillesout:
244218466Sjilles	arith_buf = buf;
245218466Sjilles	return value;
246218466Sjilles}
247