MEDIUM: errors: implement parsing context type

Create a parsing_ctx structure. This type is used to store information
about the current file/line parsed. A global context is created and
can be manipulated when haproxy is in STARTING mode. When starting is
over, the context is resetted and should not be accessed anymore.
diff --git a/include/haproxy/errors.h b/include/haproxy/errors.h
index aaf5cd8..6dd60f1 100644
--- a/include/haproxy/errors.h
+++ b/include/haproxy/errors.h
@@ -60,12 +60,22 @@
 };
 
 
-void usermsgs_clr(void);
+void usermsgs_clr(const char *prefix);
 int usermsgs_empty(void);
 const char *usermsgs_str(void);
 
 /************ Error reporting functions ***********/
 
+struct usermsgs_ctx {
+	const char *prefix;  /* prefix of every output */
+	const char *file;    /* related filename for config parsing */
+	int line;            /* related line number for config parsing */
+	enum obj_type *obj;  /* related proxy, server, ... */
+};
+void set_usermsgs_ctx(const char *file, int line, enum obj_type *obj);
+void register_parsing_obj(enum obj_type *obj);
+void reset_usermsgs_ctx(void);
+
 /*
  * Displays the message on stderr with the date and pid. Overrides the quiet
  * mode during startup.
diff --git a/src/errors.c b/src/errors.c
index 9da04f9..68fcf1a 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -22,6 +22,10 @@
 #define USER_MESSAGES_BUFSIZE 1024
 static THREAD_LOCAL struct buffer usermsgs_buf = BUF_NULL;
 
+/* A thread local context used for stderr output via ha_alert/warning/notice/diag.
+ */
+static THREAD_LOCAL struct usermsgs_ctx usermsgs_ctx = { };
+
 /* Put msg in usermsgs_buf.
  *
  * The message should not be terminated by a newline because this function
@@ -49,13 +53,19 @@
 	}
 }
 
-/* Clear the messages log buffer. */
-void usermsgs_clr(void)
+/* Clear the user messages log buffer.
+ *
+ * <prefix> will set the local-thread context appended to every output
+ * following this call. It can be NULL if not necessary.
+ */
+void usermsgs_clr(const char *prefix)
 {
 	if (likely(!b_is_null(&usermsgs_buf))) {
 		b_reset(&usermsgs_buf);
 		usermsgs_buf.area[0] = '\0';
 	}
+
+	usermsgs_ctx.prefix = prefix;
 }
 
 /* Check if the user messages buffer is empty. */
@@ -73,6 +83,40 @@
 	return b_head(&usermsgs_buf);
 }
 
+/* Set thread-local context infos to prefix forthcoming stderr output during
+ * configuration parsing.
+ *
+ * <file> and <line> specify the location of the parsed configuration.
+ *
+ * <obj> can be of various types. If not NULL, the string prefix generated will
+ * depend on its type.
+ */
+void set_usermsgs_ctx(const char *file, int line, enum obj_type *obj)
+{
+	usermsgs_ctx.file = file;
+	usermsgs_ctx.line = line;
+	usermsgs_ctx.obj = obj;
+}
+
+/* Set thread-local context infos to prefix forthcoming stderr output. It will
+ * be set as a complement to possibly already defined file/line.
+ *
+ * <obj> can be of various types. If not NULL, the string prefix generated will
+ * depend on its type.
+ */
+void register_parsing_obj(enum obj_type *obj)
+{
+	usermsgs_ctx.obj = obj;
+}
+
+/* Reset thread-local context infos for stderr output. */
+void reset_usermsgs_ctx(void)
+{
+	usermsgs_ctx.file = NULL;
+	usermsgs_ctx.line = 0;
+	usermsgs_ctx.obj = NULL;
+}
+
 /* Generic function to display messages prefixed by a label */
 static void print_message(const char *label, const char *fmt, va_list argp)
 {
diff --git a/src/haproxy.c b/src/haproxy.c
index 0e707f5..f4c24ee 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -3380,6 +3380,8 @@
 	}
 
 	global.mode &= ~MODE_STARTING;
+	reset_usermsgs_ctx();
+
 	/*
 	 * That's it : the central polling loop. Run until we stop.
 	 */