REORG: split proxy allocation functions

Create a new function parse_new_proxy specifically designed to allocate
a new proxy from the configuration file and copy settings from the
default proxy.

The function alloc_new_proxy is reduced to a minimal allocation. It is
used for default proxy allocation and could also be used for internal
proxies such as the lua Socket proxy.
diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h
index b81783a..ae50c37 100644
--- a/include/haproxy/proxy.h
+++ b/include/haproxy/proxy.h
@@ -61,8 +61,11 @@
 void proxy_free_defaults(struct proxy *defproxy);
 void proxy_destroy_defaults(struct proxy *px);
 void proxy_destroy_all_defaults();
-struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum,
-                              const struct proxy *defproxy, char **errmsg);
+struct proxy *alloc_new_proxy(const char *name, unsigned int cap,
+                              char **errmsg);
+struct proxy *parse_new_proxy(const char *name, unsigned int cap,
+                              const char *file, int linenum,
+                              const struct proxy *defproxy);
 int get_backend_server(const char *bk_name, const char *sv_name,
 		       struct proxy **bk, struct server **sv);
 void proxy_capture_error(struct proxy *proxy, int is_back,
diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c
index aa2b5eb..739dc83 100644
--- a/src/cfgparse-listen.c
+++ b/src/cfgparse-listen.c
@@ -211,7 +211,9 @@
 
 	if (!last_defproxy) {
 		/* we need a default proxy and none was created yet */
-		last_defproxy = alloc_new_proxy("", PR_CAP_DEF|PR_CAP_LISTEN, "INIT", 0, NULL, &errmsg);
+		last_defproxy = alloc_new_proxy("", PR_CAP_DEF|PR_CAP_LISTEN, &errmsg);
+		proxy_preset_defaults(last_defproxy);
+
 		curr_defproxy = last_defproxy;
 		if (!last_defproxy) {
 			ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
@@ -314,9 +316,8 @@
 			}
 		}
 
-		curproxy = alloc_new_proxy(name, rc, file, linenum, curr_defproxy, &errmsg);
+		curproxy = parse_new_proxy(name, rc, file, linenum, curr_defproxy);
 		if (!curproxy) {
-			ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
 			err_code |= ERR_ALERT | ERR_ABORT;
 			goto out;
 		}
diff --git a/src/proxy.c b/src/proxy.c
index 843941e..2514b16 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1237,17 +1237,12 @@
 	}
 }
 
-/* Allocates a new proxy <name> of type <cap> found at position <file:linenum>,
- * preset it from the defaults of <defproxy> and returns it. Un case of error,
- * an alert is printed and NULL is returned. If <errmsg> is not NULL, an error
- * message will be returned there in case of fatal error. If <defproxy> is NULL,
- * the documented default settings will be used instead.
+/* Allocates a new proxy <name> of type <cap>.
+ * Returns the proxy instance on success. On error, NULL is returned.
  */
-struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum, const struct proxy *defproxy, char **errmsg)
+struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg)
 {
-	struct logsrv *tmplogsrv;
 	struct proxy *curproxy;
-	char *tmpmsg = NULL;
 
 	if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) {
 		memprintf(errmsg, "proxy '%s': out of memory", name);
@@ -1255,17 +1250,32 @@
 	}
 
 	init_new_proxy(curproxy);
-	curproxy->conf.args.file = curproxy->conf.file = strdup(file);
-	curproxy->conf.args.line = curproxy->conf.line = linenum;
 	curproxy->last_change = now.tv_sec;
 	curproxy->id = strdup(name);
 	curproxy->cap = cap;
 	proxy_store_name(curproxy);
 
