/* original parser id follows */ /* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */ /* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */ #define YYBYACC 1 #define YYMAJOR 2 #define YYMINOR 0 #define YYPATCH 20210109 #define YYEMPTY (-1) #define yyclearin (yychar = YYEMPTY) #define yyerrok (yyerrflag = 0) #define YYRECOVERING() (yyerrflag != 0) #define YYENOMEM (-2) #define YYEOF 0 #define YYPREFIX "yy" #define YYPURE 0 #line 34 "parse.y" static const char rcsid[] = "$Id: parse.y,v 1.3 2011/11/24 13:43:27 dhartmei Exp $"; #include #include #include #include #include #include #include #include "eval.h" int yyerror(const char *, ...); static int yyparse(void); static int define_macro(const char *, struct expr *); static struct expr *find_macro(const char *); static char *err_str = NULL; static size_t err_len = 0; static const char *infile = NULL; static FILE *fin = NULL; static int lineno = 1; static int errors = 0; static struct ruleset *rs = NULL; struct macro { char *name; struct expr *expr; struct macro *next; } *macros = NULL; typedef struct { union { char *string; struct expr *expr; struct expr_list *expr_list; struct action *action; } v; int lineno; } YYSTYPE; #line 63 "y.tab.c" /* compatibility with bison */ #ifdef YYPARSE_PARAM /* compatibility with FreeBSD */ # ifdef YYPARSE_PARAM_TYPE # define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) # else # define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) # endif #else # define YYPARSE_DECL() yyparse(void) #endif /* Parameters sent to lex. */ #ifdef YYLEX_PARAM # define YYLEX_DECL() yylex(void *YYLEX_PARAM) # define YYLEX yylex(YYLEX_PARAM) #else # define YYLEX_DECL() yylex(void) # define YYLEX yylex() #endif #if !(defined(yylex) || defined(YYSTATE)) int YYLEX_DECL(); #endif /* Parameters sent to yyerror. */ #ifndef YYERROR_DECL #define YYERROR_DECL() yyerror(const char *s) #endif #ifndef YYERROR_CALL #define YYERROR_CALL(msg) yyerror(msg) #endif extern int YYPARSE_DECL(); #define ERROR 257 #define STRING 258 #define ACCEPT 259 #define REJECT 260 #define TEMPFAIL 261 #define DISCARD 262 #define QUARANTINE 263 #define CONNECT 264 #define HELO 265 #define ENVFROM 266 #define ENVRCPT 267 #define HEADER 268 #define MACRO 269 #define BODY 270 #define AND 271 #define OR 272 #define NOT 273 #define YYERRCODE 256 typedef short YYINT; static const YYINT yylhs[] = { -1, 0, 0, 0, 6, 5, 4, 4, 4, 4, 4, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; static const YYINT yylen[] = { 2, 0, 2, 2, 2, 3, 2, 2, 2, 1, 1, 1, 2, 1, 3, 3, 2, 3, 2, 2, 2, 3, 3, 2, 3, 2, }; static const YYINT yydefred[] = { 0, 0, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 2, 3, 5, 0, 18, 19, 20, 0, 0, 23, 16, 0, 25, 0, 0, 12, 17, 21, 22, 24, 14, 15, }; static const YYINT yydgoto[] = { 7, 25, 26, 27, 8, 9, 10, }; static const YYINT yysindex[] = { -238, -59, 0, -249, -247, 0, -246, 0, -36, -238, -238, -36, 0, 0, 0, -245, -242, -240, -232, -231, -230, -229, -26, -36, -228, 0, -266, -36, 0, 0, 0, -227, 0, 0, 0, -226, -223, 0, 0, -5, 0, -36, -36, 0, 0, 0, 0, 0, 0, 0, }; static const YYINT yyrindex[] = { 38, 0, 0, 0, 0, 0, 0, 0, 0, 38, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const YYINT yygindex[] = { -2, -8, 18, 0, 0, 0, 0, }; #define YYTABLESIZE 280 static const YYINT yytable[] = { 24, 13, 11, 30, 23, 41, 42, 28, 29, 12, 24, 13, 14, 31, 23, 39, 32, 4, 33, 43, 1, 2, 3, 4, 5, 6, 34, 35, 36, 37, 40, 44, 45, 48, 49, 46, 47, 13, 1, 0, 38, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, 20, 21, 0, 0, 22, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 13, 4, 4, 4, 4, 4, 4, }; static const YYINT yycheck[] = { 36, 0, 61, 11, 40, 271, 272, 9, 10, 258, 36, 258, 258, 258, 40, 23, 258, 0, 258, 27, 258, 259, 260, 261, 262, 263, 258, 258, 258, 258, 258, 258, 258, 41, 42, 258, 41, 36, 0, -1, 22, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 264, 265, 266, 267, 268, 269, 270, -1, -1, 273, 264, 265, 266, 267, 268, 269, 270, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, -1, -1, 273, 258, 259, 260, 261, 262, 263, }; #define YYFINAL 7 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 273 #define YYUNDFTOKEN 282 #define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) #if YYDEBUG static const char *const yyname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,"'$'",0,0,0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"ERROR","STRING", "ACCEPT","REJECT","TEMPFAIL","DISCARD","QUARANTINE","CONNECT","HELO","ENVFROM", "ENVRCPT","HEADER","MACRO","BODY","AND","OR","NOT",0,0,0,0,0,0,0,0, "illegal-symbol", }; static const char *const yyrule[] = { "$accept : file", "file :", "file : macro file", "file : rule file", "rule : action expr_l", "macro : STRING '=' expr", "action : REJECT STRING", "action : TEMPFAIL STRING", "action : QUARANTINE STRING", "action : DISCARD", "action : ACCEPT", "expr_l : expr", "expr_l : expr_l expr", "expr : term", "expr : term AND expr", "expr : term OR expr", "expr : NOT term", "term : CONNECT STRING STRING", "term : HELO STRING", "term : ENVFROM STRING", "term : ENVRCPT STRING", "term : HEADER STRING STRING", "term : MACRO STRING STRING", "term : BODY STRING", "term : '(' expr ')'", "term : '$' STRING", }; #endif #if YYDEBUG int yydebug; #endif int yyerrflag; int yychar; YYSTYPE yyval; YYSTYPE yylval; int yynerrs; /* define the initial stack-sizes */ #ifdef YYSTACKSIZE #undef YYMAXDEPTH #define YYMAXDEPTH YYSTACKSIZE #else #ifdef YYMAXDEPTH #define YYSTACKSIZE YYMAXDEPTH #else #define YYSTACKSIZE 10000 #define YYMAXDEPTH 10000 #endif #endif #define YYINITSTACKSIZE 200 typedef struct { unsigned stacksize; YYINT *s_base; YYINT *s_mark; YYINT *s_last; YYSTYPE *l_base; YYSTYPE *l_mark; } YYSTACKDATA; /* variables for the parser stack */ static YYSTACKDATA yystack; #line 255 "parse.y" int yyerror(const char *fmt, ...) { va_list ap; errors = 1; if (err_str == NULL || err_len <= 0) return (0); va_start(ap, fmt); snprintf(err_str, err_len, "%s:%d: ", infile, yylval.lineno); vsnprintf(err_str + strlen(err_str), err_len - strlen(err_str), fmt, ap); va_end(ap); return (0); } struct keywords { const char *k_name; int k_val; }; static int kw_cmp(const void *k, const void *e) { return (strcmp(k, ((struct keywords *)e)->k_name)); } static int lookup(char *s) { /* keep sorted */ static const struct keywords keywords[] = { { "accept", ACCEPT }, { "and", AND }, { "body", BODY }, { "connect", CONNECT }, { "discard", DISCARD }, { "envfrom", ENVFROM }, { "envrcpt", ENVRCPT }, { "header", HEADER }, { "helo", HELO }, { "macro", MACRO }, { "not", NOT }, { "or", OR }, { "quarantine", QUARANTINE }, { "reject", REJECT }, { "tempfail", TEMPFAIL }, }; const struct keywords *p; p = bsearch(s, keywords, sizeof(keywords) / sizeof(keywords[0]), sizeof(keywords[0]), &kw_cmp); if (p) return (p->k_val); else return (STRING); } static int lgetc(FILE *fin) { int c, next; restart: c = getc(fin); if (c == '\\') { next = getc(fin); if (next != '\n') { ungetc(next, fin); return (c); } yylval.lineno = lineno; lineno++; goto restart; } return (c); } static int lungetc(int c, FILE *fin) { return ungetc(c, fin); } int yylex(void) { int c; top: yylval.lineno = lineno; while ((c = lgetc(fin)) == ' ' || c == '\t') ; if (c == '#') while ((c = lgetc(fin)) != '\n' && c != EOF) ; if (c == '\"' || c == '\'') { char del = c; char buf[8192], *p = buf; while ((c = lgetc(fin)) != EOF && c != del) { *p++ = c; if ((size_t)(p - buf) >= sizeof(buf) - 1) { yyerror("yylex: message too long"); return (ERROR); } } *p = 0; yylval.v.string = strdup(buf); if (yylval.v.string == NULL) { yyerror("yylex: strdup: %s", strerror(errno)); return (ERROR); } return (STRING); } if (isalpha(c)) { char buf[8192], *p = buf; int token; do { *p++ = c; if ((size_t)(p - buf) >= sizeof(buf)) { yyerror("yylex: token too long"); return (ERROR); } } while ((c = lgetc(fin)) != EOF && (isalpha(c) || isdigit(c) || ispunct(c))); lungetc(c, fin); *p = 0; token = lookup(buf); if (token == STRING) { yylval.v.string = strdup(buf); if (yylval.v.string == NULL) { yyerror("yylex: strdup: %s", strerror(errno)); return (ERROR); } } return (token); } if (c != '\n' && c != '(' && c != ')' && c != '=' && c != '$' && c != EOF) { char del = c; char buf[8192], *p = buf; *p++ = del; while ((c = lgetc(fin)) != EOF && c != '\n' && c != del) { *p++ = c; if ((size_t)(p - buf) >= sizeof(buf) - 1) { yyerror("yylex: argument too long"); return (ERROR); } } if (c != EOF && c != '\n') { *p++ = del; while ((c = lgetc(fin)) != EOF && isalpha(c)) { *p++ = c; if ((size_t)(p - buf) >= sizeof(buf)) { yyerror("yylex: argument too long"); return (ERROR); } } } if (c != EOF) lungetc(c, fin); *p = 0; yylval.v.string = strdup(buf); if (yylval.v.string == NULL) { yyerror("yylex: strdup: %s", strerror(errno)); return (ERROR); } return (STRING); } if (c == '\n') { lineno++; goto top; } if (c == EOF) return (0); return (c); } int parse_ruleset(const char *f, struct ruleset **r, char *err, size_t len) { *r = NULL; err_str = err; err_len = len; rs = create_ruleset(); if (rs == NULL) { if (err_str != NULL && err_len > 0) snprintf(err_str, err_len, "create_ruleset"); return (1); } infile = f; fin = fopen(infile, "rb"); if (fin == NULL) { if (err_str != NULL && err_len > 0) snprintf(err_str, err_len, "fopen: %s: %s", infile, strerror(errno)); return (1); } lineno = 1; errors = 0; yyparse(); fclose(fin); while (macros != NULL) { struct macro *m = macros->next; free(macros->name); free(macros); macros = m; } if (errors) { free_ruleset(rs); return (1); } else { *r = rs; return (0); } } static int define_macro(const char *name, struct expr *e) { struct macro *m = macros; while (m != NULL && strcmp(m->name, name)) m = m->next; if (m != NULL) { yyerror("define_macro: macro '%s' already defined", name); return (1); } m = calloc(1, sizeof(struct macro)); if (m == NULL) { yyerror("define_macro: calloc: %s", strerror(errno)); return (1); } m->name = strdup(name); if (m->name == NULL) { yyerror("define_macro: strdup: %s", strerror(errno)); free(m); return (1); } m->expr = e; m->next = macros; macros = m; return (0); } static struct expr * find_macro(const char *name) { struct macro *m = macros; while (m != NULL && strcmp(m->name, name)) m = m->next; if (m == NULL) return (NULL); return (m->expr); } #line 575 "y.tab.c" #if YYDEBUG #include /* needed for printf */ #endif #include /* needed for malloc, etc */ #include /* needed for memset */ /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int yygrowstack(YYSTACKDATA *data) { int i; unsigned newsize; YYINT *newss; YYSTYPE *newvs; if ((newsize = data->stacksize) == 0) newsize = YYINITSTACKSIZE; else if (newsize >= YYMAXDEPTH) return YYENOMEM; else if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; i = (int) (data->s_mark - data->s_base); newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss)); if (newss == 0) return YYENOMEM; data->s_base = newss; data->s_mark = newss + i; newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); if (newvs == 0) return YYENOMEM; data->l_base = newvs; data->l_mark = newvs + i; data->stacksize = newsize; data->s_last = data->s_base + newsize - 1; return 0; } #if YYPURE || defined(YY_NO_LEAKS) static void yyfreestack(YYSTACKDATA *data) { free(data->s_base); free(data->l_base); memset(data, 0, sizeof(*data)); } #else #define yyfreestack(data) /* nothing */ #endif #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab int YYPARSE_DECL() { int yym, yyn, yystate; #if YYDEBUG const char *yys; if ((yys = getenv("YYDEBUG")) != 0) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yym = 0; yyn = 0; yynerrs = 0; yyerrflag = 0; yychar = YYEMPTY; yystate = 0; #if YYPURE memset(&yystack, 0, sizeof(yystack)); #endif if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; yystack.s_mark = yystack.s_base; yystack.l_mark = yystack.l_base; yystate = 0; *yystack.s_mark = 0; yyloop: if ((yyn = yydefred[yystate]) != 0) goto yyreduce; if (yychar < 0) { yychar = YYLEX; if (yychar < 0) yychar = YYEOF; #if YYDEBUG if (yydebug) { if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN]; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if (((yyn = yysindex[yystate]) != 0) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; yystate = yytable[yyn]; *++yystack.s_mark = yytable[yyn]; *++yystack.l_mark = yylval; yychar = YYEMPTY; if (yyerrflag > 0) --yyerrflag; goto yyloop; } if (((yyn = yyrindex[yystate]) != 0) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag != 0) goto yyinrecovery; YYERROR_CALL("syntax error"); goto yyerrlab; /* redundant goto avoids 'unused label' warning */ yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if (((yyn = yysindex[*yystack.s_mark]) != 0) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; yystate = yytable[yyn]; *++yystack.s_mark = yytable[yyn]; *++yystack.l_mark = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yystack.s_mark); #endif if (yystack.s_mark <= yystack.s_base) goto yyabort; --yystack.s_mark; --yystack.l_mark; } } } else { if (yychar == YYEOF) goto yyabort; #if YYDEBUG if (yydebug) { if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN]; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = YYEMPTY; goto yyloop; } yyreduce: #if YYDEBUG if (yydebug) printf("%sdebug: state %d, reducing by rule %d (%s)\n", YYPREFIX, yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; if (yym > 0) yyval = yystack.l_mark[1-yym]; else memset(&yyval, 0, sizeof yyval); switch (yyn) { case 2: #line 88 "parse.y" { } break; case 3: #line 89 "parse.y" { } break; case 4: #line 92 "parse.y" { struct expr_list *el = yystack.l_mark[0].v.expr_list, *eln; while (el != NULL) { eln = el->next; el->expr->action = yystack.l_mark[-1].v.action; free(el); el = eln; } } break; case 5: #line 104 "parse.y" { if (define_macro(yystack.l_mark[-2].v.string, yystack.l_mark[0].v.expr)) YYERROR; free(yystack.l_mark[-2].v.string); } break; case 6: #line 111 "parse.y" { yyval.v.action = create_action(rs, ACTION_REJECT, yystack.l_mark[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yystack.l_mark[0].v.string); } break; case 7: #line 119 "parse.y" { yyval.v.action = create_action(rs, ACTION_TEMPFAIL, yystack.l_mark[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yystack.l_mark[0].v.string); } break; case 8: #line 127 "parse.y" { yyval.v.action = create_action(rs, ACTION_QUARANTINE, yystack.l_mark[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yystack.l_mark[0].v.string); } break; case 9: #line 135 "parse.y" { yyval.v.action = create_action(rs, ACTION_DISCARD, ""); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } } break; case 10: #line 142 "parse.y" { yyval.v.action = create_action(rs, ACTION_ACCEPT, ""); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } } break; case 11: #line 151 "parse.y" { yyval.v.expr_list = calloc(1, sizeof(struct expr_list)); if (yyval.v.expr_list == NULL) { yyerror("yyparse: calloc: %s", strerror(errno)); YYERROR; } yyval.v.expr_list->expr = yystack.l_mark[0].v.expr; } break; case 12: #line 159 "parse.y" { yyval.v.expr_list = calloc(1, sizeof(struct expr_list)); if (yyval.v.expr_list == NULL) { yyerror("yyparse: calloc: %s", strerror(errno)); YYERROR; } yyval.v.expr_list->expr = yystack.l_mark[0].v.expr; yyval.v.expr_list->next = yystack.l_mark[-1].v.expr_list; } break; case 13: #line 170 "parse.y" { yyval.v.expr = yystack.l_mark[0].v.expr; } break; case 14: #line 173 "parse.y" { yyval.v.expr = create_expr(rs, EXPR_AND, yystack.l_mark[-2].v.expr, yystack.l_mark[0].v.expr); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 15: #line 180 "parse.y" { yyval.v.expr = create_expr(rs, EXPR_OR, yystack.l_mark[-2].v.expr, yystack.l_mark[0].v.expr); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 16: #line 187 "parse.y" { yyval.v.expr = create_expr(rs, EXPR_NOT, yystack.l_mark[0].v.expr, NULL); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 17: #line 196 "parse.y" { yyval.v.expr = create_cond(rs, COND_CONNECT, yystack.l_mark[-1].v.string, yystack.l_mark[0].v.string); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[-1].v.string); free(yystack.l_mark[0].v.string); } break; case 18: #line 203 "parse.y" { yyval.v.expr = create_cond(rs, COND_HELO, yystack.l_mark[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[0].v.string); } break; case 19: #line 209 "parse.y" { yyval.v.expr = create_cond(rs, COND_ENVFROM, yystack.l_mark[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[0].v.string); } break; case 20: #line 215 "parse.y" { yyval.v.expr = create_cond(rs, COND_ENVRCPT, yystack.l_mark[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[0].v.string); } break; case 21: #line 221 "parse.y" { yyval.v.expr = create_cond(rs, COND_HEADER, yystack.l_mark[-1].v.string, yystack.l_mark[0].v.string); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[-1].v.string); free(yystack.l_mark[0].v.string); } break; case 22: #line 228 "parse.y" { yyval.v.expr = create_cond(rs, COND_MACRO, yystack.l_mark[-1].v.string, yystack.l_mark[0].v.string); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[-1].v.string); free(yystack.l_mark[0].v.string); } break; case 23: #line 235 "parse.y" { yyval.v.expr = create_cond(rs, COND_BODY, yystack.l_mark[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yystack.l_mark[0].v.string); } break; case 24: #line 241 "parse.y" { yyval.v.expr = yystack.l_mark[-1].v.expr; } break; case 25: #line 244 "parse.y" { yyval.v.expr = find_macro(yystack.l_mark[0].v.string); if (yyval.v.expr == NULL) { yyerror("yyparse: undefined macro '%s'", yystack.l_mark[0].v.string); YYERROR; } free(yystack.l_mark[0].v.string); } break; #line 998 "y.tab.c" } yystack.s_mark -= yym; yystate = *yystack.s_mark; yystack.l_mark -= yym; yym = yylhs[yyn]; if (yystate == 0 && yym == 0) { #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state 0 to\ state %d\n", YYPREFIX, YYFINAL); #endif yystate = YYFINAL; *++yystack.s_mark = YYFINAL; *++yystack.l_mark = yyval; if (yychar < 0) { yychar = YYLEX; if (yychar < 0) yychar = YYEOF; #if YYDEBUG if (yydebug) { if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN]; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == YYEOF) goto yyaccept; goto yyloop; } if (((yyn = yygindex[yym]) != 0) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yystate) yystate = yytable[yyn]; else yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) printf("%sdebug: after reduction, shifting from state %d \ to state %d\n", YYPREFIX, *yystack.s_mark, yystate); #endif if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow; *++yystack.s_mark = (YYINT) yystate; *++yystack.l_mark = yyval; goto yyloop; yyoverflow: YYERROR_CALL("yacc stack overflow"); yyabort: yyfreestack(&yystack); return (1); yyaccept: yyfreestack(&yystack); return (0); }