arith_yylex.c revision 218466
1137587Snik/*- 2137587Snik * Copyright (c) 2002 3137587Snik * Herbert Xu. 4137587Snik * Copyright (c) 1993 5137587Snik * The Regents of the University of California. All rights reserved. 6137587Snik * 7137587Snik * This code is derived from software contributed to Berkeley by 8137587Snik * Kenneth Almquist. 9137587Snik * 10137587Snik * 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: head/bin/sh/arith_yylex.c 218466 2011-02-08 23:18:06Z jilles $"); 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 53extern const char *arith_buf; 54 55int 56yylex() 57{ 58 int value; 59 const char *buf = arith_buf; 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, (char **)&arith_buf, 0); 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 - '='; 147checkeq: 148 buf++; 149checkeqcur: 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 value += ARITH_ADD - '+'; 220 goto checkeq; 221 case '-': 222 value += ARITH_SUB - '-'; 223 goto checkeq; 224 case '~': 225 value += ARITH_BNOT - '~'; 226 break; 227 case '^': 228 value += ARITH_BXOR - '^'; 229 goto checkeq; 230 case '?': 231 value += ARITH_QMARK - '?'; 232 break; 233 case ':': 234 value += ARITH_COLON - ':'; 235 break; 236 } 237 break; 238 } 239 240 buf++; 241out: 242 arith_buf = buf; 243 return value; 244} 245