File: //usr/include/dovecot/sieve/sieve-commands.h
#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