cfg.lex
3c1a8ef8
 /*
  * $Id$
  *
  * scanner for cfg files
  */
 
 
 %{
 	#include "cfg.tab.h"
 	#include <string.h>
 
 	/* states */
 	#define INITIAL_S		0
 	#define COMMENT_S		1
 	#define COMMENT_LN_S	2
 	#define STRING_S		3
 
 	
 	static int comment_nest=0;
 	static int state=0;
 	static char* str=0;
09e52ebb
 	int line=1;
 	int column=1;
 	int startcolumn=1;
3c1a8ef8
 
 	static char* addstr(char*, char**);
 	static void count();
 
 
 %}
 
 /* start conditions */
 %x STRING1 STRING2 COMMENT COMMENT_LN
 
 /* action keywords */
 FORWARD	forward
 DROP	drop
 SEND	send
 LOG		log
 ERROR	error
 ROUTE	route
09e52ebb
 EXEC	exec
3c1a8ef8
 /* condition keywords */
 METHOD	method
 URI		uri
 SRCIP	src_ip
 DSTIP	dst_ip
 /* operators */
 EQUAL	=
 EQUAL_T	==
 MATCH	~=
09e52ebb
 NOT		!|"not"
3c1a8ef8
 AND		"and"|"&&"|"&"
 OR		"or"|"||"|"|"
 
 /* config vars. */
 DEBUG	debug
 FORK	fork
 LOGSTDERROR	log_stderror
 LISTEN		listen
 DNS		 dns
 REV_DNS	 rev_dns
 
 /* values */
 YES			"yes"|"true"|"on"|"enable"
 NO			"no"|"false"|"off"|"disable"
 
 LETTER		[a-zA-Z]
 DIGIT		[0-9]
 ALPHANUM	{LETTER}|{DIGIT}
 NUMBER		{DIGIT}+
 ID			{LETTER}{ALPHANUM}*
 QUOTES		\"
 TICK		\'
 SLASH		"/"
 SEMICOLON	;
 RPAREN		\)
 LPAREN		\(
 LBRACE		\{
 RBRACE		\}
 LBRACK		\[
 RBRACK		\]
 COMMA		,
 DOT			\.
 CR			\n
 
 
 
 COM_LINE	#
 COM_START	"/\*"
 COM_END		"\*/"
 
 EAT_ABLE	[\ \t\b\r]
 
 %%
 
 
 <INITIAL>{EAT_ABLE}	{ count(); }
 
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG; }
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
09e52ebb
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
3c1a8ef8
 
 <INITIAL>{METHOD}	{ count(); yylval.strval=yytext; return METHOD; }
 <INITIAL>{URI}	{ count(); yylval.strval=yytext; return URI; }
 <INITIAL>{SRCIP}	{ count(); yylval.strval=yytext; return SRCIP; }
 <INITIAL>{DSTIP}	{ count(); yylval.strval=yytext; return DSTIP; }
 
 <INITIAL>{DEBUG}	{ count(); yylval.strval=yytext; return DEBUG; }
 <INITIAL>{FORK}		{ count(); yylval.strval=yytext; return FORK; }
 <INITIAL>{LOGSTDERROR}	{ yylval.strval=yytext; return LOGSTDERROR; }
 <INITIAL>{LISTEN}	{ count(); yylval.strval=yytext; return LISTEN; }
 <INITIAL>{DNS}	{ count(); yylval.strval=yytext; return DNS; }
 <INITIAL>{REV_DNS}	{ count(); yylval.strval=yytext; return REV_DNS; }
 
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
 <INITIAL>{EQUAL_T}	{ count(); return EQUAL_T; }
 <INITIAL>{MATCH}	{ count(); return MATCH; }
 <INITIAL>{NOT}		{ count(); return NOT; }
 <INITIAL>{AND}		{ count(); return AND; }
 <INITIAL>{OR}		{ count(); return OR;  }
 
 <INITIAL>{NUMBER}		{ count(); yylval.intval=atoi(yytext);
 							return NUMBER; }
 <INITIAL>{YES}			{ count(); yylval.intval=1; return NUMBER; }
 <INITIAL>{NO}			{ count(); yylval.intval=0; return NUMBER; }
 
 <INITIAL>{COMMA}		{ count(); return COMMA; }
 <INITIAL>{SEMICOLON}	{ count(); return SEMICOLON; }
 <INITIAL>{RPAREN}	{ count(); return RPAREN; }
 <INITIAL>{LPAREN}	{ count(); return LPAREN; }
 <INITIAL>{LBRACE}	{ count(); return LBRACE; }
 <INITIAL>{RBRACE}	{ count(); return RBRACE; }
 <INITIAL>{LBRACK}	{ count(); return LBRACK; }
 <INITIAL>{RBRACK}	{ count(); return RBRACK; }
 <INITIAL>{SLASH}	{ count(); return SLASH; }
 <INITIAL>{DOT}		{ count(); return DOT; }
 <INITIAL>\\{CR}		{count(); } /* eat the escaped CR */
 <INITIAL>{CR}		{ count(); return CR; }
 
 
 <INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); }
 <INITIAL>{TICK} { count(); state=STRING_S; BEGIN(STRING2); }
 
 
 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
 						yytext[yyleng-1]=0; yyleng--;
 						addstr(yytext, &str);
 						if (str){
 							printf("Found string1 <%s>\n", str);
 						}else{
 							printf("WARNING: empty string\n");
 						}
