%{
// $Id: builtin-func.l,v 1.6 2002/11/29 05:28:23 vern Exp $

#include <string.h>
#include "bif_arg.h"
#include "bif_parse.h"

char* copy_string(const char* s)
	{
	char* c = new char[strlen(s)+1];
	strcpy(c, s);
	return c;
	}

int line_number = 1;

extern int in_c_code;

int check_c_mode(int t)
	{
	if ( ! in_c_code )
		return t;

	yylval.str = copy_string(yytext);
	return TOK_C_TOKEN;
	}
%}

WS	[ \t]+
ID	[A-Za-z_][A-Za-z_0-9]*
ESCSEQ	(\\([^\n]|[0-7]+|x[[:xdigit:]]+))

%%

#.*	{
	yylval.str = copy_string(yytext);
	return TOK_COMMENT;
	}

\n	{
	++line_number;
	return TOK_LF;
        }

{WS}	{
	yylval.str = copy_string(yytext);
	return TOK_WS;
	}

[=,:;]	return check_c_mode(yytext[0]);

"%{"	return TOK_LPB;
"%}"	return TOK_RPB;
"%%{"	return TOK_LPPB;
"%%}"	return TOK_RPPB;

"%("		return check_c_mode(TOK_LPP);
"%)"		return check_c_mode(TOK_RPP);
"..."		return check_c_mode(TOK_VAR_ARG);
"function"	return check_c_mode(TOK_FUNCTION);
"rewriter"	return check_c_mode(TOK_REWRITER);
"event"		return check_c_mode(TOK_EVENT);
"const"		return check_c_mode(TOK_CONST);

"@ARG@"		return TOK_ARG;
"@ARGS@"	return TOK_ARGS;
"@ARGC@"	return TOK_ARGC;

"@WRITE@"	return TOK_WRITE;
"@PUSH@"	return TOK_PUSH;
"@EOF@"		return TOK_EOF;
"@TRACE@"	return TOK_TRACE;

"T"	yylval.val = 1; return TOK_BOOL;
"F"	yylval.val = 0; return TOK_BOOL;

{ID}	{
	yylval.str = copy_string(yytext);
	return TOK_ID;
	}

&{ID}	{
	int t = check_c_mode(TOK_ATTR);

	if ( t == TOK_ATTR )
		{
		yylval.str = copy_string(yytext);
		return TOK_ATTR;
		}
	else
		return t;
	}

\"([^\\\n\"]|{ESCSEQ})*\"	{
	yylval.str = copy_string(yytext);
	return TOK_CSTR;
        }

.	{
        yylval.val = yytext[0];
        return TOK_ATOM;
        }
%%

int yywrap()
	{
	yy_delete_buffer(YY_CURRENT_BUFFER);
	return 1;
	}

extern int yyparse();
char* input_filename = 0;

FILE* fp_bro_init;
FILE* fp_func_def;
FILE* fp_func_h;
FILE* fp_func_init;
FILE* fp_netvar_h;
FILE* fp_netvar_def;
FILE* fp_netvar_init;

FILE* open_output_file(const char* surfix)
	{
	char fn[1024];
	FILE* fp;

	snprintf(fn, sizeof(fn), "%s.%s", input_filename, surfix);
	if ( (fp = fopen(fn, "w")) == NULL )
		{
		fprintf(stderr, "Error: cannot open file: %s\n", fn);
		exit(1);
		}

	return fp;
	}

int main(int argc, char* argv[])
	{
	for ( int i = 1; i < argc; i++ )
		{
		FILE* fp_input;

		input_filename = argv[i];

		if ( (fp_input = fopen(input_filename, "r")) == NULL )
			{
			fprintf(stderr, "Error: cannot open file: %s\n", input_filename);
			exit(1);
			}

		fp_bro_init = open_output_file("bro");
		fp_func_h = open_output_file("func_h");
		fp_func_def = open_output_file("func_def");
		fp_func_init = open_output_file("func_init");
		fp_netvar_h = open_output_file("netvar_h");
		fp_netvar_def = open_output_file("netvar_def");
		fp_netvar_init = open_output_file("netvar_init");

		yy_switch_to_buffer(yy_create_buffer(fp_input, YY_BUF_SIZE));
		yyparse();

		fclose(fp_input);
		fclose(fp_bro_init);
		fclose(fp_func_h);
		fclose(fp_func_def);
		fclose(fp_func_init);
		fclose(fp_netvar_h);
		fclose(fp_netvar_def);
		fclose(fp_netvar_init);
		}
	}
