summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-commands.h
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-commands.h')
-rw-r--r--pigeonhole/src/lib-sieve/sieve-commands.h286
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