Commit 1b57a009 1b57a009e0473b03e5a66657a9a2ad444ee51c0d by Sergey Poznyakoff

Fixed grammar. Added union, types and the basic actions.

1 parent 792eb440
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
3 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option) 7 the Free Software Foundation; either version 2, or (at your option)
8 any later version. 8 any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 13 GNU Lesser General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 18
...@@ -26,14 +26,24 @@ ...@@ -26,14 +26,24 @@
26 #include <sys/file.h> 26 #include <sys/file.h>
27 #include <sys/stat.h> 27 #include <sys/stat.h>
28 #include <errno.h> 28 #include <errno.h>
29 #include <string.h>
29 #include <sieve.h> 30 #include <sieve.h>
30 #include <sieve-gram.h> 31 #include <sieve-gram.h>
31 32
32
33 char *sieve_filename; 33 char *sieve_filename;
34 int sieve_line_num; 34 int sieve_line_num;
35 ino_t sieve_source_inode; 35 ino_t sieve_source_inode;
36 36
37 static list_t string_list;
38
39 static int number __P ((void));
40 static int string __P ((void));
41 static void multiline_begin __P ((void));
42 static void multiline_add __P ((void));
43 static void multiline_finish __P ((void));
44 static void ident __P((const char *text));
45 static void sieve_include __P((void));
46
37 #ifdef FLEX_SCANNER 47 #ifdef FLEX_SCANNER
38 #define xinput() (yyin ? getc(yyin) : EOF) 48 #define xinput() (yyin ? getc(yyin) : EOF)
39 #undef YY_INPUT 49 #undef YY_INPUT
...@@ -185,7 +195,7 @@ struct buffer_ctx { ...@@ -185,7 +195,7 @@ struct buffer_ctx {
185 static struct buffer_ctx *context_stack; 195 static struct buffer_ctx *context_stack;
186 196
187 static struct buffer_ctx *ctx_lookup __P((ino_t ino)); 197 static struct buffer_ctx *ctx_lookup __P((ino_t ino));
188 static int push_source __P((char *name)); 198 static int push_source __P((const char *name));
189 static int pop_source __P((void)); 199 static int pop_source __P((void));
190 200
191 struct buffer_ctx * 201 struct buffer_ctx *
...@@ -200,7 +210,7 @@ ctx_lookup (ino_t ino) ...@@ -200,7 +210,7 @@ ctx_lookup (ino_t ino)
200 } 210 }
201 211
202 int 212 int
203 push_source (char *name) 213 push_source (const char *name)
204 { 214 {
205 FILE *fp; 215 FILE *fp;
206 struct buffer_ctx *ctx; 216 struct buffer_ctx *ctx;
...@@ -300,6 +310,7 @@ pop_source () ...@@ -300,6 +310,7 @@ pop_source ()
300 310
301 WS [ \t][ \t]* 311 WS [ \t][ \t]*
302 IDENT [a-zA-Z_][a-zA-Z_0-9]+ 312 IDENT [a-zA-Z_][a-zA-Z_0-9]+
313 SIZESUF [kKmMgG]
303 314
304 %% 315 %%
305 /* C-style comments */ 316 /* C-style comments */
...@@ -320,18 +331,20 @@ elsif return ELSIF; ...@@ -320,18 +331,20 @@ elsif return ELSIF;
320 else return ELSE; 331 else return ELSE;
321 anyof return ANYOF; 332 anyof return ANYOF;
322 allof return ALLOF; 333 allof return ALLOF;
323 true return TRUE;
324 false return FALSE;
325 not return NOT; 334 not return NOT;
326 /* Other tokens */ 335 /* Other tokens */
327 {IDENT} return IDENT; 336 {IDENT} { ident (yytext); return IDENT; }
328 :{IDENT} { return TAG; } 337 :{IDENT} { ident (yytext + 1); return TAG; }
329 0[0-7]* { return NUMBER; } 338 0[0-7]*{SIZESUF}* { return number (); }
330 0x[0-9a-fA-F][0-9a-fA-F]+ { return NUMBER; } 339 0x[0-9a-fA-F][0-9a-fA-F]+{SIZESUF}* { return number (); }
331 [1-9][0-9]* { return NUMBER; } 340 [1-9][0-9]*{SIZESUF}* { return number (); }
332 \"[^"\n]*\" { return STRING; } 341 \"[^"\n]*\" { return string (); }
333 text: { BEGIN(ML); } 342 text: { BEGIN(ML); multiline_begin (); }
334 <ML>.[ \t]*\n { BEGIN(INITIAL); sieve_line_num++; return MULTILINE; } 343 <ML>.[ \t]*\n { BEGIN(INITIAL);
344 sieve_line_num++;
345 multiline_add ();
346 multiline_finish ();
347 return MULTILINE; }
335 <ML>.*\n { sieve_line_num++; } 348 <ML>.*\n { sieve_line_num++; }
336 {WS} ; 349 {WS} ;
337 \n { sieve_line_num++; } 350 \n { sieve_line_num++; }
...@@ -394,5 +407,107 @@ sieve_open_source (const char *name) ...@@ -394,5 +407,107 @@ sieve_open_source (const char *name)
394 return push_source (name); 407 return push_source (name);
395 } 408 }
396 409
410 int
411 number ()
412 {
413 char *p;
414 yylval.number = strtol (yytext, &p, 0);
415 switch (*p)
416 {
417 case 'k':
418 case 'K':
419 yylval.number *= 1024L;
420 break;
421
422 case 'm':
423 case 'M':
424 yylval.number *= 1024*1024L;
425 break;
426
427 case 'g':
428 case 'G':
429 yylval.number *= 1024*1024*1024L;
430 }
431 return NUMBER;
432 }
433
434 int
435 string ()
436 {
437 yylval.string = sieve_alloc (yyleng - 1);
438 memcpy (yylval.string, yytext + 1, yyleng - 2);
439 yylval.string[yyleng - 2] = 0;
440 return STRING;
441 }
442
443 void
444 multiline_add ()
445 {
446 char *s = strdup (yytext);
447 if (!s)
448 {
449 yyerror ("not enough memory");
450 exit (1);
451 }
452 list_append (string_list, s);
453 }
454
455 void
456 multiline_begin ()
457 {
458 int status;
459
460 if (string_list)
461 sieve_slist_destroy (&string_list);
462 status = list_create (&string_list);
463 if (status)
464 {
465 sieve_error ("list_create: %s", mu_errstring (status));
466 exit (1);
467 }
468 }
469
470 void
471 multiline_finish ()
472 {
473 iterator_t itr;
474 int length = 0;
475 char *p;
397 476
477 if (!string_list || iterator_create (&itr, string_list))
478 return;
398 479
480 /* Count number of characters in the multiline */
481 for (iterator_first (itr); !iterator_is_done (itr); iterator_next (itr))
482 {
483 char *s;
484 iterator_current (itr, (void **)&s);
485 length += strlen (s);
486 }
487
488 /* Copy the contents */
489 yylval.string = sieve_alloc (length + 1);
490 p = yylval.string;
491 for (iterator_first (itr); !iterator_is_done (itr); iterator_next (itr))
492 {
493 char *s;
494 iterator_current (itr, (void **)&s);
495 strcpy (p, s);
496 p += strlen (s);
497 free (s);
498 }
499 *p = 0;
500 iterator_destroy (&itr);
501 list_destroy (&string_list);
502 }
503
504 void
505 ident (const char *text)
506 {
507 yylval.string = strdup (text);
508 if (!yylval.string)
509 {
510 yyerror ("not enough memory");
511 exit (1);
512 }
513 }
......
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
3 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 3 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option) 7 the Free Software Foundation; either version 2, or (at your option)
8 any later version. 8 any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 13 GNU Lesser General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 18
...@@ -20,13 +20,32 @@ ...@@ -20,13 +20,32 @@
20 # include <config.h> 20 # include <config.h>
21 #endif 21 #endif
22 #include <stdio.h> 22 #include <stdio.h>
23 #include <stdlib.h>
23 #include <assert.h> 24 #include <assert.h>
24 #include <sieve.h> 25 #include <sieve.h>
25
26 %} 26 %}
27 27
28 %token IDENT TAG NUMBER STRING MULTILINE 28 %union {
29 %token REQUIRE IF ELSIF ELSE ANYOF ALLOF TRUE FALSE NOT 29 char *string;
30 long number;
31 sieve_instr_t instr;
32 sieve_value_t *value;
33 list_t list;
34 struct {
35 char *ident;
36 list_t args;
37 } command;
38 }
39
40 %token <string> IDENT TAG
41 %token <number> NUMBER
42 %token <string> STRING MULTILINE
43 %token REQUIRE IF ELSIF ELSE ANYOF ALLOF NOT
44
45 %type <value> arg
46 %type <list> slist stringlist arglist maybe_arglist
47 %type <command> command
48
30 %% 49 %%
31 50
32 input : /* empty */ 51 input : /* empty */
...@@ -38,6 +57,10 @@ list : statement ...@@ -38,6 +57,10 @@ list : statement
38 ; 57 ;
39 58
40 statement : REQUIRE stringlist ';' 59 statement : REQUIRE stringlist ';'
60 {
61 sieve_require ($2);
62 sieve_slist_destroy ($2);
63 }
41 | action ';' 64 | action ';'
42 | IF cond block maybe_elsif maybe_else 65 | IF cond block maybe_elsif maybe_else
43 ; 66 ;
...@@ -58,8 +81,8 @@ block : '{' list '}' ...@@ -58,8 +81,8 @@ block : '{' list '}'
58 ; 81 ;
59 82
60 83
61 testlist : test 84 testlist : cond
62 | testlist ',' test 85 | testlist ',' cond
63 ; 86 ;
64 87
65 cond : test 88 cond : test
...@@ -68,37 +91,101 @@ cond : test ...@@ -68,37 +91,101 @@ cond : test
68 | NOT cond 91 | NOT cond
69 ; 92 ;
70 93
71 test : FALSE 94 test : command
72 | TRUE 95 {
73 | command 96 sieve_register_t *reg = sieve_test_lookup ($1.ident);
97 if (!reg)
98 sieve_error ("%s:%d: unknown test: %s",
99 sieve_filename, sieve_line_num,
100 $1.ident);
101 else if (!reg->required)
102 sieve_error ("%s:%d: test `%s' has not been required",
103 sieve_filename, sieve_line_num,
104 $1.ident);
105 /*free unneeded memory */
106 }
74 ; 107 ;
75 108
76 command : IDENT maybe_arglist 109 command : IDENT maybe_arglist
110 {
111 $$.ident = $1;
112 $$.args = $2;
113 }
77 ; 114 ;
78 115
79 action : command 116 action : command
117 {
118 sieve_register_t *reg = sieve_action_lookup ($1.ident);
119 if (!reg)
120 sieve_error ("%s:%d: unknown action: %s",
121 sieve_filename, sieve_line_num,
122 $1.ident);
123 else if (!reg->required)
124 sieve_error ("%s:%d: action `%s' has not been required",
125 sieve_filename, sieve_line_num,
126 $1.ident);
127 /*free unneeded memory */
128 }
80 ; 129 ;
81 130
82 maybe_arglist: /* empty */ 131 maybe_arglist: /* empty */
132 {
133 $$ = NULL;
134 }
83 | arglist 135 | arglist
84 ; 136 ;
85 137
86 arglist : arg 138 arglist : arg
139 {
140 list_create (&$$);
141 list_append ($$, &$1);
142 }
87 | arglist arg 143 | arglist arg
144 {
145 list_append ($1, &$2);
146 $$ = $1;
147 }
88 ; 148 ;
89 149
90 arg : stringlist 150 arg : stringlist
151 {
152 $$ = sieve_value_create (SVT_STRING_LIST, $1);
153 }
91 | MULTILINE 154 | MULTILINE
155 {
156 $$ = sieve_value_create (SVT_STRING, $1);
157 }
92 | NUMBER 158 | NUMBER
159 {
160 $$ = sieve_value_create (SVT_NUMBER, &$1);
161 }
93 | TAG 162 | TAG
163 {
164 $$ = sieve_value_create (SVT_TAG, $1);
165 }
94 ; 166 ;
95 167
96 stringlist : STRING 168 stringlist : STRING
169 {
170 list_create (&$$);
171 list_append ($$, $1);
172 }
97 | '[' slist ']' 173 | '[' slist ']'
174 {
175 $$ = $2;
176 }
98 ; 177 ;
99 178
100 slist : STRING 179 slist : STRING
180 {
181 list_create (&$$);
182 list_append ($$, $1);
183 }
101 | slist ',' STRING 184 | slist ',' STRING
185 {
186 list_append ($1, $3);
187 $$ = $1;
188 }
102 ; 189 ;
103 190
104 %% 191 %%
...@@ -106,13 +193,15 @@ slist : STRING ...@@ -106,13 +193,15 @@ slist : STRING
106 int 193 int
107 yyerror (char *s) 194 yyerror (char *s)
108 { 195 {
109 fprintf (stderr, "%s:%d: ", sieve_filename, sieve_line_num); 196 sieve_error ("%s:%d: %s", sieve_filename, sieve_line_num, s);
110 fprintf (stderr, "%s\n", s); 197 return 0;
111 } 198 }
112 199
113 int 200 int
114 sieve_parse (const char *name) 201 sieve_parse (const char *name)
115 { 202 {
203 sieve_register_standard_actions ();
204 sieve_register_standard_tests ();
116 sieve_open_source (name); 205 sieve_open_source (name);
117 return yyparse (); 206 return yyparse ();
118 } 207 }
......