MEDIUM: pattern: get rid of arg_i in all functions making use of arguments

arg_i was almost unused, and since we migrated to use struct arg everywhere,
the rare cases where arg_i was needed could be replaced by switching to
arg->type = ARGT_STOP.
diff --git a/include/proto/pattern.h b/include/proto/pattern.h
index bb1181c..ef2c548 100644
--- a/include/proto/pattern.h
+++ b/include/proto/pattern.h
@@ -34,6 +34,6 @@
 void pattern_register_fetches(struct pattern_fetch_kw_list *psl);
 void pattern_register_convs(struct pattern_conv_kw_list *psl);
 
-int pattern_arg_ipmask(const char *arg_str, struct arg **arg_p, int *arg_i);
-int pattern_arg_str(const char *arg_str, struct arg **arg_p, int *arg_i);
+int pattern_arg_ipmask(const char *arg_str, struct arg **arg_p);
+int pattern_arg_str(const char *arg_str, struct arg **arg_p);
 #endif
diff --git a/include/types/pattern.h b/include/types/pattern.h
index e948264..1014856 100644
--- a/include/types/pattern.h
+++ b/include/types/pattern.h
@@ -63,11 +63,9 @@
 struct pattern_conv {
 	const char *kw;                           /* configuration keyword  */
 	int (*process)(const struct arg *arg_p,
-	               int arg_i,
-	               union pattern_data *data); /* process function */
+		       union pattern_data *data); /* process function */
 	int (*parse_args)(const char *arg_str,
-			  struct arg **arg_p,
-			  int *arg_i);            /* argument parser. Can be NULL. */
+			  struct arg **arg_p);    /* argument parser. May be NULL. */
 	unsigned int in_type;                     /* input needed pattern type */
 	unsigned int out_type;                    /* output pattern type */
 };
@@ -77,7 +75,6 @@
 	struct list list;                         /* member of a pattern expression */
 	struct pattern_conv *conv;                /* pattern conversion */
 	struct arg *arg_p;                        /* pointer on args */
-	int arg_i;                                /* number of args */
 };
 
 /* pattern fetch */
@@ -87,11 +84,9 @@
 	               struct session *l4,
 	               void *l7,
 	               int dir, const struct arg *arg_p,
-	               int arg_i,
 	               union pattern_data *data); /* fetch processing function */
 	int (*parse_args)(const char *arg_str,
-			  struct arg **arg_p,
-			  int *arg_i);            /* argument parser. Can be NULL. */
+			  struct arg **arg_p);    /* argument parser. Can be NULL. */
 	unsigned long out_type;                   /* output pattern type */
 	int dir;                                  /* usable directions */
 };
@@ -101,7 +96,6 @@
 	struct list list;                         /* member of list of pattern, currently not used */
 	struct pattern_fetch *fetch;              /* pattern fetch */
 	struct arg *arg_p;                        /* pointer on args */
-	int arg_i;                                /* number of args */
 	struct list conv_exprs;                   /* list of conversion expression to apply */
 };
 
diff --git a/src/haproxy.c b/src/haproxy.c
index f606ee2..decfede 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -758,21 +758,24 @@
 	}
 }
 
