16262b84eSJilles Tjoelker /*-
26262b84eSJilles Tjoelker * Copyright (c) 2002
36262b84eSJilles Tjoelker * Herbert Xu.
46262b84eSJilles Tjoelker * Copyright (c) 1993
56262b84eSJilles Tjoelker * The Regents of the University of California. All rights reserved.
66262b84eSJilles Tjoelker *
76262b84eSJilles Tjoelker * This code is derived from software contributed to Berkeley by
86262b84eSJilles Tjoelker * Kenneth Almquist.
96262b84eSJilles Tjoelker *
106262b84eSJilles Tjoelker * Redistribution and use in source and binary forms, with or without
116262b84eSJilles Tjoelker * modification, are permitted provided that the following conditions
126262b84eSJilles Tjoelker * are met:
136262b84eSJilles Tjoelker * 1. Redistributions of source code must retain the above copyright
146262b84eSJilles Tjoelker * notice, this list of conditions and the following disclaimer.
156262b84eSJilles Tjoelker * 2. Redistributions in binary form must reproduce the above copyright
166262b84eSJilles Tjoelker * notice, this list of conditions and the following disclaimer in the
176262b84eSJilles Tjoelker * documentation and/or other materials provided with the distribution.
186262b84eSJilles Tjoelker * 3. Neither the name of the University nor the names of its contributors
196262b84eSJilles Tjoelker * may be used to endorse or promote products derived from this software
206262b84eSJilles Tjoelker * without specific prior written permission.
216262b84eSJilles Tjoelker *
226262b84eSJilles Tjoelker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
236262b84eSJilles Tjoelker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
246262b84eSJilles Tjoelker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
256262b84eSJilles Tjoelker * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
266262b84eSJilles Tjoelker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
276262b84eSJilles Tjoelker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
286262b84eSJilles Tjoelker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
296262b84eSJilles Tjoelker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
306262b84eSJilles Tjoelker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
316262b84eSJilles Tjoelker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
326262b84eSJilles Tjoelker * SUCH DAMAGE.
336262b84eSJilles Tjoelker */
346262b84eSJilles Tjoelker
356262b84eSJilles Tjoelker #include <sys/cdefs.h>
36*aac5464bSJilles Tjoelker #include <ctype.h>
37*aac5464bSJilles Tjoelker #include <errno.h>
386262b84eSJilles Tjoelker #include <inttypes.h>
396262b84eSJilles Tjoelker #include <stdlib.h>
406262b84eSJilles Tjoelker #include <string.h>
416262b84eSJilles Tjoelker #include "shell.h"
426262b84eSJilles Tjoelker #include "arith_yacc.h"
436262b84eSJilles Tjoelker #include "expand.h"
446262b84eSJilles Tjoelker #include "error.h"
456262b84eSJilles Tjoelker #include "memalloc.h"
466262b84eSJilles Tjoelker #include "parser.h"
476262b84eSJilles Tjoelker #include "syntax.h"
486262b84eSJilles Tjoelker
496262b84eSJilles Tjoelker #if ARITH_BOR + 11 != ARITH_BORASS || ARITH_ASS + 11 != ARITH_EQ
506262b84eSJilles Tjoelker #error Arithmetic tokens are out of order.
516262b84eSJilles Tjoelker #endif
526262b84eSJilles Tjoelker
53*aac5464bSJilles Tjoelker arith_t
strtoarith_t(const char * restrict nptr,char ** restrict endptr)54*aac5464bSJilles Tjoelker strtoarith_t(const char *restrict nptr, char **restrict endptr)
55*aac5464bSJilles Tjoelker {
56*aac5464bSJilles Tjoelker arith_t val;
57*aac5464bSJilles Tjoelker
58*aac5464bSJilles Tjoelker while (isspace((unsigned char)*nptr))
59*aac5464bSJilles Tjoelker nptr++;
60*aac5464bSJilles Tjoelker switch (*nptr) {
61*aac5464bSJilles Tjoelker case '-':
62*aac5464bSJilles Tjoelker return strtoimax(nptr, endptr, 0);
63*aac5464bSJilles Tjoelker case '0':
64*aac5464bSJilles Tjoelker return (arith_t)strtoumax(nptr, endptr, 0);
65*aac5464bSJilles Tjoelker default:
66*aac5464bSJilles Tjoelker val = (arith_t)strtoumax(nptr, endptr, 0);
67*aac5464bSJilles Tjoelker if (val >= 0)
68*aac5464bSJilles Tjoelker return val;
69*aac5464bSJilles Tjoelker else if (val == ARITH_MIN) {
70*aac5464bSJilles Tjoelker errno = ERANGE;
71*aac5464bSJilles Tjoelker return ARITH_MIN;
72*aac5464bSJilles Tjoelker } else {
73*aac5464bSJilles Tjoelker errno = ERANGE;
74*aac5464bSJilles Tjoelker return ARITH_MAX;
75*aac5464bSJilles Tjoelker }
76*aac5464bSJilles Tjoelker }
77*aac5464bSJilles Tjoelker }
78*aac5464bSJilles Tjoelker
796262b84eSJilles Tjoelker int
yylex(void)802fae4c3dSPhilippe Charnier yylex(void)
816262b84eSJilles Tjoelker {
826262b84eSJilles Tjoelker int value;
836262b84eSJilles Tjoelker const char *buf = arith_buf;
84976018d2SJilles Tjoelker char *end;
856262b84eSJilles Tjoelker const char *p;
866262b84eSJilles Tjoelker
876262b84eSJilles Tjoelker for (;;) {
886262b84eSJilles Tjoelker value = *buf;
896262b84eSJilles Tjoelker switch (value) {
906262b84eSJilles Tjoelker case ' ':
916262b84eSJilles Tjoelker case '\t':
926262b84eSJilles Tjoelker case '\n':
936262b84eSJilles Tjoelker buf++;
946262b84eSJilles Tjoelker continue;
956262b84eSJilles Tjoelker default:
966262b84eSJilles Tjoelker return ARITH_BAD;
976262b84eSJilles Tjoelker case '0':
986262b84eSJilles Tjoelker case '1':
996262b84eSJilles Tjoelker case '2':
1006262b84eSJilles Tjoelker case '3':
1016262b84eSJilles Tjoelker case '4':
1026262b84eSJilles Tjoelker case '5':
1036262b84eSJilles Tjoelker case '6':
1046262b84eSJilles Tjoelker case '7':
1056262b84eSJilles Tjoelker case '8':
1066262b84eSJilles Tjoelker case '9':
107*aac5464bSJilles Tjoelker yylval.val = strtoarith_t(buf, &end);
108976018d2SJilles Tjoelker arith_buf = end;
1096262b84eSJilles Tjoelker return ARITH_NUM;
1106262b84eSJilles Tjoelker case 'A':
1116262b84eSJilles Tjoelker case 'B':
1126262b84eSJilles Tjoelker case 'C':
1136262b84eSJilles Tjoelker case 'D':
1146262b84eSJilles Tjoelker case 'E':
1156262b84eSJilles Tjoelker case 'F':
1166262b84eSJilles Tjoelker case 'G':
1176262b84eSJilles Tjoelker case 'H':
1186262b84eSJilles Tjoelker case 'I':
1196262b84eSJilles Tjoelker case 'J':
1206262b84eSJilles Tjoelker case 'K':
1216262b84eSJilles Tjoelker case 'L':
1226262b84eSJilles Tjoelker case 'M':
1236262b84eSJilles Tjoelker case 'N':
1246262b84eSJilles Tjoelker case 'O':
1256262b84eSJilles Tjoelker case 'P':
1266262b84eSJilles Tjoelker case 'Q':
1276262b84eSJilles Tjoelker case 'R':
1286262b84eSJilles Tjoelker case 'S':
1296262b84eSJilles Tjoelker case 'T':
1306262b84eSJilles Tjoelker case 'U':
1316262b84eSJilles Tjoelker case 'V':
1326262b84eSJilles Tjoelker case 'W':
1336262b84eSJilles Tjoelker case 'X':
1346262b84eSJilles Tjoelker case 'Y':
1356262b84eSJilles Tjoelker case 'Z':
1366262b84eSJilles Tjoelker case '_':
1376262b84eSJilles Tjoelker case 'a':
1386262b84eSJilles Tjoelker case 'b':
1396262b84eSJilles Tjoelker case 'c':
1406262b84eSJilles Tjoelker case 'd':
1416262b84eSJilles Tjoelker case 'e':
1426262b84eSJilles Tjoelker case 'f':
1436262b84eSJilles Tjoelker case 'g':
1446262b84eSJilles Tjoelker case 'h':
1456262b84eSJilles Tjoelker case 'i':
1466262b84eSJilles Tjoelker case 'j':
1476262b84eSJilles Tjoelker case 'k':
1486262b84eSJilles Tjoelker case 'l':
1496262b84eSJilles Tjoelker case 'm':
1506262b84eSJilles Tjoelker case 'n':
1516262b84eSJilles Tjoelker case 'o':
1526262b84eSJilles Tjoelker case 'p':
1536262b84eSJilles Tjoelker case 'q':
1546262b84eSJilles Tjoelker case 'r':
1556262b84eSJilles Tjoelker case 's':
1566262b84eSJilles Tjoelker case 't':
1576262b84eSJilles Tjoelker case 'u':
1586262b84eSJilles Tjoelker case 'v':
1596262b84eSJilles Tjoelker case 'w':
1606262b84eSJilles Tjoelker case 'x':
1616262b84eSJilles Tjoelker case 'y':
1626262b84eSJilles Tjoelker case 'z':
1636262b84eSJilles Tjoelker p = buf;
1646262b84eSJilles Tjoelker while (buf++, is_in_name(*buf))
1656262b84eSJilles Tjoelker ;
1666262b84eSJilles Tjoelker yylval.name = stalloc(buf - p + 1);
1676262b84eSJilles Tjoelker memcpy(yylval.name, p, buf - p);
1686262b84eSJilles Tjoelker yylval.name[buf - p] = '\0';
1696262b84eSJilles Tjoelker value = ARITH_VAR;
1706262b84eSJilles Tjoelker goto out;
1716262b84eSJilles Tjoelker case '=':
1726262b84eSJilles Tjoelker value += ARITH_ASS - '=';
1736262b84eSJilles Tjoelker checkeq:
1746262b84eSJilles Tjoelker buf++;
1756262b84eSJilles Tjoelker checkeqcur:
1766262b84eSJilles Tjoelker if (*buf != '=')
1776262b84eSJilles Tjoelker goto out;
1786262b84eSJilles Tjoelker value += 11;
1796262b84eSJilles Tjoelker break;
1806262b84eSJilles Tjoelker case '>':
1816262b84eSJilles Tjoelker switch (*++buf) {
1826262b84eSJilles Tjoelker case '=':
1836262b84eSJilles Tjoelker value += ARITH_GE - '>';
1846262b84eSJilles Tjoelker break;
1856262b84eSJilles Tjoelker case '>':
1866262b84eSJilles Tjoelker value += ARITH_RSHIFT - '>';
1876262b84eSJilles Tjoelker goto checkeq;
1886262b84eSJilles Tjoelker default:
1896262b84eSJilles Tjoelker value += ARITH_GT - '>';
1906262b84eSJilles Tjoelker goto out;
1916262b84eSJilles Tjoelker }
1926262b84eSJilles Tjoelker break;
1936262b84eSJilles Tjoelker case '<':
1946262b84eSJilles Tjoelker switch (*++buf) {
1956262b84eSJilles Tjoelker case '=':
1966262b84eSJilles Tjoelker value += ARITH_LE - '<';
1976262b84eSJilles Tjoelker break;
1986262b84eSJilles Tjoelker case '<':
1996262b84eSJilles Tjoelker value += ARITH_LSHIFT - '<';
2006262b84eSJilles Tjoelker goto checkeq;
2016262b84eSJilles Tjoelker default:
2026262b84eSJilles Tjoelker value += ARITH_LT - '<';
2036262b84eSJilles Tjoelker goto out;
2046262b84eSJilles Tjoelker }
2056262b84eSJilles Tjoelker break;
2066262b84eSJilles Tjoelker case '|':
2076262b84eSJilles Tjoelker if (*++buf != '|') {
2086262b84eSJilles Tjoelker value += ARITH_BOR - '|';
2096262b84eSJilles Tjoelker goto checkeqcur;
2106262b84eSJilles Tjoelker }
2116262b84eSJilles Tjoelker value += ARITH_OR - '|';
2126262b84eSJilles Tjoelker break;
2136262b84eSJilles Tjoelker case '&':
2146262b84eSJilles Tjoelker if (*++buf != '&') {
2156262b84eSJilles Tjoelker value += ARITH_BAND - '&';
2166262b84eSJilles Tjoelker goto checkeqcur;
2176262b84eSJilles Tjoelker }
2186262b84eSJilles Tjoelker value += ARITH_AND - '&';
2196262b84eSJilles Tjoelker break;
2206262b84eSJilles Tjoelker case '!':
2216262b84eSJilles Tjoelker if (*++buf != '=') {
2226262b84eSJilles Tjoelker value += ARITH_NOT - '!';
2236262b84eSJilles Tjoelker goto out;
2246262b84eSJilles Tjoelker }
2256262b84eSJilles Tjoelker value += ARITH_NE - '!';
2266262b84eSJilles Tjoelker break;
2276262b84eSJilles Tjoelker case 0:
2286262b84eSJilles Tjoelker goto out;
2296262b84eSJilles Tjoelker case '(':
2306262b84eSJilles Tjoelker value += ARITH_LPAREN - '(';
2316262b84eSJilles Tjoelker break;
2326262b84eSJilles Tjoelker case ')':
2336262b84eSJilles Tjoelker value += ARITH_RPAREN - ')';
2346262b84eSJilles Tjoelker break;
2356262b84eSJilles Tjoelker case '*':
2366262b84eSJilles Tjoelker value += ARITH_MUL - '*';
2376262b84eSJilles Tjoelker goto checkeq;
2386262b84eSJilles Tjoelker case '/':
2396262b84eSJilles Tjoelker value += ARITH_DIV - '/';
2406262b84eSJilles Tjoelker goto checkeq;
2416262b84eSJilles Tjoelker case '%':
2426262b84eSJilles Tjoelker value += ARITH_REM - '%';
2436262b84eSJilles Tjoelker goto checkeq;
2446262b84eSJilles Tjoelker case '+':
2457e6e930dSJilles Tjoelker if (buf[1] == '+')
2467e6e930dSJilles Tjoelker return ARITH_BAD;
2476262b84eSJilles Tjoelker value += ARITH_ADD - '+';
2486262b84eSJilles Tjoelker goto checkeq;
2496262b84eSJilles Tjoelker case '-':
2507e6e930dSJilles Tjoelker if (buf[1] == '-')
2517e6e930dSJilles Tjoelker return ARITH_BAD;
2526262b84eSJilles Tjoelker value += ARITH_SUB - '-';
2536262b84eSJilles Tjoelker goto checkeq;
2546262b84eSJilles Tjoelker case '~':
2556262b84eSJilles Tjoelker value += ARITH_BNOT - '~';
2566262b84eSJilles Tjoelker break;
2576262b84eSJilles Tjoelker case '^':
2586262b84eSJilles Tjoelker value += ARITH_BXOR - '^';
2596262b84eSJilles Tjoelker goto checkeq;
2606262b84eSJilles Tjoelker case '?':
2616262b84eSJilles Tjoelker value += ARITH_QMARK - '?';
2626262b84eSJilles Tjoelker break;
2636262b84eSJilles Tjoelker case ':':
2646262b84eSJilles Tjoelker value += ARITH_COLON - ':';
2656262b84eSJilles Tjoelker break;
2666262b84eSJilles Tjoelker }
2676262b84eSJilles Tjoelker break;
2686262b84eSJilles Tjoelker }
2696262b84eSJilles Tjoelker
2706262b84eSJilles Tjoelker buf++;
2716262b84eSJilles Tjoelker out:
2726262b84eSJilles Tjoelker arith_buf = buf;
2736262b84eSJilles Tjoelker return value;
2746262b84eSJilles Tjoelker }
275