MEDIUM: acl: have a pointer to the keyword name in acl_expr

The acl_expr struct used to hold a pointer to the ACL keyword. But since
we now have all the relevant pointers, we don't need that anymore, we just
need the pointer to the keyword as a string in order to return warnings
and error messages.

So let's change this in order to remove the dependency on the acl_keyword
struct from acl_expr.

During this change, acl_cond_kw_conflicts() used to return a pointer to an
ACL keyword but had to be changed to return a const char* for the same reason.
diff --git a/include/proto/acl.h b/include/proto/acl.h
index 39cbf46..edd4648 100644
--- a/include/proto/acl.h
+++ b/include/proto/acl.h
@@ -110,7 +110,7 @@
  * null), or false if not conflict is found. The first useless keyword is
  * returned.
  */
-int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, struct acl_keyword const **kw);
+int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, char const **kw);
 
 /*
  * Find targets for userlist and groups in acl. Function returns the number
diff --git a/include/types/acl.h b/include/types/acl.h
index 9ea0cfa..42e2e9c 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -197,7 +197,7 @@
 	struct list patterns;         /* list of acl_patterns */
 	struct eb_root pattern_tree;  /* may be used for lookup in large datasets */
 	struct list list;             /* chaining */
-	struct acl_keyword *kw;       /* back-reference to the keyword */
+	const char *kw;               /* points to the ACL kw's name or fetch's name (must not free) */
 };
 
 /* The acl will be linked to from the proxy where it is declared */
diff --git a/src/acl.c b/src/acl.c
index d1c149f..5077273 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1050,7 +1050,7 @@
 		goto out_return;
 	}
 
-	expr->kw = aclkw;
+	expr->kw = aclkw->kw;
 	LIST_INIT(&expr->patterns);
 	expr->pattern_tree = EB_ROOT_UNIQUE;
 	expr->parse = aclkw->parse;
@@ -1068,7 +1068,7 @@
 			arg++;
 			end = strchr(arg, ')');
 			if (!end) {
-				memprintf(err, "missing closing ')' after arguments to ACL keyword '%s'", expr->kw->kw);
+				memprintf(err, "missing closing ')' after arguments to ACL keyword '%s'", expr->kw);
 				goto out_free_expr;
 			}
 
@@ -1081,7 +1081,7 @@
 					       err, NULL, NULL);
 			if (nbargs < 0) {
 				/* note that make_arg_list will have set <err> here */
-				memprintf(err, "in argument to '%s', %s", expr->kw->kw, *err);
+				memprintf(err, "in argument to '%s', %s", expr->kw, *err);
 				goto out_free_expr;
 			}
 
@@ -1092,7 +1092,7 @@
 				/* invalid keyword argument, error must have been
 				 * set by val_args().
 				 */
-				memprintf(err, "in argument to '%s', %s", expr->kw->kw, *err);
+				memprintf(err, "in argument to '%s', %s", expr->kw, *err);
 				goto out_free_expr;
 			}
 		}
@@ -1104,7 +1104,7 @@
 			 * the current one later.
 			 */
 			if (type != ARGT_FE && type != ARGT_BE && type != ARGT_TAB) {
-				memprintf(err, "ACL keyword '%s' expects %d arguments", expr->kw->kw, ARGM(expr->smp->arg_mask));
+				memprintf(err, "ACL keyword '%s' expects %d arguments", expr->kw, ARGM(expr->smp->arg_mask));
 				goto out_free_expr;
 			}
 
@@ -1121,14 +1121,14 @@
 		}
 		else if (ARGM(expr->smp->arg_mask)) {
 			/* there were some mandatory arguments */
-			memprintf(err, "ACL keyword '%s' expects %d arguments", expr->kw->kw, ARGM(expr->smp->arg_mask));
+			memprintf(err, "ACL keyword '%s' expects %d arguments", expr->kw, ARGM(expr->smp->arg_mask));
 			goto out_free_expr;
 		}
 	}
 	else {
 		if (arg) {
 			/* no argument expected */
-			memprintf(err, "ACL keyword '%s' takes no argument", expr->kw->kw);
+			memprintf(err, "ACL keyword '%s' takes no argument", expr->kw);
 			goto out_free_expr;
 		}
 	}
