From 688742fa098256002cba88959c2ba6ffdae377dd Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Wed, 19 Dec 2007 14:51:36 +0100
Subject: [PATCH] Implemented support for overriding default argument
 implementations of number, string and string-list.

---
 src/lib-sieve/cmd-discard.c                   |  1 +
 src/lib-sieve/cmd-keep.c                      |  1 +
 src/lib-sieve/cmd-redirect.c                  |  3 +-
 src/lib-sieve/cmd-require.c                   |  1 +
 src/lib-sieve/ext-encoded-character.c         | 18 ++++++++
 src/lib-sieve/ext-envelope.c                  |  5 ++-
 src/lib-sieve/ext-fileinto.c                  |  3 +-
 src/lib-sieve/ext-reject.c                    |  5 ++-
 src/lib-sieve/plugins/body/tst-body.c         |  5 ++-
 src/lib-sieve/plugins/imapflags/cmd-addflag.c |  1 +
 src/lib-sieve/plugins/imapflags/cmd-setflag.c |  1 +
 .../plugins/imapflags/ext-imapflags-common.c  | 18 ++++----
 src/lib-sieve/plugins/imapflags/tag-flags.c   |  1 +
 src/lib-sieve/plugins/imapflags/tst-hasflag.c |  8 ++--
 src/lib-sieve/plugins/include/cmd-return.c    |  1 +
 src/lib-sieve/plugins/vacation/ext-vacation.c |  2 +-
 src/lib-sieve/sieve-address-parts.c           |  1 +
 src/lib-sieve/sieve-ast.h                     |  3 +-
 src/lib-sieve/sieve-code-dumper.c             |  1 +
 src/lib-sieve/sieve-commands.c                |  2 +-
 src/lib-sieve/sieve-commands.h                |  2 -
 src/lib-sieve/sieve-comparators.c             |  1 +
 src/lib-sieve/sieve-comparators.h             |  2 +
 src/lib-sieve/sieve-generator.h               |  3 +-
 src/lib-sieve/sieve-interpreter.c             |  1 +
 src/lib-sieve/sieve-parser.h                  |  4 +-
 src/lib-sieve/sieve-validator.c               | 44 +++++++++++++++----
 src/lib-sieve/sieve-validator.h               | 14 +++++-
 src/lib-sieve/tst-address.c                   |  5 ++-
 src/lib-sieve/tst-allof.c                     |  2 +
 src/lib-sieve/tst-anyof.c                     |  2 +
 src/lib-sieve/tst-exists.c                    |  3 +-
 src/lib-sieve/tst-header.c                    |  5 ++-
 src/lib-sieve/tst-not.c                       |  1 +
 src/lib-sieve/tst-size.c                      |  2 +-
 35 files changed, 126 insertions(+), 46 deletions(-)

diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c
index 232f4e5a1..0e6fcd40b 100644
--- a/src/lib-sieve/cmd-discard.c
+++ b/src/lib-sieve/cmd-discard.c
@@ -2,6 +2,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c
index 1031be7db..7834f2056 100644
--- a/src/lib-sieve/cmd-keep.c
+++ b/src/lib-sieve/cmd-keep.c
@@ -2,6 +2,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 4671c4d9f..17d35e68c 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -6,6 +6,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
@@ -97,7 +98,7 @@ static bool cmd_redirect_validate
 		(validator, cmd, arg, "address", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	 
 	return TRUE;
 }
diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c
index 83ec9d82a..f69e94d1c 100644
--- a/src/lib-sieve/cmd-require.c
+++ b/src/lib-sieve/cmd-require.c
@@ -4,6 +4,7 @@
 #include "sieve-commands-private.h"
 #include "sieve-extensions.h"
 #include "sieve-validator.h" 
+#include "sieve-generator.h"
 
 /* Types */
 
diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c
index 69f944b02..2c6d3451f 100644
--- a/src/lib-sieve/ext-encoded-character.c
+++ b/src/lib-sieve/ext-encoded-character.c
@@ -11,6 +11,7 @@
 #include "lib.h"
 
 #include "sieve-extensions.h"
+#include "sieve-commands.h"
 #include "sieve-validator.h"
 
 /* Forward declarations */
@@ -37,10 +38,27 @@ static bool ext_encoded_character_load(int ext_id)
 	return TRUE;
 }
 
+/* New argument */
+
+bool arg_encoded_string_validate
+	(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
+		struct sieve_command_context *context);
+
+const struct sieve_argument encoded_string_argument =
+	{ "@encoded-string", NULL, arg_encoded_string_validate, NULL, NULL };
+
+bool arg_encoded_string_validate
+	(struct sieve_validator *validator, struct sieve_ast_argument **arg, 
+		struct sieve_command_context *context)
+{
+	return TRUE;
+}
+
 /* Load extension into validator */
 
 static bool ext_encoded_character_validator_load
 	(struct sieve_validator *validator ATTR_UNUSED)
 {
+//	sieve_validator_argument_override(validator, 
 	return TRUE;
 }
diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 49351e675..5efa31dd8 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -15,6 +15,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
 #include "sieve-address-parts.h"
@@ -115,7 +116,7 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev
 		(validator, tst, arg, "envelope part", 1, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	arg = sieve_ast_argument_next(arg);
 	
@@ -123,7 +124,7 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev
 		(validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 
 	/* Validate the key argument to a specified match type */
 	sieve_match_type_validate(validator, tst, arg);
diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c
index 365247b3d..770a828fa 100644
--- a/src/lib-sieve/ext-fileinto.c
+++ b/src/lib-sieve/ext-fileinto.c
@@ -12,6 +12,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h"
 #include "sieve-generator.h"
@@ -93,7 +94,7 @@ static bool cmd_fileinto_validate(struct sieve_validator *validator, struct siev
 		(validator, cmd, arg, "folder", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index 2e839fac5..099fc58ae 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -18,8 +18,11 @@
 
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-binary.h"
 #include "sieve-interpreter.h"
 #include "sieve-code-dumper.h"
 #include "sieve-result.h"
@@ -129,7 +132,7 @@ static bool cmd_reject_validate(struct sieve_validator *validator, struct sieve_
 		(validator, cmd, arg, "reason", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c
index 5176c17ac..fc64e9f4c 100644
--- a/src/lib-sieve/plugins/body/tst-body.c
+++ b/src/lib-sieve/plugins/body/tst-body.c
@@ -1,5 +1,6 @@
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
 #include "sieve-address-parts.h"
@@ -140,7 +141,7 @@ static bool tag_body_transform_validate
 			(validator, cmd, tag, *arg, SAAT_STRING_LIST) ) {
 			return FALSE;
 		}
-		sieve_validator_argument_activate(validator, *arg);
+		sieve_validator_argument_activate(validator, *arg, FALSE);
 		
 		/* Assign tag parameters */
 		tag->parameters = *arg;
@@ -192,7 +193,7 @@ static bool tst_body_validate
 		(validator, tst, arg, "key list", 1, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 
 	/* Validate the key argument to a specified match type */
 	sieve_match_type_validate(validator, tst, arg);
diff --git a/src/lib-sieve/plugins/imapflags/cmd-addflag.c b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
index 7d5502a85..fa727c41e 100644
--- a/src/lib-sieve/plugins/imapflags/cmd-addflag.c
+++ b/src/lib-sieve/plugins/imapflags/cmd-addflag.c
@@ -1,6 +1,7 @@
 #include "lib.h"
 
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
diff --git a/src/lib-sieve/plugins/imapflags/cmd-setflag.c b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
index a1eeaa7b6..246e3b7c1 100644
--- a/src/lib-sieve/plugins/imapflags/cmd-setflag.c
+++ b/src/lib-sieve/plugins/imapflags/cmd-setflag.c
@@ -1,6 +1,7 @@
 #include "lib.h"
 
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
index f805c3166..411f37335 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c
@@ -1,7 +1,7 @@
 #include "lib.h"
 
-#include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
@@ -35,10 +35,9 @@ bool ext_imapflags_command_validate
 	}
 
 	arg2 = sieve_ast_argument_next(arg);
-	
-	if ( arg2 != NULL ) {
-		sieve_validator_argument_activate(validator, arg);
-		
+	if ( arg2 != NULL ) {		
+		sieve_validator_argument_activate(validator, arg, TRUE);
+
 		/* First, check syntax sanity */
 				
 		if ( sieve_ast_argument_type(arg) != SAAT_STRING ) 
@@ -71,12 +70,11 @@ bool ext_imapflags_command_validate
 				cmd->command->identifier);
 			return FALSE;
 		}
-		
-	} else 
+	} else
 		arg2 = arg;
-	
-	sieve_validator_argument_activate(validator, arg2);
-	
+
+	sieve_validator_argument_activate(validator, arg2, FALSE);	
+
 	return TRUE;
 }
 
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
index 663812402..943b6ce2f 100644
--- a/src/lib-sieve/plugins/imapflags/tag-flags.c
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -4,6 +4,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-result.h"
 #include "sieve-validator.h" 
diff --git a/src/lib-sieve/plugins/imapflags/tst-hasflag.c b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
index 716278b06..d62276ebb 100644
--- a/src/lib-sieve/plugins/imapflags/tst-hasflag.c
+++ b/src/lib-sieve/plugins/imapflags/tst-hasflag.c
@@ -1,6 +1,7 @@
 #include "lib.h"
 
 #include "sieve-commands.h"
+#include "sieve-code.h"
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
 #include "sieve-validator.h" 
@@ -103,10 +104,11 @@ static bool tst_hasflag_validate
 			"as first argument, but %s was found", sieve_ast_argument_name(arg));
 		return FALSE; 
 	}
