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.
Showing
2 changed files
with
48 additions
and
14 deletions
... | @@ -144,6 +144,7 @@ enum mu_sieve_node_type | ... | @@ -144,6 +144,7 @@ enum mu_sieve_node_type |
144 | mu_sieve_node_anyof, | 144 | mu_sieve_node_anyof, |
145 | mu_sieve_node_allof, | 145 | mu_sieve_node_allof, |
146 | mu_sieve_node_not, | 146 | mu_sieve_node_not, |
147 | mu_sieve_node_end, | ||
147 | }; | 148 | }; |
148 | 149 | ||
149 | struct mu_sieve_node | 150 | struct mu_sieve_node |
... | @@ -170,6 +171,11 @@ struct mu_sieve_node | ... | @@ -170,6 +171,11 @@ struct mu_sieve_node |
170 | } command; | 171 | } command; |
171 | } v; | 172 | } v; |
172 | }; | 173 | }; |
174 | |||
175 | struct mu_sieve_node_list | ||
176 | { | ||
177 | struct mu_sieve_node *head, *tail; | ||
178 | }; | ||
173 | 179 | ||
174 | int mu_sieve_yyerror (const char *s); | 180 | int mu_sieve_yyerror (const char *s); |
175 | int mu_sieve_yylex (void); | 181 | int mu_sieve_yylex (void); | ... | ... |
... | @@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree; | ... | @@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree; |
33 | static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, | 33 | static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, |
34 | struct mu_locus_range *); | 34 | struct mu_locus_range *); |
35 | 35 | ||
36 | static void node_list_add (struct mu_sieve_node_list *list, | ||
37 | struct mu_sieve_node *node); | ||
38 | |||
39 | |||
36 | #define YYLLOC_DEFAULT(Current, Rhs, N) \ | 40 | #define YYLLOC_DEFAULT(Current, Rhs, N) \ |
37 | do \ | 41 | do \ |
38 | { \ | 42 | { \ |
... | @@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, | ... | @@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, |
86 | size_t first; | 90 | size_t first; |
87 | size_t count; | 91 | size_t count; |
88 | } command; | 92 | } command; |
89 | struct node_list | 93 | struct mu_sieve_node_list node_list; |
90 | { | ||
91 | struct mu_sieve_node *head, *tail; | ||
92 | } node_list; | ||
93 | struct mu_sieve_node *node; | 94 | struct mu_sieve_node *node; |
94 | } | 95 | } |
95 | 96 | ||
... | @@ -112,7 +113,12 @@ input : /* empty */ | ... | @@ -112,7 +113,12 @@ input : /* empty */ |
112 | sieve_tree = NULL; | 113 | sieve_tree = NULL; |
113 | } | 114 | } |
114 | | list | 115 | | list |
115 | { | 116 | { |
117 | struct mu_locus_range lr; | ||
118 | |||
119 | lr.beg = lr.end = @1.end; | ||
120 | |||
121 | node_list_add (&$1, node_alloc (mu_sieve_node_end, &lr)); | ||
116 | sieve_tree = $1.head; | 122 | sieve_tree = $1.head; |
117 | } | 123 | } |
118 | ; | 124 | ; |
... | @@ -123,15 +129,7 @@ list : statement | ... | @@ -123,15 +129,7 @@ list : statement |
123 | } | 129 | } |
124 | | list statement | 130 | | list statement |
125 | { | 131 | { |
126 | if ($2) | 132 | node_list_add (&$1, $2); |
127 | { | ||
128 | $2->prev = $1.tail; | ||
129 | if ($1.tail) | ||
130 | $1.tail->next = $2; | ||
131 | else | ||
132 | $1.head = $2; | ||
133 | $1.tail = $2; | ||
134 | } | ||
135 | $$ = $1; | 133 | $$ = $1; |
136 | } | 134 | } |
137 | ; | 135 | ; |
... | @@ -403,6 +401,20 @@ yyerror (const char *s) | ... | @@ -403,6 +401,20 @@ yyerror (const char *s) |
403 | return 0; | 401 | return 0; |
404 | } | 402 | } |
405 | 403 | ||
404 | static void | ||
405 | node_list_add (struct mu_sieve_node_list *list, struct mu_sieve_node *node) | ||
406 | { | ||
407 | if (!node) | ||
408 | return; | ||
409 | |||
410 | node->prev = list->tail; | ||
411 | if (list->tail) | ||
412 | list->tail->next = node; | ||
413 | else | ||
414 | list->head = node; | ||
415 | list->tail = node; | ||
416 | } | ||
417 | |||
406 | static struct mu_sieve_node * | 418 | static struct mu_sieve_node * |
407 | node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr) | 419 | node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr) |
408 | { | 420 | { |
... | @@ -804,6 +816,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level, | ... | @@ -804,6 +816,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level, |
804 | mu_stream_printf (str, "NOT\n"); | 816 | mu_stream_printf (str, "NOT\n"); |
805 | node_dump (str, node->v.node, level + 1, mach); | 817 | node_dump (str, node->v.node, level + 1, mach); |
806 | } | 818 | } |
819 | |||
820 | /* mu_sieve_node_end */ | ||
821 | static void | ||
822 | code_node_end (struct mu_sieve_machine *mach, struct mu_sieve_node *node) | ||
823 | { | ||
824 | mu_i_sv_code (mach, (sieve_op_t) (sieve_instr_t) 0); | ||
825 | } | ||
826 | |||
827 | static void | ||
828 | dump_node_end (mu_stream_t str, struct mu_sieve_node *node, unsigned level, | ||
829 | struct mu_sieve_machine *mach) | ||
830 | { | ||
831 | indent (str, level); | ||
832 | mu_stream_printf (str, "END\n"); | ||
833 | } | ||
807 | 834 | ||
808 | struct node_descr | 835 | struct node_descr |
809 | { | 836 | { |
... | @@ -831,6 +858,7 @@ static struct node_descr node_descr[] = { | ... | @@ -831,6 +858,7 @@ static struct node_descr node_descr[] = { |
831 | free_node_x_of, dump_node_x_of }, | 858 | free_node_x_of, dump_node_x_of }, |
832 | [mu_sieve_node_not] = { code_node_not, optimize_node_not, | 859 | [mu_sieve_node_not] = { code_node_not, optimize_node_not, |
833 | free_node_not, dump_node_not }, | 860 | free_node_not, dump_node_not }, |
861 | [mu_sieve_node_end] = { code_node_end, NULL, NULL, dump_node_end } | ||
834 | }; | 862 | }; |
835 | 863 | ||
836 | static void | 864 | static void | ... | ... |
-
Please register or sign in to post a comment