zeek/src/builtin-func.l
Robin Sommer eb637f9f3e Merge remote-tracking branch 'origin/master' into topic/robin/plugins
Thanks to git this merge was less troublesome that I was afraid it
would be. Not all tests pass yet though (and file hashes have changed
unfortunately).

Conflicts:
	cmake
	doc/scripts/DocSourcesList.cmake
	scripts/base/init-bare.bro
	scripts/base/protocols/ftp/main.bro
	scripts/base/protocols/irc/dcc-send.bro
	scripts/test-all-policy.bro
	src/AnalyzerTags.h
	src/CMakeLists.txt
	src/analyzer/Analyzer.cc
	src/analyzer/protocol/file/File.cc
	src/analyzer/protocol/file/File.h
	src/analyzer/protocol/http/HTTP.cc
	src/analyzer/protocol/http/HTTP.h
	src/analyzer/protocol/mime/MIME.cc
	src/event.bif
	src/main.cc
	src/util-config.h.in
	testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log
	testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log
	testing/btest/Baseline/istate.events-ssl/receiver.http.log
	testing/btest/Baseline/istate.events-ssl/sender.http.log
	testing/btest/Baseline/istate.events/receiver.http.log
	testing/btest/Baseline/istate.events/sender.http.log
2013-05-16 17:58:48 -07:00

395 lines
8.6 KiB
Text