-	sieve_validator_argument_activate(validator, arg);
 	
 	arg2 = sieve_ast_argument_next(arg);
 	if ( arg2 != NULL ) {
+		sieve_validator_argument_activate(validator, arg, TRUE);
+
 		/* First, check syntax sanity */
 		
 		if ( sieve_ast_argument_type(arg2) != SAAT_STRING && 
@@ -129,10 +131,10 @@ static bool tst_hasflag_validate
 				"variable list when the variables extension is active");
 			return FALSE;
 		}
-	
-		sieve_validator_argument_activate(validator, arg2);
 	} else 
 		arg2 = arg;
+
+	sieve_validator_argument_activate(validator, arg2, FALSE);
 	
 	/* Validate the key argument to a specified match type */
 	
diff --git a/src/lib-sieve/plugins/include/cmd-return.c b/src/lib-sieve/plugins/include/cmd-return.c
index 5f0cff944..d684de2e2 100644
--- a/src/lib-sieve/plugins/include/cmd-return.c
+++ b/src/lib-sieve/plugins/include/cmd-return.c
@@ -1,5 +1,6 @@
 #include "lib.h"
 
+#include "sieve-code.h"
 #include "sieve-commands.h"
 #include "sieve-validator.h" 
 #include "sieve-generator.h"
diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c
index abb40ac25..f0e269e82 100644
--- a/src/lib-sieve/plugins/vacation/ext-vacation.c
+++ b/src/lib-sieve/plugins/vacation/ext-vacation.c
@@ -288,7 +288,7 @@ static bool cmd_vacation_validate(struct sieve_validator *validator,
 		(validator, cmd, arg, "reason", 1, SAAT_STRING) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);	
