From 8e29831ddef07c68ea9a911f80b593b11e1bbf4d Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Thu, 25 Dec 2008 18:02:06 +0100
Subject: [PATCH] Simplified handling of extension ids.

---
 src/lib-sieve/ext-encoded-character.c         | 12 +-----
 src/lib-sieve/ext-envelope.c                  | 14 ++-----
 src/lib-sieve/ext-fileinto.c                  | 14 ++-----
 src/lib-sieve/ext-reject.c                    | 14 ++-----
 src/lib-sieve/plugins/body/ext-body.c         | 14 ++-----
 .../ext-cmp-i-ascii-numeric.c                 | 15 +------
 src/lib-sieve/plugins/copy/ext-copy.c         | 13 +-----
 .../plugins/enotify/ext-enotify-common.c      |  1 +
 src/lib-sieve/plugins/enotify/ext-enotify.c   |  8 ++--
 .../plugins/imapflags/ext-imapflags.c         | 14 +------
 src/lib-sieve/plugins/include/ext-include.c   | 13 +-----
 src/lib-sieve/plugins/regex/ext-regex.c       | 13 +-----
 .../plugins/relational/ext-relational.c       | 13 +-----
 .../plugins/subaddress/ext-subaddress.c       | 13 +-----
 src/lib-sieve/plugins/vacation/ext-vacation.c | 13 +-----
 .../plugins/variables/ext-variables-common.c  |  4 +-
 .../plugins/variables/ext-variables-dump.c    |  4 +-
 .../plugins/variables/ext-variables.c         | 12 +-----
 src/lib-sieve/sieve-address-parts.c           | 10 +----
 src/lib-sieve/sieve-ast.c                     |  6 +--
 src/lib-sieve/sieve-binary-dumper.c           |  2 +-
 src/lib-sieve/sieve-binary.c                  |  4 +-
 src/lib-sieve/sieve-code-dumper.c             |  6 +--
 src/lib-sieve/sieve-comparators.c             | 10 +----
 src/lib-sieve/sieve-extensions.c              | 40 ++++++++++++-------
 src/lib-sieve/sieve-extensions.h              | 12 ++++--
 src/lib-sieve/sieve-generator.c               |  4 +-
 src/lib-sieve/sieve-interpreter.c             |  6 +--
 src/lib-sieve/sieve-match-types.c             | 14 ++-----
 src/lib-sieve/sieve-message.c                 |  4 +-
 src/lib-sieve/sieve-result.c                  |  4 +-
 src/lib-sieve/sieve-validator.c               |  6 +--
 src/testsuite/ext-testsuite.c                 | 13 +-----
 33 files changed, 103 insertions(+), 242 deletions(-)

diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c
index 77c11be24..4311152f2 100644
--- a/src/lib-sieve/ext-encoded-character.c
+++ b/src/lib-sieve/ext-encoded-character.c
@@ -24,29 +24,21 @@
  * Extension
  */
 
