Exemplo n.º 1
0
static bool cmd_filter_generate
(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd)
{
	sieve_operation_emit(cgenv->sblock, cmd->ext, &cmd_filter_operation);

	/* Emit is_test flag */
	sieve_binary_emit_byte(cgenv->sblock, ( cmd->ast_node->type == SAT_TEST ));

	/* Generate arguments */
	if ( !sieve_generate_arguments(cgenv, cmd, NULL) )
		return FALSE;

	/* Emit a placeholder when the <arguments> argument is missing */
	if ( sieve_ast_argument_next(cmd->first_positional) == NULL )
		sieve_opr_omitted_emit(cgenv->sblock);

	return TRUE;
}
Exemplo n.º 2
0
bool sieve_generate_arguments
(const struct sieve_codegen_env *cgenv, struct sieve_command *cmd,
	struct sieve_ast_argument **last_arg_r)
{
	enum { ARG_START, ARG_OPTIONAL, ARG_POSITIONAL } state = ARG_START;
	struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node);

	/* Generate all arguments with assigned generator function */

	while ( arg != NULL ) {
		const struct sieve_argument *argument;
		const struct sieve_argument_def *arg_def;

		if ( arg->argument == NULL || arg->argument->def == NULL )
			return FALSE;

		argument = arg->argument;
		arg_def = argument->def;

		switch ( state ) {
		case ARG_START:
			if ( argument->id_code == 0 )
				state = ARG_POSITIONAL;
			else {
				/* Mark start of optional operands with 0 operand identifier */
				sieve_binary_emit_byte(cgenv->sblock, SIEVE_OPERAND_OPTIONAL);

				/* Emit argument id for optional operand */
				sieve_binary_emit_byte
					(cgenv->sblock, (unsigned char) argument->id_code);

				state = ARG_OPTIONAL;
			}
			break;
		case ARG_OPTIONAL:
			if ( argument->id_code == 0 )
				state = ARG_POSITIONAL;

			/* Emit argument id for optional operand (0 marks the end of the optionals) */
			sieve_binary_emit_byte
				(cgenv->sblock, (unsigned char) argument->id_code);

			break;
		case ARG_POSITIONAL:
			if ( argument->id_code != 0 )
				return FALSE;
			break;
		}

		/* Call the generation function for the argument */
		if ( arg_def->generate != NULL ) {
			sieve_generate_debug_from_ast_argument(cgenv, arg);

			if ( !arg_def->generate(cgenv, arg, cmd) )
				return FALSE;
		} else if ( state == ARG_POSITIONAL ) break;

		arg = sieve_ast_argument_next(arg);
	}

	/* Mark end of optional list if it is still open */
	if ( state == ARG_OPTIONAL )
		sieve_binary_emit_byte(cgenv->sblock, 0);

	if ( last_arg_r != NULL )
		*last_arg_r = arg;

	return TRUE;
}