+	sieve_validator_argument_activate(validator, arg, FALSE);	
 	
 	return TRUE;
 }
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index ec007f62e..1ecfa9f75 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -9,6 +9,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-code.h"
+#include "sieve-commands.h"
 #include "sieve-binary.h"
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h
index 4268bb8fe..d958aeb48 100644
--- a/src/lib-sieve/sieve-ast.h
+++ b/src/lib-sieve/sieve-ast.h
@@ -5,7 +5,6 @@
 #include "str.h"
 
 #include "sieve-common.h"
-#include "sieve-commands.h"
 
 /*
 	Abstract Syntax Tree (AST) structure:
@@ -51,10 +50,10 @@ enum sieve_ast_argument_type {
 	SAAT_NONE,
 	
 	/* Arguments generated by parser */
+	SAAT_NUMBER,
 	SAAT_STRING,
 	SAAT_STRING_LIST,
 	SAAT_TAG,
-	SAAT_NUMBER,
 };
 
 struct sieve_ast_argument {
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index 0c8ebb7e0..b85846361 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -8,6 +8,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-generator.h"
 #include "sieve-binary.h"
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index 23737c823..675557c5f 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -5,8 +5,8 @@
 #include "sieve-generator.h"
 #include "sieve-binary.h"
 
-#include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-interpreter.h"
 
 /* Default arguments implemented in this file */
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index 8736904dc..bd86026b3 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -5,8 +5,6 @@
 
 #include "sieve-common.h"
 #include "sieve-ast.h"
-#include "sieve-validator.h"
-#include "sieve-generator.h"
 
 /* Argument */
 
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index b338be064..234d0916a 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -5,6 +5,7 @@
 
 #include "sieve-extensions.h"
 #include "sieve-code.h"
+#include "sieve-commands.h"
 #include "sieve-binary.h"
 #include "sieve-validator.h"
 #include "sieve-generator.h"
diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h
index e9325f5b8..340fc50cd 100644
--- a/src/lib-sieve/sieve-comparators.h
+++ b/src/lib-sieve/sieve-comparators.h
@@ -1,6 +1,8 @@
 #ifndef __SIEVE_COMPARATORS_H
 #define __SIEVE_COMPARATORS_H
 
+#include "sieve-common.h"
+
 enum sieve_comparator_code {
 	SIEVE_COMPARATOR_I_OCTET,
 	SIEVE_COMPARATOR_I_ASCII_CASEMAP,
diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h
index 490297845..8b832dbb7 100644
--- a/src/lib-sieve/sieve-generator.h
+++ b/src/lib-sieve/sieve-generator.h
@@ -1,8 +1,7 @@
 #ifndef __SIEVE_GENERATOR_H
 #define __SIEVE_GENERATOR_H
 
-#include "sieve-ast.h"
-#include "sieve-code.h"
+#include "sieve-common.h"
 
 struct sieve_generator;
 
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index 1f99af2be..1a4d7cb44 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -10,6 +10,7 @@
 #include "sieve-error.h"
 #include "sieve-extensions.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-generator.h"
 #include "sieve-binary.h"
diff --git a/src/lib-sieve/sieve-parser.h b/src/lib-sieve/sieve-parser.h
index b06854f78..d12eb2a4d 100644
--- a/src/lib-sieve/sieve-parser.h
+++ b/src/lib-sieve/sieve-parser.h
@@ -2,8 +2,8 @@
 #define __SIEVE_PARSER_H
 
 #include "lib.h"
-#include "sieve-lexer.h"
-#include "sieve-ast.h"
+
+#include "sieve-common.h"
 
 struct sieve_parser;
 
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 77d0fbd74..42252a1ab 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -1,4 +1,6 @@
 #include "lib.h"
+#include "array.h"
+#include "buffer.h"
 #include "mempool.h"
 #include "hash.h"
 
@@ -12,6 +14,11 @@
 #include "sieve-comparators.h"
 #include "sieve-address-parts.h"
 
+struct sieve_default_argument {
+	const struct sieve_argument *argument;
+	struct sieve_default_argument *overrides;
+};
+
 /* Context/Semantics checker implementation */
 
 struct sieve_validator {
@@ -23,9 +30,12 @@ struct sieve_validator {
 	struct sieve_error_handler *ehandler;
 	
 	/* Registries */
+	
 	struct hash_table *commands;
 	
 	ARRAY_DEFINE(ext_contexts, void *);
+	
+	struct sieve_default_argument default_arguments[SAT_COUNT];
 };
 
 /* Predeclared statics */
@@ -87,6 +97,14 @@ struct sieve_validator *sieve_validator_create
 	validator->script = sieve_ast_script(ast);
 	sieve_ast_ref(ast);
 
+	/* Setup default arguments */
+	validator->default_arguments[SAT_NUMBER].
+		argument = &number_argument;
+	validator->default_arguments[SAT_CONST_STRING].
+		argument = &string_argument;
+	validator->default_arguments[SAT_CONST_STRING_LIST].
+		argument = &string_list_argument;
+
 	/* Setup storage for extension contexts */		
 	array_create(&validator->ext_contexts, pool, sizeof(void *), 
 		sieve_extensions_get_count());
@@ -415,20 +433,30 @@ bool sieve_validate_positional_argument
 }
 
 void sieve_validator_argument_activate
-	(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument *arg)
+	(struct sieve_validator *validator ATTR_UNUSED, 
+		struct sieve_ast_argument *arg, bool constant)
 {
 	switch ( sieve_ast_argument_type(arg) ) {
 	case SAAT_NUMBER:
-		arg->argument = &number_argument;
+		arg->argument = validator->default_arguments[SAT_NUMBER].argument;
 		break;
 	case SAAT_STRING:
-		arg->argument = &string_argument;
+		if ( validator->default_arguments[SAT_VAR_STRING].argument == NULL ||
+			constant )
+			arg->argument = validator->
+					default_arguments[SAT_CONST_STRING].argument;
+		else
+			arg->argument = validator->
+					default_arguments[SAT_VAR_STRING].argument;
 		break;
 	case SAAT_STRING_LIST:
-		arg->argument = &string_list_argument;
-		break;
-	case SAAT_TAG:
-		i_error("!!BUG!!: sieve_validator_argument_activate: cannot activate tagged argument.");
+		if ( validator->default_arguments[SAT_VAR_STRING_LIST].argument == NULL ||
+			constant )
+			arg->argument = validator->
+					default_arguments[SAT_CONST_STRING_LIST].argument;
+		else
+			arg->argument = validator->
+					default_arguments[SAT_VAR_STRING_LIST].argument;
 		break;
 	default:
 		break;
@@ -451,7 +479,7 @@ bool sieve_validate_tag_parameter
 			sieve_ast_argument_type_name(req_type),	sieve_ast_argument_name(param));
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, param);
+	sieve_validator_argument_activate(validator, param, FALSE);
 	param->arg_id_code = tag->arg_id_code;
 	
 	return TRUE;
diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h
index 4072ff5c1..e565175b6 100644
--- a/src/lib-sieve/sieve-validator.h
+++ b/src/lib-sieve/sieve-validator.h
@@ -4,7 +4,16 @@
 #include "lib.h"
 
 #include "sieve-common.h"
-#include "sieve-error.h"
+
+enum sieve_argument_type {
+	SAT_NUMBER,
+	SAT_CONST_STRING,
+	SAT_CONST_STRING_LIST,
+	SAT_VAR_STRING,
+	SAT_VAR_STRING_LIST,
+	
+	SAT_COUNT
+};
 
 struct sieve_validator;
 struct sieve_command_registration;
@@ -55,7 +64,8 @@ bool sieve_validate_positional_argument
 	struct sieve_ast_argument *arg, const char *arg_name, unsigned int arg_pos,
 	enum sieve_ast_argument_type req_type);
 void sieve_validator_argument_activate
-	(struct sieve_validator *validator, struct sieve_ast_argument *arg);	 
+	(struct sieve_validator *validator, struct sieve_ast_argument *arg,
+		bool constant);	 
 bool sieve_validate_tag_parameter
 	(struct sieve_validator *validator, struct sieve_command_context *cmd,
 	struct sieve_ast_argument *tag, struct sieve_ast_argument *param,
diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c
index b7026648e..d3c68214e 100644
--- a/src/lib-sieve/tst-address.c
+++ b/src/lib-sieve/tst-address.c
@@ -2,6 +2,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
@@ -78,7 +79,7 @@ static bool tst_address_validate
 		(validator, tst, arg, "header list", 1, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 
 	arg = sieve_ast_argument_next(arg);
 	
@@ -86,7 +87,7 @@ static bool tst_address_validate
 		(validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	/* Validate the key argument to a specified match type */
 	sieve_match_type_validate(validator, tst, arg);
diff --git a/src/lib-sieve/tst-allof.c b/src/lib-sieve/tst-allof.c
index d23090ab1..fb16b86ea 100644
--- a/src/lib-sieve/tst-allof.c
+++ b/src/lib-sieve/tst-allof.c
@@ -1,6 +1,8 @@
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
 #include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-binary.h"
 #include "sieve-code.h"
 #include "sieve-binary.h"
 
diff --git a/src/lib-sieve/tst-anyof.c b/src/lib-sieve/tst-anyof.c
index 55fca774b..687a7a2bd 100644
--- a/src/lib-sieve/tst-anyof.c
+++ b/src/lib-sieve/tst-anyof.c
@@ -1,6 +1,8 @@
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-generator.h"
 #include "sieve-validator.h"
+#include "sieve-binary.h"
 #include "sieve-code.h"
 #include "sieve-binary.h"
 
diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c
index f06d7359e..2a8058481 100644
--- a/src/lib-sieve/tst-exists.c
+++ b/src/lib-sieve/tst-exists.c
@@ -2,6 +2,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-validator.h"
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
@@ -57,7 +58,7 @@ static bool tst_exists_validate
 		(validator, tst, arg, "header names", 1, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	tst->data = arg;
 	
diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c
index 8e9d6d4ec..087f4cb7a 100644
--- a/src/lib-sieve/tst-header.c
+++ b/src/lib-sieve/tst-header.c
@@ -2,6 +2,7 @@
 
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
+#include "sieve-code.h"
 #include "sieve-comparators.h"
 #include "sieve-match-types.h"
 #include "sieve-validator.h"
@@ -82,7 +83,7 @@ static bool tst_header_validate
 		(validator, tst, arg, "header names", 1, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	arg = sieve_ast_argument_next(arg);
 
@@ -90,7 +91,7 @@ static bool tst_header_validate
 		(validator, tst, arg, "key list", 2, SAAT_STRING_LIST) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 
 	/* Validate the key argument to a specified match type */
   sieve_match_type_validate(validator, tst, arg);
diff --git a/src/lib-sieve/tst-not.c b/src/lib-sieve/tst-not.c
index 95bf74cc6..5594afe5d 100644
--- a/src/lib-sieve/tst-not.c
+++ b/src/lib-sieve/tst-not.c
@@ -1,6 +1,7 @@
 #include "sieve-commands.h"
 #include "sieve-commands-private.h"
 #include "sieve-validator.h"
+#include "sieve-generator.h"
 
 /* Not test 
  *
diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c
index 8d19e804b..5643f3ff7 100644
--- a/src/lib-sieve/tst-size.c
+++ b/src/lib-sieve/tst-size.c
@@ -155,7 +155,7 @@ static bool tst_size_validate
 		(validator, tst, arg, "limit", 1, SAAT_NUMBER) ) {
 		return FALSE;
 	}
-	sieve_validator_argument_activate(validator, arg);
+	sieve_validator_argument_activate(validator, arg, FALSE);
 	
 	return TRUE;
 }
-- 
GitLab