#ifndef lint static char const yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28.2.1 2001/07/19 05:46:39 peter Exp $"; #endif #include #define YYBYACC 1 #define YYMAJOR 1 #define YYMINOR 9 #define YYLEX yylex() #define YYEMPTY -1 #define yyclearin (yychar=(YYEMPTY)) #define yyerrok (yyerrflag=0) #define YYRECOVERING() (yyerrflag!=0) #if defined(__cplusplus) || __STDC__ static int yygrowstack(void); #else static int yygrowstack(); #endif #define YYPREFIX "yy" #line 34 "milter-regex-parse.y" static const char rcsid[] = "$Id: milter-regex-parse.y,v 1.4 2006/10/05 04:27:35 ca Exp $"; #include "sm/generic.h" SM_RCSID("@(#)$Id: milter-regex-parse.y,v 1.4 2006/10/05 04:27:35 ca Exp $") #include "sm/error.h" #include "sm/assert.h" #include "sm/types.h" #include "sm/ctype.h" #include "sm/sysexits.h" #include "sm/fcntl.h" #include "sm/io.h" #include "sm/regex.h" #include "sm/signal.h" #include "sm/syslog.h" #include "sm/smreplycodes.h" #include "sm/pmilter.h" #include "sm/pmfdef.h" #include "sm/pmfapi.h" #if MTA_USE_PMILTER #include #include "milter-regex-eval.h" int yyerror(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 75 "y.tab.c" #define YYERRCODE 256 #define ERROR 257 #define STRING 258 #define ACCEPT 259 #define REJECT 260 #define TEMPFAIL 261 #define DISCARD 262 #define QUARANTINE 263 #define REJECT_QUICK 264 #define CONNECT 265 #define HELO 266 #define ENVFROM 267 #define ENVRCPT 268 #define HEADER 269 #define BODY 270 #define AND 271 #define OR 272 #define NOT 273 const short yylhs[] = { -1, 0, 0, 0, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, }; const short yylen[] = { 2, 0, 2, 2, 2, 3, 2, 2, 2, 1, 1, 2, 1, 2, 1, 3, 3, 2, 3, 2, 2, 2, 3, 2, 3, 2, }; const short yydefred[] = { 0, 0, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 2, 3, 5, 0, 19, 20, 21, 0, 23, 17, 0, 25, 0, 0, 13, 18, 22, 24, 15, 16, }; const short yydgoto[] = { 8, 26, 27, 28, 9, 10, 11, }; const short yysindex[] = { -239, -58, 0, -248, -247, 0, -246, -243, 0, -36, -239, -239, -36, 0, 0, 0, 0, -242, -232, -231, -230, -229, -228, -27, -36, -225, 0, -266, -36, 0, 0, 0, -224, 0, 0, 0, -223, 0, 0, -5, 0, -36, -36, 0, 0, 0, 0, 0, 0, }; const short yyrindex[] = { 38, 0, 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, }; const short yygindex[] = { -3, -10, 16, 0, 0, 0, 0, }; #define YYTABLESIZE 281 const short yytable[] = { 25, 14, 31, 12, 24, 41, 42, 29, 30, 25, 13, 14, 15, 24, 39, 16, 32, 4, 43, 1, 2, 3, 4, 5, 6, 7, 33, 34, 35, 36, 37, 47, 48, 40, 44, 45, 46, 14, 1, 38, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 21, 22, 0, 0, 23, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 4, 4, 4, 4, 4, 4, 4, }; const short yycheck[] = { 36, 0, 12, 61, 40, 271, 272, 10, 11, 36, 258, 258, 258, 40, 24, 258, 258, 0, 28, 258, 259, 260, 261, 262, 263, 264, 258, 258, 258, 258, 258, 41, 42, 258, 258, 258, 41, 36, 0, 23, -1, 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, -1, 265, 266, 267, 268, 269, 270, -1, -1, 273, 265, 266, 267, 268, 269, 270, -1, -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, 264, }; #define YYFINAL 8 #ifndef YYDEBUG #define YYDEBUG 0 #endif #define YYMAXTOKEN 273 #if YYDEBUG 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","REJECT_QUICK","CONNECT", "HELO","ENVFROM","ENVRCPT","HEADER","BODY","AND","OR","NOT", }; 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", "action : REJECT_QUICK STRING", "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 : BODY STRING", "term : '(' expr ')'", "term : '$' STRING", }; #endif #if YYDEBUG #include #endif #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 int yydebug; int yynerrs; int yyerrflag; int yychar; short *yyssp; YYSTYPE *yyvsp; YYSTYPE yyval; YYSTYPE yylval; short *yyss; short *yysslim; YYSTYPE *yyvs; int yystacksize; #line 268 "milter-regex-parse.y" int yyerror(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 }, { "not", NOT }, { "or", OR }, { "quarantine", QUARANTINE }, { "reject", REJECT }, { "reject_quick", REJECT_QUICK }, { "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 (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 (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 (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 (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); } #ifdef __linux__ (void)&yyrcsid; /* warning about yyrcsid declared but unused */ #endif } 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); } #endif /* MTA_USE_PMILTER */ #line 542 "y.tab.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int yygrowstack() { int newsize, i; short *newss; YYSTYPE *newvs; if ((newsize = yystacksize) == 0) newsize = YYINITSTACKSIZE; else if (newsize >= YYMAXDEPTH) return -1; else if ((newsize *= 2) > YYMAXDEPTH) newsize = YYMAXDEPTH; i = yyssp - yyss; newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : (short *)malloc(newsize * sizeof *newss); if (newss == NULL) return -1; yyss = newss; yyssp = newss + i; newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : (YYSTYPE *)malloc(newsize * sizeof *newvs); if (newvs == NULL) return -1; yyvs = newvs; yyvsp = newvs + i; yystacksize = newsize; yysslim = yyss + newsize - 1; return 0; } #define YYABORT goto yyabort #define YYREJECT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab #ifndef YYPARSE_PARAM #if defined(__cplusplus) || __STDC__ #define YYPARSE_PARAM_ARG void #define YYPARSE_PARAM_DECL #else /* ! ANSI-C/C++ */ #define YYPARSE_PARAM_ARG #define YYPARSE_PARAM_DECL #endif /* ANSI-C/C++ */ #else /* YYPARSE_PARAM */ #ifndef YYPARSE_PARAM_TYPE #define YYPARSE_PARAM_TYPE void * #endif #if defined(__cplusplus) || __STDC__ #define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM #define YYPARSE_PARAM_DECL #else /* ! ANSI-C/C++ */ #define YYPARSE_PARAM_ARG YYPARSE_PARAM #define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM; #endif /* ANSI-C/C++ */ #endif /* ! YYPARSE_PARAM */ int yyparse (YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { register int yym, yyn, yystate; #if YYDEBUG register const char *yys; if ((yys = getenv("YYDEBUG"))) { yyn = *yys; if (yyn >= '0' && yyn <= '9') yydebug = yyn - '0'; } #endif yynerrs = 0; yyerrflag = 0; yychar = (-1); if (yyss == NULL && yygrowstack()) goto yyoverflow; yyssp = yyss; yyvsp = yyvs; *yyssp = yystate = 0; yyloop: if ((yyn = yydefred[yystate])) goto yyreduce; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif } if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, shifting to state %d\n", YYPREFIX, yystate, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; yychar = (-1); if (yyerrflag > 0) --yyerrflag; goto yyloop; } if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == yychar) { yyn = yytable[yyn]; goto yyreduce; } if (yyerrflag) goto yyinrecovery; #if defined(lint) || defined(__GNUC__) goto yynewerror; #endif yynewerror: yyerror("syntax error"); #if defined(lint) || defined(__GNUC__) goto yyerrlab; #endif yyerrlab: ++yynerrs; yyinrecovery: if (yyerrflag < 3) { yyerrflag = 3; for (;;) { if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) { #if YYDEBUG if (yydebug) printf("%sdebug: state %d, error recovery shifting\ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; goto yyloop; } else { #if YYDEBUG if (yydebug) printf("%sdebug: error recovery discarding state %d\n", YYPREFIX, *yyssp); #endif if (yyssp <= yyss) goto yyabort; --yyssp; --yyvsp; } } } else { if (yychar == 0) goto yyabort; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, error recovery discards token %d (%s)\n", YYPREFIX, yystate, yychar, yys); } #endif yychar = (-1); 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]; yyval = yyvsp[1-yym]; switch (yyn) { case 2: #line 100 "milter-regex-parse.y" { } break; case 3: #line 101 "milter-regex-parse.y" { } break; case 4: #line 104 "milter-regex-parse.y" { struct expr_list *el = yyvsp[0].v.expr_list, *eln; while (el != NULL) { eln = el->next; el->expr->action = yyvsp[-1].v.action; free(el); el = eln; } } break; case 5: #line 116 "milter-regex-parse.y" { if (define_macro(yyvsp[-2].v.string, yyvsp[0].v.expr)) YYERROR; free(yyvsp[-2].v.string); } break; case 6: #line 123 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_REJECT, yyvsp[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yyvsp[0].v.string); } break; case 7: #line 131 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_TEMPFAIL, yyvsp[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yyvsp[0].v.string); } break; case 8: #line 139 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_QUARANTINE, yyvsp[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yyvsp[0].v.string); } break; case 9: #line 147 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_DISCARD, ""); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } } break; case 10: #line 154 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_ACCEPT, ""); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } } break; case 11: #line 161 "milter-regex-parse.y" { yyval.v.action = create_action(rs, ACTION_REJECT_QUICK, yyvsp[0].v.string); if (yyval.v.action == NULL) { yyerror("yyparse: create_action"); YYERROR; } free(yyvsp[0].v.string); } break; case 12: #line 171 "milter-regex-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 = yyvsp[0].v.expr; } break; case 13: #line 179 "milter-regex-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 = yyvsp[0].v.expr; yyval.v.expr_list->next = yyvsp[-1].v.expr_list; } break; case 14: #line 190 "milter-regex-parse.y" { yyval.v.expr = yyvsp[0].v.expr; } break; case 15: #line 193 "milter-regex-parse.y" { yyval.v.expr = create_expr(rs, EXPR_AND, yyvsp[-2].v.expr, yyvsp[0].v.expr); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 16: #line 200 "milter-regex-parse.y" { yyval.v.expr = create_expr(rs, EXPR_OR, yyvsp[-2].v.expr, yyvsp[0].v.expr); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 17: #line 207 "milter-regex-parse.y" { yyval.v.expr = create_expr(rs, EXPR_NOT, yyvsp[0].v.expr, NULL); if (yyval.v.expr == NULL) { yyerror("yyparse: create_expr"); YYERROR; } } break; case 18: #line 216 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_CONNECT, yyvsp[-1].v.string, yyvsp[0].v.string); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[-1].v.string); free(yyvsp[0].v.string); } break; case 19: #line 223 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_HELO, yyvsp[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[0].v.string); } break; case 20: #line 229 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_ENVFROM, yyvsp[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[0].v.string); } break; case 21: #line 235 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_ENVRCPT, yyvsp[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[0].v.string); } break; case 22: #line 241 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_HEADER, yyvsp[-1].v.string, yyvsp[0].v.string); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[-1].v.string); free(yyvsp[0].v.string); } break; case 23: #line 248 "milter-regex-parse.y" { yyval.v.expr = create_cond(rs, COND_BODY, yyvsp[0].v.string, NULL); if (yyval.v.expr == NULL) YYERROR; free(yyvsp[0].v.string); } break; case 24: #line 254 "milter-regex-parse.y" { yyval.v.expr = yyvsp[-1].v.expr; } break; case 25: #line 257 "milter-regex-parse.y" { yyval.v.expr = find_macro(yyvsp[0].v.string); if (yyval.v.expr == NULL) { yyerror("yyparse: undefined macro '%s'", yyvsp[0].v.string); YYERROR; } free(yyvsp[0].v.string); } break; #line 962 "y.tab.c" } yyssp -= yym; yystate = *yyssp; yyvsp -= 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; *++yyssp = YYFINAL; *++yyvsp = yyval; if (yychar < 0) { if ((yychar = yylex()) < 0) yychar = 0; #if YYDEBUG if (yydebug) { yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; printf("%sdebug: state %d, reading %d (%s)\n", YYPREFIX, YYFINAL, yychar, yys); } #endif } if (yychar == 0) goto yyaccept; goto yyloop; } if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && yyn <= YYTABLESIZE && yycheck[yyn] == 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, *yyssp, yystate); #endif if (yyssp >= yysslim && yygrowstack()) { goto yyoverflow; } *++yyssp = yystate; *++yyvsp = yyval; goto yyloop; yyoverflow: yyerror("yacc stack overflow"); yyabort: return (1); yyaccept: return (0); }