[MEDIUM] config: split parser and checker in two functions

This is a first step towards support of multiple configuration files.
Now readcfgfile() only reads a file in memory and performs very minimal
parsing. The checks are performed afterwards.
diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h
index 35e5614..3b376a0 100644
--- a/include/common/cfgparse.h
+++ b/include/common/cfgparse.h
@@ -64,6 +64,8 @@
 int readcfgfile(const char *file);
 void cfg_register_keywords(struct cfg_kw_list *kwl);
 void cfg_unregister_keywords(struct cfg_kw_list *kwl);
+void init_default_instance();
+int check_config_validity();
 
 #endif /* _COMMON_CFGPARSE_H */
 
diff --git a/include/proto/proxy.h b/include/proto/proxy.h
index adb16ce..8a2789d 100644
--- a/include/proto/proxy.h
+++ b/include/proto/proxy.h
@@ -40,7 +40,7 @@
 const char *proxy_mode_str(int mode);
 struct proxy *findproxy(const char *name, int mode, int cap);
 struct server *findserver(const struct proxy *px, const char *name);
-int proxy_cfg_ensure_no_http(struct proxy *curproxy, const char *file);
+int proxy_cfg_ensure_no_http(struct proxy *curproxy);
 
 /*
  * This function returns a string containing the type of the proxy in a format
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 6c00651..ce6b266 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -672,7 +672,7 @@
 }
 
 
-static void init_default_instance()
+void init_default_instance()
 {
 	memset(&defproxy, 0, sizeof(defproxy));
 	defproxy.mode = PR_MODE_TCP;
@@ -3222,17 +3222,11 @@
 	char thisline[LINESIZE];
 	FILE *f;
 	int linenum = 0;
-	int cfgerr = 0;
 	int confsect = CFG_NONE;
 
-	struct proxy *curproxy = NULL;
-	struct server *newsrv = NULL;
-
 	if ((f=fopen(file,"r")) == NULL)
 		return -1;
 
-	init_default_instance();
-
 	while (fgets(thisline, sizeof(thisline), f) != NULL) {
 		int arg, kwm = KWM_STD;
 		char *end;
@@ -3380,6 +3374,18 @@
 	free(cursection);
 	cursection = NULL;
 	fclose(f);
+	return 0;
+ err:
+	free(cursection);
+	cursection = NULL;
+	return -1;
+}
+
+int check_config_validity()
+{
+	int cfgerr = 0;
+	struct proxy *curproxy = NULL;
+	struct server *newsrv = NULL;
 
 	/*
 	 * Now, check for the integrity of all that we have collected.
@@ -3402,8 +3408,7 @@
 	}
 
 	if ((curproxy = proxy) == NULL) {
-		Alert("parsing %s : no <listen> line. Nothing to do !\n",
-		      file);
+		Alert("config : no <listen> line. Nothing to do !\n");
 		goto err;
 	}
 
@@ -3420,54 +3425,54 @@
 
 		switch (curproxy->mode) {
 		case PR_MODE_HEALTH:
-			cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
+			cfgerr += proxy_cfg_ensure_no_http(curproxy);
 			if (!(curproxy->cap & PR_CAP_FE)) {
-				Alert("parsing %s : %s '%s' cannot be in health mode as it has no frontend capability.\n",
-				      file, proxy_type_str(curproxy), curproxy->id);
+				Alert("config : %s '%s' cannot be in health mode as it has no frontend capability.\n",
+				      proxy_type_str(curproxy), curproxy->id);
 				cfgerr++;
 			}
 
 			if (curproxy->srv != NULL)
-				Warning("parsing %s : servers will be ignored for %s '%s'.\n",
-					file, proxy_type_str(curproxy), curproxy->id);
+				Warning("config : servers will be ignored for %s '%s'.\n",
+					proxy_type_str(curproxy), curproxy->id);
 			break;
 
 		case PR_MODE_TCP:
-			cfgerr += proxy_cfg_ensure_no_http(curproxy, file);
+			cfgerr += proxy_cfg_ensure_no_http(curproxy);
 			break;
 
 		case PR_MODE_HTTP:
 			if ((curproxy->cookie_name != NULL) && (curproxy->srv == NULL)) {
-				Alert("parsing %s : HTTP proxy %s has a cookie but no server list !\n",
-				      file, curproxy->id);
+				Alert("config : HTTP proxy %s has a cookie but no server list !\n",
+				      curproxy->id);
 				cfgerr++;
 			}
 			break;
 		}
 
 		if ((curproxy->cap & PR_CAP_FE) && (curproxy->listen == NULL))  {
-			Alert("parsing %s : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
-			      file, proxy_type_str(curproxy), curproxy->id);
+			Alert("config : %s '%s' has no listen address. Please either specify a valid address on the <listen> line, or use the <bind> keyword.\n",
+			      proxy_type_str(curproxy), curproxy->id);
 			cfgerr++;
 		}
 
 		if ((curproxy->cap & PR_CAP_BE) && (curproxy->mode != PR_MODE_HEALTH)) {
 			if (curproxy->lbprm.algo & BE_LB_ALGO) {
 				if (curproxy->options & PR_O_TRANSP) {
-					Alert("parsing %s : %s '%s' cannot use both transparent and balance mode.\n",
-					      file, proxy_type_str(curproxy), curproxy->id);
+					Alert("config : %s '%s' cannot use both transparent and balance mode.\n",
+					      proxy_type_str(curproxy), curproxy->id);
 					cfgerr++;
 				}
 #ifdef WE_DONT_SUPPORT_SERVERLESS_LISTENERS
 				else if (curproxy->srv == NULL) {
-					Alert("parsing %s : %s '%s' needs at least 1 server in balance mode.\n",
-					      file, proxy_type_str(curproxy), curproxy->id);
+					Alert("config : %s '%s' needs at least 1 server in balance mode.\n",
+					      proxy_type_str(curproxy), curproxy->id);
 					cfgerr++;
 				}
 #endif
 				else if (*(int *)&curproxy->dispatch_addr.sin_addr != 0) {
-					Warning("parsing %s : dispatch address of %s '%s' will be ignored in balance mode.\n",
-						file, proxy_type_str(curproxy), curproxy->id);
+					Warning("config : dispatch address of %s '%s' will be ignored in balance mode.\n",
+						proxy_type_str(curproxy), curproxy->id);
 				}
 			}
 			else if (!(curproxy->options & (PR_O_TRANSP | PR_O_HTTP_PROXY)) &&
@@ -3483,8 +3488,8 @@
 
 		if ((curproxy->options & PR_O_DISABLE404) && !(curproxy->options & PR_O_HTTP_CHK)) {
 			curproxy->options &= ~PR_O_DISABLE404;
-			Warning("parsing %s : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
-				file, "disable-on-404", proxy_type_str(curproxy), curproxy->id);
+			Warning("config : '%s' will be ignored for %s '%s' (requires 'option httpchk').\n",
+				"disable-on-404", proxy_type_str(curproxy), curproxy->id);
 		}
 
 		/* if a default backend was specified, let's find it */
