Logo Search packages:      
Sourcecode: mailutils version File versions

sieve-gram.c

/*  A Bison parser, made from /home/gray/gnu/mailutils/libsieve/./sieve.y
    by GNU Bison version 1.28  */

#define YYBISON 1  /* Identify Bison output.  */

#define     IDENT 257
#define     TAG   258
#define     NUMBER      259
#define     STRING      260
#define     MULTILINE   261
#define     REQUIRE     262
#define     IF    263
#define     ELSIF 264
#define     ELSE  265
#define     ANYOF 266
#define     ALLOF 267
#define     NOT   268

#line 1 "sieve.y"

/* GNU Mailutils -- a suite of utilities for electronic mail
   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif  
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sieve.h>

sieve_machine_t sieve_machine;
int sieve_error_count;

static void branch_fixup __P((size_t start, size_t end));
int sieve_yyerror (char *s);
int sieve_yylex (); 

#line 35 "sieve.y"
typedef union {
  char *string;
  size_t number;
  sieve_instr_t instr;
  sieve_value_t *value;
  list_t list;
  size_t pc;
  struct {
    size_t start;
    size_t end;
  } pclist;
  struct {
    char *ident;
    list_t args;
  } command;
  struct {
    size_t begin;
    size_t cond;
    size_t branch;
  } branch;
} YYSTYPE;
#ifndef YYDEBUG
#define YYDEBUG 1
#endif

#include <stdio.h>

#ifndef __cplusplus
#ifndef __STDC__
#define const
#endif
#endif



#define     YYFINAL           68
#define     YYFLAG            -32768
#define     YYNTBASE    23

#define YYTRANSLATE(x) ((unsigned)(x) <= 268 ? sieve_yytranslate[x] : 46)

static const char sieve_yytranslate[] = {     0,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,    19,
    20,     2,     2,    18,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,    15,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
    21,     2,    22,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,    16,     2,    17,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
     7,     8,     9,    10,    11,    12,    13,    14
};

#if YYDEBUG != 0
static const short sieve_yyprhs[] = {     0,
     0,     1,     3,     5,     8,    12,    15,    20,    22,    24,
    28,    29,    31,    36,    42,    44,    46,    50,    52,    56,
    58,    60,    65,    70,    73,    74,    76,    79,    81,    82,
    84,    86,    89,    91,    93,    95,    97,    99,   101,   103,
   107,   109
};

static const short sieve_yyrhs[] = {    -1,
    24,     0,    25,     0,    24,    25,     0,     8,    43,    15,
     0,    39,    15,     0,    26,    34,    32,    27,     0,     9,
     0,    28,     0,    28,    31,    32,     0,     0,    29,     0,
    30,    36,    34,    32,     0,    29,    30,    36,    34,    32,
     0,    10,     0,    11,     0,    16,    24,    17,     0,    35,
     0,    33,    18,    35,     0,    35,     0,    37,     0,    12,
    19,    33,    20,     0,    13,    19,    33,    20,     0,    14,
    35,     0,     0,    38,     0,     3,    40,     0,    38,     0,
     0,    41,     0,    42,     0,    41,    42,     0,    44,     0,
     6,     0,     7,     0,     5,     0,     4,     0,     6,     0,
    44,     0,    21,    45,    22,     0,     6,     0,    45,    18,
     6,     0
};

#endif

#if YYDEBUG != 0
static const short sieve_yyrline[] = { 0,
    71,    72,    76,    77,    80,    88,    90,    98,   104,   115,
   132,   136,   139,   145,   155,   163,   171,   177,   184,   195,
   203,   205,   209,   213,   220,   226,   245,   252,   271,   275,
   278,   283,   290,   294,   298,   302,   306,   312,   317,   320,
   326,   331
};
#endif


#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)

static const char * const sieve_yytname[] = {   "$","error","$undefined.","IDENT",
"TAG","NUMBER","STRING","MULTILINE","REQUIRE","IF","ELSIF","ELSE","ANYOF","ALLOF",
"NOT","';'","'{'","'}'","','","'('","')'","'['","']'","input","list","statement",
"if","else_part","maybe_elsif","elsif_branch","elsif","else","block","testlist",
"cond","cond_expr","begin","test","command","action","maybe_arglist","arglist",
"arg","stringorlist","stringlist","slist", NULL
};
#endif

static const short sieve_yyr1[] = {     0,
    23,    23,    24,    24,    25,    25,    25,    26,    27,    27,
    28,    28,    29,    29,    30,    31,    32,    33,    33,    34,
    35,    35,    35,    35,    36,    37,    38,    39,    40,    40,
    41,    41,    42,    42,    42,    42,    42,    43,    43,    44,
    45,    45
};

static const short sieve_yyr2[] = {     0,
     0,     1,     1,     2,     3,     2,     4,     1,     1,     3,
     0,     1,     4,     5,     1,     1,     3,     1,     3,     1,
     1,     4,     4,     2,     0,     1,     2,     1,     0,     1,
     1,     2,     1,     1,     1,     1,     1,     1,     1,     3,
     1,     3
};

static const short sieve_yydefact[] = {     1,
    29,     0,     8,     2,     3,     0,    28,     0,    37,    36,
    34,    35,     0,    27,    30,    31,    33,    38,     0,    39,
     4,     0,     0,     0,     0,    20,    21,    26,     6,    41,
     0,    32,     5,     0,     0,    24,     0,    11,     0,    40,
     0,    18,     0,     0,    15,     7,     9,    12,    25,    42,
     0,    22,    23,    17,    16,     0,    25,     0,    19,    10,
     0,     0,     0,    13,    14,     0,     0,     0
};

static const short sieve_yydefgoto[] = {    66,
     4,     5,     6,    46,    47,    48,    49,    56,    38,    41,
    25,    26,    58,    27,    28,     8,    14,    15,    16,    19,
    17,    31
};

static const short sieve_yypact[] = {    27,
     1,     3,-32768,    27,-32768,     7,-32768,   -12,-32768,-32768,
-32768,-32768,     9,-32768,     1,-32768,-32768,-32768,    12,-32768,
-32768,     4,    23,     7,    30,-32768,-32768,-32768,-32768,-32768,
    -4,-32768,-32768,     7,     7,-32768,    27,    18,    33,-32768,
    20,-32768,    25,     8,-32768,-32768,    36,    18,-32768,-32768,
     7,-32768,-32768,-32768,-32768,    30,-32768,     7,-32768,-32768,
     7,    30,    30,-32768,-32768,    48,    49,-32768
};

static const short sieve_yypgoto[] = {-32768,
    13,    -3,-32768,-32768,-32768,-32768,     5,-32768,   -30,    16,
   -27,   -22,    -5,-32768,     0,-32768,-32768,-32768,    39,-32768,
    53,-32768
};


#define     YYLAST            55


static const short sieve_yytable[] = {     7,
    21,    36,    29,     7,     9,    10,    11,    12,    18,     1,
     1,    42,    42,    39,    30,     2,     3,    40,    22,    23,
    24,    13,    34,    13,    54,    60,    33,    45,    59,     1,
    62,    64,    65,    63,     2,     3,     7,    51,    50,    52,
    21,    35,    51,     7,    53,    37,    55,    67,    68,    44,
    43,    61,    57,    32,    20
};

static const short sieve_yycheck[] = {     0,
     4,    24,    15,     4,     4,     5,     6,     7,     6,     3,
     3,    34,    35,    18,     6,     8,     9,    22,    12,    13,
    14,    21,    19,    21,    17,    56,    15,    10,    51,     3,
    58,    62,    63,    61,     8,     9,    37,    18,     6,    20,
    44,    19,    18,    44,    20,    16,    11,     0,     0,    37,
    35,    57,    48,    15,     2
};
/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
#line 3 "/usr/share/bison.simple"
/* This file comes from bison-1.28.  */