%{
#include <string.h>
#include <unistd.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]+
OWS [ \t]*
/* Note, bifcl only accepts a single "::" in IDs while the policy
layer acceptes multiple. (But the policy layer doesn't have
a hierachy. */
IDCOMPONENT [A-Za-z_][A-Za-z_0-9]*
ID {IDCOMPONENT}(::{IDCOMPONENT})?
ESCSEQ (\\([^\n]|[0-7]+|x[[:xdigit:]]+))
DEC [[:digit:]]+
HEX [0-9a-fA-F]+
%option nodefault
%%
#.* {
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);
"event" return check_c_mode(TOK_EVENT);
"const" return check_c_mode(TOK_CONST);
"enum" return check_c_mode(TOK_ENUM);
"type" return check_c_mode(TOK_TYPE);
"record" return check_c_mode(TOK_RECORD);
"set" return check_c_mode(TOK_SET);
"table" return check_c_mode(TOK_TABLE);
"vector" return check_c_mode(TOK_VECTOR);
"of" return check_c_mode(TOK_OF);
"opaque" return check_c_mode(TOK_OPAQUE);
"module" return check_c_mode(TOK_MODULE);
"@ARG@" return TOK_ARG;
"@ARGS@" return TOK_ARGS;
"@ARGC@" return TOK_ARGC;
"T" yylval.val = 1; return TOK_BOOL;
"F" yylval.val = 0; return TOK_BOOL;
{DEC} {
yylval.str = copy_string(yytext);
return TOK_INT;
}
"0x"{HEX} {
yylval.str = copy_string(yytext);
return TOK_INT;
}
{ID} {
yylval.str = copy_string(yytext);
return TOK_ID;
}
/*
Hacky way to pass along arbitrary attribute expressions since the BIF parser
has little understanding of valid Bro expressions. With this pattern, the
attribute expression should stop when it reaches another attribute, another
function argument, or the end of the function declaration.
*/
&{ID}({OWS}={OWS}[^&%;,]+)? {
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;
}
\'([^\\\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;
char* input_filename_with_path = 0;
char* plugin = 0;
int alternative_mode = 0;
FILE* fp_bro_init = 0;
FILE* fp_func_def = 0;
FILE* fp_func_h = 0;
FILE* fp_func_init = 0;
FILE* fp_netvar_h = 0;
FILE* fp_netvar_def = 0;
FILE* fp_netvar_init = 0;
void remove_file(const char *surfix);
void err_exit(void);
FILE* open_output_file(const char* surfix);
void close_if_open(FILE **fpp);
void close_all_output_files(void);
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);
err_exit();
}
return fp;
}
void usage()
{
fprintf(stderr, "usage: bifcl [-p] *.bif\n");
exit(1);
}
void init_alternative_mode()
{
fp_bro_init = open_output_file("bro");
fp_func_h = open_output_file("h");
fp_func_def = open_output_file("cc");
fp_func_init = open_output_file("init.cc");
fp_netvar_h = fp_func_h;
fp_netvar_def = fp_func_def;
fp_netvar_init = fp_func_init;
int n = 1024 + strlen(input_filename);
char auto_gen_comment[n];
snprintf(auto_gen_comment, n,
"This file was automatically generated by bifcl from %s (%s mode).",
input_filename_with_path, plugin ? "plugin" : "alternative");
fprintf(fp_bro_init, "# %s\n\n", auto_gen_comment);
fprintf(fp_func_def, "// %s\n\n", auto_gen_comment);
fprintf(fp_func_h, "// %s\n\n", auto_gen_comment);
fprintf(fp_func_init, "// %s\n\n", auto_gen_comment);
static char guard[1024];
getcwd(guard, sizeof(guard));
strncat(guard, "/", sizeof(guard));
strncat(guard, input_filename, sizeof(guard));
for ( char* p = guard; *p; p++ )
{
if ( strchr("/.-", *p) )
*p = '_';
}
fprintf(fp_func_h, "#if defined(BRO_IN_NETVAR) || ! defined(%s)\n", guard);
fprintf(fp_func_h, "#ifndef BRO_IN_NETVAR\n");
fprintf(fp_func_h, "#ifndef %s\n", guard);
fprintf(fp_func_h, "#define %s\n", guard);
fprintf(fp_func_h, "#include \"bro-bif.h\"\n");
fprintf(fp_func_h, "#endif\n");
fprintf(fp_func_h, "#endif\n");
fprintf(fp_func_h, "\n");
fprintf(fp_func_def, "\n");
fprintf(fp_func_def, "#include \"%s.h\"\n", input_filename);
fprintf(fp_func_def, "\n");
static char name[1024];
strncpy(name, input_filename, sizeof(name));
char* dot = strchr(name, '.');
if ( dot )
*dot = '\0';
if ( plugin )
{
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "#include <list>\n");
fprintf(fp_func_init, "#include <string>\n");
fprintf(fp_func_init, "#include \"%s.h\"\n", input_filename);
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "namespace plugin { namespace %s {\n", plugin);
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "std::list<std::pair<const char*, int> > __bif_%s_init()\n", name);
fprintf(fp_func_init, "\t{\n");
fprintf(fp_func_init, "\tstd::list<std::pair<const char*, int> > bifs;\n");
fprintf(fp_func_init, "\n");
}
}
void finish_alternative_mode()
{
fprintf(fp_func_h, "\n");
fprintf(fp_func_h, "#endif\n");
if ( plugin )
{
fprintf(fp_func_init, "\n");
fprintf(fp_func_init, "\treturn bifs;\n");
fprintf(fp_func_init, "\t}\n");
fprintf(fp_func_init, "} }\n");
fprintf(fp_func_init, "\n");
}
}
int main(int argc, char* argv[])
{
char opt;
while ( (opt = getopt(argc, argv, "p:s")) != -1 )
{
switch ( opt ) {
case 'p':
alternative_mode = 1;
plugin = optarg;
break;
case 's':
alternative_mode = 1;
break;
default:
usage();
}
}
for ( int i = optind; i < argc; i++ )
{
FILE* fp_input;
char* slash;
input_filename = input_filename_with_path = argv[i];
slash = strrchr(input_filename, '/');
if ( (fp_input = fopen(input_filename, "r")) == NULL )
{
fprintf(stderr, "Error: cannot open file: %s\n", input_filename);
/* no output files open. can simply exit */
exit(1);
}
if ( slash )
input_filename = slash + 1;
if ( ! alternative_mode )
{
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");
int n = 1024 + strlen(input_filename);
char auto_gen_comment[n];
snprintf(auto_gen_comment, n,
"This file was automatically generated by bifcl from %s.",
input_filename);
fprintf(fp_bro_init, "# %s\n\n", auto_gen_comment);
fprintf(fp_func_def, "// %s\n\n", auto_gen_comment);
fprintf(fp_func_h, "// %s\n\n", auto_gen_comment);
fprintf(fp_func_init, "// %s\n\n", auto_gen_comment);
fprintf(fp_netvar_def, "// %s\n\n", auto_gen_comment);
fprintf(fp_netvar_h, "// %s\n\n", auto_gen_comment);
fprintf(fp_netvar_init, "// %s\n\n", auto_gen_comment);
}
else
init_alternative_mode();
yy_switch_to_buffer(yy_create_buffer(fp_input, YY_BUF_SIZE));
yyparse();
if ( alternative_mode )
finish_alternative_mode();
fclose(fp_input);
close_all_output_files();
}
}
void close_if_open(FILE **fpp)
{
if (*fpp)
fclose(*fpp);
*fpp = NULL;
}
void close_all_output_files(void)
{
close_if_open(&fp_bro_init);
close_if_open(&fp_func_h);
close_if_open(&fp_func_def);
close_if_open(&fp_func_init);
if ( ! alternative_mode )
{
close_if_open(&fp_netvar_h);
close_if_open(&fp_netvar_def);
close_if_open(&fp_netvar_init);
}
}
void remove_file(const char *surfix)
{
char fn[1024];
snprintf(fn, sizeof(fn), "%s.%s", input_filename, surfix);
unlink(fn);
}
void err_exit(void)
{
close_all_output_files();
/* clean up. remove all output files we've generated so far */
remove_file("bro");
remove_file("func_h");
remove_file("func_def");
remove_file("func_init");
remove_file("netvar_h");
remove_file("netvar_def");
remove_file("netvar_init");
exit(1);
}