@@ -3570,11 +3575,11 @@
 		    (((curproxy->cap & PR_CAP_FE) && !curproxy->timeout.client) ||
 		     ((curproxy->cap & PR_CAP_BE) && (curproxy->srv) &&
 		      (!curproxy->timeout.connect || !curproxy->timeout.server)))) {
-			Warning("parsing %s : missing timeouts for %s '%s'.\n"
+			Warning("config : missing timeouts for %s '%s'.\n"
 				"   | While not properly invalid, you will certainly encounter various problems\n"
 				"   | with such a configuration. To fix this, please ensure that all following\n"
 				"   | timeouts are set to a non-zero value: 'client', 'connect', 'server'.\n",
-				file, proxy_type_str(curproxy), curproxy->id);
+				proxy_type_str(curproxy), curproxy->id);
 		}
 
 		/* Historically, the tarpit and queue timeouts were inherited from contimeout.
@@ -3669,8 +3674,8 @@
 		newsrv = curproxy->srv;
 		while (newsrv != NULL) {
 			if ((curproxy->mode != PR_MODE_HTTP) && (newsrv->rdr_len || newsrv->cklen)) {
-				Alert("parsing [%s:%d] : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
-				      file, linenum, proxy_type_str(curproxy), curproxy->id);
+				Alert("config : %s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
+				      proxy_type_str(curproxy), curproxy->id);
 				goto err;
 			}
 			newsrv = newsrv->next;
@@ -3693,8 +3698,8 @@
 				/* minconn was not specified, so we set it to maxconn */
 				newsrv->minconn = newsrv->maxconn;
 			} else if (newsrv->minconn != newsrv->maxconn && !curproxy->fullconn) {
-				Alert("parsing [%s:%d] : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
-				      file, linenum, proxy_type_str(curproxy), curproxy->id);
+				Alert("config : %s '%s' : fullconn is mandatory when minconn is set on a server.\n",
+				      proxy_type_str(curproxy), curproxy->id);
 				goto err;
 			}
 