-static void deinit_pattern_arg(struct arg *p, int i)
+static void deinit_pattern_arg(struct arg *p)
 {
+	struct arg *p_back = p;
+
 	if (!p)
 		return;
 
-	while (i--) {
-		if (p[i].type == ARGT_FE || p[i].type == ARGT_BE ||
-		    p[i].type == ARGT_TAB || p[i].type == ARGT_SRV ||
-		    p[i].type == ARGT_USR || p[i].type == ARGT_STR) {
-			free(p[i].data.str.str);
-			p[i].data.str.str = NULL;
+	while (p->type != ARGT_STOP) {
+		if (p->type == ARGT_FE || p->type == ARGT_BE ||
+		    p->type == ARGT_TAB || p->type == ARGT_SRV ||
+		    p->type == ARGT_USR || p->type == ARGT_STR) {
+			free(p->data.str.str);
+			p->data.str.str = NULL;
 		}
+		p++;
 	}
 
-	free(p);
+	free(p_back);
 }
 
 static void deinit_stick_rules(struct list *rules)
@@ -785,8 +788,8 @@
 		if (rule->expr) {
 			struct pattern_conv_expr *conv_expr, *conv_exprb;
 			list_for_each_entry_safe(conv_expr, conv_exprb, &rule->expr->conv_exprs, list)
-				deinit_pattern_arg(conv_expr->arg_p, conv_expr->arg_i);
-			deinit_pattern_arg(rule->expr->arg_p, rule->expr->arg_i);
+				deinit_pattern_arg(conv_expr->arg_p);
+			deinit_pattern_arg(rule->expr->arg_p);
 			free(rule->expr);
 		}
 		free(rule);
diff --git a/src/pattern.c b/src/pattern.c
index cae85a8..72c0b34 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -328,7 +328,7 @@
 		p = my_strndup(endw + 1, i);
 		if (!p)
 			goto out_error;
-		i = fetch->parse_args(p, &expr->arg_p, &expr->arg_i);
+		i = fetch->parse_args(p, &expr->arg_p);
 		free(p);
 		if (!i) {
 			p = my_strndup(str[*idx], endw - str[*idx]);
@@ -413,7 +413,7 @@
 			p = my_strndup(endw + 1, i);
 			if (!p)
 				goto out_error;
-			i = conv->parse_args(p, &conv_expr->arg_p, &conv_expr->arg_i);
+			i = conv->parse_args(p, &conv_expr->arg_p);
 			free(p);
 			if (!i) {
 				p = my_strndup(str[*idx], endw - str[*idx]);
@@ -458,7 +458,7 @@
 	if (p == NULL)
 		p = &temp_pattern;
 
-	if (!expr->fetch->process(px, l4, l7, dir, expr->arg_p, expr->arg_i, &p->data))
+	if (!expr->fetch->process(px, l4, l7, dir, expr->arg_p, &p->data))
 		return NULL;
 
 	p->type = expr->fetch->out_type;
@@ -468,7 +468,7 @@
 			return NULL;
 
 		p->type = conv_expr->conv->in_type;
-		if (!conv_expr->conv->process(conv_expr->arg_p, conv_expr->arg_i, &p->data))
+		if (!conv_expr->conv->process(conv_expr->arg_p, &p->data))
 			return NULL;
 
 		p->type = conv_expr->conv->out_type;
@@ -479,11 +479,11 @@
 /* Converts an argument string mask to a arg type IP.
  * Returns non-zero in case of success, 0 on error.
  */
-int pattern_arg_ipmask(const char *arg_str, struct arg **arg_p, int *arg_i)
+int pattern_arg_ipmask(const char *arg_str, struct arg **arg_p)
 {
-	*arg_i = 1;
-	*arg_p = calloc(1, *arg_i*sizeof(struct arg));
+	*arg_p = calloc(2, sizeof(struct arg));
 	(*arg_p)->type = ARGT_IPV4;
+	arg_p[1]->type = ARGT_STOP;
 
 	if (!str2mask(arg_str, &(*arg_p)->data.ipv4))
 		return 0;
@@ -495,14 +495,13 @@
 /* Converts an argument string to a arg type STRING.
  * Returns non-zero in case of success, 0 on error.
  */
-int pattern_arg_str(const char *arg_str, struct arg **arg_p, int *arg_i)
+int pattern_arg_str(const char *arg_str, struct arg **arg_p)
 {
-	*arg_i = 1;
-	*arg_p = calloc(1, *arg_i*sizeof(struct arg));
+	*arg_p = calloc(2, sizeof(struct arg));
 	(*arg_p)->type = ARGT_STR;
 	(*arg_p)->data.str.str = strdup(arg_str);
 	(*arg_p)->data.str.len = strlen(arg_str);
-
+	arg_p[1]->type = ARGT_STOP;
 
 	return 1;
 }
@@ -512,7 +511,7 @@
 /*    Pattern format convert functions                           */
 /*****************************************************************/
 
-static int pattern_conv_str2lower(const struct arg *arg_p, int arg_i, union pattern_data *data)
+static int pattern_conv_str2lower(const struct arg *arg_p, union pattern_data *data)
 {
 	int i;
 
@@ -526,7 +525,7 @@
 	return 1;
 }
 
-static int pattern_conv_str2upper(const struct arg *arg_p, int arg_i, union pattern_data *data)
+static int pattern_conv_str2upper(const struct arg *arg_p, union pattern_data *data)
 {
 	int i;
 
@@ -540,8 +539,8 @@
 	return 1;
 }
 
-/* takes the netmask in arg_i */
-static int pattern_conv_ipmask(const struct arg *arg_p, int arg_i, union pattern_data *data)
+/* takes the netmask in arg_p */
+static int pattern_conv_ipmask(const struct arg *arg_p, union pattern_data *data)
 {
 	data->ip.s_addr &= arg_p->data.ipv4.s_addr;
 	return 1;
diff --git a/src/proto_http.c b/src/proto_http.c
index 6dcb5ff..da7fa33 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -8344,7 +8344,7 @@
 /* Returns the last occurrence of specified header. */
 static int
 pattern_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
-		  const struct arg *arg_p, int arg_i, union pattern_data *data)
+		  const struct arg *arg_p, union pattern_data *data)
 {
 	struct http_txn *txn = l7;
 
@@ -8439,7 +8439,7 @@
 
 static int
 pattern_fetch_url_param(struct proxy *px, struct session *l4, void *l7, int dir,
-                     const struct arg *arg_p, int arg_i, union pattern_data *data)
+                     const struct arg *arg_p, union pattern_data *data)
 {
 	struct http_txn *txn = l7;
 	struct http_msg *msg = &txn->req;
@@ -8492,7 +8492,7 @@
 
 static int
 pattern_fetch_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
-                     const struct arg *arg_p, int arg_i, union pattern_data *data)
+                     const struct arg *arg_p, union pattern_data *data)
 {
 	struct http_txn *txn = l7;
 	struct http_msg *msg = &txn->req;
@@ -8514,7 +8514,7 @@
 
 static int
 pattern_fetch_set_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
-			 const struct arg *arg_p, int arg_i, union pattern_data *data)
+			 const struct arg *arg_p, union pattern_data *data)
 {
 	struct http_txn *txn = l7;
 	struct http_msg *msg = &txn->rsp;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 59d0d55..a0e315d 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1275,7 +1275,7 @@
 /* extract the connection's source ipv4 address */
 static int
 pattern_fetch_src(struct proxy *px, struct session *l4, void *l7, int dir,
-                  const struct arg *arg_p, int arg_i, union pattern_data *data)
+                  const struct arg *arg_p, union pattern_data *data)
 {
 	if (l4->si[0].addr.from.ss_family != AF_INET )
 		return 0;
@@ -1287,7 +1287,7 @@
 /* extract the connection's source ipv6 address */
 static int
 pattern_fetch_src6(struct proxy *px, struct session *l4, void *l7, int dir,
-                  const struct arg *arg_p, int arg_i, union pattern_data *data)
+                  const struct arg *arg_p, union pattern_data *data)
 {
 	if (l4->si[0].addr.from.ss_family != AF_INET6)
 		return 0;
@@ -1337,7 +1337,7 @@
 /* extract the connection's destination ipv4 address */
 static int
 pattern_fetch_dst(struct proxy *px, struct session *l4, void *l7, int dir,
-                  const struct arg *arg_p, int arg_i, union pattern_data *data)
+                  const struct arg *arg_p, union pattern_data *data)
 {
 	stream_sock_get_to_addr(&l4->si[0]);
 
@@ -1351,7 +1351,7 @@
 /* extract the connection's destination ipv6 address */
 static int
 pattern_fetch_dst6(struct proxy *px, struct session *l4, void *l7, int dir,
-                  const struct arg *arg_p, int arg_i, union pattern_data *data)
+                  const struct arg *arg_p, union pattern_data *data)
 {
 	stream_sock_get_to_addr(&l4->si[0]);
 
@@ -1378,7 +1378,7 @@
 
 static int
 pattern_fetch_dport(struct proxy *px, struct session *l4, void *l7, int dir,
-                    const struct arg *arg, int i, union pattern_data *data)
+                    const struct arg *arg, union pattern_data *data)
 {
 	stream_sock_get_to_addr(&l4->si[0]);
 
@@ -1389,7 +1389,7 @@
 }
 
 static int
-pattern_arg_fetch_payloadlv(const char *arg, struct arg **arg_p, int *arg_i)
+pattern_arg_fetch_payloadlv(const char *arg, struct arg **arg_p)
 {
 	int member = 0;
 	int len_offset = 0;
@@ -1445,21 +1445,21 @@
 		buf_offset = len_offset + len_size - buf_offset;
 	}
 
-	*arg_i = 3;
-	*arg_p = calloc(1, *arg_i*sizeof(struct arg));
+	*arg_p = calloc(4, sizeof(struct arg));
 	(*arg_p)[0].type = ARGT_UINT;
 	(*arg_p)[0].data.uint = len_offset;
 	(*arg_p)[1].type = ARGT_UINT;
 	(*arg_p)[1].data.uint = len_size;
 	(*arg_p)[2].type = ARGT_UINT;
 	(*arg_p)[2].data.uint = buf_offset;
+	(*arg_p)[3].type = ARGT_STOP;
 
 	return 1;
 }
 
 static int
 pattern_fetch_payloadlv(struct proxy *px, struct session *l4, void *l7, int dir,
-                        const struct arg *arg_p, int arg_i, union pattern_data *data)
+                        const struct arg *arg_p, union pattern_data *data)
 {
 	int len_offset = arg_p[0].data.uint;
 	int len_size = arg_p[1].data.uint;
@@ -1500,7 +1500,7 @@
 }
 
 static int
