/* -*- fundamental -*- */
%{
#include "com.h"
#include "symtab.h"
#include "y.tab.h"

extern char *file;
extern int copythrough;
static int line = 1;
static char strbuf[1024];
static char *strptr;
%}

%x comment
%x string

%%
struct			return STRUCT;
typedef			return TYPEDEF;
unsigned		return UNSIGNED;
signed                  return SIGNED;
__signed__              return SIGNED;
notypedef		return NOTHDR;
generate		return GENERATE;

	/* Purely C keywords */
static			return STATIC;
extern			return EXTERN;
(__)?const		return CONST;
(__)?volatile		return VOLATILE;
"..."			return ELLIPSIS;

[_a-zA-Z][_a-zA-Z0-9]*	{
				Var *v = lookup(global, yytext);
				if (v != NULL && v->type->tclass == Typedef)
				{
					Type *t = v->type;
					if (t->indir == 1)
						t = t->i.typedef_i.t;

					yylval.type = t;
					return TYPE;
				}
				yylval.name = strdup(yytext);
				return IDENT;
			}
[0-9]+			{ yylval.num = atoi(yytext); return NUM; }
[+-/{}[\]*;,()]		return *yytext;
"/*"			BEGIN(comment);
^#\ [0-9]+\ \"[a-zA-Z_.0-9/]+\".*$	{
				char *cp;

				line = strtol(&yytext[2], &cp, 10);
				free(file);
				file = cp+2;
				for(cp = file; *cp && *cp != '"'; cp++)
					;
				*cp = 0;
				file = strdup(file);
			}
\"			strptr = strbuf; BEGIN(string);
^#.*$			;
[ \t]			;
\n			line++;
^"%".*			if (copythrough) { fputs(&yytext[1], stdout); fputc('\n', stdout); }
.			fprintf(stderr, "Uncaught char '%c'\n", *yytext);

<comment>[^*\n]+	/* eat up anything up to '*' */
<comment>"*"+[^*/\n]*	/* eat up rows of '*' not followed by '/' */
<comment>\n		line++;
<comment>"*"+"/"	BEGIN(INITIAL);

<string>\\.		*strptr++ = yytext[1];
<string>\"		*strptr=0; yylval.name = strdup(strbuf); BEGIN(INITIAL); return STRING;
<string>[^\\\"]+	{char *cp = yytext; while(*cp) *strptr++ = *cp++; }

%%

#include <stdio.h>
#include <stdarg.h>

void
yyerror(const char *msg, ...)
{
	va_list va;

	fprintf(stderr, "%s:%d:", file, line, msg);

	va_start(va, msg);
	vfprintf(stderr, msg, va);
	va_end(va);
}

