From c527430b02a3e3712dd1883ed48a15d967b2d7bf Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 20 Dec 2011 20:05:21 +0100 Subject: [PATCH] lib-sieve: adjusted code fetch api for handling omitted operands better. Removes quite a bit of duplicated source code. --- src/lib-sieve/cmd-redirect.c | 4 +- src/lib-sieve/ext-fileinto.c | 4 +- src/lib-sieve/plugins/date/tst-date.c | 26 +------- .../plugins/editheader/cmd-deleteheader.c | 26 ++------ src/lib-sieve/plugins/imap4flags/tag-flags.c | 57 +++++++----------- src/lib-sieve/sieve-code.c | 59 +++++++++++++++++-- src/lib-sieve/sieve-code.h | 10 +++- 7 files changed, 96 insertions(+), 90 deletions(-) diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 6ce20a20d..6b1e1f35e 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -209,8 +209,8 @@ static int cmd_redirect_operation_execute return ret; /* Read the address */ - if ( (ret=sieve_opr_string_read_ex(renv, address, "address", &redirect, - &literal_address)) <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "address", FALSE, &redirect, &literal_address)) <= 0 ) return ret; /* diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 93c466d34..ec98dee5d 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -183,8 +183,8 @@ static int ext_fileinto_operation_execute return ret; /* Folder operand */ - if ( (ret=sieve_opr_string_read_ex(renv, address, "folder", &folder, - &folder_literal)) <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "folder", FALSE, &folder, &folder_literal)) <= 0 ) return ret; /* diff --git a/src/lib-sieve/plugins/date/tst-date.c b/src/lib-sieve/plugins/date/tst-date.c index eeb13070d..9dab18772 100644 --- a/src/lib-sieve/plugins/date/tst-date.c +++ b/src/lib-sieve/plugins/date/tst-date.c @@ -331,7 +331,6 @@ static bool tst_date_operation_dump { int opt_code = 0; const struct sieve_operation *op = denv->oprtn; - struct sieve_operand operand; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(op)); sieve_code_descend(denv); @@ -347,18 +346,8 @@ static bool tst_date_operation_dump switch ( opt_code ) { case OPT_DATE_ZONE: - if ( !sieve_operand_read(denv->sblock, address, "zone", &operand) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); + if ( !sieve_opr_string_dump_ex(denv, address, "zone", "ORIGINAL") ) return FALSE; - } - - if ( sieve_operand_is_omitted(&operand) ) { - sieve_code_dumpf(denv, "zone: ORIGINAL"); - } else { - if ( !sieve_opr_string_dump_data - (denv, &operand, address, "zone") ) - return FALSE; - } break; default: return FALSE; @@ -388,7 +377,6 @@ static int tst_date_operation_execute SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); - struct sieve_operand oprnd; string_t *date_part = NULL, *zone = NULL; struct sieve_stringlist *hdr_list = NULL, *hdr_value_list; struct sieve_stringlist *value_list, *key_list; @@ -408,18 +396,10 @@ static int tst_date_operation_execute switch ( opt_code ) { case OPT_DATE_ZONE: - if ( (ret=sieve_operand_runtime_read(renv, address, "zone", &oprnd)) - <= 0 ) + if ( (ret=sieve_opr_string_read_ex + (renv, address, "zone", TRUE, &zone, &zone_literal)) <= 0 ) return ret; - if ( !sieve_operand_is_omitted(&oprnd) ) { - if ( (ret=sieve_opr_string_read_data - (renv, &oprnd, address, "zone", &zone)) <= 0 ) - return ret; - - zone_literal = sieve_operand_is_string_literal(&oprnd); - } - zone_specified = TRUE; break; default: diff --git a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c index 7030350f6..433d36ed2 100644 --- a/src/lib-sieve/plugins/editheader/cmd-deleteheader.c +++ b/src/lib-sieve/plugins/editheader/cmd-deleteheader.c @@ -316,7 +316,6 @@ static bool cmd_deleteheader_generate static bool cmd_deleteheader_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand oprnd; int opt_code = 0; sieve_code_dumpf(denv, "DELETEHEADER"); @@ -347,19 +346,7 @@ static bool cmd_deleteheader_operation_dump if ( !sieve_opr_string_dump(denv, address, "field name") ) return FALSE; - sieve_code_mark(denv); - - if ( !sieve_operand_read - (denv->sblock, address, "value patterns", &oprnd) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); - return FALSE; - } - - if ( sieve_operand_is_omitted(&oprnd) ) - return TRUE; - - return sieve_opr_stringlist_dump_data - (denv, &oprnd, address, "value patterns"); + return sieve_opr_stringlist_dump_ex(denv, address, "value patterns", ""); } /* @@ -371,7 +358,6 @@ static int cmd_deleteheader_operation_execute { const struct sieve_extension *this_ext = renv->oprtn->ext; int opt_code = 0; - struct sieve_operand oprnd; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = @@ -423,13 +409,9 @@ static int cmd_deleteheader_operation_execute <= 0 ) return ret; - /* Read value-patterns */ - if ( (ret=sieve_operand_runtime_read - (renv, address, "value-patterns", &oprnd)) <= 0 ) - return ret; - - if ( !sieve_operand_is_omitted(&oprnd) && (ret=sieve_opr_stringlist_read_data - (renv, &oprnd, address, "value-patterns", &vpattern_list)) <= 0 ) + /* Read value-patterns */ + if ( (ret=sieve_opr_stringlist_read_ex + (renv, address, "value-patterns", TRUE, &vpattern_list)) <= 0 ) return ret; /* diff --git a/src/lib-sieve/plugins/imap4flags/tag-flags.c b/src/lib-sieve/plugins/imap4flags/tag-flags.c index 7d53d9aa2..e0f960e03 100644 --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c @@ -197,19 +197,7 @@ static bool seff_flags_dump_context (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand oprnd; - - if ( !sieve_operand_read(denv->sblock, address, "flags", &oprnd) ) { - sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); - return FALSE; - } - - if ( sieve_operand_is_omitted(&oprnd) ) { - sieve_code_dumpf(denv, "flags: INTERNAL"); - return TRUE; - } - - return sieve_opr_stringlist_dump_data(denv, &oprnd, address, "flags"); + return sieve_opr_stringlist_dump_ex(denv, address, "flags", "INTERNAL"); } static struct seff_flags_context *seff_flags_get_implicit_context @@ -252,43 +240,30 @@ static struct seff_flags_context *seff_flags_get_implicit_context return ctx; } -static int seff_flags_read_context +static int seff_flags_do_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { - struct sieve_operand oprnd; pool_t pool = sieve_result_pool(renv->result); struct seff_flags_context *ctx; string_t *flags_item; - struct sieve_stringlist *flag_list; - int ret; - - t_push(); + struct sieve_stringlist *flag_list = NULL; + int ret; - /* Check whether explicit flag list operand is present */ - if ( (ret=sieve_operand_runtime_read(renv, address, "flags", &oprnd)) <= 0 ) { - t_pop(); + if ( (ret=sieve_opr_stringlist_read_ex + (renv, address, "flags", TRUE, &flag_list)) <= 0 ) return ret; - } - if ( sieve_operand_is_omitted(&oprnd) ) { + if ( flag_list == NULL ) { /* Flag list is omitted, use current value of internal * variable to construct side effect context. */ *se_context = seff_flags_get_implicit_context (SIEVE_OBJECT_EXTENSION(seffect), renv->result); - t_pop(); return SIEVE_EXEC_OK; } - - /* Read flag-list */ - if ( (ret=sieve_opr_stringlist_read_data - (renv, &oprnd, address, NULL, &flag_list)) <= 0 ) { - t_pop(); - return ret; - } - + ctx = p_new(pool, struct seff_flags_context, 1); p_array_init(&ctx->keywords, pool, 2); @@ -325,12 +300,24 @@ static int seff_flags_read_context } *se_context = (void *) ctx; - - t_pop(); return SIEVE_EXEC_OK; } +static int seff_flags_read_context +(const struct sieve_side_effect *seffect, + const struct sieve_runtime_env *renv, sieve_size_t *address, + void **se_context) +{ + int ret; + + T_BEGIN { + ret = seff_flags_do_read_context(seffect, renv, address, se_context); + } T_END; + + return ret; +} + /* Result verification */ static int seff_flags_merge diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index 5269702df..1b8232dba 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -536,7 +536,7 @@ bool sieve_opr_string_dump bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name, bool *literal_r) + const char *field_name, const char *omitted_value) { struct sieve_operand operand; @@ -546,7 +546,11 @@ bool sieve_opr_string_dump_ex return FALSE; } - *literal_r = sieve_operand_is_string_literal(&operand); + if ( omitted_value != NULL && sieve_operand_is_omitted(&operand) ) { + if ( *omitted_value != '\0' ) + sieve_code_dumpf(denv, "%s: %s", field_name, omitted_value); + return TRUE; + } return sieve_opr_string_dump_data(denv, &operand, address, field_name); } @@ -592,7 +596,7 @@ int sieve_opr_string_read int sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name, string_t **str_r, bool *literal_r) + const char *field_name, bool optional, string_t **str_r, bool *literal_r) { struct sieve_operand operand; int ret; @@ -601,7 +605,13 @@ int sieve_opr_string_read_ex <= 0 ) return ret; - *literal_r = sieve_operand_is_string_literal(&operand); + if ( optional && sieve_operand_is_omitted(&operand) ) { + *str_r = NULL; + return TRUE; + } + + if ( literal_r != NULL ) + *literal_r = sieve_operand_is_string_literal(&operand); return sieve_opr_string_read_data(renv, &operand, address, field_name, str_r); } @@ -732,6 +742,27 @@ bool sieve_opr_stringlist_dump return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); } +bool sieve_opr_stringlist_dump_ex +(const struct sieve_dumptime_env *denv, sieve_size_t *address, + const char *field_name, const char *omitted_value) +{ + struct sieve_operand operand; + + sieve_code_mark(denv); + + if ( !sieve_operand_read(denv->sblock, address, field_name, &operand) ) { + return FALSE; + } + + if ( omitted_value != NULL && sieve_operand_is_omitted(&operand) ) { + if ( *omitted_value != '\0' ) + sieve_code_dumpf(denv, "%s: %s", field_name, omitted_value); + return TRUE; + } + + return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); +} + int sieve_opr_stringlist_read_data (const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, @@ -799,6 +830,26 @@ int sieve_opr_stringlist_read (renv, &operand, address, field_name, strlist_r); } +int sieve_opr_stringlist_read_ex +(const struct sieve_runtime_env *renv, sieve_size_t *address, + const char *field_name, bool optional, struct sieve_stringlist **strlist_r) +{ + struct sieve_operand operand; + int ret; + + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0 ) + return ret; + + if ( optional && sieve_operand_is_omitted(&operand) ) { + *strlist_r = NULL; + return TRUE; + } + + return sieve_opr_stringlist_read_data + (renv, &operand, address, field_name, strlist_r); +} + static bool opr_stringlist_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, sieve_size_t *address) diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index 04cdbfbbc..ac4e9a585 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -213,7 +213,7 @@ bool sieve_opr_string_dump const char *field_name); bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name, bool *literal_r); + const char *field_name, const char *omitted_value); int sieve_opr_string_read_data (const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, string_t **str_r); @@ -222,7 +222,7 @@ int sieve_opr_string_read const char *field_name, string_t **str_r); int sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name, string_t **str_r, bool *literal_r); + const char *field_name, bool optional, string_t **str_r, bool *literal_r); static inline bool sieve_operand_is_string (const struct sieve_operand *operand) @@ -252,6 +252,9 @@ bool sieve_opr_stringlist_dump_data bool sieve_opr_stringlist_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); +bool sieve_opr_stringlist_dump_ex + (const struct sieve_dumptime_env *denv, sieve_size_t *address, + const char *field_name, const char *omitted_value); int sieve_opr_stringlist_read_data (const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, @@ -259,6 +262,9 @@ int sieve_opr_stringlist_read_data int sieve_opr_stringlist_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_stringlist **strlist_r); +int sieve_opr_stringlist_read_ex + (const struct sieve_runtime_env *renv, sieve_size_t *address, + const char *field_name, bool optional, struct sieve_stringlist **strlist_r); static inline bool sieve_operand_is_stringlist (const struct sieve_operand *operand) -- GitLab