/* Skeleton output parser for bison,
   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* As a special exception, when this file is copied by Bison into a
   Bison output file, you may use that output file without restriction.
   This special exception was added by the Free Software Foundation
   in version 1.24 of Bison.  */

/* This is the parser code that is written into each bison parser
  when the %semantic_parser declaration is not specified in the grammar.
  It was written by Richard Stallman by simplifying the hairy parser
  used when %semantic_parser is specified.  */

#ifndef YYSTACK_USE_ALLOCA
#ifdef alloca
#define YYSTACK_USE_ALLOCA
#else /* alloca not defined */
#ifdef __GNUC__
#define YYSTACK_USE_ALLOCA
#define alloca __builtin_alloca
#else /* not GNU C.  */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
#define YYSTACK_USE_ALLOCA
#include <alloca.h>
#else /* not sparc */
/* We think this test detects Watcom and Microsoft C.  */
/* This used to test MSDOS, but that is a bad idea
   since that symbol is in the user namespace.  */
#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
#if 0 /* No need for malloc.h, which pollutes the namespace;
       instead, just don't use alloca.  */
#include <malloc.h>
#endif
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
/* I don't know what this was needed for, but it pollutes the namespace.
   So I turned it off.   rms, 2 May 1997.  */
/* #include <malloc.h>  */
 #pragma alloca
#define YYSTACK_USE_ALLOCA
#else /* not MSDOS, or __TURBOC__, or _AIX */
#if 0
#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
             and on HPUX 10.  Eventually we can turn this on.  */
#define YYSTACK_USE_ALLOCA
#define alloca __builtin_alloca
#endif /* __hpux */
#endif
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
#endif /* not sparc */
#endif /* not GNU C */
#endif /* alloca not defined */
#endif /* YYSTACK_USE_ALLOCA not defined */

#ifdef YYSTACK_USE_ALLOCA
#define YYSTACK_ALLOC alloca
#else
#define YYSTACK_ALLOC malloc
#endif

/* Note: there must be only one dollar sign in this file.
   It is replaced by the list of actions, each action
   as one case of the switch.  */

#define sieve_yyerrok         (sieve_yyerrstatus = 0)
#define sieve_yyclearin (sieve_yychar = YYEMPTY)
#define YYEMPTY         -2
#define YYEOF           0
#define YYACCEPT  goto sieve_yyacceptlab
#define YYABORT   goto sieve_yyabortlab
#define YYERROR         goto sieve_yyerrlab1
/* Like YYERROR except do call sieve_yyerror.
   This remains here temporarily to ease the
   transition to the new meaning of YYERROR, for GCC.
   Once GCC version 2 has supplanted version 1, this can go.  */
#define YYFAIL          goto sieve_yyerrlab
#define YYRECOVERING()  (!!sieve_yyerrstatus)
#define YYBACKUP(token, value) \
do                                              \
  if (sieve_yychar == YYEMPTY && sieve_yylen == 1)                      \
    { sieve_yychar = (token), sieve_yylval = (value);             \
      sieve_yychar1 = YYTRANSLATE (sieve_yychar);                       \
      YYPOPSTACK;                               \
      goto sieve_yybackup;                                  \
    }                                           \
  else                                                \
    { sieve_yyerror ("syntax error: cannot back up"); YYERROR; }  \
while (0)

#define YYTERROR  1
#define YYERRCODE 256

#ifndef YYPURE
#define YYLEX           sieve_yylex()
#endif

#ifdef YYPURE
#ifdef YYLSP_NEEDED
#ifdef YYLEX_PARAM
#define YYLEX           sieve_yylex(&sieve_yylval, &sieve_yylloc, YYLEX_PARAM)
#else
#define YYLEX           sieve_yylex(&sieve_yylval, &sieve_yylloc)
#endif
#else /* not YYLSP_NEEDED */
#ifdef YYLEX_PARAM
#define YYLEX           sieve_yylex(&sieve_yylval, YYLEX_PARAM)
#else
#define YYLEX           sieve_yylex(&sieve_yylval)
#endif
#endif /* not YYLSP_NEEDED */
#endif

/* If nonreentrant, generate the variables here */

#ifndef YYPURE

int   sieve_yychar;                 /*  the lookahead symbol            */
YYSTYPE     sieve_yylval;                 /*  the semantic value of the       */
                        /*  lookahead symbol                */