-pattern_arg_fetch_payload (const char *arg, struct arg **arg_p, int *arg_i)
+pattern_arg_fetch_payload (const char *arg, struct arg **arg_p)
 {
 	int member = 0;
 	int buf_offset = 0;
@@ -1527,19 +1527,19 @@
 	if (!buf_size)
 		return 0;
 
-	*arg_i = 2;
-	*arg_p = calloc(1, *arg_i*sizeof(struct arg));
+	*arg_p = calloc(3, sizeof(struct arg));
 	(*arg_p)[0].type = ARGT_UINT;
 	(*arg_p)[0].data.uint = buf_offset;
 	(*arg_p)[1].type = ARGT_UINT;
 	(*arg_p)[1].data.uint = buf_size;
+	(*arg_p)[2].type = ARGT_STOP;
 
 	return 1;
 }
 
 static int
 pattern_fetch_payload(struct proxy *px, struct session *l4, void *l7, int dir,
-                      const struct arg *arg_p, int arg_i, union pattern_data *data)
+                      const struct arg *arg_p, union pattern_data *data)
 {
 	int buf_offset = arg_p[0].data.uint;
 	int buf_size = arg_p[1].data.uint;
@@ -1564,7 +1564,7 @@
 
 static int
 pattern_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
-                         const struct arg *arg_p, int arg_i, union pattern_data *data)
+                         const struct arg *arg_p, union pattern_data *data)
 {
 	int ret;
 	struct acl_expr  expr;