-static bool ext_encoded_character_load(int ext_id);
 static bool ext_encoded_character_validator_load
 	(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 	
 struct sieve_extension encoded_character_extension = { 
 	"encoded-character", 
 	&ext_my_id,
-	ext_encoded_character_load,
-	NULL,
+	NULL, NULL,
 	ext_encoded_character_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
 	SIEVE_EXT_DEFINE_NO_OPERANDS
 };
 
-static bool ext_encoded_character_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 /*
  * Encoded string argument
  */
diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c
index 55c764e75..ced44b11b 100644
--- a/src/lib-sieve/ext-envelope.c
+++ b/src/lib-sieve/ext-envelope.c
@@ -42,28 +42,20 @@ const struct sieve_extension envelope_extension;
  * Extension 
  */
 
-static int ext_my_id;
-
-static bool ext_envelope_load(int ext_id);
 static bool ext_envelope_validator_load(struct sieve_validator *validator);
 
+static int ext_my_id = -1;
+
 const struct sieve_extension envelope_extension = { 
 	"envelope", 
 	&ext_my_id,
-	ext_envelope_load,
-	NULL,
+	NULL, NULL,
 	ext_envelope_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATION(envelope_operation), 
 	SIEVE_EXT_DEFINE_NO_OPERANDS 
 };
 
-static bool ext_envelope_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 static bool ext_envelope_validator_load(struct sieve_validator *validator)
 {
 	/* Register new test */
diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c
index 81d0a48c5..08976def5 100644
--- a/src/lib-sieve/ext-fileinto.c
+++ b/src/lib-sieve/ext-fileinto.c
@@ -39,28 +39,20 @@ const struct sieve_extension fileinto_extension;
  * Extension
  */
 
-static int ext_my_id;
-
-static bool ext_fileinto_load(int ext_id);
 static bool ext_fileinto_validator_load(struct sieve_validator *validator);
 
+static int ext_my_id = -1;
+
 const struct sieve_extension fileinto_extension = { 
 	"fileinto", 
 	&ext_my_id,
-	ext_fileinto_load,
-	NULL,
+	NULL, NULL,
 	ext_fileinto_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATION(fileinto_operation), 
 	SIEVE_EXT_DEFINE_NO_OPERANDS	
 };
 
-static bool ext_fileinto_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 static bool ext_fileinto_validator_load(struct sieve_validator *validator)
 {
 	/* Register new command */
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index 6bac6c003..6e61f951f 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -46,28 +46,20 @@ struct sieve_extension reject_extension;
  * Extension
  */
 
-static int ext_my_id;
-
-static bool ext_reject_load(int ext_id);
 static bool ext_reject_validator_load(struct sieve_validator *validator);
+
+static int ext_my_id = -1;
 	
 struct sieve_extension reject_extension = { 
 	"reject", 
 	&ext_my_id,
-	ext_reject_load,
-	NULL,
+	NULL, NULL,
 	ext_reject_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATION(reject_operation), 
 	SIEVE_EXT_DEFINE_NO_OPERANDS
 };
 
-static bool ext_reject_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 static bool ext_reject_validator_load(struct sieve_validator *validator)
 {
 	/* Register new command */
diff --git a/src/lib-sieve/plugins/body/ext-body.c b/src/lib-sieve/plugins/body/ext-body.c
index d0947a5f0..56f67994d 100644
--- a/src/lib-sieve/plugins/body/ext-body.c
+++ b/src/lib-sieve/plugins/body/ext-body.c
@@ -48,28 +48,20 @@
  * Extension 
  */
 
-int ext_body_my_id;
-
-static bool ext_body_load(int ext_id);
 static bool ext_body_validator_load(struct sieve_validator *validator);
 
+int ext_body_my_id = -1;
+
 const struct sieve_extension body_extension = { 
 	"body", 
 	&ext_body_my_id,
-	ext_body_load,
-	NULL,
+	NULL, NULL,
 	ext_body_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATION(body_operation), 
 	SIEVE_EXT_DEFINE_NO_OPERANDS
 };
 
-static bool ext_body_load(int ext_id) 
-{
-	ext_body_my_id = ext_id;
-	return TRUE;
-}
-
 static bool ext_body_validator_load(struct sieve_validator *validator)
 {
 	/* Register new test */
diff --git a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
index 6301f4ae1..921930207 100644
--- a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
+++ b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c
@@ -30,8 +30,6 @@ static const struct sieve_operand my_comparator_operand;
 
 const struct sieve_comparator i_ascii_numeric_comparator;
 
-static bool ext_cmp_i_ascii_numeric_load
-	(int ext_id);
 static bool ext_cmp_i_ascii_numeric_validator_load
 	(struct sieve_validator *validator);
 
@@ -39,27 +37,18 @@ static bool ext_cmp_i_ascii_numeric_validator_load
  * Extension
  */
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension comparator_i_ascii_numeric_extension = { 
 	"comparator-i;ascii-numeric", 
 	&ext_my_id,
-	ext_cmp_i_ascii_numeric_load,
-	NULL,
+	NULL, NULL,
 	ext_cmp_i_ascii_numeric_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
 	SIEVE_EXT_DEFINE_OPERAND(my_comparator_operand)
 };
 
-static bool ext_cmp_i_ascii_numeric_load
-	(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_cmp_i_ascii_numeric_validator_load
 	(struct sieve_validator *validator)
 {
diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c
index fe5021d94..26fa3c4fe 100644
--- a/src/lib-sieve/plugins/copy/ext-copy.c
+++ b/src/lib-sieve/plugins/copy/ext-copy.c
@@ -35,29 +35,20 @@ static const struct sieve_operand copy_side_effect_operand;
  * Extension
  */
 
-static bool ext_copy_load(int ext_id);
 static bool ext_copy_validator_load(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension copy_extension = { 
 	"copy", 
 	&ext_my_id,
-	ext_copy_load,
-	NULL,
+	NULL, NULL,
 	ext_copy_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
 	SIEVE_EXT_DEFINE_OPERAND(copy_side_effect_operand)
 };
 
-static bool ext_copy_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_copy_validator_load(struct sieve_validator *validator)
 {
 	/* Register copy tag with redirect and fileinto commands and we don't care
diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.c b/src/lib-sieve/plugins/enotify/ext-enotify-common.c
index 71744c381..c735046ca 100644
--- a/src/lib-sieve/plugins/enotify/ext-enotify-common.c
+++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.c
@@ -26,6 +26,7 @@ static const char *ext_notify_get_methods_string(void);
 
 const struct sieve_extension_capabilities notify_capabilities = {
 	"notify",
+	&enotify_extension,
 	ext_notify_get_methods_string
 };
 
diff --git a/src/lib-sieve/plugins/enotify/ext-enotify.c b/src/lib-sieve/plugins/enotify/ext-enotify.c
index fc4575cdb..e2d8d7347 100644
--- a/src/lib-sieve/plugins/enotify/ext-enotify.c
+++ b/src/lib-sieve/plugins/enotify/ext-enotify.c
@@ -42,11 +42,11 @@ const struct sieve_operation *ext_enotify_operations[] = {
  * Extension
  */
 
-static bool ext_enotify_load(int ext_id);
+static bool ext_enotify_load(void);
 static void ext_enotify_unload(void);
 static bool ext_enotify_validator_load(struct sieve_validator *valdtr);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension enotify_extension = { 
 	"enotify", 
@@ -59,10 +59,8 @@ const struct sieve_extension enotify_extension = {
 	SIEVE_EXT_DEFINE_OPERAND(encodeurl_operand)
 };
 
-static bool ext_enotify_load(int ext_id)
+static bool ext_enotify_load(void)
 {
-	ext_my_id = ext_id;
-
 	ext_enotify_methods_init();
 
 	sieve_extension_capabilities_register(&notify_capabilities);
diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
index e10066b99..dd00414f7 100644
--- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c
+++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c
@@ -42,18 +42,16 @@ const struct sieve_operation *imapflags_operations[] = {
  * Extension
  */
 
-static bool ext_imapflags_load(int ext_id);
 static bool ext_imapflags_validator_load(struct sieve_validator *valdtr);
 static bool ext_imapflags_interpreter_load
 	(const struct sieve_runtime_env *renv, sieve_size_t *address);
 
-int ext_imapflags_my_id;
+int ext_imapflags_my_id = -1;
 
 const struct sieve_extension imapflags_extension = { 
 	"imap4flags", 
 	&ext_imapflags_my_id,
-	ext_imapflags_load,
-	NULL,
+	NULL, NULL,
 	ext_imapflags_validator_load, 
 	NULL, 
 	ext_imapflags_interpreter_load, 
@@ -62,14 +60,6 @@ const struct sieve_extension imapflags_extension = {
 	SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand)
 };
 
-static bool ext_imapflags_load
-(int ext_id)
-{
-	ext_imapflags_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_imapflags_validator_load
 (struct sieve_validator *valdtr)
 {
diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c
index d283b507a..c7a94b8e6 100644
--- a/src/lib-sieve/plugins/include/ext-include.c
+++ b/src/lib-sieve/plugins/include/ext-include.c
@@ -47,7 +47,6 @@ static const struct sieve_operation *ext_include_operations[] = {
  
 /* Forward declaration */
 
-static bool ext_include_load(int ext_id);
 static bool ext_include_validator_load(struct sieve_validator *validator);
 static bool ext_include_generator_load(const struct sieve_codegen_env *cgenv);
 static bool ext_include_interpreter_load
@@ -55,13 +54,12 @@ static bool ext_include_interpreter_load
 
 /* Extension objects */
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension include_extension = { 
 	"include", 
 	&ext_my_id,
-	ext_include_load,
-	NULL, 
+	NULL, NULL,
 	ext_include_validator_load, 
 	ext_include_generator_load,
 	ext_include_interpreter_load,
@@ -74,13 +72,6 @@ const struct sieve_extension include_extension = {
 
 /* Extension hooks */
 
-static bool ext_include_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_include_validator_load(struct sieve_validator *validator)
 {
 	/* Register new commands */
diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c
index 27fb3629c..dda005079 100644
--- a/src/lib-sieve/plugins/regex/ext-regex.c
+++ b/src/lib-sieve/plugins/regex/ext-regex.c
@@ -43,29 +43,20 @@
  * Extension
  */
 
-static bool ext_regex_load(int ext_id);
 static bool ext_regex_validator_load(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension regex_extension = { 
 	"regex", 
 	&ext_my_id,
-	ext_regex_load,
-	NULL,
+	NULL, NULL,
 	ext_regex_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
 	SIEVE_EXT_DEFINE_OPERAND(regex_match_type_operand)
 };
 
-static bool ext_regex_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_regex_validator_load(struct sieve_validator *validator)
 {
 	sieve_match_type_register(validator, &regex_match_type); 
diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c
index 4c9c2d79b..752111666 100644
--- a/src/lib-sieve/plugins/relational/ext-relational.c
+++ b/src/lib-sieve/plugins/relational/ext-relational.c
@@ -32,29 +32,20 @@
  * Extension
  */
 
-static bool ext_relational_load(int ext_id);
 static bool ext_relational_validator_load(struct sieve_validator *validator);
 
-int ext_relational_my_id;
+int ext_relational_my_id = -1;
 
 const struct sieve_extension relational_extension = { 
 	"relational", 
 	&ext_relational_my_id,
-	ext_relational_load,
-	NULL,
+	NULL, NULL,
 	ext_relational_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
 	SIEVE_EXT_DEFINE_OPERAND(rel_match_type_operand)
 };
 
-static bool ext_relational_load(int ext_id)
-{
-	ext_relational_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_relational_validator_load(struct sieve_validator *validator)
 {
 	sieve_match_type_register(validator, &value_match_type); 
diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
index 10021e3ad..e2329d6b8 100644
--- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c
+++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
@@ -46,29 +46,20 @@ static struct sieve_operand subaddress_operand;
  * Extension
  */
 
-static bool ext_subaddress_load(int ext_id);
 static bool ext_subaddress_validator_load(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension subaddress_extension = { 
 	"subaddress", 
 	&ext_my_id,
-	ext_subaddress_load,
-	NULL,
+	NULL, NULL,
 	ext_subaddress_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS, 
 	SIEVE_EXT_DEFINE_OPERAND(subaddress_operand)
 };
 
-static bool ext_subaddress_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_subaddress_validator_load(struct sieve_validator *validator)
 {
 	sieve_address_part_register(validator, &user_address_part); 
diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c
index db2ba415b..1fedc3667 100644
--- a/src/lib-sieve/plugins/vacation/ext-vacation.c
+++ b/src/lib-sieve/plugins/vacation/ext-vacation.c
@@ -29,29 +29,20 @@
  * Extension
  */
 
-static bool ext_vacation_load(int ext_id);
 static bool ext_vacation_validator_load(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension vacation_extension = { 
 	"vacation",
 	&ext_my_id,
-	ext_vacation_load,
-	NULL,
+	NULL, NULL,
 	ext_vacation_validator_load, 
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_OPERATION(vacation_operation),
 	SIEVE_EXT_DEFINE_NO_OPERANDS
 };
 
-static bool ext_vacation_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_vacation_validator_load(struct sieve_validator *validator)
 {
 	/* Register new command */
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index 1826fbfa4..bab1ce9b5 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -537,7 +537,7 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage
 	if ( ext == NULL )
 		return ctx->local_storage;
 
-	ext_id = *ext->id;
+	ext_id = SIEVE_EXT_ID(ext);
 	if ( ext_id >= (int) array_count(&ctx->ext_storages) ) {
 		storage = NULL;
 	} else {
@@ -560,7 +560,7 @@ void sieve_ext_variables_set_storage
 	if ( ctx == NULL || ext == NULL || storage == NULL )
 		return;
 		
-	array_idx_set(&ctx->ext_storages, (unsigned int) *ext->id, &storage);
+	array_idx_set(&ctx->ext_storages, (unsigned int) SIEVE_EXT_ID(ext), &storage);
 }
 
 
diff --git a/src/lib-sieve/plugins/variables/ext-variables-dump.c b/src/lib-sieve/plugins/variables/ext-variables-dump.c
index aa8d9256d..01ba971e5 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-dump.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-dump.c
@@ -118,7 +118,7 @@ void sieve_ext_variables_dump_set_scope
 {
 	struct ext_variables_dump_context *dctx = ext_variables_dump_get_context(denv);
 
-	array_idx_set(&dctx->ext_scopes, (unsigned int) *ext->id, &scope);	
+	array_idx_set(&dctx->ext_scopes, (unsigned int) SIEVE_EXT_ID(ext), &scope);	
 }
 
 /*
@@ -137,7 +137,7 @@ const char *ext_variables_dump_get_identifier
 		scope = dctx->main_scope;
 	else {
 		struct sieve_variable_scope *const *ext_scope;
-		int ext_id = *ext->id;
+		int ext_id = SIEVE_EXT_ID(ext);
 
 		if  ( ext_id < 0 || ext_id >= (int) array_count(&dctx->ext_scopes) )
 			return NULL;
diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c
index 5b9dc179e..67de74886 100644
--- a/src/lib-sieve/plugins/variables/ext-variables.c
+++ b/src/lib-sieve/plugins/variables/ext-variables.c
@@ -58,16 +58,14 @@ const struct sieve_operand *ext_variables_operands[] = {
  * Extension 
  */
 
-static bool ext_variables_load(int ext_id);
 static bool ext_variables_validator_load(struct sieve_validator *validator);
 
-static int ext_my_id;
+static int ext_my_id = -1;
 	
 const struct sieve_extension variables_extension = { 
 	"variables", 
 	&ext_my_id,
-	ext_variables_load,
-	NULL,
+	NULL, NULL,
 	ext_variables_validator_load, 
 	ext_variables_generator_load,
 	ext_variables_interpreter_load,
@@ -77,12 +75,6 @@ const struct sieve_extension variables_extension = {
 	SIEVE_EXT_DEFINE_OPERANDS(ext_variables_operands)
 };
 
-static bool ext_variables_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 static bool ext_variables_validator_load
 	(struct sieve_validator *validator)
 {
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index 9660f23bf..98bff09fb 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -42,14 +42,12 @@ const unsigned int sieve_core_address_parts_count =
 
 static int ext_my_id = -1;
 
-static bool addrp_extension_load(int ext_id);
 static bool addrp_validator_load(struct sieve_validator *validator);
 
 const struct sieve_extension address_part_extension = {
 	"@address-parts",
 	&ext_my_id,
-	addrp_extension_load,
-	NULL,
+	NULL, NULL,
 	addrp_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
@@ -58,12 +56,6 @@ const struct sieve_extension address_part_extension = {
 
 static const struct sieve_extension *ext_this = &address_part_extension;
 	
-static bool addrp_extension_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 /* 
  * Validator context:
  *   name-based address-part registry. 
diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c
index 7a0782a7d..1f5f4c350 100644
--- a/src/lib-sieve/sieve-ast.c
+++ b/src/lib-sieve/sieve-ast.c
@@ -125,7 +125,7 @@ struct sieve_script *sieve_ast_script(struct sieve_ast *ast)
 void sieve_ast_extension_link
 (struct sieve_ast *ast, const struct sieve_extension *ext)
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	unsigned int i, ext_count;
 	const struct sieve_extension *const *extensions;
 	
@@ -152,7 +152,7 @@ void sieve_ast_extension_register
 (struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, 
 	void *context)
 {
-	int ext_id = *ast_ext->ext->id;
+	int ext_id = SIEVE_EXT_ID(ast_ext->ext);
 	struct sieve_ast_extension_reg reg;
 
 	if ( ext_id < 0 ) return;
@@ -166,7 +166,7 @@ void sieve_ast_extension_register
 void *sieve_ast_extension_get_context
 (struct sieve_ast *ast, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	const struct sieve_ast_extension_reg *reg;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&ast->extensions) )
diff --git a/src/lib-sieve/sieve-binary-dumper.c b/src/lib-sieve/sieve-binary-dumper.c
index 43caa79bc..911e319b1 100644
--- a/src/lib-sieve/sieve-binary-dumper.c
+++ b/src/lib-sieve/sieve-binary-dumper.c
@@ -106,7 +106,7 @@ bool sieve_binary_dumper_run
 		for ( i = 0; i < count; i++ ) {
 			const struct sieve_extension *ext = sieve_binary_extension_get_by_index
 				(sbin, i);
-			sieve_binary_dumpf(denv, "%3d: %s (%d)\n", i, ext->name, *ext->id);
+			sieve_binary_dumpf(denv, "%3d: %s (%d)\n", i, ext->name, SIEVE_EXT_ID(ext));
 		}
 	}
 
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index ce22a8aa7..f8523aadc 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -1232,7 +1232,7 @@ static inline struct sieve_binary_extension_reg *
 	sieve_binary_extension_create_reg
 (struct sieve_binary *sbin, const struct sieve_extension *ext)
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	int index = array_count(&sbin->extensions);
 	struct sieve_binary_extension_reg *ereg;
 
@@ -1249,7 +1249,7 @@ static inline struct sieve_binary_extension_reg *
 static inline struct sieve_binary_extension_reg *sieve_binary_extension_get_reg 
 (struct sieve_binary *sbin, const struct sieve_extension *ext, bool create) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	struct sieve_binary_extension_reg *reg = NULL;
 
 	if ( ext_id >= 0 && ext_id < (int) array_count(&sbin->extension_index) ) {
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index 3a478705e..f29ba55de 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -83,7 +83,7 @@ void sieve_dump_extension_register
 	const struct sieve_code_dumper_extension *dump_ext, void *context)
 {
 	struct sieve_code_dumper_extension_reg reg = { dump_ext, context };
-	int ext_id = *dump_ext->ext->id;
+	int ext_id = SIEVE_EXT_ID(dump_ext->ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -95,7 +95,7 @@ void sieve_dump_extension_set_context
 	void *context)
 {
 	struct sieve_code_dumper_extension_reg reg = { NULL, context };
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -105,7 +105,7 @@ void sieve_dump_extension_set_context
 void *sieve_dump_extension_get_context
 (struct sieve_code_dumper *dumper, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	const struct sieve_code_dumper_extension_reg *reg;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&dumper->extensions) )
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index b3f383073..eabe577fb 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -44,14 +44,12 @@ static void sieve_opr_comparator_emit
 
 static int ext_my_id = -1;
 
-static bool cmp_extension_load(int ext_id);
 static bool cmp_validator_load(struct sieve_validator *validator);
 
 const struct sieve_extension comparator_extension = {
 	"@comparators",
 	&ext_my_id,
-	cmp_extension_load,
-	NULL,
+	NULL, NULL,
 	cmp_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
@@ -60,12 +58,6 @@ const struct sieve_extension comparator_extension = {
 
 static const struct sieve_extension *ext_this = &comparator_extension;
 	
-static bool cmp_extension_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 /* 
  * Validator context:
  *   name-based comparator registry. 
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index dc2bbc824..dd8a7f090 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -148,11 +148,10 @@ void sieve_extensions_deinit(void)
 /* 
  * Extension registry
  */
-
+ 
 struct sieve_extension_registration {
 	const struct sieve_extension *extension;
 	int id;
-	bool disabled;
 };
 
 static ARRAY_DEFINE(extensions, struct sieve_extension_registration); 
@@ -174,13 +173,20 @@ int sieve_extension_register(const struct sieve_extension *extension)
 	
 	ereg->extension = extension;
 	ereg->id = ext_id;
-	ereg->disabled = FALSE;
 	
 	hash_table_insert(extension_index, (void *) extension->name, (void *) ereg);
-
-	if ( extension->load != NULL && !extension->load(ext_id) ) {
-		sieve_sys_error("failed to load '%s' extension support.", extension->name);
-		return -1;
+	
+	/* Assign ID */
+	
+	if ( extension->_id != NULL ) {
+		i_assert( *(extension->_id) == -1 ); 
+		*(extension->_id) = ext_id;
+
+		if ( extension->load != NULL && !extension->load() ) {
+			sieve_sys_error("failed to load '%s' extension support.", 
+				extension->name);
+			return -1;
+		}
 	}
 
 	return ext_id;
@@ -198,7 +204,7 @@ const struct sieve_extension *sieve_extension_get_by_id(unsigned int ext_id)
 	if ( ext_id < array_count(&extensions) ) {
 		ereg = array_idx(&extensions, ext_id);
 
-		if ( !ereg->disabled ) 
+		if ( SIEVE_EXT_ENABLED(ereg->extension) )
 			return ereg->extension;
 	}
 	
@@ -215,7 +221,7 @@ const struct sieve_extension *sieve_extension_get_by_name(const char *name)
 	ereg = (struct sieve_extension_registration *) 
 		hash_table_lookup(extension_index, name);
 
-	if ( ereg == NULL || ereg->disabled )
+	if ( ereg == NULL || !SIEVE_EXT_ENABLED(ereg->extension) )
 		return NULL;
 		
 	return ereg->extension;
@@ -224,8 +230,9 @@ const struct sieve_extension *sieve_extension_get_by_name(const char *name)
 static inline bool _list_extension
 	(const struct sieve_extension_registration *ereg)
 {
-	return ( !ereg->disabled && ereg->extension->id != NULL && 
-		*(ereg->extension->name) != '@' );
+	return 
+		( SIEVE_EXT_ENABLED(ereg->extension) && 
+			*(ereg->extension->name) != '@' );
 }
 
 const char *sieve_extensions_get_string(void)
@@ -275,7 +282,7 @@ void sieve_extensions_set_string(const char *ext_string)
 		eregs = array_get_modifiable(&extensions, &ext_count);
 		
 		for ( i = 0; i < ext_count; i++ ) {
-			eregs[i].disabled = FALSE;
+			*(eregs[i].extension->_id) = eregs[i].id;
 		}
 
 		return;	
@@ -329,7 +336,11 @@ void sieve_extensions_set_string(const char *ext_string)
 			}		
 		}
 
-		eregs[i].disabled = disabled;
+		if ( disabled ) {
+			*(eregs[i].extension->_id) = -1;
+		} else {
+			*(eregs[i].extension->_id) = eregs[i].id;
+		}
 	}
 }
 
@@ -385,7 +396,8 @@ const char *sieve_extension_capabilities_get_string
 		(const struct sieve_extension_capabilities *) 
 			hash_table_lookup(capabilities_index, cap_name);
 
-	if ( cap == NULL || cap->get_string == NULL )
+	if ( cap == NULL || cap->get_string == NULL || 
+		!SIEVE_EXT_ENABLED(cap->extension) )
 		return NULL;
 		
 	return cap->get_string();
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index 0fc4d8157..fe0e2316a 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -22,9 +22,10 @@ struct sieve_extension_objects {
 
 struct sieve_extension {
 	const char *name;
-	const int *id;
-	
-	bool (*load)(int ext_id);
+
+	int *const _id;
+		
+	bool (*load)(void);
 	void (*unload)(void);
 
 	bool (*validator_load)
@@ -45,6 +46,9 @@ struct sieve_extension {
 	struct sieve_extension_objects operands;
 };
 
+#define SIEVE_EXT_ID(EXT) (*((EXT)->_id))
+#define SIEVE_EXT_ENABLED(EXT) (((EXT)->_id != NULL) && (*((EXT)->_id) >= 0))
+
 #define SIEVE_EXT_DEFINE_NO_OBJECTS \
 	{ NULL, 0 }
 #define SIEVE_EXT_DEFINE_OBJECT(OBJ) \
@@ -100,6 +104,8 @@ void sieve_extensions_set_string(const char *ext_string);
 struct sieve_extension_capabilities {
 	const char *name;
 
+	const struct sieve_extension *extension;
+
 	const char *(*get_string)(void);	
 };
 
diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c
index 1db9d9b1d..119b11787 100644
--- a/src/lib-sieve/sieve-generator.c
+++ b/src/lib-sieve/sieve-generator.c
@@ -186,13 +186,13 @@ void sieve_generator_critical
 void sieve_generator_extension_set_context
 (struct sieve_generator *gentr, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&gentr->ext_contexts, (unsigned int) *ext->id, &context);	
+	array_idx_set(&gentr->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context);	
 }
 
 const void *sieve_generator_extension_get_context
 (struct sieve_generator *gentr, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&gentr->ext_contexts) )
diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c
index cb5ad14e4..69b1e845e 100644
--- a/src/lib-sieve/sieve-interpreter.c
+++ b/src/lib-sieve/sieve-interpreter.c
@@ -272,7 +272,7 @@ void sieve_interpreter_extension_register
 	const struct sieve_interpreter_extension *int_ext, void *context)
 {
 	struct sieve_interpreter_extension_reg reg = { int_ext, context };
-	int ext_id = *int_ext->ext->id;
+	int ext_id = SIEVE_EXT_ID(int_ext->ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -284,7 +284,7 @@ void sieve_interpreter_extension_set_context
 	void *context)
 {
 	struct sieve_interpreter_extension_reg reg = { NULL, context };
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -294,7 +294,7 @@ void sieve_interpreter_extension_set_context
 void *sieve_interpreter_extension_get_context
 (struct sieve_interpreter *interp, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	const struct sieve_interpreter_extension_reg *reg;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&interp->extensions) )
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index cc253c6a6..757e4937d 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -50,16 +50,14 @@ const unsigned int sieve_core_match_types_count =
  * Match-type 'extension' 
  */
 
-static int ext_my_id = -1;
-
-static bool mtch_extension_load(int ext_id);
 static bool mtch_validator_load(struct sieve_validator *validator);
 
+static int ext_my_id = -1;
+
 const struct sieve_extension match_type_extension = {
 	"@match-types",
 	&ext_my_id,
-	mtch_extension_load,
-	NULL,
+	NULL, NULL,
 	mtch_validator_load,
 	NULL, NULL, NULL, NULL, NULL,
 	SIEVE_EXT_DEFINE_NO_OPERATIONS,
@@ -68,12 +66,6 @@ const struct sieve_extension match_type_extension = {
 
 static const struct sieve_extension *ext_this = &match_type_extension;
 	
-static bool mtch_extension_load(int ext_id) 
-{
-	ext_my_id = ext_id;
-	return TRUE;
-}
-
 /* 
  * Validator context:
  *   name-based match-type registry. 
diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c
index 908613d74..fab43b25c 100644
--- a/src/lib-sieve/sieve-message.c
+++ b/src/lib-sieve/sieve-message.c
@@ -78,13 +78,13 @@ void sieve_message_context_extension_set
 (struct sieve_message_context *msgctx, const struct sieve_extension *ext, 
 	void *context)
 {
-	array_idx_set(&msgctx->ext_contexts, (unsigned int) *ext->id, &context);	
+	array_idx_set(&msgctx->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context);	
 }
 
 const void *sieve_message_context_extension_get
 (struct sieve_message_context *msgctx, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) )
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index f79a1f16b..5c2c945d4 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -142,13 +142,13 @@ struct sieve_error_handler *sieve_result_get_error_handler(struct sieve_result *
 void sieve_result_extension_set_context
 (struct sieve_result *result, const struct sieve_extension *ext, void *context)
 {
-	array_idx_set(&result->ext_contexts, (unsigned int) *ext->id, &context);	
+	array_idx_set(&result->ext_contexts, (unsigned int) SIEVE_EXT_ID(ext), &context);	
 }
 
 const void *sieve_result_extension_get_context
 (struct sieve_result *result, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	void * const *ctx;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&result->ext_contexts) )
diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c
index 71b01437b..3b829138b 100644
--- a/src/lib-sieve/sieve-validator.c
+++ b/src/lib-sieve/sieve-validator.c
@@ -543,7 +543,7 @@ void sieve_validator_extension_register
 	const struct sieve_validator_extension *val_ext, void *context)
 {
 	struct sieve_validator_extension_reg reg = { val_ext, context };
-	int ext_id = *val_ext->ext->id;
+	int ext_id = SIEVE_EXT_ID(val_ext->ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -555,7 +555,7 @@ void sieve_validator_extension_set_context
 	void *context)
 {
 	struct sieve_validator_extension_reg reg = { NULL, context };
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 
 	if ( ext_id < 0 ) return;
 	
@@ -565,7 +565,7 @@ void sieve_validator_extension_set_context
 void *sieve_validator_extension_get_context
 (struct sieve_validator *valdtr, const struct sieve_extension *ext) 
 {
-	int ext_id = *ext->id;
+	int ext_id = SIEVE_EXT_ID(ext);
 	const struct sieve_validator_extension_reg *reg;
 
 	if  ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions) )
diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c
index 9e6452a30..47c20f037 100644
--- a/src/testsuite/ext-testsuite.c
+++ b/src/testsuite/ext-testsuite.c
@@ -74,20 +74,18 @@ const struct sieve_operand *testsuite_operands[] =
 
 /* Forward declarations */
 
-static bool ext_testsuite_load(int ext_id);
 static bool ext_testsuite_validator_load(struct sieve_validator *valdtr);
 static bool ext_testsuite_generator_load(const struct sieve_codegen_env *cgenv);
 static bool ext_testsuite_binary_load(struct sieve_binary *sbin);
 
 /* Extension object */
 
-static int ext_my_id;
+static int ext_my_id = -1;
 
 const struct sieve_extension testsuite_extension = { 
 	"vnd.dovecot.testsuite", 
 	&ext_my_id,
-	ext_testsuite_load,
-	NULL,
+	NULL, NULL,
 	ext_testsuite_validator_load,
 	ext_testsuite_generator_load,
 	NULL,
@@ -99,13 +97,6 @@ const struct sieve_extension testsuite_extension = {
 
 /* Extension implementation */
 
-static bool ext_testsuite_load(int ext_id)
-{
-	ext_my_id = ext_id;
-
-	return TRUE;
-}
-
 static bool ext_testsuite_validator_load(struct sieve_validator *valdtr)
 {
 	sieve_validator_register_command(valdtr, &cmd_test);
-- 
GitLab