%{ #include #include #include #include #include #include #include #include #include #include #include extern FILE *yyin; extern FILE *yyout; extern int yylineno; extern int yy_flex_debug; static size_t errors; enum filter_dir { GTW_IN, GTW_OUT, GTW_INOUT }; #define GODROP 0 enum filter_action { GTW_DROP = 0, GTW_PASS, }; struct mqtt_rule { char topic[128]; char from[128]; enum filter_action action; enum filter_dir dir; int log; int quick; }; static size_t parsed_lines; static size_t errors; static size_t nrule; %} %union { int64_t number; char *string; }; %token ACTION IN OUT FROM QUICK LOG SOCKET %token TOPIC WORD WORD2 %token ANY FROM %token SLASH HYPHEN %type ACTION QUICK LOG get_dir get_log get_quick %type get_from get_topic WORD SOCKET %% ruleset: /* empty */ | ruleset mqttrule | ruleset comment | ruleset error { errors++; } ; comment: COMMENT '\n' { }; mqttrule : get_log ACTION get_quick get_dir get_topic get_from { parsed_lines++; struct mqtt_rule r; memset(&r, 0, sizeof(r)); r.action = $2; r.dir = $4; if ($5) strlcpy(r.topic, $5, sizeof r.topic); if ($6) strlcpy(r.from, $6, sizeof r.from); ++nrule; if ($1==1) { printf("\t#%zu: %c %s %c %s %s;\n", nrule, $3?'!':' ', r.action == GTW_DROP ? "Drop" : "pass", r.dir==GTW_INOUT ? '=' : r.dir==GTW_IN ? '<' :'>', r.topic[0]!=0 ? r.topic :"*", r.from[0]!=0 ? r.from : ""); } }; get_quick : /*empty*/ {$$=0;} | QUICK {$$=1;} ; get_log : /*empty*/ {$$=0;} | LOG {$$ = 1;} ; get_topic : ANY {$$=NULL;} | WORD {$$=$1;} ; get_from : /*empty*/ {$$=NULL;} | SOCKET {$$ = $1;} ; get_dir : /*empty*/ {$$=GTW_INOUT;} | IN {$$=GTW_IN;} | OUT {$$=GTW_OUT;} ; %% void yyerror(msg) char *msg; { fprintf(stderr, "while parsing line %d: error occured \"%s\"\n", yylineno, msg); return; } int main( int argc, char **argv ) { ++argv, --argc; /* skip over program name */ if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; int devNull = open("/dev/null", O_WRONLY); int dup2Result = dup2(devNull, STDERR_FILENO); yyparse(); printf("#%zu. R: %zu\tE: %zu\n", parsed_lines, nrule, errors); }