From aa8f3937471137854e50c98607c311ca1ef6186b Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sun, 30 Dec 2007 02:23:24 +0100
Subject: [PATCH] Added support for adding new types operands to the engine.

---
 src/lib-sieve/sieve-actions.c       |  10 +-
 src/lib-sieve/sieve-address-parts.c |  10 +-
 src/lib-sieve/sieve-code.c          | 143 ++++++++++++++++------------
 src/lib-sieve/sieve-code.h          |   7 +-
 src/lib-sieve/sieve-comparators.c   |  10 +-
 src/lib-sieve/sieve-extensions.h    |   2 +
 src/lib-sieve/sieve-match-types.c   |  11 ++-
 7 files changed, 116 insertions(+), 77 deletions(-)

diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 5fb3ee44b..12f336bcf 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -89,14 +89,18 @@ static bool seffect_binary_load(struct sieve_binary *sbin)
  
 static struct sieve_operand_class side_effect_class = 
 	{ "side-effect", NULL };
-struct sieve_operand side_effect_operand = 
-	{ "side-effect", &side_effect_class, FALSE };
+
+struct sieve_operand side_effect_operand = { 
+	"side-effect", 
+	NULL, SIEVE_OPERAND_SIDE_EFFECT,
+	&side_effect_class
+};
 
 void sieve_opr_side_effect_emit
 	(struct sieve_binary *sbin, const struct sieve_side_effect *seffect, 
 		int ext_id)
 { 
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_SIDE_EFFECT);
+	(void) sieve_operand_emit_code(sbin, &side_effect_operand, -1);
 
 	(void) sieve_extension_emit_obj
 		(sbin, &seff_default_reg, seffect, side_effects, ext_id);
diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c
index bf6f70ddd..6e1474372 100644
--- a/src/lib-sieve/sieve-address-parts.c
+++ b/src/lib-sieve/sieve-address-parts.c
@@ -198,8 +198,12 @@ static bool addrp_binary_load(struct sieve_binary *sbin)
  
 struct sieve_operand_class address_part_class = 
 	{ "address-part", NULL };
-struct sieve_operand address_part_operand = 
-	{ "address-part", &address_part_class, FALSE };
+
+struct sieve_operand address_part_operand = { 
+	"address-part", 
+	NULL, SIEVE_OPERAND_ADDRESS_PART,
+	&address_part_class
+};
 
 /* 
  * Address-part tag 
@@ -252,7 +256,7 @@ static bool tag_address_part_validate
 static void opr_address_part_emit
 (struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id)
 {
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_ADDRESS_PART);	
+	(void) sieve_operand_emit_code(sbin, &address_part_operand, -1);	
 
 	(void) sieve_extension_emit_obj
 		(sbin, &addrp_default_reg, addrp, address_parts, ext_id);
diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c
index 603a35770..f6c14515f 100644
--- a/src/lib-sieve/sieve-code.c
+++ b/src/lib-sieve/sieve-code.c
@@ -119,9 +119,68 @@ bool sieve_coded_stringlist_read_all
 }
 
 /*
- * Operand functions
+ * Operands
  */
  
+/* Core operands */
+
+const struct sieve_operand number_operand;
+const struct sieve_operand string_operand;
+const struct sieve_operand stringlist_operand;
+extern const struct sieve_operand comparator_operand;
+extern const struct sieve_operand match_type_operand;
+extern const struct sieve_operand address_part_operand;
+extern const struct sieve_operand side_effect_operand;
+
+const struct sieve_operand *sieve_operands[] = {
+	NULL, /* SIEVE_OPERAND_OPTIONAL */
+	&number_operand,
+	&string_operand,
+	&stringlist_operand,
+	&comparator_operand,
+	&match_type_operand,
+	&address_part_operand,
+	&side_effect_operand
+}; 
+
+const unsigned int sieve_operand_count =
+	N_ELEMENTS(sieve_operands);
+
+static struct sieve_extension_obj_registry oprd_default_reg =
+	SIEVE_EXT_DEFINE_OPERANDS(sieve_operands);
+
+/* Operand functions */
+
+inline sieve_size_t sieve_operand_emit_code
+	(struct sieve_binary *sbin, const struct sieve_operand *opr, int ext_id)
+{	
+	return sieve_extension_emit_obj
+		(sbin, &oprd_default_reg, opr, operands, ext_id);
+}
+
+static const struct sieve_extension_obj_registry *
+	sieve_operand_registry_get
+(struct sieve_binary *sbin, unsigned int ext_index)
+{
+	int ext_id = -1; 
+	const struct sieve_extension *ext;
+	
+	if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id)) 
+		== NULL )
+		return NULL;
+		
+	return &(ext->operands);
+}
+
+const struct sieve_operand *sieve_operand_read
+	(struct sieve_binary *sbin, sieve_size_t *address) 
+{
+	return sieve_extension_read_obj
+		(struct sieve_operand, sbin, address, &oprd_default_reg, 
+			sieve_operand_registry_get);
+}
+
+/*
 inline sieve_size_t sieve_operand_emit_code
 	(struct sieve_binary *sbin, int operand)
 {
@@ -142,20 +201,20 @@ const struct sieve_operand *sieve_operand_read
 			else
 				return NULL;
 		} else {
-/*			int ext_id = -1;
+/ *			int ext_id = -1;
 		  const struct sieve_extension *ext = 
 		  	sieve_binary_extension_get_by_index
 		  		(sbin, operand - SIEVE_OPERAND_CUSTOM, &ext_id);
 		  
 		  if ( ext != NULL )
 		  	return ext->operand;	
-		  else*/
+		  else * /
 		  	return NULL;
 		}
 	}		
 	
 	return NULL;
