summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-01-30 12:28:40 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2017-01-30 12:28:40 +0200
commitbbd1fa8b0ad735fda363256cc77a0f6eb32f5697 (patch)
tree3e02da65c9224a1d1eda8bbc7055faaf8a251266
parentee60e76b694a73b14f2e31ece85324847e0fc57f (diff)
downloadmailutils-bbd1fa8b0ad735fda363256cc77a0f6eb32f5697.tar.gz
mailutils-bbd1fa8b0ad735fda363256cc77a0f6eb32f5697.tar.bz2
sieve: add a locus indicating end of input
The new node type mu_sieve_node_end is introduced to explicitly mark end of the parse tree. When generating code, this node triggers insertion of _mu_i_sv_instr_source/_mu_i_sv_instr_line before the end of code marker. This, in turn, ensures that a correct location is reported for implicit keep, if logging is enabled. * libmu_sieve/sieve-priv.h (mu_sieve_node_end): New node type. (mu_sieve_node_list): New type (from struct node_list in sieve.y) * libmu_sieve/sieve.y (node_list_add): New function. (input production): Add mu_sieve_node_end at the end of the tree.
-rw-r--r--libmu_sieve/sieve-priv.h6
-rw-r--r--libmu_sieve/sieve.y56
2 files changed, 48 insertions, 14 deletions
diff --git a/libmu_sieve/sieve-priv.h b/libmu_sieve/sieve-priv.h
index ee4ec91b4..041b4ea7c 100644
--- a/libmu_sieve/sieve-priv.h
+++ b/libmu_sieve/sieve-priv.h
@@ -144,6 +144,7 @@ enum mu_sieve_node_type
mu_sieve_node_anyof,
mu_sieve_node_allof,
mu_sieve_node_not,
+ mu_sieve_node_end,
};
struct mu_sieve_node
@@ -170,6 +171,11 @@ struct mu_sieve_node
} command;
} v;
};
+
+struct mu_sieve_node_list
+{
+ struct mu_sieve_node *head, *tail;
+};
int mu_sieve_yyerror (const char *s);
int mu_sieve_yylex (void);
diff --git a/libmu_sieve/sieve.y b/libmu_sieve/sieve.y
index ac53a0356..067489f13 100644
--- a/libmu_sieve/sieve.y
+++ b/libmu_sieve/sieve.y
@@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree;
static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
struct mu_locus_range *);
+static void node_list_add (struct mu_sieve_node_list *list,
+ struct mu_sieve_node *node);
+
+
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
{ \
@@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
size_t first;
size_t count;
} command;
- struct node_list
- {
- struct mu_sieve_node *head, *tail;
- } node_list;
+ struct mu_sieve_node_list node_list;
struct mu_sieve_node *node;
}
@@ -112,7 +113,12 @@ input : /* empty */
sieve_tree = NULL;
}
| list
- {
+ {
+ struct mu_locus_range lr;
+
+ lr.beg = lr.end = @1.end;
+
+ node_list_add (&$1, node_alloc (mu_sieve_node_end, &lr));
sieve_tree = $1.head;
}
;
@@ -123,15 +129,7 @@ list : statement
}
| list statement
{
- if ($2)
- {
- $2->prev = $1.tail;
- if ($1.tail)
- $1.tail->next = $2;
- else
- $1.head = $2;
- $1.tail = $2;
- }
+ node_list_add (&$1, $2);
$$ = $1;
}
;
@@ -403,6 +401,20 @@ yyerror (const char *s)
return 0;
}
+static void
+node_list_add (struct mu_sieve_node_list *list, struct mu_sieve_node *node)
+{
+ if (!node)
+ return;
+
+ node->prev = list->tail;
+ if (list->tail)
+ list->tail->next = node;
+ else
+ list->head = node;
+ list->tail = node;
+}
+
static struct mu_sieve_node *
node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr)
{
@@ -804,6 +816,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
mu_stream_printf (str, "NOT\n");
node_dump (str, node->v.node, level + 1, mach);
}
+
+/* mu_sieve_node_end */
+static void
+code_node_end (struct mu_sieve_machine *mach, struct mu_sieve_node *node)
+{
+ mu_i_sv_code (mach, (sieve_op_t) (sieve_instr_t) 0);
+}
+
+static void
+dump_node_end (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
+ struct mu_sieve_machine *mach)
+{
+ indent (str, level);
+ mu_stream_printf (str, "END\n");
+}
struct node_descr
{
@@ -831,6 +858,7 @@ static struct node_descr node_descr[] = {
free_node_x_of, dump_node_x_of },
[mu_sieve_node_not] = { code_node_not, optimize_node_not,
free_node_not, dump_node_not },
+ [mu_sieve_node_end] = { code_node_end, NULL, NULL, dump_node_end }
};
static void

Return to:

Send suggestions and report system problems to the System administrator.