#ifdef YYLSP_NEEDED
YYLTYPE sieve_yylloc;               /*  location data for the lookahead */
                        /*  symbol                    */
#endif

int sieve_yynerrs;                  /*  number of parse errors so far       */
#endif  /* not YYPURE */

#if YYDEBUG != 0
int sieve_yydebug;                  /*  nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
   from coexisting.  */
#endif

/*  YYINITDEPTH indicates the initial size of the parser's stacks */

#ifndef     YYINITDEPTH
#define YYINITDEPTH 200
#endif

/*  YYMAXDEPTH is the maximum size the stacks can grow to
    (effective only if the built-in stack extension method is used).  */

#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif

#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif

/* Define __sieve_yy_memcpy.  Note that the size argument
   should be passed with type unsigned int, because that is what the non-GCC
   definitions require.  With GCC, __builtin_memcpy takes an arg
   of type size_t, but it can handle unsigned int.  */

#if __GNUC__ > 1        /* GNU C and GNU C++ define this.  */
#define __sieve_yy_memcpy(TO,FROM,COUNT)  __builtin_memcpy(TO,FROM,COUNT)
#else                   /* not GNU C or C++ */
#ifndef __cplusplus

/* This is the most reliable way to avoid incompatibilities
   in available built-in functions on various systems.  */
static void
__sieve_yy_memcpy (to, from, count)
     char *to;
     char *from;
     unsigned int count;
{
  register char *f = from;
  register char *t = to;
  register int i = count;

  while (i-- > 0)
    *t++ = *f++;
}

#else /* __cplusplus */

/* This is the most reliable way to avoid incompatibilities
   in available built-in functions on various systems.  */
static void
__sieve_yy_memcpy (char *to, char *from, unsigned int count)
{
  register char *t = to;
  register char *f = from;
  register int i = count;

  while (i-- > 0)
    *t++ = *f++;
}

#endif
#endif

#line 217 "/usr/share/bison.simple"

/* The user can define YYPARSE_PARAM as the name of an argument to be passed
   into sieve_yyparse.  The argument should have type void *.
   It should actually point to an object.
   Grammar actions can access the variable by casting it
   to the proper pointer type.  */

#ifdef YYPARSE_PARAM
#ifdef __cplusplus
#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
#define YYPARSE_PARAM_DECL
#else /* not __cplusplus */
#define YYPARSE_PARAM_ARG YYPARSE_PARAM
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
#endif /* not __cplusplus */
#else /* not YYPARSE_PARAM */
#define YYPARSE_PARAM_ARG
#define YYPARSE_PARAM_DECL
#endif /* not YYPARSE_PARAM */

/* Prevent warning if -Wstrict-prototypes.  */
#ifdef __GNUC__
#ifdef YYPARSE_PARAM
int sieve_yyparse (void *);
#else
int sieve_yyparse (void);
#endif
#endif

