1 /* 2 * This implementation is based on the UNIX 32V release from 1978 3 * with permission from Caldera Inc. 4 * 5 * Copyright (c) 2011 Joyent, Inc. All rights reserved. 6 * Copyright (c) 2010 J. Schilling 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the copyright holder nor the names of contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 /* 34 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions are 38 * met: 39 * 1. Redistributions of source code and documentation must retain the above 40 * copyright notice, this list of conditions and the following 41 * disclaimer. 42 * 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: This product includes 49 * software developed or owned by Caldera International, Inc. 50 * 51 * 4. Neither the name of Caldera International, Inc. nor the names of other 52 * contributors may be used to endorse or promote products derived from 53 * this software without specific prior written permission. 54 * 55 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 56 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 59 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR 60 * ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 65 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 * POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69 #include "cpp.h" 70 71 /* 72 * XXX This block should be moved to cpp.h, it is douplicated in cpp.c 73 */ 74 #define isid(a) ((fastab+COFF)[(int)a]&IB) 75 #define IB 1 76 /* #if '\377' < 0 it would be nice if this worked properly!!!!! */ 77 #if pdp11 | vax | '\377' < 0 78 #define COFF 128 79 #else 80 #define COFF 0 81 #endif 82 83 static int tobinary(char *, int); 84 85 int 86 yylex(void) 87 { 88 static int ifdef=0; 89 static char *op2[]={"||", "&&" , ">>", "<<", ">=", "<=", "!=", "=="}; 90 static int val2[]={OROR, ANDAND, RS, LS, GE, LE, NE, EQ}; 91 static char *opc="b\bt\tn\nf\fr\r\\\\"; 92 extern char fastab[]; 93 extern char *outp,*inp,*newp; extern int flslvl; 94 register char savc, *s; 95 int val; 96 register char **p2; 97 struct symtab *sp; 98 99 for (;;) { 100 newp=skipbl(newp); 101 if (*inp=='\n') return(stop); /* end of #if */ 102 savc= *newp; *newp='\0'; 103 for (p2=op2+8; --p2>=op2; ) /* check 2-char ops */ 104 if (0==strcmp(*p2,inp)) {val=val2[p2-op2]; goto ret;} 105 s="+-*/%<>&^|?:!~(),"; /* check 1-char ops */ 106 while (*s) if (*s++== *inp) {val= *--s; goto ret;} 107 if (*inp<='9' && *inp>='0') {/* a number */ 108 if (*inp=='0') yylval= (inp[1]=='x' || inp[1]=='X') ? 109 tobinary(inp+2,16) : tobinary(inp+1,8); 110 else yylval=tobinary(inp,10); 111 val=number; 112 } else if (isid(*inp)) { 113 if (0==strcmp(inp,"defined")) {ifdef=1; ++flslvl; val=DEFINED;} 114 else { 115 sp=lookup(inp,-1); if (ifdef!=0) {ifdef=0; --flslvl;} 116 yylval= (sp->value==0) ? 0 : 1; 117 val=number; 118 } 119 } else if (*inp=='\'') {/* character constant */ 120 val=number; 121 if (inp[1]=='\\') {/* escaped */ 122 char c; if (newp[-1]=='\'') newp[-1]='\0'; 123 s=opc; 124 while (*s) if (*s++!=inp[2]) ++s; else {yylval= *s; goto ret;} 125 if (inp[2]<='9' && inp[2]>='0') yylval=c=tobinary(inp+2,8); 126 else yylval=inp[2]; 127 } else yylval=inp[1]; 128 } else if (0==strcmp("\\\n",inp)) {*newp=savc; continue;} 129 else { 130 *newp=savc; pperror("Illegal character %c in preprocessor if", *inp); 131 continue; 132 } 133 ret: 134 *newp=savc; outp=inp=newp; return(val); 135 } 136 } 137 138 static int 139 tobinary(st, b) 140 char *st; 141 int b; 142 { 143 int n, c, t; 144 char *s; 145 n=0; 146 s=st; 147 while ((c = *s++) != '\0') { 148 switch(c) { 149 case '0': case '1': case '2': case '3': case '4': 150 case '5': case '6': case '7': case '8': case '9': 151 t = c-'0'; break; 152 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 153 t = c-'a'; if (b>10) break; 154 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 155 t = c - 'A'; if (b>10) break; 156 default: 157 t = -1; 158 if ( c=='l' || c=='L') if (*s=='\0') break; 159 pperror("Illegal number %s", st); 160 } 161 if (t<0) break; 162 n = n*b+t; 163 } 164 return(n); 165 }