diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-04-07 09:14:32 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-04-07 09:14:32 +0000 |
commit | a6a6d420ed2e8f4924d25a9595bea4871e3d9a05 (patch) | |
tree | bb3dbd019aad52134f30ef99b9066dfac27d6596 | |
parent | dab2a03e9ed8ca6f5ba9937b7adf7cd40b284edd (diff) | |
download | mailutils-a6a6d420ed2e8f4924d25a9595bea4871e3d9a05.tar.gz mailutils-a6a6d420ed2e8f4924d25a9595bea4871e3d9a05.tar.bz2 |
Implement compilation of Sieve sources from the memory.
* include/mailutils/libsieve.h (mu_sieve_compile_buffer): New
function.
* libsieve/sieve.h (sieve_lex_begin_string): New function.
* libsieve/sieve.l: Remove support for AT&T lex.
(sieve_lex_begin_string): New function.
* libsieve/sieve.y (mu_sieve_compile_buffer): New
function.
* mailbox/header.c: Fix indentation.
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | include/mailutils/libsieve.h | 3 | ||||
-rw-r--r-- | libsieve/sieve.h | 1 | ||||
-rw-r--r-- | libsieve/sieve.l | 183 | ||||
-rw-r--r-- | libsieve/sieve.y | 24 | ||||
-rw-r--r-- | mailbox/header.c | 4 |
6 files changed, 88 insertions, 141 deletions
@@ -1,3 +1,17 @@ +2008-04-07 Sergey Poznyakoff <gray@gnu.org.ua> + + Implement compilation of Sieve sources from the memory. + + * include/mailutils/libsieve.h (mu_sieve_compile_buffer): New + function. + * libsieve/sieve.h (sieve_lex_begin_string): New function. + * libsieve/sieve.l: Remove support for AT&T lex. + (sieve_lex_begin_string): New function. + * libsieve/sieve.y (mu_sieve_compile_buffer): New + function. + + * mailbox/header.c: Fix indentation. + 2008-03-15 Sergey Poznyakoff <gray@gnu.org.ua> * libargp/tls.c (_tls_argp_parser): Take care not to pass NULL as diff --git a/include/mailutils/libsieve.h b/include/mailutils/libsieve.h index e311d5c9f..90efa95c2 100644 --- a/include/mailutils/libsieve.h +++ b/include/mailutils/libsieve.h @@ -255,6 +255,9 @@ const char *mu_sieve_type_str (mu_sieve_data_type type); /* Principal entry points */ int mu_sieve_compile (mu_sieve_machine_t mach, const char *name); +int mu_sieve_compile_buffer (mu_sieve_machine_t mach, + const char *buf, int bufsize, + const char *fname, int line); int mu_sieve_mailbox (mu_sieve_machine_t mach, mu_mailbox_t mbox); int mu_sieve_message (mu_sieve_machine_t mach, mu_message_t message); int mu_sieve_disass (mu_sieve_machine_t mach); diff --git a/libsieve/sieve.h b/libsieve/sieve.h index 70836228f..3de6c80a4 100644 --- a/libsieve/sieve.h +++ b/libsieve/sieve.h @@ -102,6 +102,7 @@ int _sieve_default_parse_error (void *unused, const char *filename, int lineno, const char *fmt, va_list ap); int sieve_lex_begin (const char *name); +int sieve_lex_begin_string (const char *buf, int bufsize, const char *fname, int line); void sieve_lex_finish (void); int mu_sieve_yyerror (char *s); int mu_sieve_yylex (); diff --git a/libsieve/sieve.l b/libsieve/sieve.l index 924b2aa3b..2762b9b72 100644 --- a/libsieve/sieve.l +++ b/libsieve/sieve.l @@ -56,20 +56,31 @@ static void sieve_include (void); static void sieve_searchpath (void); static char *str_unescape (char *text, size_t len); static int isemptystr (char *text); + +static const char *input_string_ptr; +static int input_string_level; + +static int +fillbuf(char *buf, int max_size) +{ + if (input_string_ptr) + { + int n = input_string_level; + if (n > max_size) + n = max_size; + memcpy (buf, input_string_ptr, n); + input_string_ptr += n; + input_string_level -= n; + return n; + } + else if (feof (yyin)) + return 0; + else + return fread (buf, 1, max_size, yyin); +} -#ifdef FLEX_SCANNER -#define xinput() (yyin ? getc(yyin) : EOF) #undef YY_INPUT -#define YY_INPUT(buf,result,max_size) do { \ - int i; \ - for (i = 0; i < max_size; i++) { \ - int ch = xinput(); \ - if (ch == EOF) \ - break; \ - buf[i] = ch; \ - } \ - result = i; \ -} while (0) +#define YY_INPUT(buf,result,max_size) result = fillbuf(buf, max_size) #define LEX_BUFFER_STATE YY_BUFFER_STATE #define SET_BUFFER_STATE(s) do { \ (s) = YY_CURRENT_BUFFER; \ @@ -80,122 +91,6 @@ static int isemptystr (char *text); yy_switch_to_buffer(s); \ } while (0) -#else -/* AT&T Lex */ - -static void lex_set_buffer (FILE *fp); -static void lex_delete_buffer (LEX_BUFFER_STATE buf); -static int xinput (void); -static int xunput (void); - -#undef unput -#define unput(c) xunput(c) -#undef input -#define input() xinput() - -#define LEX_BUF_SIZE 16384 -#define LEX_PUTBACK_SIZE 32 - -typedef struct { - FILE *yyin; - char *buffer; - size_t bufsize; - size_t level; - char *ptr; - char *putback; - size_t pb_size; - size_t pb_level; -} LEX_BUFFER_STATE; -LEX_BUFFER_STATE current_buffer; - -#define SET_BUFFER_STATE(s) do { \ - (s) = current_buffer; \ - lex_set_buffer(yyin); \ -} while (0) -#define RESTORE_BUFFER_STATE(s) do { \ - lex_delete_buffer(current_buffer); \ - current_buffer = (s); \ - yyin = current_buffer.yyin; \ -} while (0) - -void -lex_set_buffer (FILE *fp) -{ - char *buf; - size_t size; - - for (size = LEX_BUF_SIZE; size > 1; size /= 2) - if (buf = malloc (size)) - break; - - if (!buf) - { - sieve_compile_error (sieve_filename, sieve_line_num, _("Not enough memory")); - abort (); - } - - current_buffer.yyin = yyin; - current_buffer.buffer = buf; - current_buffer.bufsize = size; - current_buffer.level = 0; - current_buffer.ptr = current_buffer.buffer; - current_buffer.pb_size = current_buffer.pb_level = 0; - current_buffer.putback = NULL; -} - -void -lex_delete_buffer (LEX_BUFFER_STATE buf) -{ - free (buf.buffer); - if (buf.putback) - free (buf.putback); -} - -int -xinput () -{ - if (!yyin) - return EOF; - - if (current_buffer.pb_level) - return current_buffer.putback[--current_buffer.pb_level]; - - if (current_buffer.level <= 0) - { - int n; - - if (feof (yyin)) - return 0; - n = fread (current_buffer.buffer, 1, - current_buffer.bufsize, yyin); - if (n <= 0) - return 0; - current_buffer.level = n; - current_buffer.ptr = current_buffer.buffer; - } - current_buffer.level--; - return *current_buffer.ptr++; -} - -int -xunput (int c) -{ - if (current_buffer.pb_level == current_buffer.pb_size) - { - char *putback; - current_buffer.pb_size += LEX_PUTBACK_SIZE; - putback = mu_sieve_alloc (current_buffer.pb_size); - memcpy (putback, current_buffer.putback, - current_buffer.pb_level); - free (current_buffer.putback); - current_buffer.putback = putback; - } - current_buffer.putback[current_buffer.pb_level++] = c; - return c; -} - -#endif - struct buffer_ctx { struct buffer_ctx *prev; char *filename; @@ -279,14 +174,8 @@ push_source (const char *name) SET_BUFFER_STATE (ctx->state); } else - { -#ifdef FLEX_SCANNER - yyrestart (fp); -#else - yyin = fp; - lex_set_buffer (yyin); -#endif - } + yyrestart (fp); + sieve_filename = strdup (name); sieve_line_num = 1; sieve_source_inode = st.st_ino; @@ -303,9 +192,7 @@ pop_source () if (yyin) fclose (yyin); -#ifndef FLEX_SCANNER - lex_delete_buffer (current_buffer); -#endif + if (sieve_filename) free (sieve_filename); if (!context_stack) @@ -534,6 +421,24 @@ sieve_lex_begin (const char *name) return push_source (name); } +int +sieve_lex_begin_string (const char *buf, int bufsize, + const char *fname, int line) +{ + if (!fname) + return 1; + yyrestart (NULL); + + input_string_ptr = buf; + input_string_level = bufsize; + sieve_filename = strdup (fname); + sieve_line_num = line; + sieve_source_inode = 0; + + sieve_change_source (); + return 0; +} + void sieve_lex_finish () { diff --git a/libsieve/sieve.y b/libsieve/sieve.y index bd51683e5..1a9f30501 100644 --- a/libsieve/sieve.y +++ b/libsieve/sieve.y @@ -628,6 +628,30 @@ mu_sieve_compile (mu_sieve_machine_t mach, const char *name) return rc; } +int +mu_sieve_compile_buffer (mu_sieve_machine_t mach, + const char *buf, int bufsize, const char *fname, int line) +{ + int rc; + + mu_sieve_machine_begin (mach, fname); + + if (sieve_lex_begin_string (buf, bufsize, fname, line) == 0) + { + rc = yyparse (); + if (sieve_error_count) + rc = 1; + sieve_lex_finish (); + } + else + rc = 1; + + mu_sieve_machine_finish (mach); + if (rc) + mu_sieve_machine_destroy (&mach); + return rc; +} + static void _branch_fixup (size_t start, size_t end) { diff --git a/mailbox/header.c b/mailbox/header.c index ecea02adc..4c668067f 100644 --- a/mailbox/header.c +++ b/mailbox/header.c @@ -667,8 +667,8 @@ mu_header_insert (mu_header_t header, int mu_header_sget_value_n (mu_header_t header, - const char *name, int n, - const char **pval) + const char *name, int n, + const char **pval) { int status; struct mu_hdrent *ent; |