5 static int yywrap(void) {
10 /* cheesy dynamic string stuff */
11 static int stringtype;
13 static size_t stringlen;
15 static int stringcode;
17 /* append some bytes to the string */
18 static void morestring(const char *ptr, size_t len) {
19 if(len > SIZE_MAX - stringlen)
20 fatal(0, "string too long");
21 string = xrealloc_noptr(string, stringlen + len);
22 memcpy(string + stringlen, ptr, len);
26 static void newstring(const char *ptr, size_t len) {
32 /* validate a UCN - return 1 if valid, 0 if not, and report the error.
33 * Assumes yylloc set. */
34 static int ucnvalid(const char *s) {
35 /* 6.4.3 range constraints for UCNs */
39 u = strtoul(s + 2, 0, 16);
41 inputerror(&yylloc, "cannot convert UCN '%s'", yytext);
50 || (u >= 0xD800 && u <= 0xDFFF)) {
51 inputerror(&yylloc, "illegal UCN escape '%s'", yytext);
59 static inline void loc(void) {
70 %x CPP CPPSKIP LITERAL IDENT
73 UCN \\(u{HEXDIGIT}{4}|U{HEXDIGIT}{8})
74 BADUCN \\(u.{1,4}|U.{1,8})
76 IDND ([a-zA-Z_]|{UCN})
81 ^#{WS}* { BEGIN(CPP); }
85 /* collect line number, crapping out if we can't represent it */
87 l = strtol(yytext, 0, 10);
89 fatal(errno, "cannot convert line number '%s'", yytext);
91 fatal(0, "line number '%s' is too big", yytext);
94 <CPP,CPPSKIP>{WS}+ { }
96 /* collect filename */
98 stringtype = yytext[0];
103 <CPP,CPPSKIP>\n { BEGIN(INITIAL); }
107 fatal(0, "cannot count beyond line %d", INT_MAX);
113 stringtype = yytext[0];
114 stringcode = yytext[0] == '"' ? STRINGLIT : CHARLIT;
121 stringtype = yytext[1];
122 stringcode = yytext[1] == '"' ? WSTRINGLIT : WCHARLIT;
128 <LITERAL>([^\'\"\\\n]|\\[\'\"\?\\abtnvfr])+ {
129 morestring(yytext, yyleng);
131 <LITERAL>\\[0-7]{1,3} {
132 /* 6.4.4.4 escapes must fit in an unsigned char */
136 n = strtoul(yytext + 1, 0, 8);
138 inputerror(&yylloc, "cannot convert octal escape sequence '%s'", yytext);
139 else if(n > P_UCHAR_MAX)
140 inputerror(&yylloc, "octal escape sequence '%s' out of range", yytext);
141 morestring(yytext, yyleng);
143 <LITERAL>\\x[0-9a-fA-F]+ {
144 /* 6.4.4.4 escapes must fit in an unsigned char */
148 n = strtoul(yytext + 2, 0, 16);
150 inputerror(&yylloc, "cannot convert hexadecimal escape sequence '%s'",
152 else if(n > P_UCHAR_MAX)
153 inputerror(&yylloc, "hexadecimal escape sequence '%s' out of range",
155 morestring(yytext, yyleng);
158 inputerror(&yylloc, "invalid hexadecimal escape sequence '%s'", yytext);
159 morestring(yytext, yyleng);
163 morestring(yytext, yyleng);
166 inputerror(&yylloc, "invalid UCN '%s'", yytext);
167 morestring(yytext, yyleng);
170 if(yytext[0] == stringtype) {
178 /* XXX support strings with embedded 0s */
179 yylval.s = xstrndup(string, stringlen);
183 morestring(yytext, 1);
186 inputerror(&yylloc, "invalid escape sequence '%s'", yytext);
187 morestring(yytext, yyleng);
190 inputerror(&yylloc, "unterminated literal");
194 inputerror(&yylloc, "unterminated literal");
198 \.?{DIGIT}({DIGIT}|{IDND}|[eEpP][+\-]|\.)* {
199 yylval.s = xstrndup(yytext, yyleng);
204 -\> { loc(); return yylval.i = MEMBER; }
205 \+\+ { loc(); return yylval.i = INCR; }
206 -- { loc(); return yylval.i = DECR; }
207 \<\< { loc(); return yylval.i = SL; }
208 \>\> { loc(); return yylval.i = SR; }
209 \<= { loc(); return yylval.i = LE; }
210 \>= { loc(); return yylval.i = GE; }
211 == { loc(); return yylval.i = EQ; }
212 != { loc(); return yylval.i = NE; }
213 && { loc(); return yylval.i = AND; }
214 \|\| { loc(); return yylval.i = OR; }
215 \.\.\. { loc(); return yylval.i = VARARG; }
216 \*= { loc(); return yylval.i = MULEQ; }
217 \/= { loc(); return yylval.i = DIVEQ; }
218 %= { loc(); return yylval.i = MODEQ; }
219 \+= { loc(); return yylval.i = ADDEQ; }
220 -= { loc(); return yylval.i = SUBEQ; }
221 \<\<= { loc(); return yylval.i = SLEQ; }
222 \>\>= { loc(); return yylval.i = SREQ; }
223 &= { loc(); return yylval.i = ANDEQ; }
224 \^= { loc(); return yylval.i = XOREQ; }
225 \|= { loc(); return yylval.i = OREQ; }
226 \<: { loc(); return yylval.i = '['; }
227 :\> { loc(); return yylval.i = ']'; }
228 \<% { loc(); return yylval.i = '{'; }
229 %\> { loc(); return yylval.i = '}'; }
230 %: { loc(); return yylval.i = '#'; }
232 auto { yylval.u = SCS_AUTO; loc(); return AUTO; }
233 break { loc(); return BREAK; }
234 case { loc(); return CASE; }
235 char { yylval.u = TS_CHAR; loc(); return CHAR; }
236 const|__const|__const__ { yylval.u = TQ_CONST; loc(); return CONST; }
237 continue { loc(); return CONTINUE; }
238 default { loc(); return DEFAULT; }
239 do { loc(); return DO; }
240 double { yylval.u = TS_DOUBLE; loc(); return DOUBLE; }
241 else { loc(); return ELSE; }
242 enum { loc(); return ENUM; }
243 extern { yylval.u = SCS_EXTERN; loc(); return EXTERN; }
244 float { yylval.u = TS_FLOAT; loc(); return FLOAT; }
245 for { loc(); return FOR; }
246 goto { loc(); return GOTO; }
247 if { loc(); return IF; }
248 inline|__inline|__inline__ { yylval.u = FS_INLINE; loc(); return INLINE; }
249 int { yylval.u = TS_INT; loc(); return INT; }
250 long { yylval.u = TS_LONG; loc(); return LONG; }
251 register { yylval.u = SCS_REGISTER; loc(); return REGISTER; }
252 restrict|__restrict|__restrict__ { yylval.u = TQ_RESTRICT; loc(); return RESTRICT; }
253 return { loc(); return RETURN; }
254 short { yylval.u = TS_SHORT; loc(); return SHORT; }
255 signed { yylval.u = TS_SIGNED; loc(); return SIGNED; }
256 sizeof { loc(); return SIZEOF; }
257 static { yylval.u = SCS_STATIC; loc(); return STATIC; }
258 struct { yylval.u = TS_STRUCT; loc(); return STRUCT; }
259 switch { loc(); return SWITCH; }
260 typedef { yylval.u = SCS_TYPEDEF; loc(); return TYPEDEF; }
261 union { yylval.u = TS_UNION; loc(); return UNION; }
262 unsigned { yylval.u = TS_UNSIGNED; loc(); return UNSIGNED; }
263 void { yylval.u = TS_VOID; loc(); return VOID; }
264 volatile|__volatile|__volatile__ { yylval.u = TQ_VOLATILE; loc(); return VOLATILE; }
265 while { loc(); return WHILE; }
266 _Bool { yylval.u = TS_BOOL; loc(); return BOOL; }
267 _Complex { yylval.u = TS_COMPLEX; loc(); return COMPLEX; }
268 _Imaginary { yylval.u = TS_IMAGINARY; loc(); return IMAGINARY; }
271 __attribute__ { loc(); return ATTRIBUTE; }
273 __builtin_va_list { yylval.u = TS_GCC_VA_LIST; loc(); return GCC_VA_LIST; }
274 __builtin_expect { loc(); return GCC_EXPECT; }
281 [a-zA-Z_][a-zA-Z0-9_]* {
282 /* identifiers are complicated by our desire to strictly check any UCNs they
286 newstring(yytext, yyleng);
292 newstring(yytext, yyleng);
296 inputerror(&yylloc, "invalid UCN '%s'", yytext);
298 newstring(yytext, yyleng);
301 <IDENT>[a-zA-Z0-9_]+ {
302 morestring(yytext, yyleng);
306 morestring(yytext, yyleng);
309 inputerror(&yylloc, "invalid UCN '%s'", yytext);
310 morestring(yytext, yyleng);
317 /* we need to look up the declaration of each name anyway so we record the
318 * type for all of them. But we can't produce an error here as it might be a
319 * struct member or something. */
320 yylval.name.name = xstrndup(string, stringlen);
321 yylval.name.declarator = lookup(yylval.name.name);
322 if(yylval.name.declarator
323 && yylval.name.declarator->declaration_specifiers
324 && (yylval.name.declarator->declaration_specifiers->storage_class_specifiers
337 return yylval.i = yytext[0];