MAJOR: acl: convert all ACL requires to SMP use+val instead of ->requires

The ACLs now use the fetch's ->use and ->val to decide upon compatibility
between the place where they are used and where the information are fetched.
The code is capable of reporting warnings about very fine incompatibilities
between certain fetches and an exact usage location, so it is expected that
some new warnings will be emitted on some existing configurations.

Two degrees of detection are provided :
  - detecting ACLs that never match
  - detecting keywords that are ignored

All tests show that this seems to work well, though bugs are still possible.
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 3cf0d81..dfae8e3 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1189,6 +1189,8 @@
 	int arg;
 	struct tcp_rule *rule;
 	unsigned int where;
+	const struct acl *acl;
+	const struct acl_keyword *kw;
 
 	if (!*args[1]) {
 		memprintf(err, "missing argument for '%s' in %s '%s'",
@@ -1237,18 +1239,32 @@
 		if (tcp_parse_response_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0)
 			goto error;
 
-		if (rule->cond && (rule->cond->requires & ACL_USE_L6REQ_VOLATILE)) {
-			struct acl *acl;
-			const char *name;
-
-			acl = cond_find_require(rule->cond, ACL_USE_L6REQ_VOLATILE);
-			name = acl ? acl->name : "(unknown)";
+		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
+		if (acl) {
+			if (acl->name && *acl->name)
+				memprintf(err,
+					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
+					  acl->name, args[0], args[1], sample_ckp_names(where));
+			else
+				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,
+					  sample_ckp_names(where));
 
-			memprintf(err,
-			          "acl '%s' involves some request-only criteria which will be ignored in '%s %s'",
-			          name, args[0], args[1]);
 			warn++;
 		}
+		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
+			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));
+			else
+				memprintf(err,
+					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
+					  kw->kw, sample_ckp_names(where));
+			warn++;
+		}
 
 		LIST_ADDQ(&curpx->tcp_rep.inspect_rules, &rule->list);
 	}
@@ -1279,6 +1295,8 @@
 	int arg;
 	struct tcp_rule *rule;
 	unsigned int where;
+	const struct acl *acl;
+	const struct acl_keyword *kw;
 
 	if (!*args[1]) {
 		if (curpx == defpx)
@@ -1330,16 +1348,30 @@
 		if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0)
 			goto error;
 
-		if (rule->cond && (rule->cond->requires & ACL_USE_RTR_ANY)) {
-			struct acl *acl;
-			const char *name;
-
-			acl = cond_find_require(rule->cond, ACL_USE_RTR_ANY);
-			name = acl ? acl->name : "(unknown)";
+		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
+		if (acl) {
+			if (acl->name && *acl->name)
+				memprintf(err,
+					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
+					  acl->name, args[0], args[1], sample_ckp_names(where));
+			else
+				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,
+					  sample_ckp_names(where));
 
-			memprintf(err,
-			          "acl '%s' involves some response-only criteria which will be ignored in '%s %s'",
-			          name, args[0], args[1]);
+			warn++;
+		}
+		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
+			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));
+			else
+				memprintf(err,
+					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
+					  kw->kw, sample_ckp_names(where));
 			warn++;
 		}
 
@@ -1359,24 +1391,30 @@
 		if (tcp_parse_request_rule(args, arg, section_type, curpx, defpx, rule, err, where) < 0)
 			goto error;
 
-		if (rule->cond && (rule->cond->requires & (ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY))) {
-			struct acl *acl;
-			const char *name;
-
-			acl = cond_find_require(rule->cond, ACL_USE_RTR_ANY|ACL_USE_L6_ANY|ACL_USE_L7_ANY);
-			name = acl ? acl->name : "(unknown)";
+		acl = rule->cond ? acl_cond_conflicts(rule->cond, where) : NULL;
+		if (acl) {
+			if (acl->name && *acl->name)
+				memprintf(err,
+					  "acl '%s' will never match in '%s %s' because it only involves keywords that are incompatible with '%s'",
+					  acl->name, args[0], args[1], sample_ckp_names(where));
+			else
+				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,
+					  sample_ckp_names(where));
 
-			if (acl->requires & (ACL_USE_L6_ANY|ACL_USE_L7_ANY)) {
+			warn++;
+		}
+		else if (rule->cond && acl_cond_kw_conflicts(rule->cond, where, &acl, &kw)) {
+			if (acl->name && *acl->name)
 				memprintf(err,
-				          "'%s %s' may not reference acl '%s' which makes use of "
-				          "payload in %s '%s'. Please use '%s content' for this.",
-				          args[0], args[1], name, proxy_type_str(curpx), curpx->id, args[0]);
-				goto error;
-			}
-			if (acl->requires & ACL_USE_RTR_ANY)
+					  "acl '%s' involves keyword '%s' which is incompatible with '%s'",
+					  acl->name, kw->kw, sample_ckp_names(where));
+			else
 				memprintf(err,
-				          "acl '%s' involves some response-only criteria which will be ignored in '%s %s'",
-				          name, args[0], args[1]);
+					  "anonymous acl involves keyword '%s' which is incompatible with '%s'",
+					  kw->kw, sample_ckp_names(where));
 			warn++;
 		}