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