@@ -3716,8 +3721,8 @@
 				if (pname) {
 					px = findproxy(pname, curproxy->mode, PR_CAP_BE);
 					if (!px) {
-						Alert("parsing %s, %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
-							file, proxy_type_str(curproxy), curproxy->id,
+						Alert("config : %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
+							proxy_type_str(curproxy), curproxy->id,
 							newsrv->id, pname);
 						return -1;
 					}
@@ -3726,25 +3731,25 @@
 
 				srv = findserver(px, sname);
 				if (!srv) {
-					Alert("parsing %s, %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
-						file, proxy_type_str(curproxy), curproxy->id,
+					Alert("config : %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
+						proxy_type_str(curproxy), curproxy->id,
 						newsrv->id, sname);
 					return -1;
 				}
 
 				if (!(srv->state & SRV_CHECKED)) {
-					Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for "
+					Alert("config : %s '%s', server '%s': unable to use %s/%s for "
 						"tracing as it does not have checks enabled.\n",
-						file, proxy_type_str(curproxy), curproxy->id,
+						proxy_type_str(curproxy), curproxy->id,
 						newsrv->id, px->id, srv->id);
 					return -1;
 				}
 
 				if (curproxy != px &&
 					(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
-					Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for"
+					Alert("config : %s '%s', server '%s': unable to use %s/%s for"
 						"tracing: disable-on-404 option inconsistency.\n",
-						file, proxy_type_str(curproxy), curproxy->id,
+						proxy_type_str(curproxy), curproxy->id,
 						newsrv->id, px->id, srv->id);
 					return -1;
 				}
@@ -3791,7 +3796,7 @@
 	}
 
 	if (cfgerr > 0) {
-		Alert("Errors found in configuration file, aborting.\n");
+		Alert("Errors found in configuration, aborting.\n");
 		goto err;
 	}
 
@@ -3811,13 +3816,8 @@
 				global.last_checks |= cfg_opts2[optnum].checks;
 	}
 
-	free(cursection);
-	cursection = NULL;
 	return 0;
-
  err:
-	free(cursection);
-	cursection = NULL;
 	return -1;
 }
 
diff --git a/src/haproxy.c b/src/haproxy.c
index 68c8b4b..aac8ac1 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -529,19 +529,27 @@
 
 	have_appsession = 0;
 	global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */
+
+	init_default_instance();
+
 	if (readcfgfile(cfg_cfgfile) < 0) {
 		Alert("Error reading configuration file : %s\n", cfg_cfgfile);
 		exit(1);
 	}
 
-	if (have_appsession)
-		appsession_init();
+	if (check_config_validity() < 0) {
+		Alert("Errors found in configuration.\n");
+		exit(1);
+	}
 
 	if (global.mode & MODE_CHECK) {
-		qfprintf(stdout, "Configuration file is valid : %s\n", cfg_cfgfile);
+		qfprintf(stdout, "Configuration file is valid\n");
 		exit(0);
 	}
 
+	if (have_appsession)
+		appsession_init();
+
 	if (start_checks() < 0)
 		exit(1);
 
diff --git a/src/proxy.c b/src/proxy.c
index b3b33d4..69b070e 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -303,29 +303,29 @@
  * at the end of the configuration parsing if the proxy is not in http mode.
  * The <file> argument is used to construct the error message.
  */
-int proxy_cfg_ensure_no_http(struct proxy *curproxy, const char *file)
+int proxy_cfg_ensure_no_http(struct proxy *curproxy)
 {
 	if (curproxy->cookie_name != NULL) {
-		Warning("parsing %s : cookie will be ignored for %s '%s' (needs 'mode http').\n",
-			file, proxy_type_str(curproxy), curproxy->id);
+		Warning("config : cookie will be ignored for %s '%s' (needs 'mode http').\n",
+			proxy_type_str(curproxy), curproxy->id);
 	}
 	if (curproxy->rsp_exp != NULL) {
-		Warning("parsing %s : server regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
-			file, proxy_type_str(curproxy), curproxy->id);
+		Warning("config : server regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
+			proxy_type_str(curproxy), curproxy->id);
 	}
 	if (curproxy->req_exp != NULL) {
-		Warning("parsing %s : client regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
-			file, proxy_type_str(curproxy), curproxy->id);
+		Warning("config : client regular expressions will be ignored for %s '%s' (needs 'mode http').\n",
+			proxy_type_str(curproxy), curproxy->id);
 	}
 	if (curproxy->monitor_uri != NULL) {
-		Warning("parsing %s : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n",
-			file, proxy_type_str(curproxy), curproxy->id);
+		Warning("config : monitor-uri will be ignored for %s '%s' (needs 'mode http').\n",
+			proxy_type_str(curproxy), curproxy->id);
 	}
 	if (curproxy->lbprm.algo & BE_LB_PROP_L7) {
 		curproxy->lbprm.algo &= ~BE_LB_ALGO;
 		curproxy->lbprm.algo |= BE_LB_ALGO_RR;
-		Warning("parsing %s : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
-			file, proxy_type_str(curproxy), curproxy->id);
+		Warning("config : Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n",
+			proxy_type_str(curproxy), curproxy->id);
 	}
 	return 0;
 }