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