-	if (!defproxy) {
-		proxy_preset_defaults(curproxy);
-		goto done;
-	}
+ done:
+	return curproxy;
+
+ fail:
+	/* Note: in case of fatal error here, we WILL make valgrind unhappy,
+	 * but its not worth trying to unroll everything here just before
+	 * quitting.
+	 */
+	free(curproxy);
+	return NULL;
+}
+
+/* Copy the proxy settings from <defproxy> to <curproxy>.
+ * Returns 0 on success.
+ * Returns 1 on error. <errmsg> will be allocated with an error description.
+ */
+static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defproxy,
+                              char **errmsg)
+{
+	struct logsrv *tmplogsrv;
+	char *tmpmsg = NULL;
 
 	/* set default values from the specified default proxy */
 	memcpy(&curproxy->defsrv, &defproxy->defsrv, sizeof(curproxy->defsrv));
@@ -1298,7 +1308,8 @@
 	/* initialize error relocations */
 	if (!proxy_dup_default_conf_errors(curproxy, defproxy, &tmpmsg)) {
 		memprintf(errmsg, "proxy '%s' : %s", curproxy->id, tmpmsg);
-		goto fail;
+		free(tmpmsg);
+		return 1;
 	}
 
 	if (curproxy->cap & PR_CAP_FE) {
@@ -1327,8 +1338,8 @@
 		if (!LIST_ISEMPTY(&defproxy->tcpcheck_rules.preset_vars)) {
 			if (!dup_tcpcheck_vars(&curproxy->tcpcheck_rules.preset_vars,
 					       &defproxy->tcpcheck_rules.preset_vars)) {
-				memprintf(errmsg, "proxy '%s': failed to duplicate tcpcheck preset-vars", name);
-				goto fail;
+				memprintf(errmsg, "proxy '%s': failed to duplicate tcpcheck preset-vars", curproxy->id);
+				return 1;
 			}
 		}
 
@@ -1441,8 +1452,8 @@
 		struct logsrv *node = malloc(sizeof(*node));
 
 		if (!node) {
-			memprintf(errmsg, "proxy '%s': out of memory", name);
-			goto fail;
+			memprintf(errmsg, "proxy '%s': out of memory", curproxy->id);
+			return 1;
 		}
 		memcpy(node, tmplogsrv, sizeof(struct logsrv));
 		node->ref = tmplogsrv->ref;
@@ -1466,8 +1477,8 @@
 		const struct ist copy = istdup(defproxy->header_unique_id);
 
 		if (!isttest(copy)) {
-			memprintf(errmsg, "proxy '%s': out of memory for unique-id-header", name);
-			goto fail;
+			memprintf(errmsg, "proxy '%s': out of memory for unique-id-header", curproxy->id);
+			return 1;
 		}
 		curproxy->header_unique_id = copy;
 	}
@@ -1497,16 +1508,43 @@
 	curproxy->email_alert.level = defproxy->email_alert.level;
 	curproxy->email_alert.set = defproxy->email_alert.set;
 
- done:
+	return 0;
+}
+
+/* Allocates a new proxy <name> of type <cap> found at position <file:linenum>,
+ * preset it from the defaults of <defproxy> and returns it. In case of error,
+ * an alert is printed and NULL is returned.
+ */
+struct proxy *parse_new_proxy(const char *name, unsigned int cap,
+                              const char *file, int linenum,
+                              const struct proxy *defproxy)
+{
+	struct proxy *curproxy = NULL;
+	char *errmsg;
+
+	if (!(curproxy = alloc_new_proxy(name, cap, &errmsg))) {
+		ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
+		free(errmsg);
+		return NULL;
+	}
+
+	if (defproxy) {
+		if (proxy_defproxy_cpy(curproxy, defproxy, &errmsg)) {
+			ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
+			free(errmsg);
+
+			ha_free(&curproxy);
+			return NULL;
+		}
+	}
+	else {
+		proxy_preset_defaults(curproxy);
+	}
+
+	curproxy->conf.args.file = curproxy->conf.file = strdup(file);
+	curproxy->conf.args.line = curproxy->conf.line = linenum;
+
 	return curproxy;
- fail:
-	/* Note: in case of fatal error here, we WILL make valgrind unhappy,
-	 * but its not worth trying to unroll everything here just before
-	 * quitting.
-	 */
-	free(tmpmsg);
-	free(curproxy);
-	return NULL;
 }
 
 /* to be called under the proxy lock after stopping some listeners. This will