dovecot-2.2-pigeonhole: Implemented Sieve extracttext extension.
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Fri Jan 8 19:51:28 UTC 2016
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/fe174b9f29ad
changeset: 2216:fe174b9f29ad
user: Stephan Bosch <stephan at rename-it.nl>
date: Fri Jan 08 20:49:39 2016 +0100
description:
Implemented Sieve extracttext extension.
diffstat:
Makefile.am | 1 +
src/lib-sieve/plugins/mime/Makefile.am | 12 +-
src/lib-sieve/plugins/mime/cmd-extracttext.c | 367 ++++++++++++++
src/lib-sieve/plugins/mime/ext-extracttext.c | 126 ++++
src/lib-sieve/plugins/mime/ext-mime-common.h | 8 +
src/lib-sieve/plugins/variables/cmd-set.c | 233 +-------
src/lib-sieve/plugins/variables/ext-variables-modifiers.c | 255 +++++++++-
src/lib-sieve/plugins/variables/sieve-ext-variables.h | 41 +-
src/lib-sieve/sieve-extensions.c | 4 +-
tests/extensions/mime/errors.svtest | 31 +
tests/extensions/mime/errors/extracttext-nofep.sieve | 4 +
tests/extensions/mime/errors/extracttext-novar.sieve | 6 +
tests/extensions/mime/errors/extracttext.sieve | 42 +
tests/extensions/mime/extracttext.svtest | 143 +++++
14 files changed, 1061 insertions(+), 212 deletions(-)
diffs (truncated from 1561 to 300 lines):
diff -r 46a974ebd896 -r fe174b9f29ad Makefile.am
--- a/Makefile.am Fri Jan 08 20:49:39 2016 +0100
+++ b/Makefile.am Fri Jan 08 20:49:39 2016 +0100
@@ -173,6 +173,7 @@
tests/extensions/mime/execute.svtest \
tests/extensions/mime/content-header.svtest \
tests/extensions/mime/foreverypart.svtest \
+ tests/extensions/mime/extracttext.svtest \
tests/extensions/mime/calendar-example.svtest \
tests/extensions/vnd.dovecot/debug/execute.svtest \
tests/extensions/vnd.dovecot/environment/basic.svtest \
diff -r 46a974ebd896 -r fe174b9f29ad src/lib-sieve/plugins/mime/Makefile.am
--- a/src/lib-sieve/plugins/mime/Makefile.am Fri Jan 08 20:49:39 2016 +0100
+++ b/src/lib-sieve/plugins/mime/Makefile.am Fri Jan 08 20:49:39 2016 +0100
@@ -3,21 +3,27 @@
AM_CPPFLAGS = \
-I$(srcdir)/../.. \
-I$(srcdir)/../../util \
+ -I$(srcdir)/../variables \
$(LIBDOVECOT_INCLUDE)
commands = \
cmd-foreverypart.c \
- cmd-break.c
+ cmd-break.c \
+ cmd-extracttext.c
tags = \
tag-mime.c
-libsieve_ext_mime_la_SOURCES = \
+extensions = \
ext-mime.c \
ext-foreverypart.c \
+ ext-extracttext.c
+
+libsieve_ext_mime_la_SOURCES = \
ext-mime-common.c \
$(commands) \
- $(tags)
+ $(tags) \
+ $(extensions)
noinst_HEADERS = \
ext-mime-common.h
diff -r 46a974ebd896 -r fe174b9f29ad src/lib-sieve/plugins/mime/cmd-extracttext.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-sieve/plugins/mime/cmd-extracttext.c Fri Jan 08 20:49:39 2016 +0100
@@ -0,0 +1,367 @@
+/* Copyright (c) 2002-2015 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str.h"
+#include "array.h"
+
+#include "sieve-common.h"
+#include "sieve-extensions.h"
+#include "sieve-code.h"
+#include "sieve-ast.h"
+#include "sieve-commands.h"
+#include "sieve-binary.h"
+#include "sieve-message.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+#include "sieve-dump.h"
+
+#include "sieve-ext-variables.h"
+
+#include "ext-mime-common.h"
+
+/*
+ * Extracttext command
+ *
+ * Syntax:
+ * extracttext [MODIFIER] [":first" number] <varname: string>
+ */
+
+static bool cmd_extracttext_registered
+ (struct sieve_validator *valdtr, const struct sieve_extension *ext,
+ struct sieve_command_registration *cmd_reg);
+static bool cmd_extracttext_validate
+ (struct sieve_validator *valdtr, struct sieve_command *cmd);
+static bool cmd_extracttext_generate
+ (const struct sieve_codegen_env *cgenv, struct sieve_command *ctx);
+
+const struct sieve_command_def cmd_extracttext = {
+ .identifier = "extracttext",
+ .type = SCT_COMMAND,
+ .positional_args = 1,
+ .subtests = 0,
+ .block_allowed = FALSE,
+ .block_required = FALSE,
+ .registered = cmd_extracttext_registered,
+ .validate = cmd_extracttext_validate,
+ .generate = cmd_extracttext_generate
+};
+
+/*
+ * Extracttext command tags
+ */
+
+enum cmd_extracttext_optional {
+ CMD_EXTRACTTEXT_OPT_END,
+ CMD_EXTRACTTEXT_OPT_FIRST
+};
+
+static bool cmd_extracttext_validate_first_tag
+ (struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
+ struct sieve_command *cmd);
+
+static const struct sieve_argument_def extracttext_from_tag = {
+ .identifier = "first",
+ .validate = cmd_extracttext_validate_first_tag
+};
+
+/*
+ * Extracttext operation
+ */
+
+static bool cmd_extracttext_operation_dump
+ (const struct sieve_dumptime_env *denv, sieve_size_t *address);
+static int cmd_extracttext_operation_execute
+ (const struct sieve_runtime_env *renv, sieve_size_t *address);
+
+const struct sieve_operation_def extracttext_operation = {
+ .mnemonic = "EXTRACTTEXT",
+ .ext_def = &extracttext_extension,
+ .dump = cmd_extracttext_operation_dump,
+ .execute = cmd_extracttext_operation_execute
+};
+
+/*
+ * Compiler context
+ */
+
+struct cmd_extracttext_context {
+ ARRAY_TYPE(sieve_variables_modifier) modifiers;
+};
+
+/*
+ * Tag validation
+ */
+
+static bool cmd_extracttext_validate_first_tag
+(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
+ struct sieve_command *cmd)
+{
+ struct sieve_ast_argument *tag = *arg;
+
+ /* Detach the tag itself */
+ *arg = sieve_ast_arguments_detach(*arg,1);
+
+ /* Check syntax:
+ * :first <number>
+ */
+ if ( !sieve_validate_tag_parameter
+ (valdtr, cmd, tag, *arg, NULL, 0, SAAT_NUMBER, FALSE) )
+ return FALSE;
+
+ /* Skip parameter */
+ *arg = sieve_ast_argument_next(*arg);
+
+ return TRUE;
+}
+
+/* Command registration */
+
+static bool cmd_extracttext_registered
+(struct sieve_validator *valdtr, const struct sieve_extension *ext,
+ struct sieve_command_registration *cmd_reg)
+{
+ struct ext_extracttext_context *ectx =
+ (struct ext_extracttext_context *)ext->context;
+
+ sieve_validator_register_tag(valdtr, cmd_reg, ext,
+ &extracttext_from_tag, CMD_EXTRACTTEXT_OPT_FIRST);
+ sieve_variables_modifiers_link_tag
+ (valdtr, ectx->var_ext, cmd_reg);
+ return TRUE;
+}
+
+/*
+ * Command validation
+ */
+
+static bool cmd_extracttext_validate(struct sieve_validator *valdtr,
+ struct sieve_command *cmd)
+{
+ const struct sieve_extension *this_ext = cmd->ext;
+ struct ext_extracttext_context *ectx =
+ (struct ext_extracttext_context *)this_ext->context;
+ struct sieve_ast_node *node = cmd->ast_node;
+ struct sieve_ast_argument *arg = cmd->first_positional;
+ pool_t pool = sieve_command_pool(cmd);
+ struct cmd_extracttext_context *sctx;
+
+ /* Create command context */
+ sctx = p_new(pool, struct cmd_extracttext_context, 1);
+ p_array_init(&sctx->modifiers, pool, 4);
+ cmd->data = (void *) sctx;
+
+ /* Validate modifiers */
+ if ( !sieve_variables_modifiers_validate
+ (valdtr, cmd, &sctx->modifiers) )
+ return FALSE;
+
+ /* Validate varname argument */
+ if ( !sieve_validate_positional_argument
+ (valdtr, cmd, arg, "varname", 1, SAAT_STRING) ) {
+ return FALSE;
+ }
+ if ( !sieve_variable_argument_activate
+ (ectx->var_ext, valdtr, cmd, arg, TRUE) )
+ return FALSE;
+
+ /* Check foreverypart context */
+ i_assert(node != NULL);
+ while ( node != NULL ) {
+ if ( node->command != NULL &&
+ sieve_command_is(node->command, cmd_foreverypart) )
+ break;
+ node = sieve_ast_node_parent(node);
+ }
+
+ if ( node == NULL ) {
+ sieve_command_validate_error(valdtr, cmd,
+ "the extracttext command is not placed inside "
+ "a foreverypart loop");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Code generation
+ */
+
+static bool cmd_extracttext_generate
+ (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd)
+{
+ const struct sieve_extension *this_ext = cmd->ext;
+ struct sieve_binary_block *sblock = cgenv->sblock;
+ struct cmd_extracttext_context *sctx =
+ (struct cmd_extracttext_context *) cmd->data;
+
+ sieve_operation_emit(sblock, this_ext, &extracttext_operation);
+
+ /* Generate arguments */
+ if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
+ return FALSE;
+
+ /* Generate modifiers */
+ if ( !sieve_variables_modifiers_generate
+ (cgenv, &sctx->modifiers) )
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Code dump
+ */
+
+static bool cmd_extracttext_operation_dump
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
+{
+ int opt_code = 0;
+
+ sieve_code_dumpf(denv, "EXTRACTTEXT");
+ sieve_code_descend(denv);
+
+ /* Dump optional operands */
+
+ for (;;) {
+ int opt;
+ bool opok = TRUE;
+
+ if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 )
+ return FALSE;
+ if ( opt == 0 ) break;
+
+ switch ( opt_code ) {
+ case CMD_EXTRACTTEXT_OPT_FIRST:
+ opok = sieve_opr_number_dump(denv, address, "first");
+ break;
+ default:
+ return FALSE;
+ }
+ if ( !opok ) return FALSE;
+ }
+
+ /* Print both variable name and string value */
+ if ( !sieve_opr_string_dump(denv, address, "varname") )
+ return FALSE;
+
+ return sieve_variables_modifiers_code_dump(denv, address);
+}
+
More information about the dovecot-cvs
mailing list