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