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 = &macro_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