Tue Jan 5 17:13:44 2021 UTC ()
lint: in debug mode, log every newline

This helps to quickly see where in the source file the parser currently
is.  Previously, the parsing position was only printed after each
declaration, as part of "clear flags".


(rillig)
diff -r1.112 -r1.113 src/usr.bin/xlint/lint1/scan.l

cvs diff -r1.112 -r1.113 src/usr.bin/xlint/lint1/scan.l (switch to unified diff)

--- src/usr.bin/xlint/lint1/scan.l 2021/01/04 22:26:50 1.112
+++ src/usr.bin/xlint/lint1/scan.l 2021/01/05 17:13:44 1.113
@@ -1,1176 +1,1179 @@ @@ -1,1176 +1,1179 @@
1%{ 1%{
2/* $NetBSD: scan.l,v 1.112 2021/01/04 22:26:50 rillig Exp $ */ 2/* $NetBSD: scan.l,v 1.113 2021/01/05 17:13:44 rillig Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl 6 * Copyright (c) 1994, 1995 Jochen Pohl
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement: 18 * must display the following acknowledgement:
19 * This product includes software developed by Jochen Pohl for 19 * This product includes software developed by Jochen Pohl for
20 * The NetBSD Project. 20 * The NetBSD Project.
21 * 4. The name of the author may not be used to endorse or promote products 21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission. 22 * derived from this software without specific prior written permission.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37#if defined(__RCSID) && !defined(lint) 37#if defined(__RCSID) && !defined(lint)
38__RCSID("$NetBSD: scan.l,v 1.112 2021/01/04 22:26:50 rillig Exp $"); 38__RCSID("$NetBSD: scan.l,v 1.113 2021/01/05 17:13:44 rillig Exp $");
39#endif 39#endif
40 40
41#include <ctype.h> 41#include <ctype.h>
42#include <errno.h> 42#include <errno.h>
43#include <float.h> 43#include <float.h>
44#include <limits.h> 44#include <limits.h>
45#include <math.h> 45#include <math.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50#include "cgram.h" 50#include "cgram.h"
51 51
52#define CHAR_MASK ((int)(~(~0U << CHAR_BIT))) 52#define CHAR_MASK ((int)(~(~0U << CHAR_BIT)))
53 53
54/* Current position (it's also updated when an included file is parsed) */ 54/* Current position (it's also updated when an included file is parsed) */
55pos_t curr_pos = { 1, "", 0 }; 55pos_t curr_pos = { 1, "", 0 };
56 56
57/* 57/*
58 * Current position in C source (not updated when an included file is 58 * Current position in C source (not updated when an included file is
59 * parsed). 59 * parsed).
60 */ 60 */
61pos_t csrc_pos = { 1, "", 0 }; 61pos_t csrc_pos = { 1, "", 0 };
62 62
63/* Are we parsing a gcc attribute? */ 63/* Are we parsing a gcc attribute? */
64int attron; 64int attron;
65 65
66static void incline(void); 66static void incline(void);
67static void badchar(int); 67static void badchar(int);
68static sbuf_t *allocsb(void); 68static sbuf_t *allocsb(void);
69static void freesb(sbuf_t *); 69static void freesb(sbuf_t *);
70static int inpc(void); 70static int inpc(void);
71static int hash(const char *); 71static int hash(const char *);
72static sym_t *search(sbuf_t *); 72static sym_t *search(sbuf_t *);
73static int name(void); 73static int name(void);
74static int keyw(sym_t *); 74static int keyw(sym_t *);
75static int icon(int); 75static int icon(int);
76static int fcon(void); 76static int fcon(void);
77static int operator(int, op_t); 77static int operator(int, op_t);
78static int ccon(void); 78static int ccon(void);
79static int wccon(void); 79static int wccon(void);
80static int getescc(int); 80static int getescc(int);
81static void directive(void); 81static void directive(void);
82static void comment(void); 82static void comment(void);
83static void slashslashcomment(void); 83static void slashslashcomment(void);
84static int string(void); 84static int string(void);
85static int wcstrg(void); 85static int wcstrg(void);
86 86
87%} 87%}
88 88
89 89
90L [_A-Za-z] 90L [_A-Za-z]
91D [0-9] 91D [0-9]
92NZD [1-9] 92NZD [1-9]
93BD [0-1] 93BD [0-1]
94OD [0-7] 94OD [0-7]
95HD [0-9A-Fa-f] 95HD [0-9A-Fa-f]
96EX ([eE][+-]?[0-9]+) 96EX ([eE][+-]?[0-9]+)
97HX (p[+-]?[0-9A-Fa-f]+) 97HX (p[+-]?[0-9A-Fa-f]+)
98TL ([fFlL]?[i]?) 98TL ([fFlL]?[i]?)
99 99
100%option nounput 100%option nounput
101 101
102%% 102%%
103 103
104{L}({L}|{D})* return name(); 104{L}({L}|{D})* return name();
1050[bB]{BD}+[lLuU]* return icon(2); 1050[bB]{BD}+[lLuU]* return icon(2);
1060{OD}*[lLuU]* return icon(8); 1060{OD}*[lLuU]* return icon(8);
107{NZD}{D}*[lLuU]* return icon(10); 107{NZD}{D}*[lLuU]* return icon(10);
1080[xX]{HD}+[lLuU]* return icon(16); 1080[xX]{HD}+[lLuU]* return icon(16);
109{D}+\.{D}*{EX}?{TL} | 109{D}+\.{D}*{EX}?{TL} |
110{D}+{EX}{TL} | 110{D}+{EX}{TL} |
1110[xX]{HD}+\.{HD}*{HX}{TL} | 1110[xX]{HD}+\.{HD}*{HX}{TL} |
1120[xX]{HD}+{HX}{TL} | 1120[xX]{HD}+{HX}{TL} |
113\.{D}+{EX}?{TL} return fcon(); 113\.{D}+{EX}?{TL} return fcon();
114"=" return operator(T_ASSIGN, ASSIGN); 114"=" return operator(T_ASSIGN, ASSIGN);
115"*=" return operator(T_OPASS, MULASS); 115"*=" return operator(T_OPASS, MULASS);
116"/=" return operator(T_OPASS, DIVASS); 116"/=" return operator(T_OPASS, DIVASS);
117"%=" return operator(T_OPASS, MODASS); 117"%=" return operator(T_OPASS, MODASS);
118"+=" return operator(T_OPASS, ADDASS); 118"+=" return operator(T_OPASS, ADDASS);
119"-=" return operator(T_OPASS, SUBASS); 119"-=" return operator(T_OPASS, SUBASS);
120"<<=" return operator(T_OPASS, SHLASS); 120"<<=" return operator(T_OPASS, SHLASS);
121">>=" return operator(T_OPASS, SHRASS); 121">>=" return operator(T_OPASS, SHRASS);
122"&=" return operator(T_OPASS, ANDASS); 122"&=" return operator(T_OPASS, ANDASS);
123"^=" return operator(T_OPASS, XORASS); 123"^=" return operator(T_OPASS, XORASS);
124"|=" return operator(T_OPASS, ORASS); 124"|=" return operator(T_OPASS, ORASS);
125"||" return operator(T_LOGOR, LOGOR); 125"||" return operator(T_LOGOR, LOGOR);
126"&&" return operator(T_LOGAND, LOGAND); 126"&&" return operator(T_LOGAND, LOGAND);
127"|" return operator(T_OR, OR); 127"|" return operator(T_OR, OR);
128"&" return operator(T_AND, AND); 128"&" return operator(T_AND, AND);
129"^" return operator(T_XOR, XOR); 129"^" return operator(T_XOR, XOR);
130"==" return operator(T_EQOP, EQ); 130"==" return operator(T_EQOP, EQ);
131"!=" return operator(T_EQOP, NE); 131"!=" return operator(T_EQOP, NE);
132"<" return operator(T_RELOP, LT); 132"<" return operator(T_RELOP, LT);
133">" return operator(T_RELOP, GT); 133">" return operator(T_RELOP, GT);
134"<=" return operator(T_RELOP, LE); 134"<=" return operator(T_RELOP, LE);
135">=" return operator(T_RELOP, GE); 135">=" return operator(T_RELOP, GE);
136"<<" return operator(T_SHFTOP, SHL); 136"<<" return operator(T_SHFTOP, SHL);
137">>" return operator(T_SHFTOP, SHR); 137">>" return operator(T_SHFTOP, SHR);
138"++" return operator(T_INCDEC, INC); 138"++" return operator(T_INCDEC, INC);
139"--" return operator(T_INCDEC, DEC); 139"--" return operator(T_INCDEC, DEC);
140"->" return operator(T_STROP, ARROW); 140"->" return operator(T_STROP, ARROW);
141"." return operator(T_STROP, POINT); 141"." return operator(T_STROP, POINT);
142"+" return operator(T_ADDOP, PLUS); 142"+" return operator(T_ADDOP, PLUS);
143"-" return operator(T_ADDOP, MINUS); 143"-" return operator(T_ADDOP, MINUS);
144"*" return operator(T_MULT, MULT); 144"*" return operator(T_MULT, MULT);
145"/" return operator(T_DIVOP, DIV); 145"/" return operator(T_DIVOP, DIV);
146"%" return operator(T_DIVOP, MOD); 146"%" return operator(T_DIVOP, MOD);
147"!" return operator(T_UNOP, NOT); 147"!" return operator(T_UNOP, NOT);
148"~" return operator(T_UNOP, COMPL); 148"~" return operator(T_UNOP, COMPL);
149"\"" return string(); 149"\"" return string();
150"L\"" return wcstrg(); 150"L\"" return wcstrg();
151";" return T_SEMI; 151";" return T_SEMI;
152"{" return T_LBRACE; 152"{" return T_LBRACE;
153"}" return T_RBRACE; 153"}" return T_RBRACE;
154"," return T_COMMA; 154"," return T_COMMA;
155":" return T_COLON; 155":" return T_COLON;
156"?" return T_QUEST; 156"?" return T_QUEST;
157"[" return T_LBRACK; 157"[" return T_LBRACK;
158"]" return T_RBRACK; 158"]" return T_RBRACK;
159"(" return T_LPAREN; 159"(" return T_LPAREN;
160")" return T_RPAREN; 160")" return T_RPAREN;
161"..." return T_ELLIPSE; 161"..." return T_ELLIPSE;
162"'" return ccon(); 162"'" return ccon();
163"L'" return wccon(); 163"L'" return wccon();
164^#.*$ directive(); 164^#.*$ directive();
165\n incline(); 165\n incline();
166\t|" "|\f|\v ; 166\t|" "|\f|\v ;
167"/*" comment(); 167"/*" comment();
168"//" slashslashcomment(); 168"//" slashslashcomment();
169. badchar(yytext[0]); 169. badchar(yytext[0]);
170 170
171%% 171%%
172 172
173static void 173static void
174incline(void) 174incline(void)
175{ 175{
176 curr_pos.p_line++; 176 curr_pos.p_line++;
177 curr_pos.p_uniq = 0; 177 curr_pos.p_uniq = 0;
 178#ifdef DEBUG
 179 printf("parsing %s:%d\n", curr_pos.p_file, curr_pos.p_line);
 180#endif
178 if (curr_pos.p_file == csrc_pos.p_file) { 181 if (curr_pos.p_file == csrc_pos.p_file) {
179 csrc_pos.p_line++; 182 csrc_pos.p_line++;
180 csrc_pos.p_uniq = 0; 183 csrc_pos.p_uniq = 0;
181 } 184 }
182} 185}
183 186
184static void 187static void
185badchar(int c) 188badchar(int c)
186{ 189{
187 190
188 /* unknown character \%o */ 191 /* unknown character \%o */
189 error(250, c); 192 error(250, c);
190} 193}
191 194
192/* 195/*
193 * Keywords. 196 * Keywords.
194 * During initialisation they are written to the symbol table. 197 * During initialisation they are written to the symbol table.
195 */ 198 */
196static struct kwtab { 199static struct kwtab {
197 const char *kw_name; /* keyword */ 200 const char *kw_name; /* keyword */
198 int kw_token; /* token returned by yylex() */ 201 int kw_token; /* token returned by yylex() */
199 scl_t kw_scl; /* storage class if kw_token T_SCLASS */ 202 scl_t kw_scl; /* storage class if kw_token T_SCLASS */
200 tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ 203 tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */
201 tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ 204 tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */
202 bool kw_c89 : 1; /* C89 keyword */ 205 bool kw_c89 : 1; /* C89 keyword */
203 bool kw_c99 : 1; /* C99 keyword */ 206 bool kw_c99 : 1; /* C99 keyword */
204 bool kw_gcc : 1; /* GCC keyword */ 207 bool kw_gcc : 1; /* GCC keyword */
205 bool kw_attr : 1; /* GCC attribute, keyword */ 208 bool kw_attr : 1; /* GCC attribute, keyword */
206 u_int kw_deco : 3; /* 1 = name, 2 = __name, 4 = __name__ */ 209 u_int kw_deco : 3; /* 1 = name, 2 = __name, 4 = __name__ */
207} kwtab[] = { 210} kwtab[] = {
208#ifdef INT128_SIZE 211#ifdef INT128_SIZE
209 { "__int128_t", T_TYPE, 0, INT128, 0, 0,1,0,0,1 }, 212 { "__int128_t", T_TYPE, 0, INT128, 0, 0,1,0,0,1 },
210 { "__uint128_t",T_TYPE, 0, UINT128,0, 0,1,0,0,1 }, 213 { "__uint128_t",T_TYPE, 0, UINT128,0, 0,1,0,0,1 },
211#endif 214#endif
212 { "__thread", T_QUAL, 0, 0, THREAD, 0,0,1,0,1 }, 215 { "__thread", T_QUAL, 0, 0, THREAD, 0,0,1,0,1 },
213 { "_Alignof", T_ALIGNOF, 0, 0, 0, 0,0,0,0,1 }, 216 { "_Alignof", T_ALIGNOF, 0, 0, 0, 0,0,0,0,1 },
214 { "_Bool", T_TYPE, 0, BOOL, 0, 0,1,0,0,1 }, 217 { "_Bool", T_TYPE, 0, BOOL, 0, 0,1,0,0,1 },
215 { "_Complex", T_TYPE, 0, COMPLEX,0, 0,1,0,0,1 }, 218 { "_Complex", T_TYPE, 0, COMPLEX,0, 0,1,0,0,1 },
216 { "_Generic", T_GENERIC, 0, 0, 0, 0,1,0,0,1 }, 219 { "_Generic", T_GENERIC, 0, 0, 0, 0,1,0,0,1 },
217 { "_Noreturn", T_NORETURN, 0, 0, 0, 0,1,0,0,1 }, 220 { "_Noreturn", T_NORETURN, 0, 0, 0, 0,1,0,0,1 },
218 { "_Thread_local",T_QUAL, 0, 0, THREAD, 0,1,0,0,1 }, 221 { "_Thread_local",T_QUAL, 0, 0, THREAD, 0,1,0,0,1 },
219 { "alias", T_AT_ALIAS, 0, 0, 0, 0,0,1,1,5 }, 222 { "alias", T_AT_ALIAS, 0, 0, 0, 0,0,1,1,5 },
220 { "aligned", T_AT_ALIGNED, 0, 0, 0, 0,0,1,1,5 }, 223 { "aligned", T_AT_ALIGNED, 0, 0, 0, 0,0,1,1,5 },
221 { "alignof", T_ALIGNOF, 0, 0, 0, 0,0,0,0,4 }, 224 { "alignof", T_ALIGNOF, 0, 0, 0, 0,0,0,0,4 },
222 { "alloc_size", T_AT_ALLOC_SIZE,0, 0, 0, 0,0,1,1,5 }, 225 { "alloc_size", T_AT_ALLOC_SIZE,0, 0, 0, 0,0,1,1,5 },
223 { "always_inline", T_AT_ALWAYS_INLINE, 0,0, 0, 0,0,1,1,5 }, 226 { "always_inline", T_AT_ALWAYS_INLINE, 0,0, 0, 0,0,1,1,5 },
224 { "asm", T_ASM, 0, 0, 0, 0,0,1,0,7 }, 227 { "asm", T_ASM, 0, 0, 0, 0,0,1,0,7 },
225 { "attribute", T_ATTRIBUTE, 0, 0, 0, 0,0,1,0,6 }, 228 { "attribute", T_ATTRIBUTE, 0, 0, 0, 0,0,1,0,6 },
226 { "auto", T_SCLASS, AUTO, 0, 0, 0,0,0,0,1 }, 229 { "auto", T_SCLASS, AUTO, 0, 0, 0,0,0,0,1 },
227 { "bounded", T_AT_BOUNDED, 0, 0, 0, 0,0,1,1,5 }, 230 { "bounded", T_AT_BOUNDED, 0, 0, 0, 0,0,1,1,5 },
228 { "break", T_BREAK, 0, 0, 0, 0,0,0,0,1 }, 231 { "break", T_BREAK, 0, 0, 0, 0,0,0,0,1 },
229 { "buffer", T_AT_BUFFER, 0, 0, 0, 0,0,1,1,5 }, 232 { "buffer", T_AT_BUFFER, 0, 0, 0, 0,0,1,1,5 },
230 { "builtin_offsetof", T_BUILTIN_OFFSETOF, 0, 0, 0, 0,0,1,0,2 }, 233 { "builtin_offsetof", T_BUILTIN_OFFSETOF, 0, 0, 0, 0,0,1,0,2 },
231 { "case", T_CASE, 0, 0, 0, 0,0,0,0,1 }, 234 { "case", T_CASE, 0, 0, 0, 0,0,0,0,1 },
232 { "char", T_TYPE, 0, CHAR, 0, 0,0,0,0,1 }, 235 { "char", T_TYPE, 0, CHAR, 0, 0,0,0,0,1 },
233 { "cold", T_AT_COLD, 0, 0, 0, 0,0,1,1,5 }, 236 { "cold", T_AT_COLD, 0, 0, 0, 0,0,1,1,5 },
234 { "const", T_QUAL, 0, 0, CONST, 1,0,0,0,7 }, 237 { "const", T_QUAL, 0, 0, CONST, 1,0,0,0,7 },
235 { "constructor",T_AT_CONSTRUCTOR,0, 0, 0, 0,0,1,1,5 }, 238 { "constructor",T_AT_CONSTRUCTOR,0, 0, 0, 0,0,1,1,5 },
236 { "continue", T_CONTINUE, 0, 0, 0, 0,0,0,0,1 }, 239 { "continue", T_CONTINUE, 0, 0, 0, 0,0,0,0,1 },
237 { "default", T_DEFAULT, 0, 0, 0, 0,0,0,0,1 }, 240 { "default", T_DEFAULT, 0, 0, 0, 0,0,0,0,1 },
238 { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0,0,1,1,5 }, 241 { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0,0,1,1,5 },
239 { "destructor", T_AT_DESTRUCTOR,0, 0, 0, 0,0,1,1,5 }, 242 { "destructor", T_AT_DESTRUCTOR,0, 0, 0, 0,0,1,1,5 },
240 { "do", T_DO, 0, 0, 0, 0,0,0,0,1 }, 243 { "do", T_DO, 0, 0, 0, 0,0,0,0,1 },
241 { "double", T_TYPE, 0, DOUBLE, 0, 0,0,0,0,1 }, 244 { "double", T_TYPE, 0, DOUBLE, 0, 0,0,0,0,1 },
242 { "else", T_ELSE, 0, 0, 0, 0,0,0,0,1 }, 245 { "else", T_ELSE, 0, 0, 0, 0,0,0,0,1 },
243 { "enum", T_ENUM, 0, 0, 0, 0,0,0,0,1 }, 246 { "enum", T_ENUM, 0, 0, 0, 0,0,0,0,1 },
244 { "extension", T_EXTENSION, 0, 0, 0, 0,0,1,0,4 }, 247 { "extension", T_EXTENSION, 0, 0, 0, 0,0,1,0,4 },
245 { "extern", T_SCLASS, EXTERN, 0, 0, 0,0,0,0,1 }, 248 { "extern", T_SCLASS, EXTERN, 0, 0, 0,0,0,0,1 },
246 { "float", T_TYPE, 0, FLOAT, 0, 0,0,0,0,1 }, 249 { "float", T_TYPE, 0, FLOAT, 0, 0,0,0,0,1 },
247 { "for", T_FOR, 0, 0, 0, 0,0,0,0,1 }, 250 { "for", T_FOR, 0, 0, 0, 0,0,0,0,1 },
248 { "format", T_AT_FORMAT, 0, 0, 0, 0,0,1,1,5 }, 251 { "format", T_AT_FORMAT, 0, 0, 0, 0,0,1,1,5 },
249 { "format_arg", T_AT_FORMAT_ARG,0, 0, 0, 0,0,1,1,5 }, 252 { "format_arg", T_AT_FORMAT_ARG,0, 0, 0, 0,0,1,1,5 },
250 { "gnu_inline", T_AT_GNU_INLINE,0, 0, 0, 0,0,1,1,5 }, 253 { "gnu_inline", T_AT_GNU_INLINE,0, 0, 0, 0,0,1,1,5 },
251 { "gnu_printf", T_AT_FORMAT_GNU_PRINTF,0,0, 0, 0,0,1,1,5 }, 254 { "gnu_printf", T_AT_FORMAT_GNU_PRINTF,0,0, 0, 0,0,1,1,5 },
252 { "goto", T_GOTO, 0, 0, 0, 0,0,0,0,1 }, 255 { "goto", T_GOTO, 0, 0, 0, 0,0,0,0,1 },
253 { "if", T_IF, 0, 0, 0, 0,0,0,0,1 }, 256 { "if", T_IF, 0, 0, 0, 0,0,0,0,1 },
254 { "imag", T_IMAG, 0, 0, 0, 0,1,0,0,4 }, 257 { "imag", T_IMAG, 0, 0, 0, 0,1,0,0,4 },
255 { "inline", T_SCLASS, INLINE, 0, 0, 0,1,0,0,7 }, 258 { "inline", T_SCLASS, INLINE, 0, 0, 0,1,0,0,7 },
256 { "int", T_TYPE, 0, INT, 0, 0,0,0,0,1 }, 259 { "int", T_TYPE, 0, INT, 0, 0,0,0,0,1 },
257 { "long", T_TYPE, 0, LONG, 0, 0,0,0,0,1 }, 260 { "long", T_TYPE, 0, LONG, 0, 0,0,0,0,1 },
258 { "malloc", T_AT_MALLOC, 0, 0, 0, 0,0,1,1,5 }, 261 { "malloc", T_AT_MALLOC, 0, 0, 0, 0,0,1,1,5 },
259 { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0,0,1,1,5 }, 262 { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0,0,1,1,5 },
260 { "minbytes", T_AT_MINBYTES, 0, 0, 0, 0,0,1,1,5 }, 263 { "minbytes", T_AT_MINBYTES, 0, 0, 0, 0,0,1,1,5 },
261 { "mode", T_AT_MODE, 0, 0, 0, 0,0,1,1,5 }, 264 { "mode", T_AT_MODE, 0, 0, 0, 0,0,1,1,5 },
262 { "no_instrument_function", T_AT_NO_INSTRUMENT_FUNCTION, 265 { "no_instrument_function", T_AT_NO_INSTRUMENT_FUNCTION,
263 0, 0, 0, 0,0,1,1,5 }, 266 0, 0, 0, 0,0,1,1,5 },
264 { "nonnull", T_AT_NONNULL, 0, 0, 0, 0,0,1,1,5 }, 267 { "nonnull", T_AT_NONNULL, 0, 0, 0, 0,0,1,1,5 },
265 { "noinline", T_AT_NOINLINE, 0, 0, 0, 0,0,1,1,5 }, 268 { "noinline", T_AT_NOINLINE, 0, 0, 0, 0,0,1,1,5 },
266 { "noreturn", T_AT_NORETURN, 0, 0, 0, 0,0,1,1,5 }, 269 { "noreturn", T_AT_NORETURN, 0, 0, 0, 0,0,1,1,5 },
267 { "nothrow", T_AT_NOTHROW, 0, 0, 0, 0,0,1,1,5 }, 270 { "nothrow", T_AT_NOTHROW, 0, 0, 0, 0,0,1,1,5 },
268 { "optimize", T_AT_OPTIMIZE, 0, 0, 0, 0,0,1,1,5 }, 271 { "optimize", T_AT_OPTIMIZE, 0, 0, 0, 0,0,1,1,5 },
269 { "packed", T_AT_PACKED, 0, 0, 0, 0,0,1,1,5 }, 272 { "packed", T_AT_PACKED, 0, 0, 0, 0,0,1,1,5 },
270 { "packed", T_PACKED, 0, 0, 0, 0,0,0,0,2 }, 273 { "packed", T_PACKED, 0, 0, 0, 0,0,0,0,2 },
271 { "pcs", T_AT_PCS, 0, 0, 0, 0,0,0,0,5 }, 274 { "pcs", T_AT_PCS, 0, 0, 0, 0,0,0,0,5 },
272 { "printf", T_AT_FORMAT_PRINTF,0, 0, 0, 0,0,1,1,5 }, 275 { "printf", T_AT_FORMAT_PRINTF,0, 0, 0, 0,0,1,1,5 },
273 { "pure", T_AT_PURE, 0, 0, 0, 0,0,1,1,5 }, 276 { "pure", T_AT_PURE, 0, 0, 0, 0,0,1,1,5 },
274 { "real", T_REAL, 0, 0, 0, 0,1,0,0,4 }, 277 { "real", T_REAL, 0, 0, 0, 0,1,0,0,4 },
275 { "register", T_SCLASS, REG, 0, 0, 0,0,0,0,1 }, 278 { "register", T_SCLASS, REG, 0, 0, 0,0,0,0,1 },
276 { "restrict", T_QUAL, 0, 0, RESTRICT, 0,1,0,0,5 }, 279 { "restrict", T_QUAL, 0, 0, RESTRICT, 0,1,0,0,5 },
277 { "return", T_RETURN, 0, 0, 0, 0,0,0,0,1 }, 280 { "return", T_RETURN, 0, 0, 0, 0,0,0,0,1 },
278 { "returns_twice", T_AT_RETURNS_TWICE,0,0, 0, 0,0,1,1,5 }, 281 { "returns_twice", T_AT_RETURNS_TWICE,0,0, 0, 0,0,1,1,5 },
279 { "scanf", T_AT_FORMAT_SCANF,0, 0, 0, 0,0,1,1,5 }, 282 { "scanf", T_AT_FORMAT_SCANF,0, 0, 0, 0,0,1,1,5 },
280 { "section", T_AT_SECTION, 0, 0, 0, 0,0,1,1,7 }, 283 { "section", T_AT_SECTION, 0, 0, 0, 0,0,1,1,7 },
281 { "sentinel", T_AT_SENTINEL, 0, 0, 0, 0,0,1,1,5 }, 284 { "sentinel", T_AT_SENTINEL, 0, 0, 0, 0,0,1,1,5 },
282 { "short", T_TYPE, 0, SHORT, 0, 0,0,0,0,1 }, 285 { "short", T_TYPE, 0, SHORT, 0, 0,0,0,0,1 },
283 { "signed", T_TYPE, 0, SIGNED, 0, 1,0,0,0,3 }, 286 { "signed", T_TYPE, 0, SIGNED, 0, 1,0,0,0,3 },
284 { "sizeof", T_SIZEOF, 0, 0, 0, 0,0,0,0,1 }, 287 { "sizeof", T_SIZEOF, 0, 0, 0, 0,0,0,0,1 },
285 { "static", T_SCLASS, STATIC, 0, 0, 0,0,0,0,1 }, 288 { "static", T_SCLASS, STATIC, 0, 0, 0,0,0,0,1 },
286 { "strfmon", T_AT_FORMAT_STRFMON,0, 0, 0, 0,0,1,1,5 }, 289 { "strfmon", T_AT_FORMAT_STRFMON,0, 0, 0, 0,0,1,1,5 },
287 { "strftime", T_AT_FORMAT_STRFTIME,0, 0, 0, 0,0,1,1,5 }, 290 { "strftime", T_AT_FORMAT_STRFTIME,0, 0, 0, 0,0,1,1,5 },
288 { "string", T_AT_STRING, 0, 0, 0, 0,0,1,1,5 }, 291 { "string", T_AT_STRING, 0, 0, 0, 0,0,1,1,5 },
289 { "struct", T_SOU, 0, STRUCT, 0, 0,0,0,0,1 }, 292 { "struct", T_SOU, 0, STRUCT, 0, 0,0,0,0,1 },
290 { "switch", T_SWITCH, 0, 0, 0, 0,0,0,0,1 }, 293 { "switch", T_SWITCH, 0, 0, 0, 0,0,0,0,1 },
291 { "symbolrename", T_SYMBOLRENAME,0, 0, 0, 0,0,0,0,2 }, 294 { "symbolrename", T_SYMBOLRENAME,0, 0, 0, 0,0,0,0,2 },
292 { "syslog", T_AT_FORMAT_SYSLOG,0, 0, 0, 0,0,1,1,5 }, 295 { "syslog", T_AT_FORMAT_SYSLOG,0, 0, 0, 0,0,1,1,5 },
293 { "transparent_union",T_AT_TUNION,0, 0, 0, 0,0,1,1,5 }, 296 { "transparent_union",T_AT_TUNION,0, 0, 0, 0,0,1,1,5 },
294 { "tls_model", T_AT_TLS_MODEL, 0, 0, 0, 0,0,1,1,5 }, 297 { "tls_model", T_AT_TLS_MODEL, 0, 0, 0, 0,0,1,1,5 },
295 { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0,0,0,0,1 }, 298 { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0,0,0,0,1 },
296 { "typeof", T_TYPEOF, 0, 0, 0, 0,0,1,0,7 }, 299 { "typeof", T_TYPEOF, 0, 0, 0, 0,0,1,0,7 },
297 { "union", T_SOU, 0, UNION, 0, 0,0,0,0,1 }, 300 { "union", T_SOU, 0, UNION, 0, 0,0,0,0,1 },
298 { "unsigned", T_TYPE, 0, UNSIGN, 0, 0,0,0,0,1 }, 301 { "unsigned", T_TYPE, 0, UNSIGN, 0, 0,0,0,0,1 },
299 { "unused", T_AT_UNUSED, 0, 0, 0, 0,0,1,1,5 }, 302 { "unused", T_AT_UNUSED, 0, 0, 0, 0,0,1,1,5 },
300 { "used", T_AT_USED, 0, 0, 0, 0,0,1,1,5 }, 303 { "used", T_AT_USED, 0, 0, 0, 0,0,1,1,5 },
301 { "visibility", T_AT_VISIBILITY,0, 0, 0, 0,0,1,1,5 }, 304 { "visibility", T_AT_VISIBILITY,0, 0, 0, 0,0,1,1,5 },
302 { "void", T_TYPE, 0, VOID, 0, 0,0,0,0,1 }, 305 { "void", T_TYPE, 0, VOID, 0, 0,0,0,0,1 },
303 { "volatile", T_QUAL, 0, 0, VOLATILE, 1,0,0,0,7 }, 306 { "volatile", T_QUAL, 0, 0, VOLATILE, 1,0,0,0,7 },
304 { "warn_unused_result", T_AT_WARN_UNUSED_RESULT, 0, 0, 0, 0,0,1,1,5 }, 307 { "warn_unused_result", T_AT_WARN_UNUSED_RESULT, 0, 0, 0, 0,0,1,1,5 },
305 { "weak", T_AT_WEAK, 0, 0, 0, 0,0,1,1,5 }, 308 { "weak", T_AT_WEAK, 0, 0, 0, 0,0,1,1,5 },
306 { "while", T_WHILE, 0, 0, 0, 0,0,0,0,1 }, 309 { "while", T_WHILE, 0, 0, 0, 0,0,0,0,1 },
307 { NULL, 0, 0, 0, 0, 0,0,0,0,0 } 310 { NULL, 0, 0, 0, 0, 0,0,0,0,0 }
308}; 311};
309 312
310/* Symbol table */ 313/* Symbol table */
311static sym_t *symtab[HSHSIZ1]; 314static sym_t *symtab[HSHSIZ1];
312 315
313/* bit i of the entry with index i is set */ 316/* bit i of the entry with index i is set */
314uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; 317uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT];
315 318
316/* least significant i bits are set in the entry with index i */ 319/* least significant i bits are set in the entry with index i */
317uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; 320uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1];
318 321
319/* least significant i bits are not set in the entry with index i */ 322/* least significant i bits are not set in the entry with index i */
320uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; 323uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1];
321 324
322/* free list for sbuf structures */ 325/* free list for sbuf structures */
323static sbuf_t *sbfrlst; 326static sbuf_t *sbfrlst;
324 327
325/* Typ of next expected symbol */ 328/* Typ of next expected symbol */
326symt_t symtyp; 329symt_t symtyp;
327 330
328 331
329static void 332static void
330add_keyword(struct kwtab *kw, int deco) 333add_keyword(struct kwtab *kw, int deco)
331{ 334{
332 sym_t *sym; 335 sym_t *sym;
333 size_t h; 336 size_t h;
334 char buf[256]; 337 char buf[256];
335 const char *name; 338 const char *name;
336 339
337 if (!(kw->kw_deco & deco)) 340 if (!(kw->kw_deco & deco))
338 return; 341 return;
339 342
340 switch (deco) { 343 switch (deco) {
341 case 1: 344 case 1:
342 name = kw->kw_name; 345 name = kw->kw_name;
343 break; 346 break;
344 case 2: 347 case 2:
345 snprintf(buf, sizeof(buf), "__%s", kw->kw_name); 348 snprintf(buf, sizeof(buf), "__%s", kw->kw_name);
346 name = strdup(buf); 349 name = strdup(buf);
347 break; 350 break;
348 case 4: 351 case 4:
349 snprintf(buf, sizeof(buf), "__%s__", kw->kw_name); 352 snprintf(buf, sizeof(buf), "__%s__", kw->kw_name);
350 name = strdup(buf); 353 name = strdup(buf);
351 break; 354 break;
352 default: 355 default:
353 abort(); 356 abort();
354 } 357 }
355 358
356 if (name == NULL) 359 if (name == NULL)
357 err(1, "Can't init symbol table"); 360 err(1, "Can't init symbol table");
358 361
359 sym = getblk(sizeof (sym_t)); 362 sym = getblk(sizeof (sym_t));
360 sym->s_name = name; 363 sym->s_name = name;
361 sym->s_keyword = kw; 364 sym->s_keyword = kw;
362 sym->s_value.v_quad = kw->kw_token; 365 sym->s_value.v_quad = kw->kw_token;
363 if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { 366 if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) {
364 sym->s_tspec = kw->kw_tspec; 367 sym->s_tspec = kw->kw_tspec;
365 } else if (kw->kw_token == T_SCLASS) { 368 } else if (kw->kw_token == T_SCLASS) {
366 sym->s_scl = kw->kw_scl; 369 sym->s_scl = kw->kw_scl;
367 } else if (kw->kw_token == T_QUAL) { 370 } else if (kw->kw_token == T_QUAL) {
368 sym->s_tqual = kw->kw_tqual; 371 sym->s_tqual = kw->kw_tqual;
369 } 372 }
370 h = hash(sym->s_name); 373 h = hash(sym->s_name);
371 if ((sym->s_link = symtab[h]) != NULL) 374 if ((sym->s_link = symtab[h]) != NULL)
372 symtab[h]->s_rlink = &sym->s_link; 375 symtab[h]->s_rlink = &sym->s_link;
373 sym->s_rlink = &symtab[h]; 376 sym->s_rlink = &symtab[h];
374 symtab[h] = sym; 377 symtab[h] = sym;
375} 378}
376 379
377/* 380/*
378 * All keywords are written to the symbol table. This saves us looking 381 * All keywords are written to the symbol table. This saves us looking
379 * in a extra table for each name we found. 382 * in a extra table for each name we found.
380 */ 383 */
381void 384void
382initscan(void) 385initscan(void)
383{ 386{
384 struct kwtab *kw; 387 struct kwtab *kw;
385 size_t i; 388 size_t i;
386 uint64_t uq; 389 uint64_t uq;
387 390
388 for (kw = kwtab; kw->kw_name != NULL; kw++) { 391 for (kw = kwtab; kw->kw_name != NULL; kw++) {
389 if ((kw->kw_c89 || kw->kw_c99) && tflag) 392 if ((kw->kw_c89 || kw->kw_c99) && tflag)
390 continue; 393 continue;
391 if (kw->kw_c99 && !(Sflag || gflag)) 394 if (kw->kw_c99 && !(Sflag || gflag))
392 continue; 395 continue;
393 if (kw->kw_gcc && !gflag) 396 if (kw->kw_gcc && !gflag)
394 continue; 397 continue;
395 add_keyword(kw, 1); 398 add_keyword(kw, 1);
396 add_keyword(kw, 2); 399 add_keyword(kw, 2);
397 add_keyword(kw, 4); 400 add_keyword(kw, 4);
398 } 401 }
399 402
400 /* initialize bit-masks for quads */ 403 /* initialize bit-masks for quads */
401 for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) { 404 for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) {
402 qbmasks[i] = (uint64_t)1 << i; 405 qbmasks[i] = (uint64_t)1 << i;
403 uq = ~(uint64_t)0 << i; 406 uq = ~(uint64_t)0 << i;
404 qumasks[i] = uq; 407 qumasks[i] = uq;
405 qlmasks[i] = ~uq; 408 qlmasks[i] = ~uq;
406 } 409 }
407 qumasks[i] = 0; 410 qumasks[i] = 0;
408 qlmasks[i] = ~(uint64_t)0; 411 qlmasks[i] = ~(uint64_t)0;
409} 412}
410 413
411/* 414/*
412 * Get a free sbuf structure, if possible from the free list 415 * Get a free sbuf structure, if possible from the free list
413 */ 416 */
414static sbuf_t * 417static sbuf_t *
415allocsb(void) 418allocsb(void)
416{ 419{
417 sbuf_t *sb; 420 sbuf_t *sb;
418 421
419 if ((sb = sbfrlst) != NULL) { 422 if ((sb = sbfrlst) != NULL) {
420 sbfrlst = sb->sb_next; 423 sbfrlst = sb->sb_next;
421#ifdef BLKDEBUG 424#ifdef BLKDEBUG
422 (void)memset(sb, 0, sizeof (*sb)); 425 (void)memset(sb, 0, sizeof (*sb));
423#else 426#else
424 sb->sb_next = NULL; 427 sb->sb_next = NULL;
425#endif 428#endif
426 } else { 429 } else {
427 sb = xmalloc(sizeof (sbuf_t)); 430 sb = xmalloc(sizeof (sbuf_t));
428 (void)memset(sb, 0, sizeof (*sb)); 431 (void)memset(sb, 0, sizeof (*sb));
429 } 432 }
430 return sb; 433 return sb;
431} 434}
432 435
433/* 436/*
434 * Put a sbuf structure to the free list 437 * Put a sbuf structure to the free list
435 */ 438 */
436static void 439static void
437freesb(sbuf_t *sb) 440freesb(sbuf_t *sb)
438{ 441{
439 442
440 (void)memset(sb, ZERO, sizeof (*sb)); 443 (void)memset(sb, ZERO, sizeof (*sb));
441 sb->sb_next = sbfrlst; 444 sb->sb_next = sbfrlst;
442 sbfrlst = sb; 445 sbfrlst = sb;
443} 446}
444 447
445/* 448/*
446 * Read a character and ensure that it is positive (except EOF). 449 * Read a character and ensure that it is positive (except EOF).
447 * Increment line count(s) if necessary. 450 * Increment line count(s) if necessary.
448 */ 451 */
449static int 452static int
450inpc(void) 453inpc(void)
451{ 454{
452 int c; 455 int c;
453 456
454 if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n') 457 if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n')
455 incline(); 458 incline();
456 return c; 459 return c;
457} 460}
458 461
459static int 462static int
460hash(const char *s) 463hash(const char *s)
461{ 464{
462 u_int v; 465 u_int v;
463 const u_char *us; 466 const u_char *us;
464 467
465 v = 0; 468 v = 0;
466 for (us = (const u_char *)s; *us != '\0'; us++) { 469 for (us = (const u_char *)s; *us != '\0'; us++) {
467 v = (v << sizeof (v)) + *us; 470 v = (v << sizeof (v)) + *us;
468 v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); 471 v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
469 } 472 }
470 return v % HSHSIZ1; 473 return v % HSHSIZ1;
471} 474}
472 475
473/* 476/*
474 * Lex has found a letter followed by zero or more letters or digits. 477 * Lex has found a letter followed by zero or more letters or digits.
475 * It looks for a symbol in the symbol table with the same name. This 478 * It looks for a symbol in the symbol table with the same name. This
476 * symbol must either be a keyword or a symbol of the type required by 479 * symbol must either be a keyword or a symbol of the type required by
477 * symtyp (label, member, tag, ...). 480 * symtyp (label, member, tag, ...).
478 * 481 *
479 * If it is a keyword, the token is returned. In some cases it is described 482 * If it is a keyword, the token is returned. In some cases it is described
480 * more deeply by data written to yylval. 483 * more deeply by data written to yylval.
481 * 484 *
482 * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct 485 * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
483 * is stored in yylval. This struct contains the name of the symbol, its 486 * is stored in yylval. This struct contains the name of the symbol, its
484 * length and hash value. If there is already a symbol of the same name 487 * length and hash value. If there is already a symbol of the same name
485 * and type in the symbol table, the sbuf struct also contains a pointer 488 * and type in the symbol table, the sbuf struct also contains a pointer
486 * to the symbol table entry. 489 * to the symbol table entry.
487 */ 490 */
488static int 491static int
489name(void) 492name(void)
490{ 493{
491 char *s; 494 char *s;
492 sbuf_t *sb; 495 sbuf_t *sb;
493 sym_t *sym; 496 sym_t *sym;
494 int tok; 497 int tok;
495 498
496 sb = allocsb(); 499 sb = allocsb();
497 sb->sb_name = yytext; 500 sb->sb_name = yytext;
498 sb->sb_len = yyleng; 501 sb->sb_len = yyleng;
499 sb->sb_hash = hash(yytext); 502 sb->sb_hash = hash(yytext);
500 if ((sym = search(sb)) != NULL && sym->s_keyword) { 503 if ((sym = search(sb)) != NULL && sym->s_keyword) {
501 freesb(sb); 504 freesb(sb);
502 return keyw(sym); 505 return keyw(sym);
503 } 506 }
504 507
505 sb->sb_sym = sym; 508 sb->sb_sym = sym;
506 509
507 if (sym != NULL) { 510 if (sym != NULL) {
508 lint_assert(blklev >= sym->s_blklev); 511 lint_assert(blklev >= sym->s_blklev);
509 sb->sb_name = sym->s_name; 512 sb->sb_name = sym->s_name;
510 sb->sb_len = strlen(sym->s_name); 513 sb->sb_len = strlen(sym->s_name);
511 tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; 514 tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
512 } else { 515 } else {
513 s = getblk(yyleng + 1); 516 s = getblk(yyleng + 1);
514 (void)memcpy(s, yytext, yyleng + 1); 517 (void)memcpy(s, yytext, yyleng + 1);
515 sb->sb_name = s; 518 sb->sb_name = s;
516 sb->sb_len = yyleng; 519 sb->sb_len = yyleng;
517 tok = T_NAME; 520 tok = T_NAME;
518 } 521 }
519 522
520 yylval.y_sb = sb; 523 yylval.y_sb = sb;
521 return tok; 524 return tok;
522} 525}
523 526
524static sym_t * 527static sym_t *
525search(sbuf_t *sb) 528search(sbuf_t *sb)
526{ 529{
527 sym_t *sym; 530 sym_t *sym;
528 531
529 for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) { 532 for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) {
530 if (strcmp(sym->s_name, sb->sb_name) == 0) { 533 if (strcmp(sym->s_name, sb->sb_name) == 0) {
531 if (sym->s_keyword) { 534 if (sym->s_keyword) {
532 struct kwtab *kw = sym->s_keyword; 535 struct kwtab *kw = sym->s_keyword;
533 if (!kw->kw_attr || attron) 536 if (!kw->kw_attr || attron)
534 return sym; 537 return sym;
535 } else if (!attron && sym->s_kind == symtyp) 538 } else if (!attron && sym->s_kind == symtyp)
536 return sym; 539 return sym;
537 } 540 }
538 } 541 }
539 542
540 return NULL; 543 return NULL;
541} 544}
542 545
543static int 546static int
544keyw(sym_t *sym) 547keyw(sym_t *sym)
545{ 548{
546 int t; 549 int t;
547 550
548 if ((t = (int)sym->s_value.v_quad) == T_SCLASS) { 551 if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
549 yylval.y_scl = sym->s_scl; 552 yylval.y_scl = sym->s_scl;
550 } else if (t == T_TYPE || t == T_SOU) { 553 } else if (t == T_TYPE || t == T_SOU) {
551 yylval.y_tspec = sym->s_tspec; 554 yylval.y_tspec = sym->s_tspec;
552 } else if (t == T_QUAL) { 555 } else if (t == T_QUAL) {
553 yylval.y_tqual = sym->s_tqual; 556 yylval.y_tqual = sym->s_tqual;
554 } 557 }
555 return t; 558 return t;
556} 559}
557 560
558/* 561/*
559 * Convert a string representing an integer into internal representation. 562 * Convert a string representing an integer into internal representation.
560 * The value is returned in yylval. icon() (and yylex()) returns T_CON. 563 * The value is returned in yylval. icon() (and yylex()) returns T_CON.
561 */ 564 */
562static int 565static int
563icon(int base) 566icon(int base)
564{ 567{
565 int l_suffix, u_suffix; 568 int l_suffix, u_suffix;
566 int len; 569 int len;
567 const char *cp; 570 const char *cp;
568 char c, *eptr; 571 char c, *eptr;
569 tspec_t typ; 572 tspec_t typ;
570 int ansiu; 573 int ansiu;
571#ifdef TARG_INT128_MAX 574#ifdef TARG_INT128_MAX
572 __uint128_t uq = 0; 575 __uint128_t uq = 0;
573 static tspec_t contypes[2][4] = { 576 static tspec_t contypes[2][4] = {
574 { INT, LONG, QUAD, INT128, }, 577 { INT, LONG, QUAD, INT128, },
575 { UINT, ULONG, UQUAD, UINT128, } 578 { UINT, ULONG, UQUAD, UINT128, }
576 }; 579 };
577#else 580#else
578 uint64_t uq = 0; 581 uint64_t uq = 0;
579 static tspec_t contypes[2][3] = { 582 static tspec_t contypes[2][3] = {
580 { INT, LONG, QUAD, }, 583 { INT, LONG, QUAD, },
581 { UINT, ULONG, UQUAD, } 584 { UINT, ULONG, UQUAD, }
582 }; 585 };
583#endif 586#endif
584 587
585 cp = yytext; 588 cp = yytext;
586 len = yyleng; 589 len = yyleng;
587 590
588 /* skip 0[xX] or 0[bB] */ 591 /* skip 0[xX] or 0[bB] */
589 if (base == 16 || base == 2) { 592 if (base == 16 || base == 2) {
590 cp += 2; 593 cp += 2;
591 len -= 2; 594 len -= 2;
592 } 595 }
593 596
594 /* read suffixes */ 597 /* read suffixes */
595 l_suffix = u_suffix = 0; 598 l_suffix = u_suffix = 0;
596 for ( ; ; ) { 599 for ( ; ; ) {
597 if ((c = cp[len - 1]) == 'l' || c == 'L') { 600 if ((c = cp[len - 1]) == 'l' || c == 'L') {
598 l_suffix++; 601 l_suffix++;
599 } else if (c == 'u' || c == 'U') { 602 } else if (c == 'u' || c == 'U') {
600 u_suffix++; 603 u_suffix++;
601 } else { 604 } else {
602 break; 605 break;
603 } 606 }
604 len--; 607 len--;
605 } 608 }
606 if (l_suffix > 2 || u_suffix > 1) { 609 if (l_suffix > 2 || u_suffix > 1) {
607 /* malformed integer constant */ 610 /* malformed integer constant */
608 warning(251); 611 warning(251);
609 if (l_suffix > 2) 612 if (l_suffix > 2)
610 l_suffix = 2; 613 l_suffix = 2;
611 if (u_suffix > 1) 614 if (u_suffix > 1)
612 u_suffix = 1; 615 u_suffix = 1;
613 } 616 }
614 if (tflag && u_suffix != 0) { 617 if (tflag && u_suffix != 0) {
615 /* suffix U is illegal in traditional C */ 618 /* suffix U is illegal in traditional C */
616 warning(97); 619 warning(97);
617 } 620 }
618 typ = contypes[u_suffix][l_suffix]; 621 typ = contypes[u_suffix][l_suffix];
619 622
620 errno = 0; 623 errno = 0;
621 624
622 uq = strtouq(cp, &eptr, base); 625 uq = strtouq(cp, &eptr, base);
623 lint_assert(eptr == cp + len); 626 lint_assert(eptr == cp + len);
624 if (errno != 0) 627 if (errno != 0)
625 /* integer constant out of range */ 628 /* integer constant out of range */
626 warning(252); 629 warning(252);
627 630
628 /* 631 /*
629 * If the value is too big for the current type, we must choose 632 * If the value is too big for the current type, we must choose
630 * another type. 633 * another type.
631 */ 634 */
632 ansiu = 0; 635 ansiu = 0;
633 switch (typ) { 636 switch (typ) {
634 case INT: 637 case INT:
635 if (uq <= TARG_INT_MAX) { 638 if (uq <= TARG_INT_MAX) {
636 /* ok */ 639 /* ok */
637 } else if (uq <= TARG_UINT_MAX && base != 10) { 640 } else if (uq <= TARG_UINT_MAX && base != 10) {
638 typ = UINT; 641 typ = UINT;
639 } else if (uq <= TARG_LONG_MAX) { 642 } else if (uq <= TARG_LONG_MAX) {
640 typ = LONG; 643 typ = LONG;
641 } else { 644 } else {
642 typ = ULONG; 645 typ = ULONG;
643 if (uq > TARG_ULONG_MAX) { 646 if (uq > TARG_ULONG_MAX) {
644 /* integer constant out of range */ 647 /* integer constant out of range */
645 warning(252); 648 warning(252);
646 } 649 }
647 } 650 }
648 if (typ == UINT || typ == ULONG) { 651 if (typ == UINT || typ == ULONG) {
649 if (tflag) { 652 if (tflag) {
650 typ = LONG; 653 typ = LONG;
651 } else if (!sflag) { 654 } else if (!sflag) {
652 /* 655 /*
653 * Remember that the constant is unsigned 656 * Remember that the constant is unsigned
654 * only in ANSI C 657 * only in ANSI C
655 */ 658 */
656 ansiu = 1; 659 ansiu = 1;
657 } 660 }
658 } 661 }
659 break; 662 break;
660 case UINT: 663 case UINT:
661 if (uq > TARG_UINT_MAX) { 664 if (uq > TARG_UINT_MAX) {
662 typ = ULONG; 665 typ = ULONG;
663 if (uq > TARG_ULONG_MAX) { 666 if (uq > TARG_ULONG_MAX) {
664 /* integer constant out of range */ 667 /* integer constant out of range */
665 warning(252); 668 warning(252);
666 } 669 }
667 } 670 }
668 break; 671 break;
669 case LONG: 672 case LONG:
670 if (uq > TARG_LONG_MAX && !tflag) { 673 if (uq > TARG_LONG_MAX && !tflag) {
671 typ = ULONG; 674 typ = ULONG;
672 if (!sflag) 675 if (!sflag)
673 ansiu = 1; 676 ansiu = 1;
674 if (uq > TARG_ULONG_MAX) { 677 if (uq > TARG_ULONG_MAX) {
675 /* integer constant out of range */ 678 /* integer constant out of range */
676 warning(252); 679 warning(252);
677 } 680 }
678 } 681 }
679 break; 682 break;
680 case ULONG: 683 case ULONG:
681 if (uq > TARG_ULONG_MAX) { 684 if (uq > TARG_ULONG_MAX) {
682 /* integer constant out of range */ 685 /* integer constant out of range */
683 warning(252); 686 warning(252);
684 } 687 }
685 break; 688 break;
686 case QUAD: 689 case QUAD:
687 if (uq > TARG_QUAD_MAX && !tflag) { 690 if (uq > TARG_QUAD_MAX && !tflag) {
688 typ = UQUAD; 691 typ = UQUAD;
689 if (!sflag) 692 if (!sflag)
690 ansiu = 1; 693 ansiu = 1;
691 } 694 }
692 break; 695 break;
693 case UQUAD: 696 case UQUAD:
694 if (uq > TARG_UQUAD_MAX) { 697 if (uq > TARG_UQUAD_MAX) {
695 /* integer constant out of range */ 698 /* integer constant out of range */
696 warning(252); 699 warning(252);
697 } 700 }
698 break; 701 break;
699#ifdef INT128_SIZE 702#ifdef INT128_SIZE
700 case INT128: 703 case INT128:
701#ifdef TARG_INT128_MAX 704#ifdef TARG_INT128_MAX
702 if (uq > TARG_INT128_MAX && !tflag) { 705 if (uq > TARG_INT128_MAX && !tflag) {
703 typ = UINT128; 706 typ = UINT128;
704 if (!sflag) 707 if (!sflag)
705 ansiu = 1; 708 ansiu = 1;
706 } 709 }
707#endif 710#endif
708 break; 711 break;
709 case UINT128: 712 case UINT128:
710#ifdef TARG_INT128_MAX 713#ifdef TARG_INT128_MAX
711 if (uq > TARG_UINT128_MAX) { 714 if (uq > TARG_UINT128_MAX) {
712 /* integer constant out of range */ 715 /* integer constant out of range */
713 warning(252); 716 warning(252);
714 } 717 }
715#endif 718#endif
716 break; 719 break;
717#endif 720#endif
718 /* LINTED206: (enumeration values not handled in switch) */ 721 /* LINTED206: (enumeration values not handled in switch) */
719 case STRUCT: 722 case STRUCT:
720 case VOID: 723 case VOID:
721 case LDOUBLE: 724 case LDOUBLE:
722 case FUNC: 725 case FUNC:
723 case ARRAY: 726 case ARRAY:
724 case PTR: 727 case PTR:
725 case ENUM: 728 case ENUM:
726 case UNION: 729 case UNION:
727 case SIGNED: 730 case SIGNED:
728 case NOTSPEC: 731 case NOTSPEC:
729 case DOUBLE: 732 case DOUBLE:
730 case FLOAT: 733 case FLOAT:
731 case USHORT: 734 case USHORT:
732 case SHORT: 735 case SHORT:
733 case UCHAR: 736 case UCHAR:
734 case SCHAR: 737 case SCHAR:
735 case CHAR: 738 case CHAR:
736 case BOOL: 739 case BOOL:
737 case UNSIGN: 740 case UNSIGN:
738 case FCOMPLEX: 741 case FCOMPLEX:
739 case DCOMPLEX: 742 case DCOMPLEX:
740 case LCOMPLEX: 743 case LCOMPLEX:
741 case COMPLEX: 744 case COMPLEX:
742 break; 745 break;
743 } 746 }
744 747
745 uq = (uint64_t)xsign((int64_t)uq, typ, -1); 748 uq = (uint64_t)xsign((int64_t)uq, typ, -1);
746 749
747 (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; 750 (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
748 yylval.y_val->v_ansiu = ansiu; 751 yylval.y_val->v_ansiu = ansiu;
749 yylval.y_val->v_quad = (int64_t)uq; 752 yylval.y_val->v_quad = (int64_t)uq;
750 753
751 return T_CON; 754 return T_CON;
752} 755}
753 756
754/* 757/*
755 * Returns 1 if t is a signed type and the value is negative. 758 * Returns 1 if t is a signed type and the value is negative.
756 * 759 *
757 * len is the number of significant bits. If len is -1, len is set 760 * len is the number of significant bits. If len is -1, len is set
758 * to the width of type t. 761 * to the width of type t.
759 */ 762 */
760int 763int
761sign(int64_t q, tspec_t t, int len) 764sign(int64_t q, tspec_t t, int len)
762{ 765{
763 766
764 if (t == PTR || tspec_is_uint(t)) 767 if (t == PTR || tspec_is_uint(t))
765 return 0; 768 return 0;
766 return msb(q, t, len); 769 return msb(q, t, len);
767} 770}
768 771
769int 772int
770msb(int64_t q, tspec_t t, int len) 773msb(int64_t q, tspec_t t, int len)
771{ 774{
772 775
773 if (len <= 0) 776 if (len <= 0)
774 len = size(t); 777 len = size(t);
775 return (q & qbmasks[len - 1]) != 0; 778 return (q & qbmasks[len - 1]) != 0;
776} 779}
777 780
778/* 781/*
779 * Extends the sign of q. 782 * Extends the sign of q.
780 */ 783 */
781int64_t 784int64_t
782xsign(int64_t q, tspec_t t, int len) 785xsign(int64_t q, tspec_t t, int len)
783{ 786{
784 787
785 if (len <= 0) 788 if (len <= 0)
786 len = size(t); 789 len = size(t);
787 790
788 if (t == PTR || tspec_is_uint(t) || !sign(q, t, len)) { 791 if (t == PTR || tspec_is_uint(t) || !sign(q, t, len)) {
789 q &= qlmasks[len]; 792 q &= qlmasks[len];
790 } else { 793 } else {
791 q |= qumasks[len]; 794 q |= qumasks[len];
792 } 795 }
793 return q; 796 return q;
794} 797}
795 798
796/* 799/*
797 * Convert a string representing a floating point value into its integral 800 * Convert a string representing a floating point value into its integral
798 * representation. Type and value are returned in yylval. fcon() 801 * representation. Type and value are returned in yylval. fcon()
799 * (and yylex()) returns T_CON. 802 * (and yylex()) returns T_CON.
800 * XXX Currently it is not possible to convert constants of type 803 * XXX Currently it is not possible to convert constants of type
801 * long double which are greater than DBL_MAX. 804 * long double which are greater than DBL_MAX.
802 */ 805 */
803static int 806static int
804fcon(void) 807fcon(void)
805{ 808{
806 const char *cp; 809 const char *cp;
807 int len; 810 int len;
808 tspec_t typ; 811 tspec_t typ;
809 char c, *eptr; 812 char c, *eptr;
810 double d; 813 double d;
811 float f = 0; 814 float f = 0;
812 815
813 cp = yytext; 816 cp = yytext;
814 len = yyleng; 817 len = yyleng;
815 818
816 if (cp[len - 1] == 'i') { 819 if (cp[len - 1] == 'i') {
817 /* imaginary, do nothing for now */ 820 /* imaginary, do nothing for now */
818 len--; 821 len--;
819 } 822 }
820 if ((c = cp[len - 1]) == 'f' || c == 'F') { 823 if ((c = cp[len - 1]) == 'f' || c == 'F') {
821 typ = FLOAT; 824 typ = FLOAT;
822 len--; 825 len--;
823 } else if (c == 'l' || c == 'L') { 826 } else if (c == 'l' || c == 'L') {
824 typ = LDOUBLE; 827 typ = LDOUBLE;
825 len--; 828 len--;
826 } else { 829 } else {
827 if (c == 'd' || c == 'D') 830 if (c == 'd' || c == 'D')
828 len--; 831 len--;
829 typ = DOUBLE; 832 typ = DOUBLE;
830 } 833 }
831 834
832 if (tflag && typ != DOUBLE) { 835 if (tflag && typ != DOUBLE) {
833 /* suffixes F and L are illegal in traditional C */ 836 /* suffixes F and L are illegal in traditional C */
834 warning(98); 837 warning(98);
835 } 838 }
836 839
837 errno = 0; 840 errno = 0;
838 d = strtod(cp, &eptr); 841 d = strtod(cp, &eptr);
839 if (eptr != cp + len) { 842 if (eptr != cp + len) {
840 switch (*eptr) { 843 switch (*eptr) {
841 /* 844 /*
842 * XXX: non-native non-current strtod() may not handle hex 845 * XXX: non-native non-current strtod() may not handle hex
843 * floats, ignore the rest if we find traces of hex float 846 * floats, ignore the rest if we find traces of hex float
844 * syntax... 847 * syntax...
845 */ 848 */
846 case 'p': 849 case 'p':
847 case 'P': 850 case 'P':
848 case 'x': 851 case 'x':
849 case 'X': 852 case 'X':
850 d = 0; 853 d = 0;
851 errno = 0; 854 errno = 0;
852 break; 855 break;
853 default: 856 default:
854 LERROR("fcon(%s->%s)", cp, eptr); 857 LERROR("fcon(%s->%s)", cp, eptr);
855 } 858 }
856 } 859 }
857 if (errno != 0) 860 if (errno != 0)
858 /* floating-point constant out of range */ 861 /* floating-point constant out of range */
859 warning(248); 862 warning(248);
860 863
861 if (typ == FLOAT) { 864 if (typ == FLOAT) {
862 f = (float)d; 865 f = (float)d;
863 if (!finite(f)) { 866 if (!finite(f)) {
864 /* floating-point constant out of range */ 867 /* floating-point constant out of range */
865 warning(248); 868 warning(248);
866 f = f > 0 ? FLT_MAX : -FLT_MAX; 869 f = f > 0 ? FLT_MAX : -FLT_MAX;
867 } 870 }
868 } 871 }
869 872
870 (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; 873 (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ;
871 if (typ == FLOAT) { 874 if (typ == FLOAT) {
872 yylval.y_val->v_ldbl = f; 875 yylval.y_val->v_ldbl = f;
873 } else { 876 } else {
874 yylval.y_val->v_ldbl = d; 877 yylval.y_val->v_ldbl = d;
875 } 878 }
876 879
877 return T_CON; 880 return T_CON;
878} 881}
879 882
880static int 883static int
881operator(int t, op_t o) 884operator(int t, op_t o)
882{ 885{
883 886
884 yylval.y_op = o; 887 yylval.y_op = o;
885 return t; 888 return t;
886} 889}
887 890
888/* 891/*
889 * Called if lex found a leading \'. 892 * Called if lex found a leading \'.
890 */ 893 */
891static int 894static int
892ccon(void) 895ccon(void)
893{ 896{
894 size_t n; 897 size_t n;
895 int val, c; 898 int val, c;
896 char cv; 899 char cv;
897 900
898 n = 0; 901 n = 0;
899 val = 0; 902 val = 0;
900 while ((c = getescc('\'')) >= 0) { 903 while ((c = getescc('\'')) >= 0) {
901 val = (val << CHAR_BIT) + c; 904 val = (val << CHAR_BIT) + c;
902 n++; 905 n++;
903 } 906 }
904 if (c == -2) { 907 if (c == -2) {
905 /* unterminated character constant */ 908 /* unterminated character constant */
906 error(253); 909 error(253);
907 } else { 910 } else {
908 if (n > sizeof (int) || (n > 1 && (pflag || hflag))) { 911 if (n > sizeof (int) || (n > 1 && (pflag || hflag))) {
909 /* too many characters in character constant */ 912 /* too many characters in character constant */
910 error(71); 913 error(71);
911 } else if (n > 1) { 914 } else if (n > 1) {
912 /* multi-character character constant */ 915 /* multi-character character constant */
913 warning(294); 916 warning(294);
914 } else if (n == 0) { 917 } else if (n == 0) {
915 /* empty character constant */ 918 /* empty character constant */
916 error(73); 919 error(73);
917 } 920 }
918 } 921 }
919 if (n == 1) { 922 if (n == 1) {
920 cv = (char)val; 923 cv = (char)val;
921 val = cv; 924 val = cv;
922 } 925 }
923 926
924 yylval.y_val = xcalloc(1, sizeof (val_t)); 927 yylval.y_val = xcalloc(1, sizeof (val_t));
925 yylval.y_val->v_tspec = INT; 928 yylval.y_val->v_tspec = INT;
926 yylval.y_val->v_quad = val; 929 yylval.y_val->v_quad = val;
927 930
928 return T_CON; 931 return T_CON;
929} 932}
930 933
931/* 934/*
932 * Called if lex found a leading L\' 935 * Called if lex found a leading L\'
933 */ 936 */
934static int 937static int
935wccon(void) 938wccon(void)
936{ 939{
937 static char buf[MB_LEN_MAX + 1]; 940 static char buf[MB_LEN_MAX + 1];
938 size_t i; 941 size_t i;
939 int c; 942 int c;
940 wchar_t wc; 943 wchar_t wc;
941 944
942 i = 0; 945 i = 0;
943 while ((c = getescc('\'')) >= 0) { 946 while ((c = getescc('\'')) >= 0) {
944 if (i < MB_CUR_MAX) 947 if (i < MB_CUR_MAX)
945 buf[i] = (char)c; 948 buf[i] = (char)c;
946 i++; 949 i++;
947 } 950 }
948 951
949 wc = 0; 952 wc = 0;
950 953
951 if (c == -2) { 954 if (c == -2) {
952 /* unterminated character constant */ 955 /* unterminated character constant */
953 error(253); 956 error(253);
954 } else if (c == 0) { 957 } else if (c == 0) {
955 /* empty character constant */ 958 /* empty character constant */
956 error(73); 959 error(73);
957 } else { 960 } else {
958 if (i > MB_CUR_MAX) { 961 if (i > MB_CUR_MAX) {
959 i = MB_CUR_MAX; 962 i = MB_CUR_MAX;
960 /* too many characters in character constant */ 963 /* too many characters in character constant */
961 error(71); 964 error(71);
962 } else { 965 } else {
963 buf[i] = '\0'; 966 buf[i] = '\0';
964 (void)mbtowc(NULL, NULL, 0); 967 (void)mbtowc(NULL, NULL, 0);
965 if (mbtowc(&wc, buf, MB_CUR_MAX) < 0) 968 if (mbtowc(&wc, buf, MB_CUR_MAX) < 0)
966 /* invalid multibyte character */ 969 /* invalid multibyte character */
967 error(291); 970 error(291);
968 } 971 }
969 } 972 }
970 973
971 yylval.y_val = xcalloc(1, sizeof (val_t)); 974 yylval.y_val = xcalloc(1, sizeof (val_t));
972 yylval.y_val->v_tspec = WCHAR; 975 yylval.y_val->v_tspec = WCHAR;
973 yylval.y_val->v_quad = wc; 976 yylval.y_val->v_quad = wc;
974 977
975 return T_CON; 978 return T_CON;
976} 979}
977 980
978/* 981/*
979 * Read a character which is part of a character constant or of a string 982 * Read a character which is part of a character constant or of a string
980 * and handle escapes. 983 * and handle escapes.
981 * 984 *
982 * The Argument is the character which delimits the character constant or 985 * The Argument is the character which delimits the character constant or
983 * string. 986 * string.
984 * 987 *
985 * Returns -1 if the end of the character constant or string is reached, 988 * Returns -1 if the end of the character constant or string is reached,
986 * -2 if the EOF is reached, and the character otherwise. 989 * -2 if the EOF is reached, and the character otherwise.
987 */ 990 */
988static int 991static int
989getescc(int d) 992getescc(int d)
990{ 993{
991 static int pbc = -1; 994 static int pbc = -1;
992 int n, c, v; 995 int n, c, v;
993 996
994 if (pbc == -1) { 997 if (pbc == -1) {
995 c = inpc(); 998 c = inpc();
996 } else { 999 } else {
997 c = pbc; 1000 c = pbc;
998 pbc = -1; 1001 pbc = -1;
999 } 1002 }
1000 if (c == d) 1003 if (c == d)
1001 return -1; 1004 return -1;
1002 switch (c) { 1005 switch (c) {
1003 case '\n': 1006 case '\n':
1004 if (tflag) { 1007 if (tflag) {
1005 /* newline in string or char constant */ 1008 /* newline in string or char constant */
1006 error(254); 1009 error(254);
1007 return -2; 1010 return -2;
1008 } 1011 }
1009 return c; 1012 return c;
1010 case EOF: 1013 case EOF:
1011 return -2; 1014 return -2;
1012 case '\\': 1015 case '\\':
1013 switch (c = inpc()) { 1016 switch (c = inpc()) {
1014 case '"': 1017 case '"':
1015 if (tflag && d == '\'') 1018 if (tflag && d == '\'')
1016 /* \" inside character constants undef... */ 1019 /* \" inside character constants undef... */
1017 warning(262); 1020 warning(262);
1018 return '"'; 1021 return '"';
1019 case '\'': 1022 case '\'':
1020 return '\''; 1023 return '\'';
1021 case '?': 1024 case '?':
1022 if (tflag) 1025 if (tflag)
1023 /* \? undefined in traditional C */ 1026 /* \? undefined in traditional C */
1024 warning(263); 1027 warning(263);
1025 return '?'; 1028 return '?';
1026 case '\\': 1029 case '\\':
1027 return '\\'; 1030 return '\\';
1028 case 'a': 1031 case 'a':
1029 if (tflag) 1032 if (tflag)
1030 /* \a undefined in traditional C */ 1033 /* \a undefined in traditional C */
1031 warning(81); 1034 warning(81);
1032 return '\a'; 1035 return '\a';
1033 case 'b': 1036 case 'b':
1034 return '\b'; 1037 return '\b';
1035 case 'f': 1038 case 'f':
1036 return '\f'; 1039 return '\f';
1037 case 'n': 1040 case 'n':
1038 return '\n'; 1041 return '\n';
1039 case 'r': 1042 case 'r':
1040 return '\r'; 1043 return '\r';
1041 case 't': 1044 case 't':
1042 return '\t'; 1045 return '\t';
1043 case 'v': 1046 case 'v':
1044 if (tflag) 1047 if (tflag)
1045 /* \v undefined in traditional C */ 1048 /* \v undefined in traditional C */
1046 warning(264); 1049 warning(264);
1047 return '\v'; 1050 return '\v';
1048 case '8': case '9': 1051 case '8': case '9':
1049 /* bad octal digit %c */ 1052 /* bad octal digit %c */
1050 warning(77, c); 1053 warning(77, c);
1051 /* FALLTHROUGH */ 1054 /* FALLTHROUGH */
1052 case '0': case '1': case '2': case '3': 1055 case '0': case '1': case '2': case '3':
1053 case '4': case '5': case '6': case '7': 1056 case '4': case '5': case '6': case '7':
1054 n = 3; 1057 n = 3;
1055 v = 0; 1058 v = 0;
1056 do { 1059 do {
1057 v = (v << 3) + (c - '0'); 1060 v = (v << 3) + (c - '0');
1058 c = inpc(); 1061 c = inpc();
1059 } while (--n && isdigit(c) && (tflag || c <= '7')); 1062 } while (--n && isdigit(c) && (tflag || c <= '7'));
1060 if (tflag && n > 0 && isdigit(c)) 1063 if (tflag && n > 0 && isdigit(c))
1061 /* bad octal digit %c */ 1064 /* bad octal digit %c */
1062 warning(77, c); 1065 warning(77, c);
1063 pbc = c; 1066 pbc = c;
1064 if (v > TARG_UCHAR_MAX) { 1067 if (v > TARG_UCHAR_MAX) {
1065 /* character escape does not fit in character */ 1068 /* character escape does not fit in character */
1066 warning(76); 1069 warning(76);
1067 v &= CHAR_MASK; 1070 v &= CHAR_MASK;
1068 } 1071 }
1069 return v; 1072 return v;
1070 case 'x': 1073 case 'x':
1071 if (tflag) 1074 if (tflag)
1072 /* \x undefined in traditional C */ 1075 /* \x undefined in traditional C */
1073 warning(82); 1076 warning(82);
1074 v = 0; 1077 v = 0;
1075 n = 0; 1078 n = 0;
1076 while ((c = inpc()) >= 0 && isxdigit(c)) { 1079 while ((c = inpc()) >= 0 && isxdigit(c)) {
1077 c = isdigit(c) ? 1080 c = isdigit(c) ?
1078 c - '0' : toupper(c) - 'A' + 10; 1081 c - '0' : toupper(c) - 'A' + 10;
1079 v = (v << 4) + c; 1082 v = (v << 4) + c;
1080 if (n >= 0) { 1083 if (n >= 0) {
1081 if ((v & ~CHAR_MASK) != 0) { 1084 if ((v & ~CHAR_MASK) != 0) {
1082 /* overflow in hex escape */ 1085 /* overflow in hex escape */
1083 warning(75); 1086 warning(75);
1084 n = -1; 1087 n = -1;
1085 } else { 1088 } else {
1086 n++; 1089 n++;
1087 } 1090 }
1088 } 1091 }
1089 } 1092 }
1090 pbc = c; 1093 pbc = c;
1091 if (n == 0) { 1094 if (n == 0) {
1092 /* no hex digits follow \x */ 1095 /* no hex digits follow \x */
1093 error(74); 1096 error(74);
1094 } if (n == -1) { 1097 } if (n == -1) {
1095 v &= CHAR_MASK; 1098 v &= CHAR_MASK;
1096 } 1099 }
1097 return v; 1100 return v;
1098 case '\n': 1101 case '\n':
1099 return getescc(d); 1102 return getescc(d);
1100 case EOF: 1103 case EOF:
1101 return -2; 1104 return -2;
1102 default: 1105 default:
1103 if (isprint(c)) { 1106 if (isprint(c)) {
1104 /* dubious escape \%c */ 1107 /* dubious escape \%c */
1105 warning(79, c); 1108 warning(79, c);
1106 } else { 1109 } else {
1107 /* dubious escape \%o */ 1110 /* dubious escape \%o */
1108 warning(80, c); 1111 warning(80, c);
1109 } 1112 }
1110 } 1113 }
1111 } 1114 }
1112 return c; 1115 return c;
1113} 1116}
1114 1117
1115/* 1118/*
1116 * Called for preprocessor directives. Currently implemented are: 1119 * Called for preprocessor directives. Currently implemented are:
1117 * # lineno 1120 * # lineno
1118 * # lineno "filename" 1121 * # lineno "filename"
1119 */ 1122 */
1120static void 1123static void
1121directive(void) 1124directive(void)
1122{ 1125{
1123 const char *cp, *fn; 1126 const char *cp, *fn;
1124 char c, *eptr; 1127 char c, *eptr;
1125 size_t fnl; 1128 size_t fnl;
1126 long ln; 1129 long ln;
1127 static int first = 1; 1130 static int first = 1;
1128 1131
1129 /* Go to first non-whitespace after # */ 1132 /* Go to first non-whitespace after # */
1130 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) 1133 for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
1131 continue; 1134 continue;
1132 1135
1133 if (!isdigit((unsigned char)c)) { 1136 if (!isdigit((unsigned char)c)) {
1134 if (strncmp(cp, "pragma", 6) == 0 1137 if (strncmp(cp, "pragma", 6) == 0
1135 && isspace((unsigned char)cp[6])) 1138 && isspace((unsigned char)cp[6]))
1136 return; 1139 return;
1137 error: 1140 error:
1138 /* undefined or invalid # directive */ 1141 /* undefined or invalid # directive */
1139 warning(255); 1142 warning(255);
1140 return; 1143 return;
1141 } 1144 }
1142 ln = strtol(--cp, &eptr, 10); 1145 ln = strtol(--cp, &eptr, 10);
1143 if (cp == eptr) 1146 if (cp == eptr)
1144 goto error; 1147 goto error;
1145 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') 1148 if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
1146 goto error; 1149 goto error;
1147 while ((c = *cp++) == ' ' || c == '\t') 1150 while ((c = *cp++) == ' ' || c == '\t')
1148 continue; 1151 continue;
1149 if (c != '\0') { 1152 if (c != '\0') {
1150 if (c != '"') 1153 if (c != '"')
1151 goto error; 1154 goto error;
1152 fn = cp; 1155 fn = cp;
1153 while ((c = *cp) != '"' && c != '\0') 1156 while ((c = *cp) != '"' && c != '\0')
1154 cp++; 1157 cp++;
1155 if (c != '"') 1158 if (c != '"')
1156 goto error; 1159 goto error;
1157 if ((fnl = cp++ - fn) > PATH_MAX) 1160 if ((fnl = cp++ - fn) > PATH_MAX)
1158 goto error; 1161 goto error;
1159 while ((c = *cp++) == ' ' || c == '\t') 1162 while ((c = *cp++) == ' ' || c == '\t')
1160 continue; 1163 continue;
1161#if 0 1164#if 0
1162 if (c != '\0') 1165 if (c != '\0')
1163 warning("extra character(s) after directive"); 1166 warning("extra character(s) after directive");
1164#endif 1167#endif
1165 1168
1166 /* empty string means stdin */ 1169 /* empty string means stdin */
1167 if (fnl == 0) { 1170 if (fnl == 0) {
1168 fn = "{standard input}"; 1171 fn = "{standard input}";
1169 fnl = 16; /* strlen (fn) */ 1172 fnl = 16; /* strlen (fn) */
1170 } 1173 }
1171 curr_pos.p_file = fnnalloc(fn, fnl); 1174 curr_pos.p_file = fnnalloc(fn, fnl);
1172 /* 1175 /*
1173 * If this is the first directive, the name is the name 1176 * If this is the first directive, the name is the name
1174 * of the C source file as specified at the command line. 1177 * of the C source file as specified at the command line.
1175 * It is written to the output file. 1178 * It is written to the output file.
1176 */ 1179 */