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