REORG: sample: move code to release a sample expression in sample.c

This code has been moved from haproxy.c to sample.c and the function
release_sample_expr can now be called from anywhere to release a sample
expression. This function will be used by the stream processing offload engine
(SPOE).
diff --git a/src/haproxy.c b/src/haproxy.c
index b899c76..c40813b 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1342,33 +1342,6 @@
 	}
 }
 
-static void deinit_sample_arg(struct arg *p)
-{
-	struct arg *p_back = p;
-
-	if (!p)
-		return;
-
-	while (p->type != ARGT_STOP) {
-		if (p->type == ARGT_STR || p->unresolved) {
-			free(p->data.str.str);
-			p->data.str.str = NULL;
-			p->unresolved = 0;
-		}
-		else if (p->type == ARGT_REG) {
-			if (p->data.reg) {
-				regex_free(p->data.reg);
-				free(p->data.reg);
-				p->data.reg = NULL;
-			}
-		}
-		p++;
-	}
-
-	if (p_back != empty_arg_list)
-		free(p_back);
-}
-
 static void deinit_stick_rules(struct list *rules)
 {
 	struct sticking_rule *rule, *ruleb;
@@ -1376,13 +1349,7 @@
 	list_for_each_entry_safe(rule, ruleb, rules, list) {
 		LIST_DEL(&rule->list);
 		deinit_acl_cond(rule->cond);
-		if (rule->expr) {
-			struct sample_conv_expr *conv_expr, *conv_exprb;
-			list_for_each_entry_safe(conv_expr, conv_exprb, &rule->expr->conv_exprs, list)
-				deinit_sample_arg(conv_expr->arg_p);
-			deinit_sample_arg(rule->expr->arg_p);
-			free(rule->expr);
-		}
+		release_sample_expr(rule->expr);
 		free(rule);
 	}
 }
diff --git a/src/sample.c b/src/sample.c
index 1438ca1..35b5913 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1382,6 +1382,46 @@
 	return smp;
 }
 
+static void release_sample_arg(struct arg *p)
+{
+	struct arg *p_back = p;
+
+	if (!p)
+		return;
+
+	while (p->type != ARGT_STOP) {
+		if (p->type == ARGT_STR || p->unresolved) {
+			free(p->data.str.str);
+			p->data.str.str = NULL;
+			p->unresolved = 0;
+		}
+		else if (p->type == ARGT_REG) {
+			if (p->data.reg) {
+				regex_free(p->data.reg);
+				free(p->data.reg);
+				p->data.reg = NULL;
+			}
+		}
+		p++;
+	}
+
+	if (p_back != empty_arg_list)
+		free(p_back);
+}
+
+void release_sample_expr(struct sample_expr *expr)
+{
+	struct sample_conv_expr *conv_expr, *conv_exprb;
+
+	if (!expr)
+		return;
+
+	list_for_each_entry_safe(conv_expr, conv_exprb, &expr->conv_exprs, list)
+		release_sample_arg(conv_expr->arg_p);
+	release_sample_arg(expr->arg_p);
+	free(expr);
+}
+
 /*****************************************************************/
 /*    Sample format convert functions                            */
 /*    These functions set the data type on return.               */