MINOR: config: support some pseudo-variables for file/line/section

The new pseudo-variables ".FILE", ".LINE" and ".SECTION" will be resolved
on the fly by the config parser and will respectively retrieve the current
configuration file name, the current line number and the current section
being parsed. This may help emit logs, errors, and debugging information
(e.g. which rule matched).

The '.' in the first char was reserved for such pseudo-variables and no
other variable is permitted. This will allow to add support for new ones
in the future if they prove to be useful (e.g. randoms/uuid for secret
keying or automatic naming of configuration objects).
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 12d44c5..a6af2f2 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -746,6 +746,29 @@
 * HAPROXY_MASTER_CLI: In master-worker mode, listeners addresses of the master
   CLI, separated by semicolons.
 
+In addition, some pseudo-variables are internally resolved and may be used as
+regular variables. Pseudo-variables always start with a dot ('.'), and are the
+only ones where the dot is permitted. The current list of pseudo-variables is:
+
+* .FILE: the name of the configuration file currently being parsed.
+
+* .LINE: the line number of the configuration file currently being parsed,
+  starting at one.
+
+* .SECTION: the name of the section currently being parsed, or its type if the
+  section doesn't have a name (e.g. "global"), or an empty string before the
+  first section.
+
+These variables are resolved at the location where they are parsed. For example
+if a ".LINE" variable is used in a "log-format" directive located in a defaults
+section, its line number will be resolved before parsing and compiling the
+"log-format" directive, so this same line number will be reused by subsequent
+proxies.
+
+This way it is possible to emit information to help locate a rule in variables,
+logs, error statuses, health checks, header values, or even to use line numbers
+to name some config objects like servers for example.
+
 See also "external-check command" for other variables.
 
 
diff --git a/src/tools.c b/src/tools.c
index 056c9ca..c453585 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -5300,14 +5300,14 @@
 			 */
 			char *var_name;
 			char save_char;
-			char *value;
+			const char *value;
 
 			in++;
 
 			if (*in == '{')
 				brace = in++;
 
-			if (!isalpha((unsigned char)*in) && *in != '_') {
+			if (!isalpha((unsigned char)*in) && *in != '_' && *in != '.') {
 				/* unacceptable character in variable name */
 				err |= PARSE_ERR_VARNAME;
 				if (errptr)
@@ -5316,12 +5316,31 @@
 			}
 
 			var_name = in;
+			if (*in == '.')
+				in++;
 			while (isalnum((unsigned char)*in) || *in == '_')
 				in++;
 
 			save_char = *in;
 			*in = '\0';
-			value = getenv(var_name);
+			if (unlikely(*var_name == '.')) {
+				/* internal pseudo-variables */
+				if (strcmp(var_name, ".LINE") == 0)
+					value = ultoa(global.cfg_curr_line);
+				else if (strcmp(var_name, ".FILE") == 0)
+					value = global.cfg_curr_file;
+				else if (strcmp(var_name, ".SECTION") == 0)
+					value = global.cfg_curr_section;
+				else {
+					/* unsupported internal variable name */
+					err |= PARSE_ERR_VARNAME;
+					if (errptr)
+						*errptr = var_name;
+					goto leave;
+				}
+			} else {
+				value = getenv(var_name);
+			}
 			*in = save_char;
 
 			/* support for '[*]' sequence to force word expansion,