int
sieve_yyparse(YYPARSE_PARAM_ARG)
     YYPARSE_PARAM_DECL
{
  register int sieve_yystate;
  register int sieve_yyn;
  register short *sieve_yyssp;
  register YYSTYPE *sieve_yyvsp;
  int sieve_yyerrstatus;      /*  number of tokens to shift before error messages enabled */
  int sieve_yychar1 = 0;            /*  lookahead token as an internal (translated) token number */

  short     sieve_yyssa[YYINITDEPTH];     /*  the state stack                 */
  YYSTYPE sieve_yyvsa[YYINITDEPTH]; /*  the semantic value stack        */

  short *sieve_yyss = sieve_yyssa;        /*  refer to the stacks thru separate pointers */
  YYSTYPE *sieve_yyvs = sieve_yyvsa;      /*  to allow sieve_yyoverflow to reallocate them elsewhere */

#ifdef YYLSP_NEEDED
  YYLTYPE sieve_yylsa[YYINITDEPTH]; /*  the location stack              */
  YYLTYPE *sieve_yyls = sieve_yylsa;
  YYLTYPE *sieve_yylsp;

#define YYPOPSTACK   (sieve_yyvsp--, sieve_yyssp--, sieve_yylsp--)
#else
#define YYPOPSTACK   (sieve_yyvsp--, sieve_yyssp--)
#endif

  int sieve_yystacksize = YYINITDEPTH;
  int sieve_yyfree_stacks = 0;

#ifdef YYPURE
  int sieve_yychar;
  YYSTYPE sieve_yylval;
  int sieve_yynerrs;
#ifdef YYLSP_NEEDED
  YYLTYPE sieve_yylloc;
#endif
#endif

  YYSTYPE sieve_yyval;        /*  the variable used to return           */
                        /*  semantic values from the action */
                        /*  routines                        */

  int sieve_yylen;

#if YYDEBUG != 0
  if (sieve_yydebug)
    fprintf(stderr, "Starting parse\n");
#endif

  sieve_yystate = 0;
  sieve_yyerrstatus = 0;
  sieve_yynerrs = 0;
  sieve_yychar = YYEMPTY;           /* Cause a token to be read.  */

  /* Initialize stack pointers.
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized.  */

  sieve_yyssp = sieve_yyss - 1;
  sieve_yyvsp = sieve_yyvs;
#ifdef YYLSP_NEEDED
  sieve_yylsp = sieve_yyls;
#endif

/* Push a new state, which is found in  sieve_yystate  .  */
/* In all cases, when you get here, the value and location stacks
   have just been pushed. so pushing a state here evens the stacks.  */
sieve_yynewstate:

  *++sieve_yyssp = sieve_yystate;

  if (sieve_yyssp >= sieve_yyss + sieve_yystacksize - 1)
    {
      /* Give user a chance to reallocate the stack */
      /* Use copies of these so that the &'s don't force the real ones into memory. */
      YYSTYPE *sieve_yyvs1 = sieve_yyvs;
      short *sieve_yyss1 = sieve_yyss;
#ifdef YYLSP_NEEDED
      YYLTYPE *sieve_yyls1 = sieve_yyls;
#endif

      /* Get the current used size of the three stacks, in elements.  */
      int size = sieve_yyssp - sieve_yyss + 1;

#ifdef sieve_yyoverflow
      /* Each stack pointer address is followed by the size of
       the data in use in that stack, in bytes.  */
#ifdef YYLSP_NEEDED
      /* This used to be a conditional around just the two extra args,
       but that might be undefined if sieve_yyoverflow is a macro.  */
      sieve_yyoverflow("parser stack overflow",
             &sieve_yyss1, size * sizeof (*sieve_yyssp),
             &sieve_yyvs1, size * sizeof (*sieve_yyvsp),
             &sieve_yyls1, size * sizeof (*sieve_yylsp),
             &sieve_yystacksize);
#else
      sieve_yyoverflow("parser stack overflow",
             &sieve_yyss1, size * sizeof (*sieve_yyssp),
             &sieve_yyvs1, size * sizeof (*sieve_yyvsp),
             &sieve_yystacksize);
#endif

      sieve_yyss = sieve_yyss1; sieve_yyvs = sieve_yyvs1;
#ifdef YYLSP_NEEDED
      sieve_yyls = sieve_yyls1;
#endif
#else /* no sieve_yyoverflow */
      /* Extend the stack our own way.  */
      if (sieve_yystacksize >= YYMAXDEPTH)
      {
        sieve_yyerror("parser stack overflow");
        if (sieve_yyfree_stacks)
          {
            free (sieve_yyss);
            free (sieve_yyvs);
#ifdef YYLSP_NEEDED
            free (sieve_yyls);
#endif
          }
        return 2;
      }
      sieve_yystacksize *= 2;
      if (sieve_yystacksize > YYMAXDEPTH)
      sieve_yystacksize = YYMAXDEPTH;
#ifndef YYSTACK_USE_ALLOCA
      sieve_yyfree_stacks = 1;
#endif
      sieve_yyss = (short *) YYSTACK_ALLOC (sieve_yystacksize * sizeof (*sieve_yyssp));
      __sieve_yy_memcpy ((char *)sieve_yyss, (char *)sieve_yyss1,
               size * (unsigned int) sizeof (*sieve_yyssp));
      sieve_yyvs = (YYSTYPE *) YYSTACK_ALLOC (sieve_yystacksize * sizeof (*sieve_yyvsp));
      __sieve_yy_memcpy ((char *)sieve_yyvs, (char *)sieve_yyvs1,
               size * (unsigned int) sizeof (*sieve_yyvsp));
#ifdef YYLSP_NEEDED
      sieve_yyls = (YYLTYPE *) YYSTACK_ALLOC (sieve_yystacksize * sizeof (*sieve_yylsp));
      __sieve_yy_memcpy ((char *)sieve_yyls, (char *)sieve_yyls1,
               size * (unsigned int) sizeof (*sieve_yylsp));
#endif
#endif /* no sieve_yyoverflow */

      sieve_yyssp = sieve_yyss + size - 1;
      sieve_yyvsp = sieve_yyvs + size - 1;
#ifdef YYLSP_NEEDED
      sieve_yylsp = sieve_yyls + size - 1;
#endif

#if YYDEBUG != 0
      if (sieve_yydebug)
      fprintf(stderr, "Stack size increased to %d\n", sieve_yystacksize);
#endif

      if (sieve_yyssp >= sieve_yyss + sieve_yystacksize - 1)
      YYABORT;
    }

#if YYDEBUG != 0
  if (sieve_yydebug)
    fprintf(stderr, "Entering state %d\n", sieve_yystate);
#endif

  goto sieve_yybackup;
 sieve_yybackup:

/* Do appropriate processing given the current state.  */
/* Read a lookahead token if we need one and don't already have one.  */
/* sieve_yyresume: */

  /* First try to decide what to do without reference to lookahead token.  */

  sieve_yyn = sieve_yypact[sieve_yystate];
  if (sieve_yyn == YYFLAG)
    goto sieve_yydefault;

  /* Not known => get a lookahead token if don't already have one.  */

  /* sieve_yychar is either YYEMPTY or YYEOF
     or a valid token in external form.  */

  if (sieve_yychar == YYEMPTY)
    {
#if YYDEBUG != 0
      if (sieve_yydebug)
      fprintf(stderr, "Reading a token: ");
#endif
      sieve_yychar = YYLEX;
    }

  /* Convert token to internal form (in sieve_yychar1) for indexing tables with */

  if (sieve_yychar <= 0)            /* This means end of input. */
    {
      sieve_yychar1 = 0;
      sieve_yychar = YYEOF;         /* Don't call YYLEX any more */

#if YYDEBUG != 0
      if (sieve_yydebug)
      fprintf(stderr, "Now at end of input.\n");
#endif
    }
  else
    {
      sieve_yychar1 = YYTRANSLATE(sieve_yychar);

#if YYDEBUG != 0
      if (sieve_yydebug)
      {
        fprintf (stderr, "Next token is %d (%s", sieve_yychar, sieve_yytname[sieve_yychar1]);
        /* Give the individual parser a way to print the precise meaning
           of a token, for further debugging info.  */
#ifdef YYPRINT
        YYPRINT (stderr, sieve_yychar, sieve_yylval);
#endif
        fprintf (stderr, ")\n");
      }
#endif
    }

  sieve_yyn += sieve_yychar1;
  if (sieve_yyn < 0 || sieve_yyn > YYLAST || sieve_yycheck[sieve_yyn] != sieve_yychar1)
    goto sieve_yydefault;

  sieve_yyn = sieve_yytable[sieve_yyn];

  /* sieve_yyn is what to do for this token type in this state.
     Negative => reduce, -sieve_yyn is rule number.
     Positive => shift, sieve_yyn is new state.
       New state is final state => don't bother to shift,
       just return success.
     0, or most negative number => error.  */

  if (sieve_yyn < 0)
    {
      if (sieve_yyn == YYFLAG)
      goto sieve_yyerrlab;
      sieve_yyn = -sieve_yyn;
      goto sieve_yyreduce;
    }
  else if (sieve_yyn == 0)
    goto sieve_yyerrlab;

  if (sieve_yyn == YYFINAL)
    YYACCEPT;

  /* Shift the lookahead token.  */

#if YYDEBUG != 0
  if (sieve_yydebug)
    fprintf(stderr, "Shifting token %d (%s), ", sieve_yychar, sieve_yytname[sieve_yychar1]);
#endif

  /* Discard the token being shifted unless it is eof.  */
  if (sieve_yychar != YYEOF)
    sieve_yychar = YYEMPTY;

  *++sieve_yyvsp = sieve_yylval;
#ifdef YYLSP_NEEDED
  *++sieve_yylsp = sieve_yylloc;
#endif

  /* count tokens shifted since error; after three, turn off error status.  */
  if (sieve_yyerrstatus) sieve_yyerrstatus--;

  sieve_yystate = sieve_yyn;
  goto sieve_yynewstate;

/* Do the default action for the current state.  */
sieve_yydefault:

  sieve_yyn = sieve_yydefact[sieve_yystate];
  if (sieve_yyn == 0)
    goto sieve_yyerrlab;

/* Do a reduction.  sieve_yyn is the number of a rule to reduce with.  */
sieve_yyreduce:
  sieve_yylen = sieve_yyr2[sieve_yyn];
  if (sieve_yylen > 0)
    sieve_yyval = sieve_yyvsp[1-sieve_yylen]; /* implement default value of the action */

#if YYDEBUG != 0
  if (sieve_yydebug)
    {
      int i;

      fprintf (stderr, "Reducing via rule %d (line %d), ",
             sieve_yyn, sieve_yyrline[sieve_yyn]);

      /* Print the symbols being reduced, and their result.  */
      for (i = sieve_yyprhs[sieve_yyn]; sieve_yyrhs[i] > 0; i++)
      fprintf (stderr, "%s ", sieve_yytname[sieve_yyrhs[i]]);
      fprintf (stderr, " -> %s\n", sieve_yytname[sieve_yyr1[sieve_yyn]]);
    }
#endif


  switch (sieve_yyn) {

case 2:
#line 73 "sieve.y"
{ /* to placate bison */ ;
    break;}
case 5:
#line 81 "sieve.y"
{
             sieve_require (sieve_yyvsp[-1].list);
             /*  All the items in $2 are registered in memory_pool,
                 so we don't free them */
             list_destroy (&sieve_yyvsp[-1].list);
             sieve_yyval.pc = sieve_machine->pc;
             ;
    break;}
case 7:
#line 91 "sieve.y"
{
             sieve_machine->prog[sieve_yyvsp[-2].pc].pc = sieve_yyvsp[0].branch.begin - sieve_yyvsp[-2].pc - 1;
             if (sieve_yyvsp[0].branch.branch)
               branch_fixup (sieve_yyvsp[0].branch.branch, sieve_machine->pc);
             ;
    break;}
case 8:
#line 99 "sieve.y"
{
             sieve_yyval.pc = sieve_machine->pc;
             ;
    break;}
case 9:
#line 105 "sieve.y"
{
             if (sieve_yyvsp[0].branch.begin)
               sieve_machine->prog[sieve_yyvsp[0].branch.cond].pc =
                              sieve_machine->pc - sieve_yyvsp[0].branch.cond - 1;
             else
               {
                 sieve_yyval.branch.begin = sieve_machine->pc;
                 sieve_yyval.branch.branch = 0;
               }
             ;
    break;}
case 10:
#line 116 "sieve.y"
{
             if (sieve_yyvsp[-2].branch.begin)
               {
                 sieve_machine->prog[sieve_yyvsp[-2].branch.cond].pc = sieve_yyvsp[0].pc - sieve_yyvsp[-2].branch.cond - 1;
                 sieve_machine->prog[sieve_yyvsp[-1].pc].pc = sieve_yyvsp[-2].branch.branch;
                 sieve_yyval.branch.begin = sieve_yyvsp[-2].branch.begin;
                 sieve_yyval.branch.branch = sieve_yyvsp[-1].pc;
               }
             else
               {
                 sieve_yyval.branch.begin = sieve_yyvsp[0].pc;
                 sieve_yyval.branch.branch = sieve_yyvsp[-1].pc;
               }
             ;
    break;}
case 11:
#line 133 "sieve.y"
{
             sieve_yyval.branch.begin = 0;
             ;
    break;}
case 13:
#line 140 "sieve.y"
{
             sieve_yyval.branch.begin = sieve_yyvsp[-2].pc; 
             sieve_yyval.branch.branch = sieve_yyvsp[-3].pc;
             sieve_yyval.branch.cond = sieve_yyvsp[-1].pc;
             ;
    break;}
case 14:
#line 146 "sieve.y"
{
             sieve_machine->prog[sieve_yyvsp[-4].branch.cond].pc = sieve_yyvsp[-2].pc - sieve_yyvsp[-4].branch.cond - 1;
             sieve_machine->prog[sieve_yyvsp[-3].pc].pc = sieve_yyvsp[-4].branch.branch;
             sieve_yyval.branch.begin = sieve_yyvsp[-4].branch.begin;
             sieve_yyval.branch.branch = sieve_yyvsp[-3].pc;
             sieve_yyval.branch.cond = sieve_yyvsp[-1].pc;
             ;
    break;}
case 15:
#line 156 "sieve.y"
{
             sieve_code_instr (instr_branch);
             sieve_yyval.pc = sieve_machine->pc;
             sieve_code_number (0);
             ;
    break;}
case 16:
#line 164 "sieve.y"
{
             sieve_code_instr (instr_branch);
             sieve_yyval.pc = sieve_machine->pc;
             sieve_code_number (0);
             ;
    break;}
case 17:
#line 172 "sieve.y"
{
             sieve_yyval.pc = sieve_yyvsp[-1].pc;
             ;
    break;}
case 18:
#line 178 "sieve.y"
{
             sieve_yyval.pclist.start = sieve_yyval.pclist.end = sieve_machine->pc;
             if (sieve_code_instr (instr_brz)
                 || sieve_code_number (0))
               YYERROR;
             ;
    break;}
case 19:
#line 185 "sieve.y"
{
             sieve_machine->prog[sieve_yyvsp[-2].pclist.end+1].pc = sieve_machine->pc;
             sieve_yyvsp[-2].pclist.end = sieve_machine->pc;
             if (sieve_code_instr (instr_brz)
                 || sieve_code_number (0))
               YYERROR;
             sieve_yyval.pclist = sieve_yyvsp[-2].pclist;
             ;
    break;}
case 20:
#line 196 "sieve.y"
{
             sieve_code_instr (instr_brz);
             sieve_yyval.pc = sieve_machine->pc;
             sieve_code_number (0);
             ;
    break;}
case 21:
#line 204 "sieve.y"
{ /* to placate bison */ ;
    break;}
case 22:
#line 206 "sieve.y"
{
             sieve_code_anyof (sieve_yyvsp[-1].pclist.start);
             ;
    break;}
case 23:
#line 210 "sieve.y"
{
             sieve_code_allof (sieve_yyvsp[-1].pclist.start);
             ;
    break;}
case 24:
#line 214 "sieve.y"
{
             if (sieve_code_instr (instr_not))
               YYERROR;
             ;
    break;}
case 25:
#line 221 "sieve.y"
{
             sieve_yyval.pc = sieve_machine->pc;
             ;
    break;}
case 26:
#line 227 "sieve.y"
{
             sieve_register_t *reg = sieve_test_lookup (sieve_machine,
                                              sieve_yyvsp[0].command.ident);
             sieve_yyval.pc = sieve_machine->pc;

             if (!reg)
               sieve_compile_error (sieve_filename, sieve_line_num,
                                _("unknown test: %s"),
                        sieve_yyvsp[0].command.ident);
             else if (!reg->required)
               sieve_compile_error (sieve_filename, sieve_line_num,
                                _("test `%s' has not been required"),
                        sieve_yyvsp[0].command.ident);
             else if (sieve_code_test (reg, sieve_yyvsp[0].command.args))
               YYERROR;
             ;
    break;}
case 27:
#line 246 "sieve.y"
{
             sieve_yyval.command.ident = sieve_yyvsp[-1].string;
             sieve_yyval.command.args = sieve_yyvsp[0].list;
             ;
    break;}
case 28:
#line 253 "sieve.y"
{
             sieve_register_t *reg = sieve_action_lookup (sieve_machine,
                                                sieve_yyvsp[0].command.ident);
             
             sieve_yyval.pc = sieve_machine->pc;
             if (!reg)
               sieve_compile_error (sieve_filename, sieve_line_num,
                                _("unknown action: %s"),
                        sieve_yyvsp[0].command.ident);
             else if (!reg->required)
               sieve_compile_error (sieve_filename, sieve_line_num,
                                _("action `%s' has not been required"),
                        sieve_yyvsp[0].command.ident);
             else if (sieve_code_action (reg, sieve_yyvsp[0].command.args))
               YYERROR;
             ;
    break;}
case 29:
#line 272 "sieve.y"
{
             sieve_yyval.list = NULL;
             ;
    break;}
case 31:
#line 279 "sieve.y"
{
             list_create (&sieve_yyval.list);
             list_append (sieve_yyval.list, sieve_yyvsp[0].value);
             ;
    break;}
case 32:
#line 284 "sieve.y"
{
             list_append (sieve_yyvsp[-1].list, sieve_yyvsp[0].value);
             sieve_yyval.list = sieve_yyvsp[-1].list;
             ;
    break;}
case 33:
#line 291 "sieve.y"
{
             sieve_yyval.value = sieve_value_create (SVT_STRING_LIST, sieve_yyvsp[0].list);
             ;
    break;}
case 34:
#line 295 "sieve.y"
{
             sieve_yyval.value = sieve_value_create (SVT_STRING, sieve_yyvsp[0].string);
               ;
    break;}
case 35:
#line 299 "sieve.y"
{
             sieve_yyval.value = sieve_value_create (SVT_STRING, sieve_yyvsp[0].string);
             ;
    break;}
case 36:
#line 303 "sieve.y"
{
             sieve_yyval.value = sieve_value_create (SVT_NUMBER, &sieve_yyvsp[0].number);
             ;
    break;}
case 37:
#line 307 "sieve.y"
{
             sieve_yyval.value = sieve_value_create (SVT_TAG, sieve_yyvsp[0].string);
             ;
    break;}
case 38:
#line 313 "sieve.y"
{
             list_create (&sieve_yyval.list);
             list_append (sieve_yyval.list, sieve_yyvsp[0].string);
             ;
    break;}
case 40:
#line 321 "sieve.y"
{
             sieve_yyval.list = sieve_yyvsp[-1].list;
             ;
    break;}
case 41:
#line 327 "sieve.y"
{
             list_create (&sieve_yyval.list);
             list_append (sieve_yyval.list, sieve_yyvsp[0].string);
             ;
    break;}
case 42:
#line 332 "sieve.y"
{
             list_append (sieve_yyvsp[-2].list, sieve_yyvsp[0].string);
             sieve_yyval.list = sieve_yyvsp[-2].list;
             ;
    break;}
}
   /* the action file gets copied in in place of this dollarsign */
#line 543 "/usr/share/bison.simple"

  sieve_yyvsp -= sieve_yylen;
  sieve_yyssp -= sieve_yylen;
#ifdef YYLSP_NEEDED
  sieve_yylsp -= sieve_yylen;
#endif

#if YYDEBUG != 0
  if (sieve_yydebug)
    {
      short *ssp1 = sieve_yyss - 1;
      fprintf (stderr, "state stack now");
      while (ssp1 != sieve_yyssp)
      fprintf (stderr, " %d", *++ssp1);
      fprintf (stderr, "\n");
    }
#endif

  *++sieve_yyvsp = sieve_yyval;

#ifdef YYLSP_NEEDED
  sieve_yylsp++;
  if (sieve_yylen == 0)
    {
      sieve_yylsp->first_line = sieve_yylloc.first_line;
      sieve_yylsp->first_column = sieve_yylloc.first_column;
      sieve_yylsp->last_line = (sieve_yylsp-1)->last_line;
      sieve_yylsp->last_column = (sieve_yylsp-1)->last_column;
      sieve_yylsp->text = 0;
    }
  else
    {
      sieve_yylsp->last_line = (sieve_yylsp+sieve_yylen-1)->last_line;
      sieve_yylsp->last_column = (sieve_yylsp+sieve_yylen-1)->last_column;
    }
#endif

  /* Now "shift" the result of the reduction.
     Determine what state that goes to,
     based on the state we popped back to
     and the rule number reduced by.  */

  sieve_yyn = sieve_yyr1[sieve_yyn];

  sieve_yystate = sieve_yypgoto[sieve_yyn - YYNTBASE] + *sieve_yyssp;
  if (sieve_yystate >= 0 && sieve_yystate <= YYLAST && sieve_yycheck[sieve_yystate] == *sieve_yyssp)
    sieve_yystate = sieve_yytable[sieve_yystate];
  else
    sieve_yystate = sieve_yydefgoto[sieve_yyn - YYNTBASE];

  goto sieve_yynewstate;

sieve_yyerrlab:   /* here on detecting error */

  if (! sieve_yyerrstatus)
    /* If not already recovering from an error, report this error.  */
    {
      ++sieve_yynerrs;

#ifdef YYERROR_VERBOSE
      sieve_yyn = sieve_yypact[sieve_yystate];

      if (sieve_yyn > YYFLAG && sieve_yyn < YYLAST)
      {
        int size = 0;
        char *msg;
        int x, count;

        count = 0;
        /* Start X at -sieve_yyn if nec to avoid negative indexes in sieve_yycheck.  */
        for (x = (sieve_yyn < 0 ? -sieve_yyn : 0);
             x < (sizeof(sieve_yytname) / sizeof(char *)); x++)
          if (sieve_yycheck[x + sieve_yyn] == x)
            size += strlen(sieve_yytname[x]) + 15, count++;
        msg = (char *) malloc(size + 15);
        if (msg != 0)
          {
            strcpy(msg, "parse error");

            if (count < 5)
            {
              count = 0;
              for (x = (sieve_yyn < 0 ? -sieve_yyn : 0);
                   x < (sizeof(sieve_yytname) / sizeof(char *)); x++)
                if (sieve_yycheck[x + sieve_yyn] == x)
                  {
                  strcat(msg, count == 0 ? ", expecting `" : " or `");
                  strcat(msg, sieve_yytname[x]);
                  strcat(msg, "'");
                  count++;
                  }
            }
            sieve_yyerror(msg);
            free(msg);
          }
        else
          sieve_yyerror ("parse error; also virtual memory exceeded");
      }
      else
#endif /* YYERROR_VERBOSE */
      sieve_yyerror("parse error");
    }

  goto sieve_yyerrlab1;
sieve_yyerrlab1:   /* here on error raised explicitly by an action */

  if (sieve_yyerrstatus == 3)
    {
      /* if just tried and failed to reuse lookahead token after an error, discard it.  */

      /* return failure if at end of input */
      if (sieve_yychar == YYEOF)
      YYABORT;

#if YYDEBUG != 0
      if (sieve_yydebug)
      fprintf(stderr, "Discarding token %d (%s).\n", sieve_yychar, sieve_yytname[sieve_yychar1]);
#endif

      sieve_yychar = YYEMPTY;
    }

  /* Else will try to reuse lookahead token
     after shifting the error token.  */

  sieve_yyerrstatus = 3;            /* Each real token shifted decrements this */

  goto sieve_yyerrhandle;

sieve_yyerrdefault:  /* current state does not do anything special for the error token. */

#if 0
  /* This is wrong; only states that explicitly want error tokens
     should shift them.  */
  sieve_yyn = sieve_yydefact[sieve_yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
  if (sieve_yyn) goto sieve_yydefault;
#endif

sieve_yyerrpop:   /* pop the current state because it cannot handle the error token */

  if (sieve_yyssp == sieve_yyss) YYABORT;
  sieve_yyvsp--;
  sieve_yystate = *--sieve_yyssp;
#ifdef YYLSP_NEEDED
  sieve_yylsp--;
#endif

#if YYDEBUG != 0
  if (sieve_yydebug)
    {
      short *ssp1 = sieve_yyss - 1;
      fprintf (stderr, "Error: state stack now");
      while (ssp1 != sieve_yyssp)
      fprintf (stderr, " %d", *++ssp1);
      fprintf (stderr, "\n");
    }
#endif

sieve_yyerrhandle:

  sieve_yyn = sieve_yypact[sieve_yystate];
  if (sieve_yyn == YYFLAG)
    goto sieve_yyerrdefault;

  sieve_yyn += YYTERROR;
  if (sieve_yyn < 0 || sieve_yyn > YYLAST || sieve_yycheck[sieve_yyn] != YYTERROR)
    goto sieve_yyerrdefault;

  sieve_yyn = sieve_yytable[sieve_yyn];
  if (sieve_yyn < 0)
    {
      if (sieve_yyn == YYFLAG)
      goto sieve_yyerrpop;
      sieve_yyn = -sieve_yyn;
      goto sieve_yyreduce;
    }
  else if (sieve_yyn == 0)
    goto sieve_yyerrpop;

  if (sieve_yyn == YYFINAL)
    YYACCEPT;

#if YYDEBUG != 0
  if (sieve_yydebug)
    fprintf(stderr, "Shifting error token, ");
#endif

  *++sieve_yyvsp = sieve_yylval;
#ifdef YYLSP_NEEDED
  *++sieve_yylsp = sieve_yylloc;
#endif

  sieve_yystate = sieve_yyn;
  goto sieve_yynewstate;

 sieve_yyacceptlab:
  /* YYACCEPT comes here.  */
  if (sieve_yyfree_stacks)
    {
      free (sieve_yyss);
      free (sieve_yyvs);
#ifdef YYLSP_NEEDED
      free (sieve_yyls);
#endif
    }
  return 0;

 sieve_yyabortlab:
  /* YYABORT comes here.  */
  if (sieve_yyfree_stacks)
    {
      free (sieve_yyss);
      free (sieve_yyvs);
#ifdef YYLSP_NEEDED
      free (sieve_yyls);
#endif
    }
  return 1;
}
#line 338 "sieve.y"


int
sieve_yyerror (char *s)
{
  sieve_compile_error (sieve_filename, sieve_line_num, "%s", s);
  return 0;
}

int
sieve_machine_init (sieve_machine_t *pmach, void *data)
{
  int rc;
  sieve_machine_t mach;
  
  mach = malloc (sizeof (*mach));
  if (!mach)
    return ENOMEM;
  memset (mach, 0, sizeof (*mach));
  rc = list_create (&mach->memory_pool);
  if (rc)
    {
      free (mach);
      return rc;
    }
  
  mach->data = data;
  mach->error_printer = _sieve_default_error_printer;
  mach->parse_error_printer = _sieve_default_parse_error;
  *pmach = mach;
  return 0;
}

void
sieve_set_error (sieve_machine_t mach, sieve_printf_t error_printer)
{
  mach->error_printer = error_printer ?
                           error_printer : _sieve_default_error_printer;
}

void
sieve_set_parse_error (sieve_machine_t mach, sieve_parse_error_t p)
{
  mach->parse_error_printer = p ? p : _sieve_default_parse_error;
}

void
sieve_set_debug (sieve_machine_t mach, sieve_printf_t debug)
{
  mach->debug_printer = debug;
}

void
sieve_set_debug_level (sieve_machine_t mach, mu_debug_t dbg, int level)
{
  mach->mu_debug = dbg;
  mach->debug_level = level;
}

void
sieve_set_logger (sieve_machine_t mach, sieve_action_log_t logger)
{
  mach->logger = logger;
}

void
sieve_set_ticket (sieve_machine_t mach, ticket_t ticket)
{
  mach->ticket = ticket;
}

ticket_t
sieve_get_ticket (sieve_machine_t mach)
{
  return mach->ticket;
}

mailer_t
sieve_get_mailer (sieve_machine_t mach)
{
  if (!mach->mailer)
    {
      mailer_create (&mach->mailer, NULL);
      if (mach->mu_debug)
      mailer_set_debug (mach->mailer, mach->mu_debug);
    }

  return mach->mailer;
}

void
sieve_set_mailer (sieve_machine_t mach, mailer_t mailer)
{
  mailer_destroy (&mach->mailer);
  mach->mailer = mailer;
}

#define MAILER_DAEMON_PFX "MAILER-DAEMON@"

char *
sieve_get_daemon_email (sieve_machine_t mach)
{
  if (!mach->daemon_email)
    {
      const char *domain = NULL;
      
      mu_get_user_email_domain (&domain);
      mach->daemon_email = sieve_malloc (mach,
                               sizeof(MAILER_DAEMON_PFX) +
                               strlen (domain));
      sprintf (mach->daemon_email, "%s%s", MAILER_DAEMON_PFX, domain);
    }
  return mach->daemon_email;
}

void
sieve_set_daemon_email (sieve_machine_t mach, const char *email)
{
  sieve_mfree (mach, (void *)mach->daemon_email);
  mach->daemon_email = sieve_mstrdup (mach, email);
}

struct sieve_destr_record
{
  sieve_destructor_t destr;
  void *ptr;
};

int
sieve_machine_add_destructor (sieve_machine_t mach, sieve_destructor_t destr,
                        void *ptr)
{
  struct sieve_destr_record *p;

  if (!mach->destr_list && list_create (&mach->destr_list))
    return 1;
  p = sieve_malloc (mach, sizeof (*p));
  if (!p)
    return 1;
  p->destr = destr;
  p->ptr = ptr;
  return list_prepend (mach->destr_list, p);
}

static int
_run_destructor (void *data, void *unused)
{
  struct sieve_destr_record *p = data;
  p->destr (p->ptr);
  return 0;
}

void
sieve_machine_destroy (sieve_machine_t *pmach)
{
  sieve_machine_t mach = *pmach;
  mailer_destroy (&mach->mailer);
  list_do (mach->destr_list, _run_destructor, NULL);
  list_destroy (&mach->destr_list);
  list_destroy (&mach->action_list);
  list_destroy (&mach->test_list);
  list_destroy (&mach->comp_list);
  list_destroy (&mach->source_list);
  sieve_slist_destroy (&mach->memory_pool);
  free (mach);
  *pmach = NULL;
}

static int
string_comp (const void *item, const void *value)
{
  return strcmp (item, value);
}

void
sieve_machine_begin (sieve_machine_t mach, const char *file)
{
  sieve_machine = mach;
  sieve_error_count = 0;
  sieve_code_instr (NULL);

  list_create (&mach->source_list);
  list_set_comparator (mach->source_list, string_comp);
  
  sieve_register_standard_actions (mach);
  sieve_register_standard_tests (mach);
  sieve_register_standard_comparators (mach);
}

void
sieve_machine_finish (sieve_machine_t mach)
{
  sieve_code_instr (NULL);
}

int
sieve_compile (sieve_machine_t mach, const char *name)
{
  int rc;
  
  sieve_machine_begin (mach, name);

  if (sieve_lex_begin (name) == 0)
    {
      rc = sieve_yyparse ();
      if (sieve_error_count)
      rc = 1;
      sieve_lex_finish ();
    }
  else
    rc = 1;
  
  sieve_machine_finish (mach);
  if (rc)
    sieve_machine_destroy (&mach);
  return rc;
}

static void
_branch_fixup (size_t start, size_t end)
{
  size_t prev = sieve_machine->prog[start].pc;
  if (!prev)
    return;
  branch_fixup (prev, end);
  sieve_machine->prog[prev].pc = end - prev - 1;
}

void
branch_fixup (size_t start, size_t end)
{
  _branch_fixup (start, end);
  sieve_machine->prog[start].pc = end - start - 1;
}

Generated by  Doxygen 1.6.0   Back to index