diff options
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-commands.h')
-rw-r--r-- | pigeonhole/src/lib-sieve/sieve-commands.h | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/sieve-commands.h b/pigeonhole/src/lib-sieve/sieve-commands.h new file mode 100644 index 0000000..f9b83e3 --- /dev/null +++ b/pigeonhole/src/lib-sieve/sieve-commands.h @@ -0,0 +1,286 @@ +#ifndef SIEVE_COMMANDS_H +#define SIEVE_COMMANDS_H + +#include "lib.h" + +#include "sieve-common.h" +#include "sieve-ast.h" + +/* + * Argument definition + */ + +enum sieve_argument_flag { + /* More than one of this (type of) tagged argument is allowed */ + SIEVE_ARGUMENT_FLAG_MULTIPLE = (1 << 0) +}; + +struct sieve_argument_def { + const char *identifier; + enum sieve_argument_flag flags; + + bool (*is_instance_of) + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext, const char *identifier, void **data); + + bool (*validate) + (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, + struct sieve_command *cmd); + bool (*validate_context) + (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, + struct sieve_command *cmd); + bool (*validate_persistent) + (struct sieve_validator *valdtr, struct sieve_command *cmd, + const struct sieve_extension *ext); + + bool (*generate) + (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command *cmd); +}; + +/* + * Argument instance + */ + +struct sieve_argument { + const struct sieve_argument_def *def; + const struct sieve_extension *ext; + int id_code; + + /* Context data */ + void *data; +}; + +#define sieve_argument_is(ast_arg, definition) \ + ( (ast_arg)->argument->def == &(definition) ) +#define sieve_argument_ext(ast_arg) \ + ( (ast_arg)->argument->ext ) +#define sieve_argument_identifier(ast_arg) \ + ( (ast_arg)->argument->def->identifier ) + +/* Utility macros */ + +#define sieve_argument_is_string_literal(arg) \ + ( (arg)->argument->def == &string_argument ) + +/* Error handling */ + +#define sieve_argument_validate_error(validator, arg_node, ...) \ + sieve_validator_error(validator, \ + ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ + __VA_ARGS__) +#define sieve_argument_validate_warning(validator, arg_node, ...) \ + sieve_validator_warning(validator, \ + ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ + __VA_ARGS__) + +#define sieve_argument_generate_error(gentr, arg_node, ...) \ + sieve_generator_error(gentr, \ + ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ + __VA_ARGS__) +#define sieve_argument_generate_warning(gentr, arg_node, ...) \ + sieve_generator_warning(gentr, \ + ((arg_node) == NULL ? 0 : (arg_node)->source_line), \ + __VA_ARGS__) + +/* Argument API */ + +struct sieve_argument *sieve_argument_create + (struct sieve_ast *ast, const struct sieve_argument_def *def, + const struct sieve_extension *ext, int id_code); + +/* Literal arguments */ + +extern const struct sieve_argument_def number_argument; +extern const struct sieve_argument_def string_argument; +extern const struct sieve_argument_def string_list_argument; + +/* Catenated string argument */ + +bool sieve_arg_catenated_string_generate + (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command *context); + +struct sieve_arg_catenated_string; + +struct sieve_arg_catenated_string *sieve_arg_catenated_string_create + (struct sieve_ast_argument *orig_arg); +void sieve_arg_catenated_string_add_element + (struct sieve_arg_catenated_string *strdata, + struct sieve_ast_argument *element); + +/* + * Command definition + */ + +enum sieve_command_type { + SCT_NONE, + SCT_COMMAND, + SCT_TEST, + SCT_HYBRID +}; + +struct sieve_command_def { + const char *identifier; + enum sieve_command_type type; + + /* High-level command syntax */ + int positional_args; + int subtests; + bool block_allowed; + bool block_required; + + bool (*registered) + (struct sieve_validator *valdtr, const struct sieve_extension *ext, + struct sieve_command_registration *cmd_reg); + bool (*pre_validate) + (struct sieve_validator *valdtr, struct sieve_command *cmd); + bool (*validate) + (struct sieve_validator *valdtr, struct sieve_command *cmd); + bool (*validate_const) + (struct sieve_validator *valdtr, struct sieve_command *cmd, + int *const_current, int const_next); + bool (*generate) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd); + bool (*control_generate) + (const struct sieve_codegen_env *cgenv, struct sieve_command *cmd, + struct sieve_jumplist *jumps, bool jump_true); +}; + +/* + * Command instance + */ + +struct sieve_command { + const struct sieve_command_def *def; + const struct sieve_extension *ext; + + /* The registration of this command in the validator (sieve-validator.h) */ + struct sieve_command_registration *reg; + + /* The ast node of this command */ + struct sieve_ast_node *ast_node; + + /* First positional argument, found during argument validation */ + struct sieve_ast_argument *first_positional; + + /* The child ast node that unconditionally exits this command's block */ + struct sieve_command *block_exit_command; + + /* Context data*/ + void *data; +}; + +#define sieve_command_is(cmd, definition) \ + ( (cmd)->def == &(definition) ) +#define sieve_command_identifier(cmd) \ + ( (cmd)->def->identifier ) + +#define sieve_commands_equal(cmd1, cmd2) \ + ( (cmd1) != NULL && (cmd2) != NULL && (cmd1)->def == (cmd2)->def ) + +/* Context API */ + +struct sieve_command *sieve_command_create + (struct sieve_ast_node *cmd_node, const struct sieve_extension *ext, + const struct sieve_command_def *cmd_def, + struct sieve_command_registration *cmd_reg); + +const char *sieve_command_def_type_name + (const struct sieve_command_def *cmd_def); +const char *sieve_command_type_name + (const struct sieve_command *cmd); + +struct sieve_command *sieve_command_prev + (struct sieve_command *cmd); +struct sieve_command *sieve_command_parent + (struct sieve_command *cmd); + +struct sieve_ast_argument *sieve_command_add_dynamic_tag + (struct sieve_command *cmd, const struct sieve_extension *ext, + const struct sieve_argument_def *tag, int id_code); +struct sieve_ast_argument *sieve_command_find_argument + (struct sieve_command *cmd, const struct sieve_argument_def *argument); + +void sieve_command_exit_block_unconditionally + (struct sieve_command *cmd); +bool sieve_command_block_exits_unconditionally + (struct sieve_command *cmd); + +/* Error handling */ + +#define sieve_command_validate_error(validator, context, ...) \ + sieve_validator_error(validator, \ + ((context) == NULL ? 0 : (context)->ast_node->source_line), \ + __VA_ARGS__) +#define sieve_command_validate_warning(validator, context, ...) \ + sieve_validator_warning(validator, \ + ((context) == NULL ? 0 : (context)->ast_node->source_line), \ + __VA_ARGS__) + +#define sieve_command_generate_error(gentr, context, ...) \ + sieve_generator_error(gentr, \ + ((context) == NULL ? 0 : (context)->ast_node->source_line), \ + __VA_ARGS__) +#define sieve_command_generate_warning(gentr, context, ...) \ + sieve_generator_warning(gentr, \ + ((context) == NULL ? 0 : (context)->ast_node->source_line), \ + __VA_ARGS__) + +/* Utility macros */ + +#define sieve_command_pool(context) \ + sieve_ast_node_pool((context)->ast_node) + +#define sieve_command_source_line(context) \ + (context)->ast_node->source_line + +#define sieve_command_first_argument(context) \ + sieve_ast_argument_first((context)->ast_node) + +#define sieve_command_is_toplevel(context) \ + ( sieve_ast_node_type(sieve_ast_node_parent((context)->ast_node)) == SAT_ROOT ) +#define sieve_command_is_first(context) \ + ( sieve_ast_node_prev((context)->ast_node) == NULL ) + +/* + * Core commands + */ + +extern const struct sieve_command_def cmd_require; +extern const struct sieve_command_def cmd_stop; +extern const struct sieve_command_def cmd_if; +extern const struct sieve_command_def cmd_elsif; +extern const struct sieve_command_def cmd_else; +extern const struct sieve_command_def cmd_redirect; +extern const struct sieve_command_def cmd_keep; +extern const struct sieve_command_def cmd_discard; + +extern const struct sieve_command_def *sieve_core_commands[]; +extern const unsigned int sieve_core_commands_count; + +/* + * Core tests + */ + +extern const struct sieve_command_def tst_true; +extern const struct sieve_command_def tst_false; +extern const struct sieve_command_def tst_not; +extern const struct sieve_command_def tst_anyof; +extern const struct sieve_command_def tst_allof; +extern const struct sieve_command_def tst_address; +extern const struct sieve_command_def tst_header; +extern const struct sieve_command_def tst_exists; +extern const struct sieve_command_def tst_size; + +extern const struct sieve_command_def *sieve_core_tests[]; +extern const unsigned int sieve_core_tests_count; + +/* + * Command utility functions + */ + +bool sieve_command_verify_headers_argument +(struct sieve_validator *valdtr, struct sieve_ast_argument *headers); + +#endif |