summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-04-07 09:14:32 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-04-07 09:14:32 +0000
commita6a6d420ed2e8f4924d25a9595bea4871e3d9a05 (patch)
treebb3dbd019aad52134f30ef99b9066dfac27d6596
parentdab2a03e9ed8ca6f5ba9937b7adf7cd40b284edd (diff)
downloadmailutils-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--ChangeLog14
-rw-r--r--include/mailutils/libsieve.h3
-rw-r--r--libsieve/sieve.h1
-rw-r--r--libsieve/sieve.l183
-rw-r--r--libsieve/sieve.y24
-rw-r--r--mailbox/header.c4
6 files changed, 88 insertions, 141 deletions
diff --git a/ChangeLog b/ChangeLog
index d3667b1fd..3fddc9dca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;

Return to:

Send suggestions and report system problems to the System administrator.