@@ -1184,7 +1184,7 @@
 				expr->match = acl_match_fcts[idx];
 			}
 			else {
-				memprintf(err, "matching method '%s' cannot be used with fetch keyword '%s'", args[1], expr->kw->kw);
+				memprintf(err, "matching method '%s' cannot be used with fetch keyword '%s'", args[1], expr->kw);
 				goto out_free_expr;
 			}
 			args++;
@@ -1791,7 +1791,7 @@
  * null), or false if not conflict is found. The first useless keyword is
  * returned.
  */
-int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, struct acl_keyword const **kw)
+int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, char const **kw)
 {
 	struct acl_term_suite *suite;
 	struct acl_term *term;
@@ -1840,7 +1840,7 @@
 
 					if (!arg->data.str.len) {
 						Alert("proxy %s: acl '%s' %s(): missing server name.\n",
-						      p->id, acl->name, expr->kw->kw);
+						      p->id, acl->name, expr->kw);
 						cfgerr++;
 						continue;
 					}
@@ -1860,7 +1860,7 @@
 						px = findproxy(pname, PR_CAP_BE);
 						if (!px) {
 							Alert("proxy %s: acl '%s' %s(): unable to find proxy '%s'.\n",
-							      p->id, acl->name, expr->kw->kw, pname);
+							      p->id, acl->name, expr->kw, pname);
 							cfgerr++;
 							continue;
 						}
@@ -1869,7 +1869,7 @@
 					srv = findserver(px, sname);
 					if (!srv) {
 						Alert("proxy %s: acl '%s' %s(): unable to find server '%s'.\n",
-						      p->id, acl->name, expr->kw->kw, sname);
+						      p->id, acl->name, expr->kw, sname);
 						cfgerr++;
 						continue;
 					}
