1117395Skan/* -*- indented-text -*- */ 2117395Skan/* Process source files and output type information. 3169689Skan Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4117395Skan 5117395SkanThis file is part of GCC. 6117395Skan 7117395SkanGCC is free software; you can redistribute it and/or modify it under 8117395Skanthe terms of the GNU General Public License as published by the Free 9117395SkanSoftware Foundation; either version 2, or (at your option) any later 10117395Skanversion. 11117395Skan 12117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 14117395SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15117395Skanfor more details. 16117395Skan 17117395SkanYou should have received a copy of the GNU General Public License 18117395Skanalong with GCC; see the file COPYING. If not, write to the Free 19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20169689Skan02110-1301, USA. */ 21117395Skan 22117395Skan%{ 23132718Skan#include "bconfig.h" 24132718Skan#include "coretypes.h" 25117395Skan#include "system.h" 26117395Skan 27117395Skan#define malloc xmalloc 28117395Skan#define realloc xrealloc 29117395Skan 30117395Skan#include "gengtype.h" 31117395Skan#include "gengtype-yacc.h" 32117395Skan 33169689Skan#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE)) 34169689Skan 35169689Skanstatic unsigned macro_input (char *buffer, unsigned); 36169689Skanstatic const char *push_macro_expansion (const char *, unsigned, 37169689Skan const char *, unsigned); 38169689Skanstatic char *mangle_macro_name (const char *, unsigned, 39169689Skan const char *, unsigned); 40132718Skanstatic void update_lineno (const char *l, size_t len); 41117395Skan 42117395Skanstruct fileloc lexer_line; 43117395Skanint lexer_toplevel_done; 44117395Skan 45117395Skanstatic void 46132718Skanupdate_lineno (const char *l, size_t len) 47117395Skan{ 48117395Skan while (len-- > 0) 49117395Skan if (*l++ == '\n') 50117395Skan lexer_line.line++; 51117395Skan} 52117395Skan 53117395Skan%} 54117395Skan 55117395SkanID [[:alpha:]_][[:alnum:]_]* 56117395SkanWS [[:space:]]+ 57169689SkanIWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD 58117395SkanITYPE {IWORD}({WS}{IWORD})* 59117395Skan 60117395Skan%x in_struct in_struct_comment in_comment in_yacc_escape 61117395Skan%option warn noyywrap nounput nodefault perf-report 62117395Skan%option 8bit never-interactive 63117395Skan%% 64117395Skan 65117395Skan[^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" { 66117395Skan char *tagstart; 67117395Skan size_t taglen; 68117395Skan char *namestart; 69117395Skan size_t namelen; 70117395Skan int is_pointer = 0; 71117395Skan struct type *t; 72117395Skan int union_p; 73117395Skan 74117395Skan tagstart = yytext + strlen (" typedef "); 75117395Skan while (ISSPACE (*tagstart)) 76117395Skan tagstart++; 77117395Skan union_p = tagstart[0] == 'u'; 78117395Skan tagstart += strlen ("union "); 79117395Skan while (ISSPACE (*tagstart)) 80117395Skan tagstart++; 81117395Skan for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) 82117395Skan ; 83117395Skan for (namestart = tagstart + taglen; 84117395Skan ! ISIDNUM (*namestart); 85117395Skan namestart++) 86117395Skan if (*namestart == '*') 87117395Skan is_pointer = 1; 88117395Skan for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++) 89117395Skan ; 90169689Skan t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1), 91169689Skan union_p); 92117395Skan if (is_pointer) 93117395Skan t = create_pointer (t); 94169689Skan namestart = (char *) xmemdup (namestart, namelen, namelen+1); 95169689Skan#ifdef USE_MAPPED_LOCATION 96169689Skan /* temporary kludge - gentype doesn't handle cpp conditionals */ 97169689Skan if (strcmp (namestart, "location_t") != 0 98169689Skan && strcmp (namestart, "expanded_location") != 0) 99169689Skan#endif 100169689Skan do_typedef (namestart, t, &lexer_line); 101117395Skan update_lineno (yytext, yyleng); 102117395Skan} 103117395Skan 104117395Skan[^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" { 105117395Skan 106117395Skan char *namestart; 107117395Skan size_t namelen; 108117395Skan struct type *t; 109117395Skan char *typestart; 110117395Skan size_t typelen; 111117395Skan 112117395Skan for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) 113117395Skan ; 114117395Skan for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 115117395Skan ; 116117395Skan namestart -= namelen - 1; 117117395Skan for (typestart = yytext + strlen (" typedef "); 118117395Skan ISSPACE(*typestart); 119117395Skan typestart++) 120117395Skan ; 121169689Skan for (typelen = namestart - typestart; 122169689Skan ISSPACE (typestart[typelen-1]); 123117395Skan typelen--) 124117395Skan ; 125117395Skan 126117395Skan t = create_scalar_type (typestart, typelen); 127169689Skan do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 128169689Skan &lexer_line); 129117395Skan update_lineno (yytext, yyleng); 130117395Skan} 131117395Skan 132117395Skan[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS { 133117395Skan char *namestart; 134117395Skan size_t namelen; 135117395Skan struct type *t; 136117395Skan 137117395Skan for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--) 138117395Skan ; 139117395Skan for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 140117395Skan ; 141117395Skan namestart -= namelen - 1; 142117395Skan 143117395Skan t = create_scalar_type ("function type", sizeof ("function type")-1); 144169689Skan do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 145169689Skan &lexer_line); 146117395Skan update_lineno (yytext, yyleng); 147117395Skan} 148132718Skan 149132718Skan[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" { 150117395Skan char *namestart; 151117395Skan size_t namelen; 152117395Skan struct type *t; 153117395Skan 154132718Skan for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) 155132718Skan ; 156132718Skan for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) 157132718Skan ; 158132718Skan namestart -= namelen - 1; 159132718Skan 160132718Skan t = create_scalar_type ("function type", sizeof ("function type")-1); 161169689Skan do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 162169689Skan &lexer_line); 163132718Skan update_lineno (yytext, yyleng); 164132718Skan} 165132718Skan 166132718Skan[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS { 167132718Skan char *namestart; 168132718Skan size_t namelen; 169132718Skan struct type *t; 170132718Skan 171117395Skan for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--) 172117395Skan ; 173117395Skan for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) 174117395Skan ; 175117395Skan namestart -= namelen - 1; 176117395Skan 177117395Skan t = create_scalar_type ("function type", sizeof ("function type")-1); 178169689Skan do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 179169689Skan &lexer_line); 180117395Skan update_lineno (yytext, yyleng); 181117395Skan} 182117395Skan 183132718Skan[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" { 184132718Skan char *namestart; 185132718Skan size_t namelen; 186132718Skan struct type *t; 187132718Skan 188132718Skan for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--) 189132718Skan ; 190132718Skan for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) 191132718Skan ; 192132718Skan namestart -= namelen - 1; 193132718Skan 194132718Skan t = create_scalar_type ("function type", sizeof ("function type")-1); 195169689Skan do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, 196169689Skan &lexer_line); 197132718Skan update_lineno (yytext, yyleng); 198132718Skan} 199132718Skan 200117395Skan[^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" { 201117395Skan char *tagstart; 202117395Skan size_t taglen; 203117395Skan int typedef_p; 204117395Skan int union_p; 205117395Skan 206117395Skan typedef_p = yytext[1] == 't'; 207117395Skan if (typedef_p) 208117395Skan for (tagstart = yytext + strlen (" typedef "); 209117395Skan ISSPACE(*tagstart); 210117395Skan tagstart++) 211117395Skan ; 212117395Skan else 213117395Skan tagstart = yytext + 1; 214117395Skan 215117395Skan union_p = tagstart[0] == 'u'; 216117395Skan tagstart += strlen ("union "); 217117395Skan while (ISSPACE (*tagstart)) 218117395Skan tagstart++; 219117395Skan for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) 220117395Skan ; 221117395Skan 222169689Skan yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen, 223169689Skan taglen + 1), 224169689Skan union_p); 225117395Skan BEGIN(in_struct); 226117395Skan update_lineno (yytext, yyleng); 227117395Skan return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT; 228117395Skan} 229117395Skan 230117395Skan[^[:alnum:]_](extern|static){WS}/"GTY" { 231117395Skan BEGIN(in_struct); 232117395Skan update_lineno (yytext, yyleng); 233117395Skan return ENT_EXTERNSTATIC; 234117395Skan} 235117395Skan 236117395Skan^"%union"{WS}"{"{WS}/"GTY" { 237117395Skan BEGIN(in_struct); 238117395Skan update_lineno (yytext, yyleng); 239117395Skan return ENT_YACCUNION; 240117395Skan} 241117395Skan 242169689Skan^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { 243169689Skan char *macro, *arg; 244169689Skan unsigned macro_len, arg_len; 245169689Skan char *ptr = yytext; 246169689Skan const char *additional; 247169689Skan type_p t; 248169689Skan 249169689Skan /* Find the macro name. */ 250169689Skan for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) 251169689Skan continue; 252169689Skan for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++) 253169689Skan continue; 254169689Skan 255169689Skan /* Find the argument(s). */ 256169689Skan for (arg = ptr; *ptr != ')'; ptr++) 257169689Skan continue; 258169689Skan arg_len = ptr - arg; 259169689Skan 260169689Skan /* Create the struct and typedef. */ 261169689Skan ptr = mangle_macro_name ("VEC", 3, arg, arg_len); 262169689Skan 263169689Skan t = find_structure (ptr, 0); 264169689Skan do_typedef (ptr, t, &lexer_line); 265169689Skan 266169689Skan /* Push the macro for later expansion. */ 267169689Skan additional = push_macro_expansion (macro, macro_len, arg, arg_len); 268169689Skan 269169689Skan if (additional) 270169689Skan { 271169689Skan ptr = mangle_macro_name (ptr, strlen (ptr), 272169689Skan additional, strlen (additional)); 273169689Skan t = find_structure (ptr, 0); 274169689Skan do_typedef (ptr, t, &lexer_line); 275169689Skan } 276169689Skan} 277169689Skan 278117395Skan<in_struct>{ 279117395Skan 280117395Skan"/*" { BEGIN(in_struct_comment); } 281117395Skan 282169689Skan^"%{" { BEGIN(in_yacc_escape); } /* } */ 283117395Skan 284117395Skan{WS} { update_lineno (yytext, yyleng); } 285117395Skan 286117395Skan"const"/[^[:alnum:]_] /* don't care */ 287117395Skan"GTY"/[^[:alnum:]_] { return GTY_TOKEN; } 288117395Skan"union"/[^[:alnum:]_] { return UNION; } 289117395Skan"struct"/[^[:alnum:]_] { return STRUCT; } 290117395Skan"enum"/[^[:alnum:]_] { return ENUM; } 291117395Skan"ptr_alias"/[^[:alnum:]_] { return ALIAS; } 292169689Skan"nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; } 293117395Skan[0-9]+ { return NUM; } 294169689Skan"param"[0-9]*"_is"/[^[:alnum:]_] { 295169689Skan yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); 296117395Skan return PARAM_IS; 297117395Skan} 298117395Skan 299117395Skan{IWORD}({WS}{IWORD})*/[^[:alnum:]_] | 300117395Skan"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { 301117395Skan size_t len; 302117395Skan 303117395Skan for (len = yyleng; ISSPACE (yytext[len-1]); len--) 304117395Skan ; 305117395Skan 306117395Skan yylval.t = create_scalar_type (yytext, len); 307117395Skan update_lineno (yytext, yyleng); 308117395Skan return SCALAR; 309117395Skan} 310117395Skan 311169689Skan"VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { 312169689Skan char *macro, *arg; 313169689Skan unsigned macro_len, arg_len; 314169689Skan char *ptr = yytext; 315169689Skan 316169689Skan /* Find the macro name */ 317169689Skan for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) 318169689Skan continue; 319169689Skan for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++) 320169689Skan continue; 321169689Skan 322169689Skan /* Find the arguments. */ 323169689Skan for (arg = ptr; *ptr != ')'; ptr++) 324169689Skan continue; 325169689Skan arg_len = ptr - arg; 326169689Skan 327169689Skan ptr = mangle_macro_name (macro, macro_len, arg, arg_len); 328169689Skan yylval.s = ptr; 329169689Skan return ID; 330169689Skan} 331169689Skan 332117395Skan{ID}/[^[:alnum:]_] { 333169689Skan yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); 334117395Skan return ID; 335117395Skan} 336117395Skan 337117395Skan\"([^"\\]|\\.)*\" { 338169689Skan yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); 339117395Skan return STRING; 340117395Skan} 341117395Skan"["[^\[\]]*"]" { 342169689Skan yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); 343117395Skan return ARRAY; 344117395Skan} 345117395Skan^"%"{ID} { 346169689Skan yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng); 347117395Skan return PERCENT_ID; 348117395Skan} 349117395Skan"'"("\\".|[^\\])"'" { 350169689Skan yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng); 351117395Skan return CHAR; 352117395Skan} 353117395Skan 354117395Skan[(){},*:<>] { return yytext[0]; } 355117395Skan 356117395Skan[;=] { 357117395Skan if (lexer_toplevel_done) 358117395Skan { 359117395Skan BEGIN(INITIAL); 360117395Skan lexer_toplevel_done = 0; 361117395Skan } 362117395Skan return yytext[0]; 363117395Skan} 364117395Skan 365117395Skan^"%%" { 366117395Skan BEGIN(INITIAL); 367117395Skan return PERCENTPERCENT; 368117395Skan} 369117395Skan 370169689Skan"#define"[^\n]*\n {lexer_line.line++;} 371169689Skan 372117395Skan. { 373117395Skan error_at_line (&lexer_line, "unexpected character `%s'", yytext); 374117395Skan} 375117395Skan} 376117395Skan 377117395Skan"/*" { BEGIN(in_comment); } 378117395Skan\n { lexer_line.line++; } 379117395Skan{ID} | 380117395Skan"'"("\\".|[^\\])"'" | 381117395Skan[^"/\n] /* do nothing */ 382117395Skan\"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } 383117395Skan"/"/[^*] /* do nothing */ 384117395Skan 385117395Skan<in_comment,in_struct_comment>{ 386117395Skan\n { lexer_line.line++; } 387117395Skan[^*\n]{16} | 388117395Skan[^*\n] /* do nothing */ 389117395Skan"*"/[^/] /* do nothing */ 390117395Skan} 391117395Skan<in_comment>"*/" { BEGIN(INITIAL); } 392117395Skan<in_struct_comment>"*/" { BEGIN(in_struct); } 393117395Skan 394117395Skan<in_yacc_escape>{ 395117395Skan\n { lexer_line.line++; } 396117395Skan[^%]{16} | 397117395Skan[^%] /* do nothing */ 398117395Skan"%"/[^}] /* do nothing */ 399117395Skan"%}" { BEGIN(in_struct); } 400117395Skan"%" { 401117395Skan error_at_line (&lexer_line, 402117395Skan "unterminated %%{; unexpected EOF"); 403117395Skan} 404117395Skan} 405117395Skan 406117395Skan 407117395Skan["/] | 408117395Skan<in_struct_comment,in_comment>"*" { 409117395Skan error_at_line (&lexer_line, 410117395Skan "unterminated comment or string; unexpected EOF"); 411117395Skan} 412117395Skan 413169689Skan^"#define"{WS}"GTY(" /* do nothing */ 414169689Skan{WS}"GTY"{WS}?"(" { 415169689Skan error_at_line (&lexer_line, "stray GTY marker"); 416169689Skan} 417169689Skan 418117395Skan%% 419117395Skan 420169689Skan/* Deal with the expansion caused by the DEF_VEC_x macros. */ 421169689Skan 422169689Skan/* Mangle a macro and argument list as done by cpp concatenation in 423169689Skan the compiler proper. */ 424169689Skanstatic char * 425169689Skanmangle_macro_name (const char *macro, unsigned macro_len, 426169689Skan const char *arg, unsigned arg_len) 427169689Skan{ 428169689Skan char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2); 429169689Skan 430169689Skan /* Now copy and concatenate each argument */ 431169689Skan while (arg_len) 432169689Skan { 433169689Skan ptr[macro_len++] = '_'; 434169689Skan for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--) 435169689Skan ptr[macro_len++] = *arg++; 436169689Skan for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--) 437169689Skan arg++; 438169689Skan } 439169689Skan ptr[macro_len] = 0; 440169689Skan 441169689Skan return ptr; 442169689Skan} 443169689Skan 444169689Skantypedef struct macro_def 445169689Skan{ 446169689Skan const char *name; 447169689Skan const char *expansion; 448169689Skan const char *additional; 449169689Skan} macro_def_t; 450169689Skan 451169689Skantypedef struct macro 452169689Skan{ 453169689Skan const macro_def_t *def; 454169689Skan struct macro *next; 455169689Skan const char *args[10]; 456169689Skan} macro_t; 457169689Skan 458169689Skanstatic const macro_def_t macro_defs[] = 459169689Skan{ 460169689Skan#define IN_GENGTYPE 1 461169689Skan#include "vec.h" 462169689Skan {NULL, NULL, NULL} 463169689Skan}; 464169689Skan 465169689Skan/* Chain of macro expansions to do at end of scanning. */ 466169689Skanstatic macro_t *macro_expns; 467169689Skanstatic macro_t *macro_expns_end; 468169689Skan 469169689Skan/* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the 470169689Skan expansion queue. We ensure NAME is known at this point. */ 471169689Skan 472169689Skanstatic const char * 473169689Skanpush_macro_expansion (const char *name, unsigned name_len, 474169689Skan const char *arg, unsigned arg_len) 475169689Skan{ 476169689Skan unsigned ix; 477169689Skan 478169689Skan for (ix = 0; macro_defs[ix].name; ix++) 479169689Skan if (strlen (macro_defs[ix].name) == name_len 480169689Skan && !memcmp (name, macro_defs[ix].name, name_len)) 481169689Skan { 482169689Skan macro_t *expansion = XNEW (macro_t); 483169689Skan char *args; 484169689Skan unsigned argno, last_arg; 485169689Skan 486169689Skan expansion->def = ¯o_defs[ix]; 487169689Skan expansion->next = NULL; 488169689Skan args = (char *) xmemdup (arg, arg_len, arg_len+1); 489169689Skan args[arg_len] = 0; 490169689Skan for (argno = 0; *args;) 491169689Skan { 492169689Skan expansion->args[argno++] = args; 493169689Skan while (*args && (ISALNUM (*args) || *args == '_')) 494169689Skan args++; 495169689Skan if (argno == 1) 496169689Skan expansion->args[argno++] = "base"; 497169689Skan if (!*args) 498169689Skan break; 499169689Skan *args++ = 0; 500169689Skan while (*args && !(ISALNUM (*args) || *args == '_')) 501169689Skan args++; 502169689Skan } 503169689Skan last_arg = argno; 504169689Skan for (; argno != 10; argno++) 505169689Skan expansion->args[argno] = NULL; 506169689Skan if (macro_expns_end) 507169689Skan macro_expns_end->next = expansion; 508169689Skan else 509169689Skan macro_expns = expansion; 510169689Skan macro_expns_end = expansion; 511169689Skan if (macro_defs[ix].additional) 512169689Skan { 513169689Skan macro_t *expn2 = XNEW (macro_t); 514169689Skan memcpy (expn2, expansion, sizeof (*expn2)); 515169689Skan expansion = expn2; 516169689Skan expansion->def += 1; 517169689Skan expansion->args[last_arg++] = macro_defs[ix].additional; 518169689Skan macro_expns_end->next = expansion; 519169689Skan macro_expns_end = expansion; 520169689Skan } 521169689Skan if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap")) 522169689Skan expansion->args[last_arg++] = "GTY (())"; 523169689Skan return macro_defs[ix].additional; 524169689Skan } 525169689Skan error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'", 526169689Skan name_len, name, arg_len, arg); 527169689Skan return NULL; 528169689Skan} 529169689Skan 530169689Skan/* Attempt to read some input. Use fread until we're at the end of 531169689Skan file. At end of file expand the next queued macro. We presume the 532169689Skan buffer is large enough for the entire expansion. */ 533169689Skan 534169689Skanstatic unsigned 535169689Skanmacro_input (char *buffer, unsigned size) 536169689Skan{ 537169689Skan unsigned result; 538169689Skan 539169689Skan result = fread (buffer, 1, size, yyin); 540169689Skan if (result) 541169689Skan /*NOP*/; 542169689Skan else if (ferror (yyin)) 543169689Skan YY_FATAL_ERROR ("read of source file failed"); 544169689Skan else if (macro_expns) 545169689Skan { 546169689Skan const char *expn; 547169689Skan unsigned len; 548169689Skan 549169689Skan for (expn = macro_expns->def->expansion; *expn; expn++) 550169689Skan { 551169689Skan if (*expn == '#') 552169689Skan { 553169689Skan int argno; 554169689Skan 555169689Skan argno = expn[1] - '0'; 556169689Skan expn += 1; 557169689Skan 558169689Skan /* Remove inserted space? */ 559169689Skan if (buffer[result-1] == ' ' && buffer[result-2] == '_') 560169689Skan result--; 561169689Skan 562169689Skan /* Insert the argument value */ 563169689Skan if (macro_expns->args[argno]) 564169689Skan { 565169689Skan len = strlen (macro_expns->args[argno]); 566169689Skan memcpy (&buffer[result], macro_expns->args[argno], len); 567169689Skan result += len; 568169689Skan } 569169689Skan 570169689Skan /* Skip next space? */ 571169689Skan if (expn[1] == ' ' && expn[2] == '_') 572169689Skan expn++; 573169689Skan } 574169689Skan else 575169689Skan { 576169689Skan buffer[result++] = *expn; 577169689Skan if (*expn == ';' || *expn == '{') 578169689Skan buffer[result++] = '\n'; 579169689Skan } 580169689Skan } 581169689Skan if (result > size) 582169689Skan YY_FATAL_ERROR ("buffer too small to expand macro"); 583169689Skan macro_expns = macro_expns->next; 584169689Skan if (!macro_expns) 585169689Skan macro_expns_end = NULL; 586169689Skan } 587169689Skan return result; 588169689Skan} 589169689Skan 590117395Skanvoid 591132718Skanyyerror (const char *s) 592117395Skan{ 593222097Sbenl error_at_line (&lexer_line, "%s", s); 594117395Skan} 595117395Skan 596117395Skanvoid 597132718Skanparse_file (const char *fname) 598117395Skan{ 599117395Skan yyin = fopen (fname, "r"); 600117395Skan lexer_line.file = fname; 601117395Skan lexer_line.line = 1; 602117395Skan if (yyin == NULL) 603117395Skan { 604117395Skan perror (fname); 605117395Skan exit (1); 606117395Skan } 607117395Skan if (yyparse() != 0) 608117395Skan exit (1); 609117395Skan fclose (yyin); 610117395Skan} 611