Merge branch 'vendor/OPENSSL'
[dragonfly.git] / bin / sh / arith_yylex.c
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 }