c07508e2
 						yylval.strval=str; str=0;
 						return STRING;
3c1a8ef8
 					}
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
 						yytext[yyleng-1]=0; yyleng--;
 						printf("Found string1 <%s>\n", yytext);
c07508e2
 						addstr(yytext, &str);
 						yylval.strval=str;
 						str=0;
 						return STRING;
3c1a8ef8
 					}
 <STRING2>.|{EAT_ABLE}|{CR}	{ yymore(); }
 
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); } 
 <STRING1>.|{EAT_ABLE}|{CR}	{ yymore(); }
 
 
 <INITIAL,COMMENT>{COM_START}	{ count(); comment_nest++; state=COMMENT_S;
 										BEGIN(COMMENT); }
 <COMMENT>{COM_END}				{ count(); comment_nest--;
 										if (comment_nest==0){
 											state=INITIAL_S;
 											BEGIN(INITIAL);
 										}
 								}
 <COMMENT>.|{EAT_ABLE}|{CR}				{ count(); };
 
 <INITIAL>{COM_LINE}.*{CR}	{ count(); } 
 
09e52ebb
 <INITIAL>{ID}			{ count(); addstr(yytext, &str);
 						  yylval.strval=str; str=0; return ID; }
3c1a8ef8
 
 
 <<EOF>>							{
 									switch(state){
 										case STRING_S: 
 											printf("Unexpected EOF: closed string\n");
 											if (str) {free(str); str=0;}
 											break;
 										case COMMENT_S:
 											printf("Unexpected EOF:%d comments open\n", comment_nest);
 											break;
 										case COMMENT_LN_S:
 											printf("Unexpected EOF: comment line open\n");
 											break;
 									}
 									return 0;
 								}
 			
 %%
 
 static char* addstr(char * src, char ** dest)
 {
 	char *tmp;
 	int len1, len2;
 	
 	if (*dest==0){
 		*dest=strdup(src);
 	}else{
 		len1=strlen(*dest);
 		len2=strlen(src);
 		tmp=malloc(len1+len2+1);
 		if (tmp==0) goto error;
 		memcpy(tmp, *dest, len1);
 		memcpy(tmp+len1, src, len2);
 		tmp[len1+len2]=0;
 		free(*dest);
 		*dest=tmp;
 	}
 	return *dest;
 error:
 	fprintf(stderr, "lex:addstr: memory allocation error\n");
 	return 0;
 }
 
 
 
 static void count()
 {
 	int i;
 	
09e52ebb
 	startcolumn=column;
3c1a8ef8
 	for (i=0; i<yyleng;i++){
 		if (yytext[i]=='\n'){
 			line++;
09e52ebb
 			column=startcolumn=1;
3c1a8ef8
 		}else if (yytext[i]=='\t'){
09e52ebb
 			column++;
 			/*column+=8 -(column%8);*/
3c1a8ef8
 		}else{
 			column++;
 		}
 	}
 }