arith_yylex.c revision 218466
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: head/bin/sh/arith_yylex.c 218466 2011-02-08 23:18:06Z jilles $");
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;
60218466Sjilles	const char *p;
61218466Sjilles
62218466Sjilles	for (;;) {
63218466Sjilles		value = *buf;
64218466Sjilles		switch (value) {
65218466Sjilles		case ' ':
66218466Sjilles		case '\t':
67218466Sjilles		case '\n':
68218466Sjilles			buf++;
69218466Sjilles			continue;
70218466Sjilles		default:
71218466Sjilles			return ARITH_BAD;
72218466Sjilles		case '0':
73218466Sjilles		case '1':
74218466Sjilles		case '2':
75218466Sjilles		case '3':
76218466Sjilles		case '4':
77218466Sjilles		case '5':
78218466Sjilles		case '6':
79218466Sjilles		case '7':
80218466Sjilles		case '8':
81218466Sjilles		case '9':
82218466Sjilles			yylval.val = strtoarith_t(buf, (char **)&arith_buf, 0);
83218466Sjilles			return ARITH_NUM;
84218466Sjilles		case 'A':
85218466Sjilles		case 'B':
86218466Sjilles		case 'C':
87218466Sjilles		case 'D':
88218466Sjilles		case 'E':
89218466Sjilles		case 'F':
90218466Sjilles		case 'G':
91218466Sjilles		case 'H':
92218466Sjilles		case 'I':
93218466Sjilles		case 'J':
94218466Sjilles		case 'K':
95218466Sjilles		case 'L':
96218466Sjilles		case 'M':
97218466Sjilles		case 'N':
98218466Sjilles		case 'O':
99218466Sjilles		case 'P':
100218466Sjilles		case 'Q':
101218466Sjilles		case 'R':
102218466Sjilles		case 'S':
103218466Sjilles		case 'T':
104218466Sjilles		case 'U':
105218466Sjilles		case 'V':
106218466Sjilles		case 'W':
107218466Sjilles		case 'X':
108218466Sjilles		case 'Y':
109218466Sjilles		case 'Z':
110218466Sjilles		case '_':
111218466Sjilles		case 'a':
112218466Sjilles		case 'b':
113218466Sjilles		case 'c':
114218466Sjilles		case 'd':
115218466Sjilles		case 'e':
116218466Sjilles		case 'f':
117218466Sjilles		case 'g':
118218466Sjilles		case 'h':
119218466Sjilles		case 'i':
120218466Sjilles		case 'j':
121218466Sjilles		case 'k':
122218466Sjilles		case 'l':
123218466Sjilles		case 'm':
124218466Sjilles		case 'n':
125218466Sjilles		case 'o':
126218466Sjilles		case 'p':
127218466Sjilles		case 'q':
128218466Sjilles		case 'r':
129218466Sjilles		case 's':
130218466Sjilles		case 't':
131218466Sjilles		case 'u':
132218466Sjilles		case 'v':
133218466Sjilles		case 'w':
134218466Sjilles		case 'x':
135218466Sjilles		case 'y':
136218466Sjilles		case 'z':
137218466Sjilles			p = buf;
138218466Sjilles			while (buf++, is_in_name(*buf))
139218466Sjilles				;
140218466Sjilles			yylval.name = stalloc(buf - p + 1);
141218466Sjilles			memcpy(yylval.name, p, buf - p);
142218466Sjilles			yylval.name[buf - p] = '\0';
143218466Sjilles			value = ARITH_VAR;
144218466Sjilles			goto out;
145218466Sjilles		case '=':
146218466Sjilles			value += ARITH_ASS - '=';
147218466Sjillescheckeq:
148218466Sjilles			buf++;
149218466Sjillescheckeqcur:
150218466Sjilles			if (*buf != '=')
151218466Sjilles				goto out;
152218466Sjilles			value += 11;
153218466Sjilles			break;
154218466Sjilles		case '>':
155218466Sjilles			switch (*++buf) {
156218466Sjilles			case '=':
157218466Sjilles				value += ARITH_GE - '>';
158218466Sjilles				break;
159218466Sjilles			case '>':
160218466Sjilles				value += ARITH_RSHIFT - '>';
161218466Sjilles				goto checkeq;
162218466Sjilles			default:
163218466Sjilles				value += ARITH_GT - '>';
164218466Sjilles				goto out;
165218466Sjilles			}
166218466Sjilles			break;
167218466Sjilles		case '<':
168218466Sjilles			switch (*++buf) {
169218466Sjilles			case '=':
170218466Sjilles				value += ARITH_LE - '<';
171218466Sjilles				break;
172218466Sjilles			case '<':
173218466Sjilles				value += ARITH_LSHIFT - '<';
174218466Sjilles				goto checkeq;
175218466Sjilles			default:
176218466Sjilles				value += ARITH_LT - '<';
177218466Sjilles				goto out;
178218466Sjilles			}
179218466Sjilles			break;
180218466Sjilles		case '|':
181218466Sjilles			if (*++buf != '|') {
182218466Sjilles				value += ARITH_BOR - '|';
183218466Sjilles				goto checkeqcur;
184218466Sjilles			}
185218466Sjilles			value += ARITH_OR - '|';
186218466Sjilles			break;
187218466Sjilles		case '&':
188218466Sjilles			if (*++buf != '&') {
189218466Sjilles				value += ARITH_BAND - '&';
190218466Sjilles				goto checkeqcur;
191218466Sjilles			}
192218466Sjilles			value += ARITH_AND - '&';
193218466Sjilles			break;
194218466Sjilles		case '!':
195218466Sjilles			if (*++buf != '=') {
196218466Sjilles				value += ARITH_NOT - '!';
197218466Sjilles				goto out;
198218466Sjilles			}
199218466Sjilles			value += ARITH_NE - '!';
200218466Sjilles			break;
201218466Sjilles		case 0:
202218466Sjilles			goto out;
203218466Sjilles		case '(':
204218466Sjilles			value += ARITH_LPAREN - '(';
205218466Sjilles			break;
206218466Sjilles		case ')':
207218466Sjilles			value += ARITH_RPAREN - ')';
208218466Sjilles			break;
209218466Sjilles		case '*':
210218466Sjilles			value += ARITH_MUL - '*';
211218466Sjilles			goto checkeq;
212218466Sjilles		case '/':
213218466Sjilles			value += ARITH_DIV - '/';
214218466Sjilles			goto checkeq;
215218466Sjilles		case '%':
216218466Sjilles			value += ARITH_REM - '%';
217218466Sjilles			goto checkeq;
218218466Sjilles		case '+':
219218466Sjilles			value += ARITH_ADD - '+';
220218466Sjilles			goto checkeq;
221218466Sjilles		case '-':
222218466Sjilles			value += ARITH_SUB - '-';
223218466Sjilles			goto checkeq;
224218466Sjilles		case '~':
225218466Sjilles			value += ARITH_BNOT - '~';
226218466Sjilles			break;
227218466Sjilles		case '^':
228218466Sjilles			value += ARITH_BXOR - '^';
229218466Sjilles			goto checkeq;
230218466Sjilles		case '?':
231218466Sjilles			value += ARITH_QMARK - '?';
232218466Sjilles			break;
233218466Sjilles		case ':':
234218466Sjilles			value += ARITH_COLON - ':';
235218466Sjilles			break;
236218466Sjilles		}
237218466Sjilles		break;
238218466Sjilles	}
239218466Sjilles
240218466Sjilles	buf++;
241218466Sjillesout:
242218466Sjilles	arith_buf = buf;
243218466Sjilles	return value;
244218466Sjilles}
245