@@ -1890,14 +1890,14 @@
 
 					if (!prx) {
 						Alert("proxy %s: acl '%s' %s(): unable to find frontend '%s'.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
 
 					if (!(prx->cap & PR_CAP_FE)) {
 						Alert("proxy %s: acl '%s' %s(): proxy '%s' has no frontend capability.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
@@ -1918,14 +1918,14 @@
 
 					if (!prx) {
 						Alert("proxy %s: acl '%s' %s(): unable to find backend '%s'.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
 
 					if (!(prx->cap & PR_CAP_BE)) {
 						Alert("proxy %s: acl '%s' %s(): proxy '%s' has no backend capability.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
@@ -1946,7 +1946,7 @@
 
 					if (!prx) {
 						Alert("proxy %s: acl '%s' %s(): unable to find table '%s'.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
@@ -1954,7 +1954,7 @@
 
 					if (!prx->table.size) {
 						Alert("proxy %s: acl '%s' %s(): no table in proxy '%s'.\n",
-						      p->id, acl->name, expr->kw->kw, pname);
+						      p->id, acl->name, expr->kw, pname);
 						cfgerr++;
 						continue;
 					}
@@ -1967,7 +1967,7 @@
 				else if (arg->type == ARGT_USR) {
 					if (!arg->data.str.len) {
 						Alert("proxy %s: acl '%s' %s(): missing userlist name.\n",
-						      p->id, acl->name, expr->kw->kw);
+						      p->id, acl->name, expr->kw);
 						cfgerr++;
 						continue;
 					}
@@ -1980,7 +1980,7 @@
 
 					if (!ul) {
 						Alert("proxy %s: acl '%s' %s(%s): unable to find userlist.\n",
-						      p->id, acl->name, expr->kw->kw, arg->data.str.str);
+						      p->id, acl->name, expr->kw, arg->data.str.str);
 						cfgerr++;
 						continue;
 					}
@@ -1998,12 +1998,12 @@
 			if (cfgerr)
 				break;
 
-			if (!strcmp(expr->kw->kw, "http_auth_group")) {
+			if (!strcmp(expr->kw, "http_auth_group")) {
 				/* note: argument resolved above thanks to ARGT_USR */
 
 				if (LIST_ISEMPTY(&expr->patterns)) {
 					Alert("proxy %s: acl %s %s(): no groups specified.\n",
-						p->id, acl->name, expr->kw->kw);
+						p->id, acl->name, expr->kw);
 					cfgerr++;
 					continue;
 				}
@@ -2018,7 +2018,7 @@
 
 					if (!pattern->val.group_mask) {
 						Alert("proxy %s: acl %s %s(): invalid group(s).\n",
-							p->id, acl->name, expr->kw->kw);
+							p->id, acl->name, expr->kw);
 						cfgerr++;
 						continue;
 					}
diff --git a/src/cfgparse.c b/src/cfgparse.c
index bd3382c..b82a2dc 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -422,7 +422,7 @@
 static int warnif_cond_conflicts(const struct acl_cond *cond, unsigned int where, const char *file, int line)
 {
 	const struct acl *acl;
-	const struct acl_keyword *kw;
+	const char *kw;
 
 	if (!cond)
 		return 0;
@@ -434,7 +434,7 @@
 			        file, line, acl->name, sample_ckp_names(where));
 		else
 			Warning("parsing [%s:%d] : anonymous acl will never match because it uses keyword '%s' which is incompatible with '%s'\n",
-			        file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw->kw, sample_ckp_names(where));
+			        file, line, LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw, sample_ckp_names(where));
 		return ERR_WARN;
 	}
 	if (!acl_cond_kw_conflicts(cond, where, &acl, &kw))
@@ -442,10 +442,10 @@
 
 	if (acl->name && *acl->name)
 		Warning("parsing [%s:%d] : acl '%s' involves keywords '%s' which is incompatible with '%s'\n",
-		        file, line, acl->name, kw->kw, sample_ckp_names(where));
+		        file, line, acl->name, kw, sample_ckp_names(where));
 	else
 		Warning("parsing [%s:%d] : anonymous acl involves keyword '%s' which is incompatible with '%s'\n",
-		        file, line, kw->kw, sample_ckp_names(where));
+		        file, line, kw, sample_ckp_names(where));
 	return ERR_WARN;
 }
 
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index e8d7d60..dc3817e 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1190,7 +1190,7 @@
 	struct tcp_rule *rule;
 	unsigned int where;
 	const struct acl *acl;
-	const struct acl_keyword *kw;
+	const char *kw;
 
 	if (!*args[1]) {
 		memprintf(err, "missing argument for '%s' in %s '%s'",
@@ -1249,7 +1249,7 @@
 				memprintf(err,
 					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
 					  args[0], args[1],
-					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw->kw,
+					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
 					  sample_ckp_names(where));
 
 			warn++;
@@ -1258,11 +1258,11 @@
 			if (acl->name && *acl->name)
 				memprintf(err,
 					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
-					  acl->name, kw->kw, sample_ckp_names(where));
+					  acl->name, kw, sample_ckp_names(where));
 			else
 				memprintf(err,
 					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
-					  kw->kw, sample_ckp_names(where));
+					  kw, sample_ckp_names(where));
 			warn++;
 		}
 
@@ -1296,7 +1296,7 @@
 	struct tcp_rule *rule;
 	unsigned int where;
 	const struct acl *acl;
-	const struct acl_keyword *kw;
+	const char *kw;
 
 	if (!*args[1]) {
 		if (curpx == defpx)
@@ -1358,7 +1358,7 @@
 				memprintf(err,
 					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
 					  args[0], args[1],
-					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw->kw,
+					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
 					  sample_ckp_names(where));
 
 			warn++;
@@ -1367,11 +1367,11 @@
 			if (acl->name && *acl->name)
 				memprintf(err,
 					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
-					  acl->name, kw->kw, sample_ckp_names(where));
+					  acl->name, kw, sample_ckp_names(where));
 			else
 				memprintf(err,
 					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
-					  kw->kw, sample_ckp_names(where));
+					  kw, sample_ckp_names(where));
 			warn++;
 		}
 
@@ -1401,7 +1401,7 @@
 				memprintf(err,
 					  "anonymous acl will never match in '%s %s' because it uses keyword '%s' which is incompatible with '%s'",
 					  args[0], args[1],
-					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw->kw,
+					  LIST_ELEM(acl->expr.n, struct acl_expr *, list)->kw,
 					  sample_ckp_names(where));
 
 			warn++;
@@ -1410,11 +1410,11 @@
 			if (acl->name && *acl->name)
 				memprintf(err,
 					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
-					  acl->name, kw->kw, sample_ckp_names(where));
+					  acl->name, kw, sample_ckp_names(where));
 			else
 				memprintf(err,
 					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
-					  kw->kw, sample_ckp_names(where));
+					  kw, sample_ckp_names(where));
 			warn++;
 		}