| @@ -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) */ |
55 | pos_t curr_pos = { 1, "", 0 }; | | 55 | pos_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 | */ |
61 | pos_t csrc_pos = { 1, "", 0 }; | | 61 | pos_t csrc_pos = { 1, "", 0 }; |
62 | | | 62 | |
63 | /* Are we parsing a gcc attribute? */ | | 63 | /* Are we parsing a gcc attribute? */ |
64 | int attron; | | 64 | int attron; |
65 | | | 65 | |
66 | static void incline(void); | | 66 | static void incline(void); |
67 | static void badchar(int); | | 67 | static void badchar(int); |
68 | static sbuf_t *allocsb(void); | | 68 | static sbuf_t *allocsb(void); |
69 | static void freesb(sbuf_t *); | | 69 | static void freesb(sbuf_t *); |
70 | static int inpc(void); | | 70 | static int inpc(void); |
71 | static int hash(const char *); | | 71 | static int hash(const char *); |
72 | static sym_t *search(sbuf_t *); | | 72 | static sym_t *search(sbuf_t *); |
73 | static int name(void); | | 73 | static int name(void); |
74 | static int keyw(sym_t *); | | 74 | static int keyw(sym_t *); |
75 | static int icon(int); | | 75 | static int icon(int); |
76 | static int fcon(void); | | 76 | static int fcon(void); |
77 | static int operator(int, op_t); | | 77 | static int operator(int, op_t); |
78 | static int ccon(void); | | 78 | static int ccon(void); |
79 | static int wccon(void); | | 79 | static int wccon(void); |
80 | static int getescc(int); | | 80 | static int getescc(int); |
81 | static void directive(void); | | 81 | static void directive(void); |
82 | static void comment(void); | | 82 | static void comment(void); |
83 | static void slashslashcomment(void); | | 83 | static void slashslashcomment(void); |
84 | static int string(void); | | 84 | static int string(void); |
85 | static int wcstrg(void); | | 85 | static int wcstrg(void); |
86 | | | 86 | |
87 | %} | | 87 | %} |
88 | | | 88 | |
89 | | | 89 | |
90 | L [_A-Za-z] | | 90 | L [_A-Za-z] |
91 | D [0-9] | | 91 | D [0-9] |
92 | NZD [1-9] | | 92 | NZD [1-9] |
93 | BD [0-1] | | 93 | BD [0-1] |
94 | OD [0-7] | | 94 | OD [0-7] |
95 | HD [0-9A-Fa-f] | | 95 | HD [0-9A-Fa-f] |
96 | EX ([eE][+-]?[0-9]+) | | 96 | EX ([eE][+-]?[0-9]+) |
97 | HX (p[+-]?[0-9A-Fa-f]+) | | 97 | HX (p[+-]?[0-9A-Fa-f]+) |
98 | TL ([fFlL]?[i]?) | | 98 | TL ([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(); |
105 | 0[bB]{BD}+[lLuU]* return icon(2); | | 105 | 0[bB]{BD}+[lLuU]* return icon(2); |
106 | 0{OD}*[lLuU]* return icon(8); | | 106 | 0{OD}*[lLuU]* return icon(8); |
107 | {NZD}{D}*[lLuU]* return icon(10); | | 107 | {NZD}{D}*[lLuU]* return icon(10); |
108 | 0[xX]{HD}+[lLuU]* return icon(16); | | 108 | 0[xX]{HD}+[lLuU]* return icon(16); |
109 | {D}+\.{D}*{EX}?{TL} | | | 109 | {D}+\.{D}*{EX}?{TL} | |
110 | {D}+{EX}{TL} | | | 110 | {D}+{EX}{TL} | |
111 | 0[xX]{HD}+\.{HD}*{HX}{TL} | | | 111 | 0[xX]{HD}+\.{HD}*{HX}{TL} | |
112 | 0[xX]{HD}+{HX}{TL} | | | 112 | 0[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 | |
173 | static void | | 173 | static void |
174 | incline(void) | | 174 | incline(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 | |
184 | static void | | 187 | static void |
185 | badchar(int c) | | 188 | badchar(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 | */ |
196 | static struct kwtab { | | 199 | static 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 */ |
311 | static sym_t *symtab[HSHSIZ1]; | | 314 | static 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 */ |
314 | uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; | | 317 | uint64_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 */ |
317 | uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; | | 320 | uint64_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 */ |
320 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; | | 323 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; |
321 | | | 324 | |
322 | /* free list for sbuf structures */ | | 325 | /* free list for sbuf structures */ |
323 | static sbuf_t *sbfrlst; | | 326 | static sbuf_t *sbfrlst; |
324 | | | 327 | |
325 | /* Typ of next expected symbol */ | | 328 | /* Typ of next expected symbol */ |
326 | symt_t symtyp; | | 329 | symt_t symtyp; |
327 | | | 330 | |
328 | | | 331 | |
329 | static void | | 332 | static void |
330 | add_keyword(struct kwtab *kw, int deco) | | 333 | add_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 | */ |
381 | void | | 384 | void |
382 | initscan(void) | | 385 | initscan(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 | */ |
414 | static sbuf_t * | | 417 | static sbuf_t * |
415 | allocsb(void) | | 418 | allocsb(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 | */ |
436 | static void | | 439 | static void |
437 | freesb(sbuf_t *sb) | | 440 | freesb(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 | */ |
449 | static int | | 452 | static int |
450 | inpc(void) | | 453 | inpc(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 | |
459 | static int | | 462 | static int |
460 | hash(const char *s) | | 463 | hash(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 | */ |
488 | static int | | 491 | static int |
489 | name(void) | | 492 | name(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 | |
524 | static sym_t * | | 527 | static sym_t * |
525 | search(sbuf_t *sb) | | 528 | search(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 | |
543 | static int | | 546 | static int |
544 | keyw(sym_t *sym) | | 547 | keyw(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 | */ |
562 | static int | | 565 | static int |
563 | icon(int base) | | 566 | icon(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 | */ |
760 | int | | 763 | int |
761 | sign(int64_t q, tspec_t t, int len) | | 764 | sign(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 | |
769 | int | | 772 | int |
770 | msb(int64_t q, tspec_t t, int len) | | 773 | msb(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 | */ |
781 | int64_t | | 784 | int64_t |
782 | xsign(int64_t q, tspec_t t, int len) | | 785 | xsign(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 | */ |
803 | static int | | 806 | static int |
804 | fcon(void) | | 807 | fcon(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 | |
880 | static int | | 883 | static int |
881 | operator(int t, op_t o) | | 884 | operator(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 | */ |
891 | static int | | 894 | static int |
892 | ccon(void) | | 895 | ccon(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 | */ |
934 | static int | | 937 | static int |
935 | wccon(void) | | 938 | wccon(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 | */ |
988 | static int | | 991 | static int |
989 | getescc(int d) | | 992 | getescc(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 | */ |
1120 | static void | | 1123 | static void |
1121 | directive(void) | | 1124 | directive(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 | */ |