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