-}
+}*/
 
 bool sieve_operand_optional_present
 	(struct sieve_binary *sbin, sieve_size_t *address)
@@ -202,8 +261,11 @@ const struct sieve_opr_number_interface number_interface = {
 const struct sieve_operand_class number_class = 
 	{ "number", &number_interface };
 	
-const struct sieve_operand number_operand = 
-	{ "@number", &number_class, TRUE };
+const struct sieve_operand number_operand = { 
+	"@number", 
+	NULL, SIEVE_OPERAND_NUMBER,
+	&number_class 
+};
 
 /* String */
 
@@ -220,9 +282,11 @@ const struct sieve_opr_string_interface string_interface ={
 const struct sieve_operand_class string_class = 
 	{ "string", &string_interface };
 	
-const struct sieve_operand string_operand = 
-	{ "@string", &string_class, TRUE };
-	
+const struct sieve_operand string_operand = { 
+	"@string", 
+	NULL, SIEVE_OPERAND_STRING,
+	&string_class
+};	
 
 /* String List */
 
@@ -239,29 +303,11 @@ const struct sieve_opr_stringlist_interface stringlist_interface = {
 const struct sieve_operand_class stringlist_class = 
 	{ "string-list", &stringlist_interface };
 
-const struct sieve_operand stringlist_operand = 
-	{ "@string-list", &stringlist_class, TRUE };
-	
-/* Core operands */
-
-extern struct sieve_operand comparator_operand;
-extern struct sieve_operand match_type_operand;
-extern struct sieve_operand address_part_operand;
-extern struct sieve_operand side_effect_operand;
-
-const struct sieve_operand *sieve_operands[] = {
-	NULL, /* SIEVE_OPERAND_OPTIONAL */
-	&number_operand,
-	&string_operand,
-	&stringlist_operand,
-	&comparator_operand,
-	&match_type_operand,
-	&address_part_operand,
-	&side_effect_operand
-}; 
-
-const unsigned int sieve_operand_count =
-	N_ELEMENTS(sieve_operands);
+const struct sieve_operand stringlist_operand =	{ 
+	"@string-list", 
+	NULL, SIEVE_OPERAND_STRING_LIST,
+	&stringlist_class
+};
 	
 /* 
  * Operand implementations 
@@ -271,7 +317,7 @@ const unsigned int sieve_operand_count =
 
 void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number) 
 {
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_NUMBER);
+	(void) sieve_operand_emit_code(sbin, &number_operand, -1);
 	(void) sieve_binary_emit_integer(sbin, number);
 }
 
@@ -337,7 +383,7 @@ static bool opr_number_read
 
 void sieve_opr_string_emit(struct sieve_binary *sbin, string_t *str)
 {
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_STRING);
+	(void) sieve_operand_emit_code(sbin, &string_operand, -1);
 	(void) sieve_binary_emit_string(sbin, str);
 }
 
@@ -417,7 +463,7 @@ void sieve_opr_stringlist_emit_start
 	sieve_size_t *end_offset = t_new(sieve_size_t, 1);
 
 	/* Emit byte identifying the type of operand */	  
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_STRING_LIST);
+	(void) sieve_operand_emit_code(sbin, &stringlist_operand, -1);
   
 	/* Give the interpreter an easy way to skip over this string list */
 	*end_offset = sieve_binary_emit_offset(sbin, 0);
@@ -672,34 +718,7 @@ const struct sieve_operation *sieve_operation_read
 	return sieve_extension_read_obj
 		(struct sieve_operation, sbin, address, &oprt_default_reg, 
 			sieve_operation_registry_get);
-
-/*	unsigned int opcode;
-	
-	if ( sieve_binary_read_byte(sbin, address, &opcode) ) {
-		if ( opcode < SIEVE_OPERATION_CUSTOM ) {
-			if ( opcode < sieve_operations_count )
-				return sieve_operations[opcode];
-			else
-				return NULL;
-		} else {
-			struct sieve_operation *op;
-			int ext_id = -1; 
-			const struct sieve_extension *ext;
-			
-			if ( (ext=sieve_binary_extension_get_by_index
-				(sbin, opcode - SIEVE_OPERATION_CUSTOM, &ext_id)) == NULL )
-				return NULL;
-	
-			sieve_extension_read_object 
-				(ext, struct sieve_operation, opcodes, sbin, address, op)
-
-			return op;
-		}
-	}		
-	
-	return NULL;*/
 }
-
 	
 /* Code dump for core commands */
 
diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h
index 1c817c222..a05d9074c 100644
--- a/src/lib-sieve/sieve-code.h
+++ b/src/lib-sieve/sieve-code.h
@@ -38,9 +38,10 @@ struct sieve_operand_class {
 struct sieve_operand {
 	const char *name;
 	
+	struct sieve_extension *extension;
+	unsigned int code;
+	
 	const struct sieve_operand_class *class;
-
-	unsigned int positional:1;
 };
 
 struct sieve_opr_number_interface {
@@ -81,7 +82,7 @@ extern const struct sieve_operand *sieve_operands[];
 extern const unsigned int sieve_operand_count;
 
 inline sieve_size_t sieve_operand_emit_code
-	(struct sieve_binary *sbin, int operand);
+	(struct sieve_binary *sbin, const struct sieve_operand *opr, int ext_id);
 const struct sieve_operand *sieve_operand_read
 	(struct sieve_binary *sbin, sieve_size_t *address);
 
diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c
index 644247f2d..e018663d8 100644
--- a/src/lib-sieve/sieve-comparators.c
+++ b/src/lib-sieve/sieve-comparators.c
@@ -201,8 +201,12 @@ static bool cmp_binary_load(struct sieve_binary *sbin)
  
 struct sieve_operand_class comparator_class = 
 	{ "comparator", NULL };
-struct sieve_operand comparator_operand = 
-	{ "comparator", &comparator_class, FALSE };
+
+struct sieve_operand comparator_operand = { 
+	"comparator", 
+	NULL, SIEVE_OPERAND_COMPARATOR, 
+	&comparator_class
+};
 
 /* 
  * Comparator tag 
@@ -305,7 +309,7 @@ inline const struct sieve_comparator *sieve_comparator_tag_get
 static void opr_comparator_emit
 	(struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id)
 { 
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_COMPARATOR);	
+	(void) sieve_operand_emit_code(sbin, &comparator_operand, -1);	
 
 	(void) sieve_extension_emit_obj
 		(sbin, &cmp_default_reg, cmp, comparators, ext_id);
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index 1db54d10f..e952ef1b5 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -44,6 +44,8 @@ struct sieve_extension {
 #define SIEVE_EXT_DEFINE_OPERATIONS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
 
 #define SIEVE_EXT_DEFINE_NO_OPERANDS SIEVE_EXT_DEFINE_NO_OBJECTS
+#define SIEVE_EXT_DEFINE_OPERAND(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
+#define SIEVE_EXT_DEFINE_OPERANDS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
 
 /* Pre-loaded extensions */
 
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index edd79cfba..1cf22c434 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -195,8 +195,13 @@ static bool mtch_binary_load(struct sieve_binary *sbin)
  
 struct sieve_operand_class match_type_class = 
 	{ "match-type", NULL };
-struct sieve_operand match_type_operand = 
-	{ "match-type", &match_type_class, FALSE };
+
+struct sieve_operand match_type_operand = { 
+	"match-type", 
+	NULL,
+	SIEVE_OPERAND_MATCH_TYPE,
+	&match_type_class
+};
 
 /* 
  * Match-type tag 
@@ -295,7 +300,7 @@ bool sieve_match_type_validate
 static void opr_match_type_emit
 	(struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id)
 { 
-	(void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_MATCH_TYPE);	
+	(void) sieve_operand_emit_code(sbin, &match_type_operand, -1);	
 	
 	(void) sieve_extension_emit_obj
 		(sbin, &mtch_default_reg, mtch, match_types, ext_id);
-- 
GitLab