summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorFabien Coelho <fabien@apache.org>2013-01-20 10:07:44 +0000
committerFabien Coelho <fabien@apache.org>2013-01-20 10:07:44 +0000
commitcecc389cfdd90b3412a8311bd780c232a916c0c0 (patch)
tree4de1b9e2fc40a82d5e55e5578884dd72612867f9 /modules
parent0b54d4d68edc85f7f4595647092f2d7986d527ee (diff)
downloadhttpd-cecc389cfdd90b3412a8311bd780c232a916c0c0.tar.gz
Add "mod_macro" as a standard module, compiled in with "most".
This module was created in 1998 and has been distributed independently ever since. It is hereby donated to the Apache Software Foundation. There are quite a few comments in the source code to explain how it works, as well as extensive non regression tests. Some utilities about array processing could be moved to "core.c". However, I finally decided against for now so that it stays as an external and independent module, and thus may be backported with minimal impact on the source tree. Details of the addition: * modules/core/mod_macro.c: module source code * modules/core/test: non regression tests modules/core/test/conf/: configuration files modules/core/test/ref/: expected results * docs/manual/mod/mod_macro.xml: English documentation * docs/manual/mod/mod_macro.xml.fr: French documentation git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1435811 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/core/config.m42
-rw-r--r--modules/core/mod_macro.c953
-rwxr-xr-xmodules/core/test/Makefile69
-rw-r--r--modules/core/test/conf/inc63_1.conf5
-rw-r--r--modules/core/test/conf/inc63_2.conf3
-rwxr-xr-xmodules/core/test/conf/test01.conf3
-rwxr-xr-xmodules/core/test/conf/test02.conf3
-rwxr-xr-xmodules/core/test/conf/test03.conf5
-rwxr-xr-xmodules/core/test/conf/test04.conf5
-rwxr-xr-xmodules/core/test/conf/test05.conf5
-rwxr-xr-xmodules/core/test/conf/test06.conf6
-rwxr-xr-xmodules/core/test/conf/test07.conf3
-rwxr-xr-xmodules/core/test/conf/test08.conf3
-rwxr-xr-xmodules/core/test/conf/test09.conf6
-rwxr-xr-xmodules/core/test/conf/test10.conf10
-rwxr-xr-xmodules/core/test/conf/test11.conf15
-rwxr-xr-xmodules/core/test/conf/test12.conf12
-rwxr-xr-xmodules/core/test/conf/test13.conf18
-rwxr-xr-xmodules/core/test/conf/test14.conf23
-rwxr-xr-xmodules/core/test/conf/test15.conf9
-rwxr-xr-xmodules/core/test/conf/test16.conf11
-rwxr-xr-xmodules/core/test/conf/test17.conf10
-rwxr-xr-xmodules/core/test/conf/test18.conf10
-rwxr-xr-xmodules/core/test/conf/test19.conf26
-rwxr-xr-xmodules/core/test/conf/test20.conf11
-rwxr-xr-xmodules/core/test/conf/test21.conf11
-rwxr-xr-xmodules/core/test/conf/test22.conf11
-rwxr-xr-xmodules/core/test/conf/test23.conf15
-rwxr-xr-xmodules/core/test/conf/test24.conf23
-rwxr-xr-xmodules/core/test/conf/test25.conf27
-rwxr-xr-xmodules/core/test/conf/test26.conf19
-rwxr-xr-xmodules/core/test/conf/test27.conf22
-rwxr-xr-xmodules/core/test/conf/test28.conf13
-rwxr-xr-xmodules/core/test/conf/test29.conf10
-rwxr-xr-xmodules/core/test/conf/test30.conf12
-rwxr-xr-xmodules/core/test/conf/test31.conf16
-rwxr-xr-xmodules/core/test/conf/test32.conf7
-rwxr-xr-xmodules/core/test/conf/test33.conf3
-rwxr-xr-xmodules/core/test/conf/test34.conf14
-rwxr-xr-xmodules/core/test/conf/test35.conf10
-rwxr-xr-xmodules/core/test/conf/test36.conf12
-rwxr-xr-xmodules/core/test/conf/test37.conf7
-rwxr-xr-xmodules/core/test/conf/test38.conf10
-rwxr-xr-xmodules/core/test/conf/test39.conf23
-rwxr-xr-xmodules/core/test/conf/test40.conf33
-rwxr-xr-xmodules/core/test/conf/test41.conf20
-rwxr-xr-xmodules/core/test/conf/test42.conf13
-rwxr-xr-xmodules/core/test/conf/test43.conf29
-rwxr-xr-xmodules/core/test/conf/test44.conf19
-rwxr-xr-xmodules/core/test/conf/test45.conf7
-rwxr-xr-xmodules/core/test/conf/test46.conf11
-rwxr-xr-xmodules/core/test/conf/test47.conf15
-rwxr-xr-xmodules/core/test/conf/test48.conf23
-rw-r--r--modules/core/test/conf/test49.conf2
-rw-r--r--modules/core/test/conf/test50.conf5
-rw-r--r--modules/core/test/conf/test51.conf9
-rw-r--r--modules/core/test/conf/test52.conf8
-rwxr-xr-xmodules/core/test/conf/test53.conf2
-rw-r--r--modules/core/test/conf/test54.conf6
-rw-r--r--modules/core/test/conf/test55.conf11
-rw-r--r--modules/core/test/conf/test56.conf18
-rw-r--r--modules/core/test/conf/test57.conf4
-rw-r--r--modules/core/test/conf/test58.conf4
-rw-r--r--modules/core/test/conf/test59.conf4
-rw-r--r--modules/core/test/conf/test60.conf17
-rw-r--r--modules/core/test/conf/test61.conf18
-rw-r--r--modules/core/test/conf/test62.conf25
-rw-r--r--modules/core/test/conf/test63.conf9
-rw-r--r--modules/core/test/conf/test64.conf5
-rw-r--r--modules/core/test/conf/test65.conf11
-rw-r--r--modules/core/test/conf/test66.conf7
-rw-r--r--modules/core/test/conf/test67.conf1
-rw-r--r--modules/core/test/conf/test68.conf5
-rw-r--r--modules/core/test/conf/test69.conf14
-rw-r--r--modules/core/test/ref/test01.out3
-rw-r--r--modules/core/test/ref/test02.out3
-rw-r--r--modules/core/test/ref/test03.out3
-rw-r--r--modules/core/test/ref/test04.out3
-rw-r--r--modules/core/test/ref/test05.out3
-rw-r--r--modules/core/test/ref/test06.out3
-rw-r--r--modules/core/test/ref/test07.out3
-rw-r--r--modules/core/test/ref/test08.out3
-rw-r--r--modules/core/test/ref/test09.out3
-rw-r--r--modules/core/test/ref/test10.out3
-rw-r--r--modules/core/test/ref/test11.out6
-rw-r--r--modules/core/test/ref/test12.out7
-rw-r--r--modules/core/test/ref/test13.out8
-rw-r--r--modules/core/test/ref/test14.out14
-rw-r--r--modules/core/test/ref/test15.out6
-rw-r--r--modules/core/test/ref/test16.out5
-rw-r--r--modules/core/test/ref/test17.out7
-rw-r--r--modules/core/test/ref/test18.out7
-rw-r--r--modules/core/test/ref/test19.out9
-rw-r--r--modules/core/test/ref/test20.out4
-rw-r--r--modules/core/test/ref/test21.out5
-rw-r--r--modules/core/test/ref/test22.out6
-rw-r--r--modules/core/test/ref/test23.out7
-rw-r--r--modules/core/test/ref/test24.out8
-rw-r--r--modules/core/test/ref/test25.out9
-rw-r--r--modules/core/test/ref/test26.out11
-rw-r--r--modules/core/test/ref/test27.out8
-rw-r--r--modules/core/test/ref/test28.out6
-rw-r--r--modules/core/test/ref/test29.out4
-rw-r--r--modules/core/test/ref/test30.out7
-rw-r--r--modules/core/test/ref/test31.out23
-rw-r--r--modules/core/test/ref/test32.out3
-rw-r--r--modules/core/test/ref/test33.out3
-rw-r--r--modules/core/test/ref/test34.out13
-rw-r--r--modules/core/test/ref/test35.out13
-rw-r--r--modules/core/test/ref/test36.out20
-rw-r--r--modules/core/test/ref/test37.out3
-rw-r--r--modules/core/test/ref/test38.out6
-rw-r--r--modules/core/test/ref/test39.out7
-rw-r--r--modules/core/test/ref/test40.out18
-rw-r--r--modules/core/test/ref/test41.out9
-rw-r--r--modules/core/test/ref/test42.out15
-rw-r--r--modules/core/test/ref/test43.out8
-rw-r--r--modules/core/test/ref/test44.out5
-rw-r--r--modules/core/test/ref/test45.out19
-rw-r--r--modules/core/test/ref/test46.out9
-rw-r--r--modules/core/test/ref/test47.out8
-rw-r--r--modules/core/test/ref/test48.out20
-rw-r--r--modules/core/test/ref/test49.out3
-rw-r--r--modules/core/test/ref/test50.out3
-rw-r--r--modules/core/test/ref/test51.out3
-rw-r--r--modules/core/test/ref/test52.out6
-rw-r--r--modules/core/test/ref/test53.out3
-rw-r--r--modules/core/test/ref/test54.out6
-rw-r--r--modules/core/test/ref/test55.out8
-rw-r--r--modules/core/test/ref/test56.out12
-rw-r--r--modules/core/test/ref/test57.out3
-rw-r--r--modules/core/test/ref/test58.out3
-rw-r--r--modules/core/test/ref/test59.out3
-rw-r--r--modules/core/test/ref/test60.out15
-rw-r--r--modules/core/test/ref/test61.out9
-rw-r--r--modules/core/test/ref/test62.out15
-rw-r--r--modules/core/test/ref/test63.out10
-rw-r--r--modules/core/test/ref/test64.out7
-rw-r--r--modules/core/test/ref/test65.out7
-rw-r--r--modules/core/test/ref/test66.out7
-rw-r--r--modules/core/test/ref/test67.out5
-rw-r--r--modules/core/test/ref/test68.out6
-rw-r--r--modules/core/test/ref/test69.out10
143 files changed, 2366 insertions, 0 deletions
diff --git a/modules/core/config.m4 b/modules/core/config.m4
index e2799c91a9..8bb39a5cb2 100644
--- a/modules/core/config.m4
+++ b/modules/core/config.m4
@@ -53,6 +53,8 @@ APACHE_MODULE(watchdog, Watchdog module, , , , [
fi
])
+APACHE_MODULE(macro, Define and use macros in configuration files, , , most)
+
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
APACHE_MODPATH_FINISH
diff --git a/modules/core/mod_macro.c b/modules/core/mod_macro.c
new file mode 100644
index 0000000000..34ae3ad3c6
--- /dev/null
+++ b/modules/core/mod_macro.c
@@ -0,0 +1,953 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ $Id$
+*/
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_hash.h"
+
+/************************************************ COMPILE TIME DEBUG CONTROL */
+/*
+ debug:
+ #define MOD_MACRO_DEBUG 1
+
+ gdb:
+ run -f ./test/conf/test??.conf
+*/
+/* #define MOD_MACRO_DEBUG 1 */
+#undef MOD_MACRO_DEBUG
+
+#if defined(debug)
+#undef debug
+#endif /* debug */
+
+#if defined(MOD_MACRO_DEBUG)
+#define debug(stmt) stmt
+#else
+#define debug(stmt)
+#endif /* MOD_MACRO_DEBUG */
+
+/******************************************************** MODULE DECLARATION */
+
+module AP_MODULE_DECLARE_DATA macro_module;
+
+/********************************************************** MACRO MANAGEMENT */
+
+/*
+ this is a macro: name, arguments, contents, location.
+*/
+typedef struct
+{
+ char *name; /* lower case name of the macro */
+ apr_array_header_t *arguments; /* of char*, macro parameter names */
+ apr_array_header_t *contents; /* of char*, macro body */
+ char *location; /* of macro definition, for error messages */
+} ap_macro_t;
+
+/* configuration tokens.
+ */
+#define BEGIN_MACRO "<Macro"
+#define END_MACRO "</Macro>"
+#define USE_MACRO "Use"
+#define UNDEF_MACRO "UndefMacro"
+
+/*
+ Macros are kept globally...
+ They are not per-server or per-directory entities.
+
+ I would need a hook BEFORE and AFTER configuration processing
+ to initialize and close them properly, but no such thing is exported,
+ although it could be available from within apache.
+
+ I would have such a hook if in server/config.c
+ The "initializer" does not seem to be called before.
+
+ note: they are in a temp_pool, and there is a lazy initialization.
+
+ hash type: (char *) name -> (ap_macro_t *) macro
+*/
+static apr_hash_t *ap_macros = NULL;
+
+/*************************************************************** PARSE UTILS */
+
+#define empty_string_p(p) (!(p) || *(p) == '\0')
+#define trim(line) while (*(line) == ' ' || *(line) == '\t') (line)++
+
+/*
+ return configuration-parsed arguments from line as an array.
+ the line is expected not to contain any '\n'?
+*/
+static apr_array_header_t *get_arguments(apr_pool_t * pool, const char *line)
+{
+ apr_array_header_t *args = apr_array_make(pool, 1, sizeof(char *));
+
+ trim(line);
+ while (*line) {
+ char *arg = ap_getword_conf(pool, &line);
+ char **new = apr_array_push(args);
+ *new = arg;
+ trim(line);
+ }
+
+ return args;
+}
+
+/*
+ warn if anything non blank appears, but ignore comments...
+*/
+static void warn_if_non_blank(
+ const char * what,
+ char * ptr,
+ ap_configfile_t * cfg)
+{
+ char * p;
+ for (p=ptr; *p; p++) {
+ if (*p == '#')
+ break;
+ if (*p != ' ' && *p != '\t') {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "%s on line %d of %s: %s",
+ what, cfg->line_number, cfg->name, ptr);
+ break;
+ }
+ }
+}
+
+/*
+ get read lines as an array till end_token.
+ counts nesting for begin_token/end_token.
+ it assumes a line-per-line configuration (thru getline).
+ this function could be exported.
+ begin_token may be NULL.
+*/
+static char *get_lines_till_end_token(apr_pool_t * pool,
+ ap_configfile_t * config_file,
+ const char *end_token,
+ const char *begin_token,
+ const char *where,
+ apr_array_header_t ** plines)
+{
+ apr_array_header_t *lines = apr_array_make(pool, 1, sizeof(char *));
+ char line[MAX_STRING_LEN]; /* sorry, but this is expected by getline:-( */
+ int macro_nesting = 1, any_nesting = 1;
+ int line_number_start = config_file->line_number;
+
+ while (!ap_cfg_getline(line, MAX_STRING_LEN, config_file)) {
+ char *ptr = line;
+ char *first, **new;
+ /* skip comments */
+ if (*line == '#')
+ continue;
+ first = ap_getword_conf_nc(pool, &ptr);
+ if (first) {
+ /* detect nesting... */
+ if (!strncmp(first, "</", 2)) {
+ any_nesting--;
+ if (any_nesting < 0) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING,
+ 0, NULL,
+ "bad (negative) nesting on line %d of %s",
+ config_file->line_number - line_number_start,
+ where);
+ }
+ }
+ else if (!strncmp(first, "<", 1)) {
+ any_nesting++;
+ }
+
+ if (!strcasecmp(first, end_token)) {
+ /* check for proper closing */
+ char * endp = (char *) ap_strrchr_c(line, '>');
+
+ /* this cannot happen if end_token contains '>' */
+ if (endp == NULL) {
+ return "end directive missing closing '>'";
+ }
+
+ warn_if_non_blank(
+ "non blank chars found after directive closing",
+ endp+1, config_file);
+
+ macro_nesting--;
+ if (!macro_nesting) {
+ if (any_nesting) {
+ ap_log_error(APLOG_MARK,
+ APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "bad cumulated nesting (%+d) in %s",
+ any_nesting, where);
+ }
+ *plines = lines;
+ return NULL;
+ }
+ }
+ else if (begin_token && !strcasecmp(first, begin_token)) {
+ macro_nesting++;
+ }
+ }
+ new = apr_array_push(lines);
+ *new = apr_psprintf(pool, "%s" APR_EOL_STR, line); /* put EOL back? */
+ }
+
+ return apr_psprintf(pool, "expected token not found: %s", end_token);
+}
+
+/* the @* arguments are double-quote escaped when substituted */
+#define ESCAPE_ARG '@'
+
+/* other $* and %* arguments are simply replaced without escaping */
+#define ARG_PREFIX "$%@"
+
+/*
+ characters allowed in an argument?
+ not used yet, because that would trigger some backward compatibility.
+*/
+#define ARG_CONTENT \
+ "abcdefghijklmnopqrstuvwxyz" \
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "0123456789_" ARG_PREFIX
+
+/*
+ returns whether it looks like an argument, i.e. prefixed by ARG_PREFIX.
+*/
+static int looks_like_an_argument(const char *word)
+{
+ return ap_strchr(ARG_PREFIX, *word) != 0;
+}
+
+/*
+ generates an error on macro with two arguments of the same name.
+ generates an error if a macro argument name is empty.
+ generates a warning if arguments name prefixes conflict.
+ generates a warning if the first char of an argument is not in ARG_PREFIX
+*/
+static const char *check_macro_arguments(apr_pool_t * pool,
+ const ap_macro_t * macro)
+{
+ char **tab = (char **) macro->arguments->elts;
+ int nelts = macro->arguments->nelts;
+ int i;
+
+ for (i = 0; i < nelts; i++) {
+ size_t ltabi = strlen(tab[i]);
+ int j;
+
+ if (ltabi == 0) {
+ return apr_psprintf(pool,
+ "macro '%s' (%s): empty argument #%d name",
+ macro->name, macro->location, i + 1);
+ }
+ else if (!looks_like_an_argument(tab[i])) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "macro '%s' (%s) "
+ "argument name '%s' (#%d) without expected prefix, "
+ "better prefix argument names with one of '%s'.",
+ macro->name, macro->location,
+ tab[i], i + 1, ARG_PREFIX);
+ }
+
+ for (j = i + 1; j < nelts; j++) {
+ size_t ltabj = strlen(tab[j]);
+
+ /* must not use the same argument name twice */
+ if (!strcmp(tab[i], tab[j])) {
+ return apr_psprintf(pool,
+ "argument name conflict in macro '%s' (%s): "
+ "argument '%s': #%d and #%d, "
+ "change argument names!",
+ macro->name, macro->location,
+ tab[i], i + 1, j + 1);
+ }
+
+ /* warn about common prefix, but only if non empty names */
+ if (ltabi && ltabj &&
+ !strncmp(tab[i], tab[j], ltabi < ltabj ? ltabi : ltabj)) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING,
+ 0, NULL,
+ "macro '%s' (%s): "
+ "argument name prefix conflict (%s #%d and %s #%d),"
+ " be careful about your macro definition!",
+ macro->name, macro->location,
+ tab[i], i + 1, tab[j], j + 1);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ warn about empty strings in array. could be legitimate.
+*/
+static void check_macro_use_arguments(const char *where,
+ const apr_array_header_t * array)
+{
+ char **tab = (char **) array->elts;
+ int i;
+ for (i = 0; i < array->nelts; i++) {
+ if (empty_string_p(tab[i])) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "%s: empty argument #%d", where, i + 1);
+ }
+ }
+}
+
+/******************************************************** SUBSTITUTION UTILS */
+
+/* could be switched to '\'' */
+#define DELIM '"'
+#define ESCAPE '\\'
+
+/*
+ returns the number of needed escapes for the string
+*/
+static int number_of_escapes(const char delim, const char *str)
+{
+ int nesc = 0;
+ const char *s = str;
+ while (*s) {
+ if (*s == ESCAPE || *s == delim)
+ nesc++;
+ s++;
+ }
+ debug(fprintf(stderr, "escapes: %d ---%s---\n", nesc, str));
+ return nesc;
+}
+
+/*
+ replace name by replacement at the beginning of buf of bufsize.
+ returns an error message or NULL.
+ C is not really a nice language for processing strings.
+*/
+static char *substitute(char *buf,
+ const int bufsize,
+ const char *name,
+ const char *replacement, const int do_esc)
+{
+ int lbuf = strlen(buf),
+ lname = strlen(name),
+ lrepl = strlen(replacement),
+ lsubs = lrepl +
+ (do_esc ? (2 + number_of_escapes(DELIM, replacement)) : 0),
+ shift = lsubs - lname, size = lbuf + shift, i, j;
+
+ /* buf must starts with name */
+ ap_assert(!strncmp(buf, name, lname));
+
+ /* hmmm??? */
+ if (!strcmp(name, replacement))
+ return NULL;
+
+ debug(fprintf(stderr,
+ "substitute(%s,%s,%s,%d,sh=%d,lbuf=%d,lrepl=%d,lsubs=%d)\n",
+ buf, name, replacement, do_esc, shift, lbuf, lrepl, lsubs));
+
+ if (size >= bufsize) {
+ /* could/should I reallocate? */
+ return "cannot substitute, buffer size too small";
+ }
+
+ /* cannot use strcpy as strings may overlap */
+ if (shift != 0) {
+ memmove(buf + lname + shift, buf + lname, lbuf - lname + 1);
+ }
+
+ /* insert the replacement with escapes */
+ j = 0;
+ if (do_esc)
+ buf[j++] = DELIM;
+ for (i = 0; i < lrepl; i++, j++) {
+ if (do_esc && (replacement[i] == DELIM || replacement[i] == ESCAPE))
+ buf[j++] = ESCAPE;
+ buf[j] = replacement[i];
+ }
+ if (do_esc)
+ buf[j++] = DELIM;
+
+ return NULL;
+}
+
+/*
+ find first occurence of args in buf.
+ in case of conflict, the LONGEST argument is kept. (could be the FIRST?).
+ returns the pointer and the whichone found, or NULL.
+*/
+static char *next_substitution(const char *buf,
+ const apr_array_header_t * args, int *whichone)
+{
+ char *chosen = NULL, **tab = (char **) args->elts;
+ size_t lchosen = 0;
+ int i;
+
+ for (i = 0; i < args->nelts; i++) {
+ char *found = ap_strstr((char *) buf, tab[i]);
+ size_t lfound = strlen(tab[i]);
+ if (found && (!chosen || found < chosen ||
+ (found == chosen && lchosen < lfound))) {
+ chosen = found;
+ lchosen = lfound;
+ *whichone = i;
+ }
+ }
+
+ return chosen;
+}
+
+/*
+ substitute macro arguments by replacements in buf of bufsize.
+ returns an error message or NULL.
+ if used is defined, returns the used macro arguments.
+*/
+static const char *substitute_macro_args(
+ char *buf,
+ int bufsize,
+ const ap_macro_t * macro,
+ const apr_array_header_t * replacements,
+ apr_array_header_t * used)
+{
+ char *ptr = buf,
+ **atab = (char **) macro->arguments->elts,
+ **rtab = (char **) replacements->elts;
+ int whichone = -1;
+
+ if (used) {
+ ap_assert(used->nalloc >= replacements->nelts);
+ }
+ debug(fprintf(stderr, "1# %s", buf));
+
+ while ((ptr = next_substitution(ptr, macro->arguments, &whichone))) {
+ const char *errmsg = substitute(ptr, buf - ptr + bufsize,
+ atab[whichone], rtab[whichone],
+ atab[whichone][0] == ESCAPE_ARG);
+ if (errmsg) {
+ return errmsg;
+ }
+ ptr += strlen(rtab[whichone]);
+ if (used) {
+ used->elts[whichone] = 1;
+ }
+ }
+ debug(fprintf(stderr, "2# %s", buf));
+
+ return NULL;
+}
+
+/*
+ perform substitutions in a macro contents and
+ return the result as a newly allocated array, if result is defined.
+ may also return an error message.
+ passes used down to substitute_macro_args.
+*/
+static const char *process_content(apr_pool_t * pool,
+ const ap_macro_t * macro,
+ const apr_array_header_t * replacements,
+ apr_array_header_t * used,
+ apr_array_header_t ** result)
+{
+ apr_array_header_t *contents = macro->contents;
+ char line[MAX_STRING_LEN];
+ int i;
+
+ if (result) {
+ *result = apr_array_make(pool, 1, sizeof(char *));
+ }
+
+ /* for each line of the macro body */
+ for (i = 0; i < contents->nelts; i++) {
+ const char *errmsg;
+ /* copy the line and subtitute macro parameters */
+ strncpy(line, ((char **) contents->elts)[i], MAX_STRING_LEN - 1);
+ errmsg = substitute_macro_args(line, MAX_STRING_LEN,
+ macro, replacements, used);
+ if (errmsg) {
+ return apr_psprintf(pool,
+ "while processing line %d of macro '%s' (%s) %s",
+ i + 1, macro->name, macro->location, errmsg);
+ }
+ /* append substituted line to result array */
+ if (result) {
+ char **new = apr_array_push(*result);
+ *new = apr_pstrdup(pool, line);
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ warn if some macro arguments are not used.
+*/
+static const char *check_macro_contents(apr_pool_t * pool,
+ const ap_macro_t * macro)
+{
+ int nelts = macro->arguments->nelts;
+ char **names = (char **) macro->arguments->elts;
+ apr_array_header_t *used;
+ int i;
+ const char *errmsg;
+
+ if (macro->contents->nelts == 0) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "macro '%s' (%s): empty contents!",
+ macro->name, macro->location);
+ return NULL; /* no need to further warnings... */
+ }
+
+ used = apr_array_make(pool, nelts, sizeof(char));
+
+ for (i = 0; i < nelts; i++) {
+ used->elts[i] = 0;
+ }
+
+ errmsg = process_content(pool, macro, macro->arguments, used, NULL);
+
+ if (errmsg) {
+ return errmsg;
+ }
+
+ for (i = 0; i < nelts; i++) {
+ if (!used->elts[i]) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "macro '%s' (%s): argument '%s' (#%d) never used",
+ macro->name, macro->location, names[i], i + 1);
+ }
+ }
+
+ return NULL;
+}
+
+
+/************************************************** MACRO PSEUDO CONFIG FILE */
+
+/*
+ The expanded content of the macro is to be parsed as a ap_configfile_t.
+ This is used to have some kind of old fashionned C object oriented inherited
+ data structure for configs.
+
+ The following struct stores the contents.
+
+ This structure holds pointers (next, upper) to the current "file" which was
+ being processed and is interrupted by the macro expansion. At the end
+ of processing the macro, the initial data structure will be put back
+ in place (see function next_one) and the reading will go on from there.
+
+ If macros are used within macros, there may be a cascade of such temporary
+ arrays used to insert the expanded macro contents before resuming the real
+ file processing.
+
+ There is some hopus-pocus to deal with line_number when transiting from
+ one config to the other.
+*/
+typedef struct
+{
+ int index; /* current element */
+ int char_index; /* current char in element */
+ int length; /* cached length of the current line */
+ apr_array_header_t *contents; /* array of char * */
+ ap_configfile_t *next; /* next config once this one is processed */
+ ap_configfile_t **upper; /* hack: where to update it if needed */
+} array_contents_t;
+
+/*
+ Get next config if any.
+ this may be called several times if there are continuations.
+*/
+static int next_one(array_contents_t * ml)
+{
+ if (ml->next) {
+ ap_assert(ml->upper);
+ *(ml->upper) = ml->next;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ returns next char if possible
+ this may involve switching to enclosing config.
+*/
+static apr_status_t array_getch(char *ch, void *param)
+{
+ array_contents_t *ml = (array_contents_t *) param;
+ char **tab = (char **) ml->contents->elts;
+
+ while (ml->char_index >= ml->length) {
+ if (ml->index >= ml->contents->nelts) {
+ /* maybe update */
+ if (ml->next && ml->next->getch && next_one(ml)) {
+ apr_status_t rc = ml->next->getch(ch, ml->next->param);
+ if (*ch==LF)
+ ml->next->line_number++;
+ return rc;
+ }
+ return APR_EOF;
+ }
+ ml->index++;
+ ml->char_index = 0;
+ ml->length = ml->index >= ml->contents->nelts ?
+ 0 : strlen(tab[ml->index]);
+ }
+
+ *ch = tab[ml->index][ml->char_index++];
+ return APR_SUCCESS;
+}
+
+/*
+ returns a buf a la fgets.
+ no more than a line at a time, otherwise the parsing is too much ahead...
+ NULL at EOF.
+*/
+static apr_status_t array_getstr(void *buf, size_t bufsize, void *param)
+{
+ array_contents_t *ml = (array_contents_t *) param;
+ char *buffer = (char *) buf;
+ char next = '\0';
+ size_t i = 0;
+ apr_status_t rc = APR_SUCCESS;
+
+ /* read chars from stream, stop on newline */
+ while (i < bufsize - 1 && next != LF &&
+ ((rc = array_getch(&next, param)) == APR_SUCCESS)) {
+ buffer[i++] = next;
+ }
+
+ if (rc == APR_EOF) {
+ /* maybe update to next, possibly a recursion */
+ if (next_one(ml)) {
+ ap_assert(ml->next->getstr);
+ /* keep next line count in sync! the caller will update
+ the current line_number, we need to forward to the next */
+ ml->next->line_number++;
+ return ml->next->getstr(buf, bufsize, ml->next->param);
+ }
+ /* else that is really all we can do */
+ return APR_EOF;
+ }
+
+ buffer[i] = '\0';
+
+ return APR_SUCCESS;
+}
+
+/*
+ close the array stream?
+*/
+static apr_status_t array_close(void *param)
+{
+ array_contents_t *ml = (array_contents_t *) param;
+ /* move index at end of stream... */
+ ml->index = ml->contents->nelts;
+ ml->char_index = ml->length;
+ return APR_SUCCESS;
+}
+
+/*
+ create an array config stream insertion "object".
+ could be exported.
+*/
+static ap_configfile_t *make_array_config(apr_pool_t * pool,
+ apr_array_header_t * contents,
+ const char *where,
+ ap_configfile_t * cfg,
+ ap_configfile_t ** upper)
+{
+ array_contents_t *ls =
+ (array_contents_t *) apr_palloc(pool, sizeof(array_contents_t));
+ ap_assert(ls!=NULL);
+
+ ls->index = 0;
+ ls->char_index = 0;
+ ls->contents = contents;
+ ls->length = ls->contents->nelts < 1 ?
+ 0 : strlen(((char **) ls->contents->elts)[0]);
+ ls->next = cfg;
+ ls->upper = upper;
+
+ return ap_pcfg_open_custom(pool, where, (void *) ls,
+ array_getch, array_getstr, array_close);
+}
+
+
+/********************************************************** KEYWORD HANDLING */
+
+/*
+ handles: <Macro macroname arg1 arg2 ...> any trash there is ignored...
+*/
+static const char *macro_section(cmd_parms * cmd,
+ void *dummy, const char *arg)
+{
+ apr_pool_t *pool;
+ char *endp, *name, *where;
+ const char *errmsg;
+ ap_macro_t *macro;
+
+ debug(fprintf(stderr, "macro_section: arg='%s'\n", arg));
+
+ /* lazy initialization */
+ if (ap_macros == NULL)
+ ap_macros = apr_hash_make(cmd->temp_pool);
+ ap_assert(ap_macros != NULL);
+
+ pool = apr_hash_pool_get(ap_macros);
+
+ endp = (char *) ap_strrchr_c(arg, '>');
+
+ if (endp == NULL) {
+ return BEGIN_MACRO "> directive missing closing '>'";
+ }
+
+ if (endp == arg) {
+ return BEGIN_MACRO " macro definition: empty name";
+ }
+
+ warn_if_non_blank("non blank chars found after " BEGIN_MACRO " closing '>'",
+ endp+1, cmd->config_file);
+
+ /* coldly drop '>[^>]*$' out */
+ *endp = '\0';
+
+ /* get lowercase macro name */
+ name = ap_getword_conf(pool, &arg);
+ if (empty_string_p(name)) {
+ return BEGIN_MACRO " macro definition: name not found";
+ }
+
+ ap_str_tolower(name);
+ macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
+
+ if (macro != NULL) {
+ /* already defined: warn about the redefinition */
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "macro '%s' multiply defined: "
+ "%s, redefined on line %d of \"%s\"",
+ macro->name, macro->location,
+ cmd->config_file->line_number, cmd->config_file->name);
+ }
+ else {
+ /* allocate a new macro */
+ macro = (ap_macro_t *) apr_palloc(pool, sizeof(ap_macro_t));
+ macro->name = name;
+ }
+
+ debug(fprintf(stderr, "macro_section: name=%s\n", name));
+
+ /* get macro arguments */
+ macro->location = apr_psprintf(pool,
+ "defined on line %d of \"%s\"",
+ cmd->config_file->line_number,
+ cmd->config_file->name);
+ debug(fprintf(stderr, "macro_section: location=%s\n", macro->location));
+
+ where =
+ apr_psprintf(pool, "macro '%s' (%s)", macro->name, macro->location);
+
+ if (looks_like_an_argument(name)) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, 0, NULL,
+ "%s better prefix a macro name with any of '%s'",
+ where, ARG_PREFIX);
+ }
+
+ /* get macro parameters */
+ macro->arguments = get_arguments(pool, arg);
+
+ errmsg = check_macro_arguments(cmd->temp_pool, macro);
+
+ if (errmsg) {
+ return errmsg;
+ }
+
+ errmsg = get_lines_till_end_token(pool, cmd->config_file,
+ END_MACRO, BEGIN_MACRO,
+ where, &macro->contents);
+
+ if (errmsg) {
+ return apr_psprintf(cmd->temp_pool,
+ "%s" APR_EOL_STR "\tcontents error: %s",
+ where, errmsg);
+ }
+
+ errmsg = check_macro_contents(cmd->temp_pool, macro);
+
+ if (errmsg) {
+ return apr_psprintf(cmd->temp_pool,
+ "%s" APR_EOL_STR "\tcontents checking error: %s",
+ where, errmsg);
+ }
+
+ /* store the new macro */
+ apr_hash_set(ap_macros, name, APR_HASH_KEY_STRING, macro);
+
+ return NULL;
+}
+
+/*
+ handles: Use name value1 value2 ...
+*/
+static const char *use_macro(cmd_parms * cmd, void *dummy, const char *arg)
+{
+ char *name, *recursion, *where;
+ const char *errmsg;
+ ap_macro_t *macro;
+ apr_array_header_t *replacements;
+ apr_array_header_t *contents;
+
+ debug(fprintf(stderr, "use_macro -%s-\n", arg));
+
+ /* must be initialized, or no macros has been defined */
+ if (ap_macros == NULL) {
+ return "no macro defined before " USE_MACRO;
+ }
+
+ /* get lowercase macro name */
+ name = ap_getword_conf(cmd->temp_pool, &arg);
+ ap_str_tolower(name);
+
+ if (empty_string_p(name)) {
+ return "no macro name specified with " USE_MACRO;
+ }
+
+ /* get macro definition */
+ macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
+
+ if (!macro) {
+ return apr_psprintf(cmd->temp_pool, "macro '%s' undefined", name);
+ }
+
+ /* recursion is detected here by looking at the config file name,
+ * which may already contains "macro 'foo'". Ok, it looks like a hack,
+ * but otherwise it is uneasy to keep this data available somewhere...
+ * the name has just the needed visibility and liveness.
+ */
+ recursion =
+ apr_pstrcat(cmd->temp_pool, "macro '", macro->name, "'", NULL);
+
+ if (ap_strstr((char *) cmd->config_file->name, recursion)) {
+ return apr_psprintf(cmd->temp_pool,
+ "recursive use of macro '%s' is invalid",
+ macro->name);
+ }
+
+ /* get macro arguments */
+ replacements = get_arguments(cmd->temp_pool, arg);
+
+ if (macro->arguments->nelts != replacements->nelts) {
+ return apr_psprintf(cmd->temp_pool,
+ "macro '%s' (%s) used "
+ "with %d arguments instead of %d",
+ macro->name, macro->location,
+ replacements->nelts, macro->arguments->nelts);
+ }
+
+ where = apr_psprintf(cmd->temp_pool,
+ "macro '%s' (%s) used on line %d of \"%s\"",
+ macro->name, macro->location,
+ cmd->config_file->line_number,
+ cmd->config_file->name);
+
+ check_macro_use_arguments(where, replacements);
+
+ errmsg = process_content(cmd->temp_pool, macro, replacements,
+ NULL, &contents);
+
+ if (errmsg) {
+ return apr_psprintf(cmd->temp_pool,
+ "%s error while substituting: %s",
+ where, errmsg);
+ }
+
+ /* the current "config file" is replaced by a string array...
+ at the end of processing the array, the initial config file
+ will be returned there (see next_one) so as to go on. */
+ cmd->config_file = make_array_config(cmd->temp_pool, contents, where,
+ cmd->config_file, &cmd->config_file);
+
+ return NULL;
+}
+
+static const char *undef_macro(cmd_parms * cmd, void *dummy, const char *arg)
+{
+ char *name;
+ ap_macro_t *macro;
+
+ /* must be initialized, or no macros has been defined */
+ if (ap_macros == NULL) {
+ return "no macro defined before " UNDEF_MACRO;
+ }
+
+ if (empty_string_p(arg)) {
+ return "no macro name specified with " UNDEF_MACRO;
+ }
+
+ /* check that the macro is defined */
+ name = apr_pstrdup(cmd->temp_pool, arg);
+ ap_str_tolower(name);
+ macro = apr_hash_get(ap_macros, name, APR_HASH_KEY_STRING);
+ if (macro == NULL) {
+ /* could be a warning? */
+ return apr_psprintf(cmd->temp_pool,
+ "cannot remove undefined macro '%s'", name);
+ }
+
+ /* free macro: cannot do that */
+ /* remove macro from hash table */
+ apr_hash_set(ap_macros, name, APR_HASH_KEY_STRING, NULL);
+
+ return NULL;
+}
+
+/************************************************************* EXPORT MODULE */
+
+/*
+ macro module commands.
+ configuration file macro stuff
+ they are processed immediatly when found, hence the EXEC_ON_READ.
+*/
+static const command_rec macro_cmds[] = {
+ AP_INIT_RAW_ARGS(BEGIN_MACRO, macro_section, NULL, EXEC_ON_READ | OR_ALL,
+ "Beginning of a macro definition section."),
+ AP_INIT_RAW_ARGS(USE_MACRO, use_macro, NULL, EXEC_ON_READ | OR_ALL,
+ "Use of a macro."),
+ AP_INIT_TAKE1(UNDEF_MACRO, undef_macro, NULL, EXEC_ON_READ | OR_ALL,
+ "Remove a macro definition."),
+
+ {NULL}
+};
+
+/*
+ Module hooks are request-oriented thus it does not suit configuration
+ file utils a lot. I haven't found any clean hook to apply something
+ before then after configuration file processing. Also what about
+ .htaccess files?
+
+ Thus I think that server/util.c or server/config.c
+ would be a better place for this stuff.
+*/
+
+AP_DECLARE_MODULE(macro) = {
+ STANDARD20_MODULE_STUFF, /* common stuff */
+ NULL, /* create per-directory config */
+ NULL, /* merge per-directory config structures */
+ NULL, /* create per-server config structure */
+ NULL, /* merge per-server config structures */
+ macro_cmds, /* configuration commands */
+ NULL /* register hooks */
+};
diff --git a/modules/core/test/Makefile b/modules/core/test/Makefile
new file mode 100755
index 0000000000..d5a54fb415
--- /dev/null
+++ b/modules/core/test/Makefile
@@ -0,0 +1,69 @@
+#
+# $Id$
+#
+# mod_macro non regression tests
+
+# where is apache
+APA.dir = /tmp/apache
+
+# apache executable with mod macro loaded
+HTTPD = \
+ $(APA.dir)/bin/httpd \
+ -C 'LoadModule macro_module modules/mod_macro.so' \
+ -C "Define PWD $$PWD/conf"
+
+# default target
+.PHONY: default
+default: clean
+
+# run all non regression tests
+.PHONY: check
+check: check-out
+
+# result directory
+OUT = out
+out:
+ mkdir $@
+
+# test cases & results
+F.conf = $(wildcard conf/test*.conf)
+F.out = $(F.conf:conf/%.conf=$(OUT)/%.out)
+
+# run all tests
+.PHONY: run-test
+run-test: $(F.out)
+
+# generate & compare in a separate directory
+.PHONY: check-out
+check-out: out
+ $(RM) out/*.out
+ $(MAKE) OUT=out run-test
+ diff -r out/ ref/
+
+# generate & compare in the same directory
+.PHONY: check-ref
+check-ref:
+ $(RM) ref/*.out
+ $(MAKE) OUT=ref run-test
+ svn diff ref/
+
+# run one test case
+# filter output so that it is portable
+# use '|' sed separator because $PWD will contain plenty '/'
+$(OUT)/%.out: conf/%.conf
+ { \
+ echo "# testing with $<" ; \
+ $(HTTPD) -f $$PWD/$< 2>&1 ; \
+ echo "# exit: $$?" ; \
+ } > $@.tmp ; \
+ sed -e "s|$$PWD|.|g" \
+ -e "s|^\[[\.a-zA-Z0-9 :]*\] ||" \
+ -e "s|\[pid [0-9]*:tid [0-9]*] ||" \
+ $@.tmp > $@ ; \
+ $(RM) $@.tmp
+
+# cleanup
+.PHONY: clean
+clean:
+ $(RM) *~
+ $(RM) -r out
diff --git a/modules/core/test/conf/inc63_1.conf b/modules/core/test/conf/inc63_1.conf
new file mode 100644
index 0000000000..6a436f9c2f
--- /dev/null
+++ b/modules/core/test/conf/inc63_1.conf
@@ -0,0 +1,5 @@
+# macro for include
+<Macro Foo $where>
+ Warning "Foo macro at $where"
+</Macro>
+Use Foo "inc63_.conf:5"
diff --git a/modules/core/test/conf/inc63_2.conf b/modules/core/test/conf/inc63_2.conf
new file mode 100644
index 0000000000..3a0da9ea1e
--- /dev/null
+++ b/modules/core/test/conf/inc63_2.conf
@@ -0,0 +1,3 @@
+# use macro defined elsewhere
+Use Foo "inc63_2.conf:2"
+Use Bla "inc63_2.conf:3"
diff --git a/modules/core/test/conf/test01.conf b/modules/core/test/conf/test01.conf
new file mode 100755
index 0000000000..9a3d9abb20
--- /dev/null
+++ b/modules/core/test/conf/test01.conf
@@ -0,0 +1,3 @@
+# no macro name
+<Macro>
+</Macro>
diff --git a/modules/core/test/conf/test02.conf b/modules/core/test/conf/test02.conf
new file mode 100755
index 0000000000..1fe4b41220
--- /dev/null
+++ b/modules/core/test/conf/test02.conf
@@ -0,0 +1,3 @@
+# no macro name and spaces
+<Macro >
+</Macro>
diff --git a/modules/core/test/conf/test03.conf b/modules/core/test/conf/test03.conf
new file mode 100755
index 0000000000..fdcf4c8cac
--- /dev/null
+++ b/modules/core/test/conf/test03.conf
@@ -0,0 +1,5 @@
+# use undefined macro
+<Macro foo>
+ Warning "macro foo"
+</Macro>
+Use bla
diff --git a/modules/core/test/conf/test04.conf b/modules/core/test/conf/test04.conf
new file mode 100755
index 0000000000..8228775457
--- /dev/null
+++ b/modules/core/test/conf/test04.conf
@@ -0,0 +1,5 @@
+# wrong args
+<Macro foo>
+ Warning "macro foo"
+</Macro>
+Use foo hello
diff --git a/modules/core/test/conf/test05.conf b/modules/core/test/conf/test05.conf
new file mode 100755
index 0000000000..2166acaedd
--- /dev/null
+++ b/modules/core/test/conf/test05.conf
@@ -0,0 +1,5 @@
+# wrong args
+<Macro foo $premier>
+ Warning "macro foo $premier"
+</Macro>
+Use foo
diff --git a/modules/core/test/conf/test06.conf b/modules/core/test/conf/test06.conf
new file mode 100755
index 0000000000..35e6b684b4
--- /dev/null
+++ b/modules/core/test/conf/test06.conf
@@ -0,0 +1,6 @@
+# wrong args
+<Macro foo $premier>
+ Warning "macro foo $premier"
+</Macro>
+Use foo one two
+
diff --git a/modules/core/test/conf/test07.conf b/modules/core/test/conf/test07.conf
new file mode 100755
index 0000000000..06f050e4a1
--- /dev/null
+++ b/modules/core/test/conf/test07.conf
@@ -0,0 +1,3 @@
+# missing end macro
+<Macro foo $premier>
+hello
diff --git a/modules/core/test/conf/test08.conf b/modules/core/test/conf/test08.conf
new file mode 100755
index 0000000000..333dbd9bea
--- /dev/null
+++ b/modules/core/test/conf/test08.conf
@@ -0,0 +1,3 @@
+# missing begin macro
+ServerName hello
+</Macro>
diff --git a/modules/core/test/conf/test09.conf b/modules/core/test/conf/test09.conf
new file mode 100755
index 0000000000..2513b6ebd2
--- /dev/null
+++ b/modules/core/test/conf/test09.conf
@@ -0,0 +1,6 @@
+# recursion is bad
+<Macro foo>
+Use foo
+</Macro>
+
+Use foo
diff --git a/modules/core/test/conf/test10.conf b/modules/core/test/conf/test10.conf
new file mode 100755
index 0000000000..157129d01c
--- /dev/null
+++ b/modules/core/test/conf/test10.conf
@@ -0,0 +1,10 @@
+# indirect recursion is bad
+<Macro foo>
+Use bla
+</Macro>
+
+<Macro bla>
+Use foo
+</Macro>
+
+Use foo
diff --git a/modules/core/test/conf/test11.conf b/modules/core/test/conf/test11.conf
new file mode 100755
index 0000000000..f397ec63b4
--- /dev/null
+++ b/modules/core/test/conf/test11.conf
@@ -0,0 +1,15 @@
+# inner macros...
+<Macro foo $arg>
+<Macro $arg.in>
+Warning "macro $arg.in line 1"
+</Macro>
+</Macro>
+
+# generate a one.in macro
+Use foo one
+
+# use it!
+Use one.in
+
+# end processing
+Error "done line 15."
diff --git a/modules/core/test/conf/test12.conf b/modules/core/test/conf/test12.conf
new file mode 100755
index 0000000000..84403c6cbb
--- /dev/null
+++ b/modules/core/test/conf/test12.conf
@@ -0,0 +1,12 @@
+# multiply defined generates a warning
+<Macro foo>
+ Warning "macro foo 1, line 1"
+</Macro>
+
+<Macro foo>
+ Warning "macro foo 2, line 1"
+</Macro>
+
+Use foo
+
+Error "done line 12."
diff --git a/modules/core/test/conf/test13.conf b/modules/core/test/conf/test13.conf
new file mode 100755
index 0000000000..244470df4a
--- /dev/null
+++ b/modules/core/test/conf/test13.conf
@@ -0,0 +1,18 @@
+# case insensitive
+<Macro FOO>
+ Warning "macro FOO line 1"
+</MACRO>
+
+<MACRO bla>
+ Warning "macro bla line 1"
+</macro>
+
+use foo
+
+<macro foo>
+ Warning "redefined macro foo line 1"
+</macro>
+
+use FOO
+
+Error "done line 18."
diff --git a/modules/core/test/conf/test14.conf b/modules/core/test/conf/test14.conf
new file mode 100755
index 0000000000..48d888892c
--- /dev/null
+++ b/modules/core/test/conf/test14.conf
@@ -0,0 +1,23 @@
+# VirtualHost example
+
+<Macro MyVirtualHost $host $port $dir>
+ Listen $port
+ <VirtualHost $host:$port>
+ DocumentRoot $dir
+ <Directory $dir>
+ Warning "directory $dir"
+ </Directory>
+ # limit access to intranet subdir.
+ <Directory $dir/intranet>
+ Warning "directory $dir/intranet"
+ </Directory>
+ </VirtualHost>
+</Macro>
+
+Use MyVirtualHost www.apache.org 80 /projects/apache/web
+
+Use MyVirtualHost www.perl.com 8080 /projects/perl/web
+
+Use MyVirtualHost www.ensmp.fr 1234 /projects/mines/web
+
+Error "done line 23."
diff --git a/modules/core/test/conf/test15.conf b/modules/core/test/conf/test15.conf
new file mode 100755
index 0000000000..7990e1549a
--- /dev/null
+++ b/modules/core/test/conf/test15.conf
@@ -0,0 +1,9 @@
+# non nested...
+<macro test>
+<directory /tmp>
+</macro>
+
+use test
+</directory>
+
+Error should not reach this point.
diff --git a/modules/core/test/conf/test16.conf b/modules/core/test/conf/test16.conf
new file mode 100755
index 0000000000..471f66e679
--- /dev/null
+++ b/modules/core/test/conf/test16.conf
@@ -0,0 +1,11 @@
+# bad nesting
+
+<Macro foo>
+</Limit>
+</Macro>
+
+<Limit GET>
+Use foo
+</Limit>
+
+stop
diff --git a/modules/core/test/conf/test17.conf b/modules/core/test/conf/test17.conf
new file mode 100755
index 0000000000..f6294bbb1e
--- /dev/null
+++ b/modules/core/test/conf/test17.conf
@@ -0,0 +1,10 @@
+# bad but good nesting
+
+<Macro foo>
+</Directory>
+</Macro>
+
+<Directory /tmp>
+Use foo
+
+Error "done on line 10."
diff --git a/modules/core/test/conf/test18.conf b/modules/core/test/conf/test18.conf
new file mode 100755
index 0000000000..118617de9c
--- /dev/null
+++ b/modules/core/test/conf/test18.conf
@@ -0,0 +1,10 @@
+# bad but good nesting
+
+<Macro foo>
+</Location>
+</Macro>
+
+<Location /intranet>
+Use foo
+
+Error "done on line 10."
diff --git a/modules/core/test/conf/test19.conf b/modules/core/test/conf/test19.conf
new file mode 100755
index 0000000000..6568e968bd
--- /dev/null
+++ b/modules/core/test/conf/test19.conf
@@ -0,0 +1,26 @@
+# okay till done
+
+<Macro foo $where>
+ # something
+ Warning "macro foo line 2 in $where"
+</Macro>
+
+<Directory /tmp>
+ Use foo Directory
+</Directory>
+
+<Location /intra>
+ Use foo Location
+</Location>
+
+<VirtualHost www.apache.org>
+ Use foo VirtualHost
+</VirtualHost>
+
+<VirtualHost www.perl.com>
+ <Directory /tmp>
+ Use foo "VirtualHost & Directory"
+ </Directory>
+</VirtualHost>
+
+Error "done line 26."
diff --git a/modules/core/test/conf/test20.conf b/modules/core/test/conf/test20.conf
new file mode 100755
index 0000000000..ccbae0d384
--- /dev/null
+++ b/modules/core/test/conf/test20.conf
@@ -0,0 +1,11 @@
+# directory in directory through a macro
+
+<Macro foo $dir>
+ <Directory $dir>
+ Warning "macro foo $dir"
+ </Directory>
+</Macro>
+
+<Directory /tmp>
+ Use foo /tmp
+</Directory>
diff --git a/modules/core/test/conf/test21.conf b/modules/core/test/conf/test21.conf
new file mode 100755
index 0000000000..7a8c4c9a17
--- /dev/null
+++ b/modules/core/test/conf/test21.conf
@@ -0,0 +1,11 @@
+# raise an error
+
+<Macro foo>
+ <Directory /tmp>
+ Error "macro foo dir /tmp"
+ </Directory>
+</Macro>
+
+<VirtualHost *>
+ Use foo
+</VirtualHost>
diff --git a/modules/core/test/conf/test22.conf b/modules/core/test/conf/test22.conf
new file mode 100755
index 0000000000..5a89f83aa7
--- /dev/null
+++ b/modules/core/test/conf/test22.conf
@@ -0,0 +1,11 @@
+# simple nesting
+
+<Macro foo>
+ <Directory /tmp>
+ Warning "macro foo"
+ </Directory>
+</Macro>
+
+Use foo
+
+Error "done on line 11."
diff --git a/modules/core/test/conf/test23.conf b/modules/core/test/conf/test23.conf
new file mode 100755
index 0000000000..e21e2ee6b5
--- /dev/null
+++ b/modules/core/test/conf/test23.conf
@@ -0,0 +1,15 @@
+# macro defined in a directory
+
+<Directory /tmp>
+ <Macro foo>
+ Warning "macro foo in /tmp"
+ </Macro>
+</Directory>
+
+Use foo
+
+<Directory /tmp>
+ Use foo
+</Directory>
+
+Error "done!"
diff --git a/modules/core/test/conf/test24.conf b/modules/core/test/conf/test24.conf
new file mode 100755
index 0000000000..d35070e60c
--- /dev/null
+++ b/modules/core/test/conf/test24.conf
@@ -0,0 +1,23 @@
+# nesting...
+
+<Macro bla>
+ <Location /intra>
+ Warning "macro bla intra"
+ </Location>
+ <Location /private>
+ Warning "macro bla private"
+ </Location>
+</Macro>
+
+# ok location in config
+Use bla
+
+# ok, location in VH
+<VirtualHost foo.com>
+ Use bla
+</VirtualHost>
+
+<Directory /tmp>
+ # fails: Location within an Directory
+ Use bla
+</Directory>
diff --git a/modules/core/test/conf/test25.conf b/modules/core/test/conf/test25.conf
new file mode 100755
index 0000000000..724cf94265
--- /dev/null
+++ b/modules/core/test/conf/test25.conf
@@ -0,0 +1,27 @@
+# ok till stop.
+
+<Macro RestrictedAccessPolicy $ips>
+ Warning "restricted access policy $ips"
+</Macro>
+
+<Directory /unexpected/1>
+ Use RestrictedAccessPolicy 10.0.0.0/8
+</Directory>
+
+<Macro LocalAccessOnly>
+ Use RestrictedAccessPolicy 10.0.0.0/8
+</Macro>
+
+<Directory /unexpected/2>
+ Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24 10.0.0.0/8"
+</Directory>
+
+<Location /intra>
+ Use LocalAccessOnly
+</Location>
+
+<Location /admin>
+ Use LocalAccessOnly
+</Location>
+
+Error "done line 27."
diff --git a/modules/core/test/conf/test26.conf b/modules/core/test/conf/test26.conf
new file mode 100755
index 0000000000..bb4b5ad037
--- /dev/null
+++ b/modules/core/test/conf/test26.conf
@@ -0,0 +1,19 @@
+# ok till stop.
+# test quotes...
+
+<Macro funny "first arg" 'second ... arg'>
+ <Directory first arg>
+ Warning "funny directory"
+ </Directory>
+ <Location second ... arg>
+ Warning "funny location"
+ </Location>
+</Macro>
+
+Use funny /unexpected/1 /intra
+
+<VirtualHost www.apache.org>
+ Use funny /unexpected/2 /intranet
+</VirtualHost>
+
+Error "done!"
diff --git a/modules/core/test/conf/test27.conf b/modules/core/test/conf/test27.conf
new file mode 100755
index 0000000000..2f3e83c7a0
--- /dev/null
+++ b/modules/core/test/conf/test27.conf
@@ -0,0 +1,22 @@
+# define a macro in a macro.
+
+<Macro foo $dir $name>
+ <Macro foo.$name>
+ <Directory $dir>
+ Warning "foo.$name $dir"
+ </Directory>
+ </Macro>
+</Macro>
+
+Use foo /unexpected/1 one
+Use foo /unexpected/2 two
+
+Use foo.one
+Use foo.two
+Use foo.one
+
+UndefMacro foo.one
+UndefMacro foo.two
+UndefMacro foo
+
+Error "done!"
diff --git a/modules/core/test/conf/test28.conf b/modules/core/test/conf/test28.conf
new file mode 100755
index 0000000000..69c1c9b633
--- /dev/null
+++ b/modules/core/test/conf/test28.conf
@@ -0,0 +1,13 @@
+# interaction with IfModule
+
+<IfModule mod_macro.c>
+ <Macro foo>
+ Warning "macro foo"
+ </Macro>
+
+ Use foo
+
+ Error "done!"
+</IfModule>
+
+Error "should not get there"
diff --git a/modules/core/test/conf/test29.conf b/modules/core/test/conf/test29.conf
new file mode 100755
index 0000000000..7d1f380f71
--- /dev/null
+++ b/modules/core/test/conf/test29.conf
@@ -0,0 +1,10 @@
+# trigger line overflow during expansion
+
+<Macro toobigaline a>
+ Warning aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</Macro>
+
+Use toobigaline "cette ligne va etre vraiment trop longue ya pas de doute"
+
+Error "should not get there!"
diff --git a/modules/core/test/conf/test30.conf b/modules/core/test/conf/test30.conf
new file mode 100755
index 0000000000..72b2bb2c99
--- /dev/null
+++ b/modules/core/test/conf/test30.conf
@@ -0,0 +1,12 @@
+# name conficts: the longest is chosen
+# also test a parametric section
+
+<Macro foo $dir $directive>
+ <$directive $dir>
+ Warning "section $directive $dir"
+ </$directive>
+</Macro>
+
+Use foo /unexpected/1 Directory
+
+Error "done!"
diff --git a/modules/core/test/conf/test31.conf b/modules/core/test/conf/test31.conf
new file mode 100755
index 0000000000..14964ba372
--- /dev/null
+++ b/modules/core/test/conf/test31.conf
@@ -0,0 +1,16 @@
+# parameter name conflicts
+
+<Macro bla $dir $di $dd $d>
+ Warning "argument name conflicts"
+ $d $di $dir $dd
+</Macro>
+
+Use bla '' '' 8080 Listen
+
+<Macro foo $d $di $dir $dd>
+ Warning "conflicts, but arguments are not used"
+</Macro>
+
+Use foo '' '' 8080 Listen
+
+Error "done on line 16."
diff --git a/modules/core/test/conf/test32.conf b/modules/core/test/conf/test32.conf
new file mode 100755
index 0000000000..0b116eca98
--- /dev/null
+++ b/modules/core/test/conf/test32.conf
@@ -0,0 +1,7 @@
+# error if same argument name.
+
+<Macro foo $arg1 $arg2 $arg3 $arg2>
+# bad
+</Macro>
+
+
diff --git a/modules/core/test/conf/test33.conf b/modules/core/test/conf/test33.conf
new file mode 100755
index 0000000000..2a8a6dba61
--- /dev/null
+++ b/modules/core/test/conf/test33.conf
@@ -0,0 +1,3 @@
+# empty name.
+
+Use ''
diff --git a/modules/core/test/conf/test34.conf b/modules/core/test/conf/test34.conf
new file mode 100755
index 0000000000..1f4671f46a
--- /dev/null
+++ b/modules/core/test/conf/test34.conf
@@ -0,0 +1,14 @@
+# macro parameter prefix conflicts in two orders
+
+<Macro foo $d $dd>
+ Warning "macro foo conflict one"
+</Macro>
+
+<Macro bla $dd $d>
+ Warning "macro bla conflict two"
+</Macro>
+
+Use foo 1 2
+Use bla 1 2
+
+Error "done on line 14."
diff --git a/modules/core/test/conf/test35.conf b/modules/core/test/conf/test35.conf
new file mode 100755
index 0000000000..37a623ed59
--- /dev/null
+++ b/modules/core/test/conf/test35.conf
@@ -0,0 +1,10 @@
+# unused arguments
+
+<Macro warnings u1 u2 n1 n2 u3>
+ Warning "macro cannot be used just within a comment u1 u2 u3"
+ # n1 n2
+</Macro>
+
+Use warnings 1 2 3 4 5
+
+Error "done on line 10."
diff --git a/modules/core/test/conf/test36.conf b/modules/core/test/conf/test36.conf
new file mode 100755
index 0000000000..a68667e10d
--- /dev/null
+++ b/modules/core/test/conf/test36.conf
@@ -0,0 +1,12 @@
+<Macro warnings $u $n $u1 $n1 $u2 $n2>
+ Warning "many warnings! $u $u1 $u2"
+ # $n $n1 $n2
+</Macro>
+
+# warn about unused arguments
+Use warnings 1 2 3 4 5 6
+
+# may warn about empty arguments?
+Use warnings '' '' '' '' '' ''
+
+Error "done!"
diff --git a/modules/core/test/conf/test37.conf b/modules/core/test/conf/test37.conf
new file mode 100755
index 0000000000..296dde75ef
--- /dev/null
+++ b/modules/core/test/conf/test37.conf
@@ -0,0 +1,7 @@
+# empty argument name
+
+<Macro stupid ''>
+ Warn "macro stupid"
+</Macro>
+
+Use stupid hello
diff --git a/modules/core/test/conf/test38.conf b/modules/core/test/conf/test38.conf
new file mode 100755
index 0000000000..184763f09e
--- /dev/null
+++ b/modules/core/test/conf/test38.conf
@@ -0,0 +1,10 @@
+# ifmodule
+
+<IfModule mod_macro.c>
+Warning it is really a good idea to have mod_macro.c installed.
+</IfModule>
+
+<IfModule !mod_perl.c>
+Error it seems you do not have mod perl installed.
+</IfModule>
+
diff --git a/modules/core/test/conf/test39.conf b/modules/core/test/conf/test39.conf
new file mode 100755
index 0000000000..792232f2eb
--- /dev/null
+++ b/modules/core/test/conf/test39.conf
@@ -0,0 +1,23 @@
+# okay till stop.
+
+<IfModule mod_macro.c>
+ <Macro ModMacro>
+ Warning Thanks for using mod_macro!
+ </Macro>
+</IfModule>
+
+<IfModule !mod_macro.c>
+ <Macro ModMacro>
+ Error Sorry, mod_macro must be installed to run this configuration file.
+ </Macro>
+</IfModule>
+
+Use ModMacro
+
+<Macro foo>
+ Warning "macro foo"
+</Macro>
+
+Use foo
+
+Error "done!"
diff --git a/modules/core/test/conf/test40.conf b/modules/core/test/conf/test40.conf
new file mode 100755
index 0000000000..e6b81f7a6f
--- /dev/null
+++ b/modules/core/test/conf/test40.conf
@@ -0,0 +1,33 @@
+# configuration example with mod_macro
+#
+
+<VirtualHost www.foo.com>
+ DocumentRoot /foo/document/root/directory
+
+ <Macro SubDirAccessControl $subdir>
+ # access control to subdirs...
+ <Location /$subdir>
+ Warning "location /$subdir"
+ </Location>
+ </Macro>
+
+ # repeat uses
+ Use SubDirAccessControl A
+ Use SubDirAccessControl B
+ Use SubDirAccessControl C
+ Use SubDirAccessControl D
+ Use SubDirAccessControl E
+ Use SubDirAccessControl G
+ Use SubDirAccessControl H
+ Use SubDirAccessControl J
+ Use SubDirAccessControl K
+ Use SubDirAccessControl L
+ Use SubDirAccessControl M
+ Use SubDirAccessControl N
+
+ # cleanup
+ UndefMacro SubDirAccessControl
+
+</VirtualHost>
+
+Error Stop configuration file processing.
diff --git a/modules/core/test/conf/test41.conf b/modules/core/test/conf/test41.conf
new file mode 100755
index 0000000000..c4e6bdbe56
--- /dev/null
+++ b/modules/core/test/conf/test41.conf
@@ -0,0 +1,20 @@
+# another configuration example without mod_macro
+
+<VirtualHost www.foo.com>
+ DocumentRoot /foo/document/root/directory
+
+ <Location /A>
+ Warning "location /A"
+ </Location>
+
+ <Location /B>
+ Warning "location /B"
+ </Location>
+
+ <Location /C>
+ Warning "location /C"
+ </Location>
+
+</VirtualHost>
+
+Error Stop configuration file processing.
diff --git a/modules/core/test/conf/test42.conf b/modules/core/test/conf/test42.conf
new file mode 100755
index 0000000000..a1426041c3
--- /dev/null
+++ b/modules/core/test/conf/test42.conf
@@ -0,0 +1,13 @@
+# multiple macro uses
+
+<Macro foo $p>
+ Warning "macro foo $p"
+</Macro>
+
+Use foo ''
+Use foo ''
+Use foo ''
+Use foo ''
+Use foo ''
+
+Error "done on line 13."
diff --git a/modules/core/test/conf/test43.conf b/modules/core/test/conf/test43.conf
new file mode 100755
index 0000000000..264b916776
--- /dev/null
+++ b/modules/core/test/conf/test43.conf
@@ -0,0 +1,29 @@
+# non necessarily nested.
+
+<Macro begindir $dir>
+<Directory $dir>
+# hello
+</Macro>
+
+<Macro enddir>
+</Directory>
+</Macro>
+
+Use begindir /unexpected/1
+Use enddir
+
+
+Use begindir /unexpected/2
+Use enddir
+
+Use begindir /unexpected/3
+<Limit GET>
+</Limit>
+Use enddir
+
+<VirtualHost foo.com>
+Use begindir /unexpected/4
+Use enddir
+</VirtualHost>
+
+Error ok!
diff --git a/modules/core/test/conf/test44.conf b/modules/core/test/conf/test44.conf
new file mode 100755
index 0000000000..ef4883eb55
--- /dev/null
+++ b/modules/core/test/conf/test44.conf
@@ -0,0 +1,19 @@
+# working recursion...
+
+<Macro foo>
+use bla
+</Macro>
+
+<Macro bla>
+<IfDefine NoFoo>
+use foo
+</IfDefine>
+</Macro>
+
+
+<IfDefine !NoFoo>
+# foo gonna call bla, bla wont call foo back...
+use foo
+</IfDefine>
+
+Error okay.
diff --git a/modules/core/test/conf/test45.conf b/modules/core/test/conf/test45.conf
new file mode 100755
index 0000000000..039493589c
--- /dev/null
+++ b/modules/core/test/conf/test45.conf
@@ -0,0 +1,7 @@
+# strange chars
+
+<Macro warnings $1 %2 &3 @4 #5 ~6 *7 .8 ,9 !a -b +c =d :e ;f ?g>
+# hello $1 %2 &3 @4 #5 ~6 *7 .8 ,9 !a -b +c =d :e ;f ?g
+</Macro>
+
+Error "done on line 7."
diff --git a/modules/core/test/conf/test46.conf b/modules/core/test/conf/test46.conf
new file mode 100755
index 0000000000..50520ed7e2
--- /dev/null
+++ b/modules/core/test/conf/test46.conf
@@ -0,0 +1,11 @@
+# various working prefixes
+
+<Macro $i %j @k>
+# hello %j @k
+</Macro>
+
+<Macro warnings $i second>
+# not used.
+</Macro>
+
+Error okay.
diff --git a/modules/core/test/conf/test47.conf b/modules/core/test/conf/test47.conf
new file mode 100755
index 0000000000..6e736641dd
--- /dev/null
+++ b/modules/core/test/conf/test47.conf
@@ -0,0 +1,15 @@
+# empty macro contents...
+
+<Macro foo>
+</Macro>
+
+Use foo
+
+<Macro bla $i>
+</Macro>
+
+<Macro bof $i>
+# some contents...
+</Macro>
+
+Error okay.
diff --git a/modules/core/test/conf/test48.conf b/modules/core/test/conf/test48.conf
new file mode 100755
index 0000000000..96bf461556
--- /dev/null
+++ b/modules/core/test/conf/test48.conf
@@ -0,0 +1,23 @@
+# test substitution...
+
+<Macro M %premier>
+Warning %premier
+</Macro>
+
+Use M 1
+Use M 12
+Use M 123
+Use M 1234
+Use M 12345
+Use M 123456
+Use M 1234567
+Use M 12345678
+Use M 123456789
+Use M 1234567890
+Use M 1234567890a
+Use M 1234567890ab
+Use M 1234567890abc
+Use M 1234567890abcd
+Use M 1234567890abcde
+
+Error "done line 23."
diff --git a/modules/core/test/conf/test49.conf b/modules/core/test/conf/test49.conf
new file mode 100644
index 0000000000..7a21c823ac
--- /dev/null
+++ b/modules/core/test/conf/test49.conf
@@ -0,0 +1,2 @@
+# undef macro before anything
+UndefMacro foo
diff --git a/modules/core/test/conf/test50.conf b/modules/core/test/conf/test50.conf
new file mode 100644
index 0000000000..33dd359f9a
--- /dev/null
+++ b/modules/core/test/conf/test50.conf
@@ -0,0 +1,5 @@
+# undef non existing macro
+<Macro foo>
+ Warning "foo macro"
+</Macro>
+UndefMacro bla
diff --git a/modules/core/test/conf/test51.conf b/modules/core/test/conf/test51.conf
new file mode 100644
index 0000000000..50214fa3c8
--- /dev/null
+++ b/modules/core/test/conf/test51.conf
@@ -0,0 +1,9 @@
+# undef existing macro, and try to use it
+<Macro foo>
+ Warning "foo macro contents"
+</Macro>
+# expanded, but will not be processed because of error
+Use foo
+UndefMacro foo
+# error, does not exist anymore
+Use foo
diff --git a/modules/core/test/conf/test52.conf b/modules/core/test/conf/test52.conf
new file mode 100644
index 0000000000..bb77c73770
--- /dev/null
+++ b/modules/core/test/conf/test52.conf
@@ -0,0 +1,8 @@
+# undef existing macro, and try to use it
+<Macro foo>
+ Warning "foo macro contents line 1"
+</Macro>
+Use foo
+UndefMacro foo
+
+Error "done line 8."
diff --git a/modules/core/test/conf/test53.conf b/modules/core/test/conf/test53.conf
new file mode 100755
index 0000000000..08e8c988b3
--- /dev/null
+++ b/modules/core/test/conf/test53.conf
@@ -0,0 +1,2 @@
+# use undefined macro without prior definition
+Use bla
diff --git a/modules/core/test/conf/test54.conf b/modules/core/test/conf/test54.conf
new file mode 100644
index 0000000000..7dd30aca5f
--- /dev/null
+++ b/modules/core/test/conf/test54.conf
@@ -0,0 +1,6 @@
+# empty macro
+<Macro foo>
+</Macro>
+Use foo
+
+Error "done line 6."
diff --git a/modules/core/test/conf/test55.conf b/modules/core/test/conf/test55.conf
new file mode 100644
index 0000000000..bd978e98b3
--- /dev/null
+++ b/modules/core/test/conf/test55.conf
@@ -0,0 +1,11 @@
+# line numbers...
+<Macro foo $where>
+ Warning "macro foo(:2) line 1 ($where)"
+</Macro>
+<Macro bla $where>
+ Warning "macro bla(:5) line 1 ($where)"
+ Use foo "bla line 2"
+</Macro>
+Use foo "file line 9"
+Use bla "file line 10"
+Error "done line 11."
diff --git a/modules/core/test/conf/test56.conf b/modules/core/test/conf/test56.conf
new file mode 100644
index 0000000000..b7366a28a9
--- /dev/null
+++ b/modules/core/test/conf/test56.conf
@@ -0,0 +1,18 @@
+# nesting warnings
+<Macro Open $dir>
+ <Directory $dir>
+ Warning "Open:2 $dir"
+</Macro>
+<Macro Close>
+ Warning "Close:1"
+ </Directory>
+</Macro>
+
+# some uses
+Use Open /tmp
+Use Close
+
+Use Open /etc
+Use Close
+
+Error "done line 18."
diff --git a/modules/core/test/conf/test57.conf b/modules/core/test/conf/test57.conf
new file mode 100644
index 0000000000..7c36868b84
--- /dev/null
+++ b/modules/core/test/conf/test57.conf
@@ -0,0 +1,4 @@
+# empty argument name
+<Macro foo $x ''>
+ Warning "macro foo line 1"
+</Macro>
diff --git a/modules/core/test/conf/test58.conf b/modules/core/test/conf/test58.conf
new file mode 100644
index 0000000000..6c8a2eb76e
--- /dev/null
+++ b/modules/core/test/conf/test58.conf
@@ -0,0 +1,4 @@
+# bad directive closing
+<Macro foo
+ Warning "macro foo line 1"
+</Macro>
diff --git a/modules/core/test/conf/test59.conf b/modules/core/test/conf/test59.conf
new file mode 100644
index 0000000000..9f43d7d3fe
--- /dev/null
+++ b/modules/core/test/conf/test59.conf
@@ -0,0 +1,4 @@
+# empty name
+<Macro ''>
+ Warning "empty quoted name macro"
+</Macro>
diff --git a/modules/core/test/conf/test60.conf b/modules/core/test/conf/test60.conf
new file mode 100644
index 0000000000..969a4ebe10
--- /dev/null
+++ b/modules/core/test/conf/test60.conf
@@ -0,0 +1,17 @@
+# @ escaping
+<Macro Foo $one $two>
+ Warning "macro Foo arg 1: $one"
+ Warning "macro Foo arg 2: $two"
+</Macro>
+<Macro Bla @first @second>
+ Warning Macro Bla arg 1: @first
+ Warning Macro Bla arg 2: @second
+ Use Foo @first 'second'
+ Use Foo 'first' @second
+ Use Foo @first @second
+</Macro>
+
+Use Foo hello world
+Use Bla "hello world" "thank you"
+
+Error "done on line 17."
diff --git a/modules/core/test/conf/test61.conf b/modules/core/test/conf/test61.conf
new file mode 100644
index 0000000000..cd2859780f
--- /dev/null
+++ b/modules/core/test/conf/test61.conf
@@ -0,0 +1,18 @@
+# deep expansion
+<Macro F1 $x>
+ Warning "F1:1 x=$x"
+</Macro>
+<Macro F2 $x>
+ Warning "F2:1 x=$x"
+ Use F1 $x
+</Macro>
+<Macro F3 $x>
+ Warning "F3:1 x=$x"
+ Use F2 $x
+</Macro>
+<Macro F4 $x>
+ Warning "F4:1 x=$x"
+ Use F3 $x
+</Macro>
+Use F4 "line=17"
+Error "done line 18."
diff --git a/modules/core/test/conf/test62.conf b/modules/core/test/conf/test62.conf
new file mode 100644
index 0000000000..9d611de5da
--- /dev/null
+++ b/modules/core/test/conf/test62.conf
@@ -0,0 +1,25 @@
+# test continuations
+<Macro Line \
+ $start \
+ $stop>
+ Warning \
+ "Line:1-2 start at $start"
+ Warning \
+ "Line:3-4 stop at $stop"
+</Macro>
+
+Use Line 11 11
+Use Line \
+ 12 13
+Use Line \
+ 14 \
+ 16
+Use Line 17 \
+ 18
+Use Line \
+ \
+ 19 \
+ \
+ 23
+
+Error "done line 25."
diff --git a/modules/core/test/conf/test63.conf b/modules/core/test/conf/test63.conf
new file mode 100644
index 0000000000..7988ae4416
--- /dev/null
+++ b/modules/core/test/conf/test63.conf
@@ -0,0 +1,9 @@
+# include
+include ${PWD}/inc63_1.conf
+Use Foo "test63.conf:3"
+<Macro Bla $where>
+ Warning "Bla at $where"
+</Macro>
+include ${PWD}/inc63_2.conf
+Use Bla "test63.conf:8"
+Error "done at line 9."
diff --git a/modules/core/test/conf/test64.conf b/modules/core/test/conf/test64.conf
new file mode 100644
index 0000000000..6c123281d6
--- /dev/null
+++ b/modules/core/test/conf/test64.conf
@@ -0,0 +1,5 @@
+# just continuations
+Warning "on line 2"
+Warning \
+ "from line 3 to line 4"
+Error "done on line 5."
diff --git a/modules/core/test/conf/test65.conf b/modules/core/test/conf/test65.conf
new file mode 100644
index 0000000000..df9adc3222
--- /dev/null
+++ b/modules/core/test/conf/test65.conf
@@ -0,0 +1,11 @@
+# simple use continuation
+<Macro Line $line>
+ # first macro line is a comment
+ Warning "Line: $line"
+</Macro>
+Use Line \
+ "on line 6-7"
+Use \
+ Line \
+ "on line 8-10"
+Error "done on line 11."
diff --git a/modules/core/test/conf/test66.conf b/modules/core/test/conf/test66.conf
new file mode 100644
index 0000000000..a14e58782d
--- /dev/null
+++ b/modules/core/test/conf/test66.conf
@@ -0,0 +1,7 @@
+# no double substitution
+<Macro Foo $x $y>
+ Warning "Foo: x=$x y=$y"
+</Macro>
+Use Foo X Y
+Use Foo "$y" "$x"
+Error "done on line 7."
diff --git a/modules/core/test/conf/test67.conf b/modules/core/test/conf/test67.conf
new file mode 100644
index 0000000000..04a5d3d95d
--- /dev/null
+++ b/modules/core/test/conf/test67.conf
@@ -0,0 +1 @@
+Error "done at line 1 without LF." \ No newline at end of file
diff --git a/modules/core/test/conf/test68.conf b/modules/core/test/conf/test68.conf
new file mode 100644
index 0000000000..2a7b85bd9f
--- /dev/null
+++ b/modules/core/test/conf/test68.conf
@@ -0,0 +1,5 @@
+# two directives with continuations & no eol at eof
+Warning \
+ "line 2-3"
+Error \
+ "done on line 4-5." \ No newline at end of file
diff --git a/modules/core/test/conf/test69.conf b/modules/core/test/conf/test69.conf
new file mode 100644
index 0000000000..11a083001d
--- /dev/null
+++ b/modules/core/test/conf/test69.conf
@@ -0,0 +1,14 @@
+# warn if ignored non-blank stuff after closing '>'
+<Macro Foo> this stuff is ignored...
+ Warning "Foo"
+</Macro> this stuff is ignored as well...
+Use Foo
+<Macro Bla>
+ Warning "Bla"
+</Macro>
+Use Bla
+<Macro Comments> # comments are fine
+ Warning "Comments"
+</Macro> # comments are fine
+Use Comments
+Error "done on line 14."
diff --git a/modules/core/test/ref/test01.out b/modules/core/test/ref/test01.out
new file mode 100644
index 0000000000..9ea6665718
--- /dev/null
+++ b/modules/core/test/ref/test01.out
@@ -0,0 +1,3 @@
+# testing with conf/test01.conf
+httpd: Syntax error on line 2 of ./conf/test01.conf: <Macro macro definition: empty name
+# exit: 1
diff --git a/modules/core/test/ref/test02.out b/modules/core/test/ref/test02.out
new file mode 100644
index 0000000000..6b49191300
--- /dev/null
+++ b/modules/core/test/ref/test02.out
@@ -0,0 +1,3 @@
+# testing with conf/test02.conf
+httpd: Syntax error on line 2 of ./conf/test02.conf: <Macro macro definition: empty name
+# exit: 1
diff --git a/modules/core/test/ref/test03.out b/modules/core/test/ref/test03.out
new file mode 100644
index 0000000000..f85790124a
--- /dev/null
+++ b/modules/core/test/ref/test03.out
@@ -0,0 +1,3 @@
+# testing with conf/test03.conf
+httpd: Syntax error on line 5 of ./conf/test03.conf: macro 'bla' undefined
+# exit: 1
diff --git a/modules/core/test/ref/test04.out b/modules/core/test/ref/test04.out
new file mode 100644
index 0000000000..aaa2e6bc88
--- /dev/null
+++ b/modules/core/test/ref/test04.out
@@ -0,0 +1,3 @@
+# testing with conf/test04.conf
+httpd: Syntax error on line 5 of ./conf/test04.conf: macro 'foo' (defined on line 2 of "./conf/test04.conf") used with 1 arguments instead of 0
+# exit: 1
diff --git a/modules/core/test/ref/test05.out b/modules/core/test/ref/test05.out
new file mode 100644
index 0000000000..184c40cd72
--- /dev/null
+++ b/modules/core/test/ref/test05.out
@@ -0,0 +1,3 @@
+# testing with conf/test05.conf
+httpd: Syntax error on line 5 of ./conf/test05.conf: macro 'foo' (defined on line 2 of "./conf/test05.conf") used with 0 arguments instead of 1
+# exit: 1
diff --git a/modules/core/test/ref/test06.out b/modules/core/test/ref/test06.out
new file mode 100644
index 0000000000..221dd057ed
--- /dev/null
+++ b/modules/core/test/ref/test06.out
@@ -0,0 +1,3 @@
+# testing with conf/test06.conf
+httpd: Syntax error on line 5 of ./conf/test06.conf: macro 'foo' (defined on line 2 of "./conf/test06.conf") used with 2 arguments instead of 1
+# exit: 1
diff --git a/modules/core/test/ref/test07.out b/modules/core/test/ref/test07.out
new file mode 100644
index 0000000000..60003ecb58
--- /dev/null
+++ b/modules/core/test/ref/test07.out
@@ -0,0 +1,3 @@
+# testing with conf/test07.conf
+httpd: Syntax error on line 2 of ./conf/test07.conf: macro 'foo' (defined on line 2 of "./conf/test07.conf")\n\tcontents error: expected token not found: </Macro>
+# exit: 1
diff --git a/modules/core/test/ref/test08.out b/modules/core/test/ref/test08.out
new file mode 100644
index 0000000000..124c7a0911
--- /dev/null
+++ b/modules/core/test/ref/test08.out
@@ -0,0 +1,3 @@
+# testing with conf/test08.conf
+httpd: Syntax error on line 3 of ./conf/test08.conf: </Macro> without matching <Macro> section
+# exit: 1
diff --git a/modules/core/test/ref/test09.out b/modules/core/test/ref/test09.out
new file mode 100644
index 0000000000..9af1225559
--- /dev/null
+++ b/modules/core/test/ref/test09.out
@@ -0,0 +1,3 @@
+# testing with conf/test09.conf
+httpd: Syntax error on line 1 of macro 'foo' (defined on line 2 of "./conf/test09.conf") used on line 6 of "./conf/test09.conf": recursive use of macro 'foo' is invalid
+# exit: 1
diff --git a/modules/core/test/ref/test10.out b/modules/core/test/ref/test10.out
new file mode 100644
index 0000000000..4d81abcf71
--- /dev/null
+++ b/modules/core/test/ref/test10.out
@@ -0,0 +1,3 @@
+# testing with conf/test10.conf
+httpd: Syntax error on line 1 of macro 'bla' (defined on line 6 of "./conf/test10.conf") used on line 1 of "macro 'foo' (defined on line 2 of "./conf/test10.conf") used on line 10 of "./conf/test10.conf"": recursive use of macro 'foo' is invalid
+# exit: 1
diff --git a/modules/core/test/ref/test11.out b/modules/core/test/ref/test11.out
new file mode 100644
index 0000000000..d18c95eb5c
--- /dev/null
+++ b/modules/core/test/ref/test11.out
@@ -0,0 +1,6 @@
+# testing with conf/test11.conf
+[core:warn] macro one.in line 1 on line 1 of macro 'one.in' (defined on line 1 of "macro 'foo' (defined on line 2 of "./conf/test11.conf") used on line 9 of "./conf/test11.conf"") used on line 12 of "./conf/test11.conf"
+[core:error] done line 15. on line 15 of ./conf/test11.conf
+AH00526: Syntax error on line 15 of ./conf/test11.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test12.out b/modules/core/test/ref/test12.out
new file mode 100644
index 0000000000..b1ab2348c9
--- /dev/null
+++ b/modules/core/test/ref/test12.out
@@ -0,0 +1,7 @@
+# testing with conf/test12.conf
+[macro:warn] macro 'foo' multiply defined: defined on line 2 of "./conf/test12.conf", redefined on line 6 of "./conf/test12.conf"
+[core:warn] macro foo 2, line 1 on line 1 of macro 'foo' (defined on line 6 of "./conf/test12.conf") used on line 10 of "./conf/test12.conf"
+[core:error] done line 12. on line 12 of ./conf/test12.conf
+AH00526: Syntax error on line 12 of ./conf/test12.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test13.out b/modules/core/test/ref/test13.out
new file mode 100644
index 0000000000..13d501e3b9
--- /dev/null
+++ b/modules/core/test/ref/test13.out
@@ -0,0 +1,8 @@
+# testing with conf/test13.conf
+[macro:warn] macro 'foo' multiply defined: defined on line 2 of "./conf/test13.conf", redefined on line 12 of "./conf/test13.conf"
+[core:warn] macro FOO line 1 on line 1 of macro 'foo' (defined on line 2 of "./conf/test13.conf") used on line 10 of "./conf/test13.conf"
+[core:warn] redefined macro foo line 1 on line 1 of macro 'foo' (defined on line 12 of "./conf/test13.conf") used on line 16 of "./conf/test13.conf"
+[core:error] done line 18. on line 18 of ./conf/test13.conf
+AH00526: Syntax error on line 18 of ./conf/test13.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test14.out b/modules/core/test/ref/test14.out
new file mode 100644
index 0000000000..16507157f1
--- /dev/null
+++ b/modules/core/test/ref/test14.out
@@ -0,0 +1,14 @@
+# testing with conf/test14.conf
+AH00112: Warning: DocumentRoot [/projects/apache/web] does not exist
+[core:warn] directory /projects/apache/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 17 of "./conf/test14.conf"
+[core:warn] directory /projects/apache/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 17 of "./conf/test14.conf"
+AH00112: Warning: DocumentRoot [/projects/perl/web] does not exist
+[core:warn] directory /projects/perl/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 19 of "./conf/test14.conf"
+[core:warn] directory /projects/perl/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 19 of "./conf/test14.conf"
+AH00112: Warning: DocumentRoot [/projects/mines/web] does not exist
+[core:warn] directory /projects/mines/web on line 5 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 21 of "./conf/test14.conf"
+[core:warn] directory /projects/mines/web/intranet on line 8 of macro 'myvirtualhost' (defined on line 3 of "./conf/test14.conf") used on line 21 of "./conf/test14.conf"
+[core:error] done line 23. on line 23 of ./conf/test14.conf
+AH00526: Syntax error on line 23 of ./conf/test14.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test15.out b/modules/core/test/ref/test15.out
new file mode 100644
index 0000000000..b0b82b7bb2
--- /dev/null
+++ b/modules/core/test/ref/test15.out
@@ -0,0 +1,6 @@
+# testing with conf/test15.conf
+[macro:warn] bad cumulated nesting (+1) in macro 'test' (defined on line 2 of "./conf/test15.conf")
+[core:error] should not reach this point. on line 9 of ./conf/test15.conf
+AH00526: Syntax error on line 9 of ./conf/test15.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test16.out b/modules/core/test/ref/test16.out
new file mode 100644
index 0000000000..6e0f9cad1a
--- /dev/null
+++ b/modules/core/test/ref/test16.out
@@ -0,0 +1,5 @@
+# testing with conf/test16.conf
+[macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test16.conf")
+[macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test16.conf")
+httpd: Syntax error on line 9 of ./conf/test16.conf: </Limit> without matching <Limit> section
+# exit: 1
diff --git a/modules/core/test/ref/test17.out b/modules/core/test/ref/test17.out
new file mode 100644
index 0000000000..c6ca16d021
--- /dev/null
+++ b/modules/core/test/ref/test17.out
@@ -0,0 +1,7 @@
+# testing with conf/test17.conf
+[macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test17.conf")
+[macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test17.conf")
+[core:error] done on line 10. on line 10 of ./conf/test17.conf
+AH00526: Syntax error on line 10 of ./conf/test17.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test18.out b/modules/core/test/ref/test18.out
new file mode 100644
index 0000000000..c5cee819df
--- /dev/null
+++ b/modules/core/test/ref/test18.out
@@ -0,0 +1,7 @@
+# testing with conf/test18.conf
+[macro:warn] bad (negative) nesting on line 2 of macro 'foo' (defined on line 3 of "./conf/test18.conf")
+[macro:warn] bad cumulated nesting (-1) in macro 'foo' (defined on line 3 of "./conf/test18.conf")
+[core:error] done on line 10. on line 10 of ./conf/test18.conf
+AH00526: Syntax error on line 10 of ./conf/test18.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test19.out b/modules/core/test/ref/test19.out
new file mode 100644
index 0000000000..411e5694a0
--- /dev/null
+++ b/modules/core/test/ref/test19.out
@@ -0,0 +1,9 @@
+# testing with conf/test19.conf
+[core:warn] macro foo line 2 in Directory on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 9 of "./conf/test19.conf"
+[core:warn] macro foo line 2 in Location on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 13 of "./conf/test19.conf"
+[core:warn] macro foo line 2 in VirtualHost on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 17 of "./conf/test19.conf"
+[core:warn] macro foo line 2 in VirtualHost & Directory on line 1 of macro 'foo' (defined on line 3 of "./conf/test19.conf") used on line 22 of "./conf/test19.conf"
+[core:error] done line 26. on line 26 of ./conf/test19.conf
+AH00526: Syntax error on line 26 of ./conf/test19.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test20.out b/modules/core/test/ref/test20.out
new file mode 100644
index 0000000000..3ce2b6073c
--- /dev/null
+++ b/modules/core/test/ref/test20.out
@@ -0,0 +1,4 @@
+# testing with conf/test20.conf
+AH00526: Syntax error on line 1 of macro 'foo' (defined on line 3 of "./conf/test20.conf") used on line 10 of "./conf/test20.conf":
+<Directory not allowed here
+# exit: 1
diff --git a/modules/core/test/ref/test21.out b/modules/core/test/ref/test21.out
new file mode 100644
index 0000000000..ac8d843b52
--- /dev/null
+++ b/modules/core/test/ref/test21.out
@@ -0,0 +1,5 @@
+# testing with conf/test21.conf
+[core:error] macro foo dir /tmp on line 2 of macro 'foo' (defined on line 3 of "./conf/test21.conf") used on line 10 of "./conf/test21.conf"
+AH00526: Syntax error on line 2 of macro 'foo' (defined on line 3 of "./conf/test21.conf") used on line 10 of "./conf/test21.conf":
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test22.out b/modules/core/test/ref/test22.out
new file mode 100644
index 0000000000..def17dd391
--- /dev/null
+++ b/modules/core/test/ref/test22.out
@@ -0,0 +1,6 @@
+# testing with conf/test22.conf
+[core:warn] macro foo on line 2 of macro 'foo' (defined on line 3 of "./conf/test22.conf") used on line 9 of "./conf/test22.conf"
+[core:error] done on line 11. on line 11 of ./conf/test22.conf
+AH00526: Syntax error on line 11 of ./conf/test22.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test23.out b/modules/core/test/ref/test23.out
new file mode 100644
index 0000000000..827c861a78
--- /dev/null
+++ b/modules/core/test/ref/test23.out
@@ -0,0 +1,7 @@
+# testing with conf/test23.conf
+[core:warn] macro foo in /tmp on line 1 of macro 'foo' (defined on line 4 of "./conf/test23.conf") used on line 9 of "./conf/test23.conf"
+[core:warn] macro foo in /tmp on line 1 of macro 'foo' (defined on line 4 of "./conf/test23.conf") used on line 12 of "./conf/test23.conf"
+[core:error] done! on line 15 of ./conf/test23.conf
+AH00526: Syntax error on line 15 of ./conf/test23.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test24.out b/modules/core/test/ref/test24.out
new file mode 100644
index 0000000000..e5d370dcc6
--- /dev/null
+++ b/modules/core/test/ref/test24.out
@@ -0,0 +1,8 @@
+# testing with conf/test24.conf
+[core:warn] macro bla intra on line 2 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 13 of "./conf/test24.conf"
+[core:warn] macro bla private on line 5 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 13 of "./conf/test24.conf"
+[core:warn] macro bla intra on line 2 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 17 of "./conf/test24.conf"
+[core:warn] macro bla private on line 5 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 17 of "./conf/test24.conf"
+AH00526: Syntax error on line 1 of macro 'bla' (defined on line 3 of "./conf/test24.conf") used on line 22 of "./conf/test24.conf":
+<Location not allowed here
+# exit: 1
diff --git a/modules/core/test/ref/test25.out b/modules/core/test/ref/test25.out
new file mode 100644
index 0000000000..56bb0bd332
--- /dev/null
+++ b/modules/core/test/ref/test25.out
@@ -0,0 +1,9 @@
+# testing with conf/test25.conf
+[core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 8 of "./conf/test25.conf"
+[core:warn] restricted access policy 192.54.172.0/24 192.54.148.0/24 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 16 of "./conf/test25.conf"
+[core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 1 of "macro 'localaccessonly' (defined on line 11 of "./conf/test25.conf") used on line 20 of "./conf/test25.conf""
+[core:warn] restricted access policy 10.0.0.0/8 on line 1 of macro 'restrictedaccesspolicy' (defined on line 3 of "./conf/test25.conf") used on line 1 of "macro 'localaccessonly' (defined on line 11 of "./conf/test25.conf") used on line 24 of "./conf/test25.conf""
+[core:error] done line 27. on line 27 of ./conf/test25.conf
+AH00526: Syntax error on line 27 of ./conf/test25.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test26.out b/modules/core/test/ref/test26.out
new file mode 100644
index 0000000000..28cba28dcf
--- /dev/null
+++ b/modules/core/test/ref/test26.out
@@ -0,0 +1,11 @@
+# testing with conf/test26.conf
+[macro:warn] macro 'funny' (defined on line 4 of "./conf/test26.conf") argument name 'first arg' (#1) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'funny' (defined on line 4 of "./conf/test26.conf") argument name 'second ... arg' (#2) without expected prefix, better prefix argument names with one of '$%@'.
+[core:warn] funny directory on line 2 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 13 of "./conf/test26.conf"
+[core:warn] funny location on line 5 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 13 of "./conf/test26.conf"
+[core:warn] funny directory on line 2 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 16 of "./conf/test26.conf"
+[core:warn] funny location on line 5 of macro 'funny' (defined on line 4 of "./conf/test26.conf") used on line 16 of "./conf/test26.conf"
+[core:error] done! on line 19 of ./conf/test26.conf
+AH00526: Syntax error on line 19 of ./conf/test26.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test27.out b/modules/core/test/ref/test27.out
new file mode 100644
index 0000000000..46aa8ea6e9
--- /dev/null
+++ b/modules/core/test/ref/test27.out
@@ -0,0 +1,8 @@
+# testing with conf/test27.conf
+[core:warn] foo.one /unexpected/1 on line 2 of macro 'foo.one' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 11 of "./conf/test27.conf"") used on line 14 of "./conf/test27.conf"
+[core:warn] foo.two /unexpected/2 on line 2 of macro 'foo.two' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 12 of "./conf/test27.conf"") used on line 15 of "./conf/test27.conf"
+[core:warn] foo.one /unexpected/1 on line 2 of macro 'foo.one' (defined on line 1 of "macro 'foo' (defined on line 3 of "./conf/test27.conf") used on line 11 of "./conf/test27.conf"") used on line 16 of "./conf/test27.conf"
+[core:error] done! on line 22 of ./conf/test27.conf
+AH00526: Syntax error on line 22 of ./conf/test27.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test28.out b/modules/core/test/ref/test28.out
new file mode 100644
index 0000000000..eb0a23f359
--- /dev/null
+++ b/modules/core/test/ref/test28.out
@@ -0,0 +1,6 @@
+# testing with conf/test28.conf
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 4 of "./conf/test28.conf") used on line 8 of "./conf/test28.conf"
+[core:error] done! on line 10 of ./conf/test28.conf
+AH00526: Syntax error on line 10 of ./conf/test28.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test29.out b/modules/core/test/ref/test29.out
new file mode 100644
index 0000000000..48488f9b4d
--- /dev/null
+++ b/modules/core/test/ref/test29.out
@@ -0,0 +1,4 @@
+# testing with conf/test29.conf
+[macro:warn] macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") argument name 'a' (#1) without expected prefix, better prefix argument names with one of '$%@'.
+httpd: Syntax error on line 8 of ./conf/test29.conf: macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") used on line 8 of "./conf/test29.conf" error while substituting: while processing line 1 of macro 'toobigaline' (defined on line 3 of "./conf/test29.conf") cannot substitute, buffer size too small
+# exit: 1
diff --git a/modules/core/test/ref/test30.out b/modules/core/test/ref/test30.out
new file mode 100644
index 0000000000..a84c69f495
--- /dev/null
+++ b/modules/core/test/ref/test30.out
@@ -0,0 +1,7 @@
+# testing with conf/test30.conf
+[macro:warn] macro 'foo' (defined on line 4 of "./conf/test30.conf"): argument name prefix conflict ($dir #1 and $directive #2), be careful about your macro definition!
+[core:warn] section Directory /unexpected/1 on line 2 of macro 'foo' (defined on line 4 of "./conf/test30.conf") used on line 10 of "./conf/test30.conf"
+[core:error] done! on line 12 of ./conf/test30.conf
+AH00526: Syntax error on line 12 of ./conf/test30.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test31.out b/modules/core/test/ref/test31.out
new file mode 100644
index 0000000000..831a78417e
--- /dev/null
+++ b/modules/core/test/ref/test31.out
@@ -0,0 +1,23 @@
+# testing with conf/test31.conf
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dir #1 and $di #2), be careful about your macro definition!
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dir #1 and $d #4), be careful about your macro definition!
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($di #2 and $d #4), be careful about your macro definition!
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf"): argument name prefix conflict ($dd #3 and $d #4), be careful about your macro definition!
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf": empty argument #1
+[macro:warn] macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf": empty argument #2
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $di #2), be careful about your macro definition!
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $dir #3), be careful about your macro definition!
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($d #1 and $dd #4), be careful about your macro definition!
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument name prefix conflict ($di #2 and $dir #3), be careful about your macro definition!
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$d' (#1) never used
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$di' (#2) never used
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$dir' (#3) never used
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf"): argument '$dd' (#4) never used
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf": empty argument #1
+[macro:warn] macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf": empty argument #2
+[core:warn] argument name conflicts on line 1 of macro 'bla' (defined on line 3 of "./conf/test31.conf") used on line 8 of "./conf/test31.conf"
+[core:warn] conflicts, but arguments are not used on line 1 of macro 'foo' (defined on line 10 of "./conf/test31.conf") used on line 14 of "./conf/test31.conf"
+[core:error] done on line 16. on line 16 of ./conf/test31.conf
+AH00526: Syntax error on line 16 of ./conf/test31.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test32.out b/modules/core/test/ref/test32.out
new file mode 100644
index 0000000000..b1620afb6e
--- /dev/null
+++ b/modules/core/test/ref/test32.out
@@ -0,0 +1,3 @@
+# testing with conf/test32.conf
+httpd: Syntax error on line 3 of ./conf/test32.conf: argument name conflict in macro 'foo' (defined on line 3 of "./conf/test32.conf"): argument '$arg2': #2 and #4, change argument names!
+# exit: 1
diff --git a/modules/core/test/ref/test33.out b/modules/core/test/ref/test33.out
new file mode 100644
index 0000000000..cc5b3d0945
--- /dev/null
+++ b/modules/core/test/ref/test33.out
@@ -0,0 +1,3 @@
+# testing with conf/test33.conf
+httpd: Syntax error on line 3 of ./conf/test33.conf: no macro defined before Use
+# exit: 1
diff --git a/modules/core/test/ref/test34.out b/modules/core/test/ref/test34.out
new file mode 100644
index 0000000000..1264a546de
--- /dev/null
+++ b/modules/core/test/ref/test34.out
@@ -0,0 +1,13 @@
+# testing with conf/test34.conf
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument name prefix conflict ($d #1 and $dd #2), be careful about your macro definition!
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument '$d' (#1) never used
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test34.conf"): argument '$dd' (#2) never used
+[macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument name prefix conflict ($dd #1 and $d #2), be careful about your macro definition!
+[macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument '$dd' (#1) never used
+[macro:warn] macro 'bla' (defined on line 7 of "./conf/test34.conf"): argument '$d' (#2) never used
+[core:warn] macro foo conflict one on line 1 of macro 'foo' (defined on line 3 of "./conf/test34.conf") used on line 11 of "./conf/test34.conf"
+[core:warn] macro bla conflict two on line 1 of macro 'bla' (defined on line 7 of "./conf/test34.conf") used on line 12 of "./conf/test34.conf"
+[core:error] done on line 14. on line 14 of ./conf/test34.conf
+AH00526: Syntax error on line 14 of ./conf/test34.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test35.out b/modules/core/test/ref/test35.out
new file mode 100644
index 0000000000..fb56238380
--- /dev/null
+++ b/modules/core/test/ref/test35.out
@@ -0,0 +1,13 @@
+# testing with conf/test35.conf
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u1' (#1) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u2' (#2) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'n1' (#3) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'n2' (#4) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf") argument name 'u3' (#5) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf"): argument 'n1' (#3) never used
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test35.conf"): argument 'n2' (#4) never used
+[core:warn] macro cannot be used just within a comment 1 2 5 on line 1 of macro 'warnings' (defined on line 3 of "./conf/test35.conf") used on line 8 of "./conf/test35.conf"
+[core:error] done on line 10. on line 10 of ./conf/test35.conf
+AH00526: Syntax error on line 10 of ./conf/test35.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test36.out b/modules/core/test/ref/test36.out
new file mode 100644
index 0000000000..4c627d7dad
--- /dev/null
+++ b/modules/core/test/ref/test36.out
@@ -0,0 +1,20 @@
+# testing with conf/test36.conf
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($u #1 and $u1 #3), be careful about your macro definition!
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($u #1 and $u2 #5), be careful about your macro definition!
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($n #2 and $n1 #4), be careful about your macro definition!
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument name prefix conflict ($n #2 and $n2 #6), be careful about your macro definition!
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n' (#2) never used
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n1' (#4) never used
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf"): argument '$n2' (#6) never used
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #1
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #2
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #3
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #4
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #5
+[macro:warn] macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf": empty argument #6
+[core:warn] many warnings! 1 3 5 on line 1 of macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 7 of "./conf/test36.conf"
+[core:warn] many warnings! on line 1 of macro 'warnings' (defined on line 1 of "./conf/test36.conf") used on line 10 of "./conf/test36.conf"
+[core:error] done! on line 12 of ./conf/test36.conf
+AH00526: Syntax error on line 12 of ./conf/test36.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test37.out b/modules/core/test/ref/test37.out
new file mode 100644
index 0000000000..fc119c82cf
--- /dev/null
+++ b/modules/core/test/ref/test37.out
@@ -0,0 +1,3 @@
+# testing with conf/test37.conf
+httpd: Syntax error on line 3 of ./conf/test37.conf: macro 'stupid' (defined on line 3 of "./conf/test37.conf"): empty argument #1 name
+# exit: 1
diff --git a/modules/core/test/ref/test38.out b/modules/core/test/ref/test38.out
new file mode 100644
index 0000000000..ed3f1bb08f
--- /dev/null
+++ b/modules/core/test/ref/test38.out
@@ -0,0 +1,6 @@
+# testing with conf/test38.conf
+[core:warn] it is really a good idea to have mod_macro.c installed. on line 4 of ./conf/test38.conf
+[core:error] it seems you do not have mod perl installed. on line 8 of ./conf/test38.conf
+AH00526: Syntax error on line 8 of ./conf/test38.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test39.out b/modules/core/test/ref/test39.out
new file mode 100644
index 0000000000..ea2cede9ce
--- /dev/null
+++ b/modules/core/test/ref/test39.out
@@ -0,0 +1,7 @@
+# testing with conf/test39.conf
+[core:warn] Thanks for using mod_macro! on line 1 of macro 'modmacro' (defined on line 4 of "./conf/test39.conf") used on line 15 of "./conf/test39.conf"
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 17 of "./conf/test39.conf") used on line 21 of "./conf/test39.conf"
+[core:error] done! on line 23 of ./conf/test39.conf
+AH00526: Syntax error on line 23 of ./conf/test39.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test40.out b/modules/core/test/ref/test40.out
new file mode 100644
index 0000000000..e3c5971abb
--- /dev/null
+++ b/modules/core/test/ref/test40.out
@@ -0,0 +1,18 @@
+# testing with conf/test40.conf
+AH00112: Warning: DocumentRoot [/foo/document/root/directory] does not exist
+[core:warn] location /A on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 15 of "./conf/test40.conf"
+[core:warn] location /B on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 16 of "./conf/test40.conf"
+[core:warn] location /C on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 17 of "./conf/test40.conf"
+[core:warn] location /D on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 18 of "./conf/test40.conf"
+[core:warn] location /E on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 19 of "./conf/test40.conf"
+[core:warn] location /G on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 20 of "./conf/test40.conf"
+[core:warn] location /H on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 21 of "./conf/test40.conf"
+[core:warn] location /J on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 22 of "./conf/test40.conf"
+[core:warn] location /K on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 23 of "./conf/test40.conf"
+[core:warn] location /L on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 24 of "./conf/test40.conf"
+[core:warn] location /M on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 25 of "./conf/test40.conf"
+[core:warn] location /N on line 2 of macro 'subdiraccesscontrol' (defined on line 7 of "./conf/test40.conf") used on line 26 of "./conf/test40.conf"
+[core:error] Stop configuration file processing. on line 33 of ./conf/test40.conf
+AH00526: Syntax error on line 33 of ./conf/test40.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test41.out b/modules/core/test/ref/test41.out
new file mode 100644
index 0000000000..3bef2853da
--- /dev/null
+++ b/modules/core/test/ref/test41.out
@@ -0,0 +1,9 @@
+# testing with conf/test41.conf
+AH00112: Warning: DocumentRoot [/foo/document/root/directory] does not exist
+[core:warn] location /A on line 7 of ./conf/test41.conf
+[core:warn] location /B on line 11 of ./conf/test41.conf
+[core:warn] location /C on line 15 of ./conf/test41.conf
+[core:error] Stop configuration file processing. on line 20 of ./conf/test41.conf
+AH00526: Syntax error on line 20 of ./conf/test41.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test42.out b/modules/core/test/ref/test42.out
new file mode 100644
index 0000000000..bab1510b8d
--- /dev/null
+++ b/modules/core/test/ref/test42.out
@@ -0,0 +1,15 @@
+# testing with conf/test42.conf
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 7 of "./conf/test42.conf": empty argument #1
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 8 of "./conf/test42.conf": empty argument #1
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 9 of "./conf/test42.conf": empty argument #1
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 10 of "./conf/test42.conf": empty argument #1
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 11 of "./conf/test42.conf": empty argument #1
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 7 of "./conf/test42.conf"
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 8 of "./conf/test42.conf"
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 9 of "./conf/test42.conf"
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 10 of "./conf/test42.conf"
+[core:warn] macro foo on line 1 of macro 'foo' (defined on line 3 of "./conf/test42.conf") used on line 11 of "./conf/test42.conf"
+[core:error] done on line 13. on line 13 of ./conf/test42.conf
+AH00526: Syntax error on line 13 of ./conf/test42.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test43.out b/modules/core/test/ref/test43.out
new file mode 100644
index 0000000000..04a72d8a2e
--- /dev/null
+++ b/modules/core/test/ref/test43.out
@@ -0,0 +1,8 @@
+# testing with conf/test43.conf
+[macro:warn] bad cumulated nesting (+1) in macro 'begindir' (defined on line 3 of "./conf/test43.conf")
+[macro:warn] bad (negative) nesting on line 2 of macro 'enddir' (defined on line 8 of "./conf/test43.conf")
+[macro:warn] bad cumulated nesting (-1) in macro 'enddir' (defined on line 8 of "./conf/test43.conf")
+[core:error] ok! on line 29 of ./conf/test43.conf
+AH00526: Syntax error on line 29 of ./conf/test43.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test44.out b/modules/core/test/ref/test44.out
new file mode 100644
index 0000000000..e744cda69b
--- /dev/null
+++ b/modules/core/test/ref/test44.out
@@ -0,0 +1,5 @@
+# testing with conf/test44.conf
+[core:error] okay. on line 19 of ./conf/test44.conf
+AH00526: Syntax error on line 19 of ./conf/test44.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test45.out b/modules/core/test/ref/test45.out
new file mode 100644
index 0000000000..daadaac7d4
--- /dev/null
+++ b/modules/core/test/ref/test45.out
@@ -0,0 +1,19 @@
+# testing with conf/test45.conf
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '&3' (#3) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '#5' (#5) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '~6' (#6) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '*7' (#7) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '.8' (#8) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ',9' (#9) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '!a' (#10) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '-b' (#11) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '+c' (#12) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '=d' (#13) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ':e' (#14) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name ';f' (#15) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf") argument name '?g' (#16) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 3 of "./conf/test45.conf"): empty contents!
+[core:error] done on line 7. on line 7 of ./conf/test45.conf
+AH00526: Syntax error on line 7 of ./conf/test45.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test46.out b/modules/core/test/ref/test46.out
new file mode 100644
index 0000000000..8059744e68
--- /dev/null
+++ b/modules/core/test/ref/test46.out
@@ -0,0 +1,9 @@
+# testing with conf/test46.conf
+[macro:warn] macro '$i' (defined on line 3 of "./conf/test46.conf") better prefix a macro name with any of '$%@'
+[macro:warn] macro '$i' (defined on line 3 of "./conf/test46.conf"): empty contents!
+[macro:warn] macro 'warnings' (defined on line 7 of "./conf/test46.conf") argument name 'second' (#2) without expected prefix, better prefix argument names with one of '$%@'.
+[macro:warn] macro 'warnings' (defined on line 7 of "./conf/test46.conf"): empty contents!
+[core:error] okay. on line 11 of ./conf/test46.conf
+AH00526: Syntax error on line 11 of ./conf/test46.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test47.out b/modules/core/test/ref/test47.out
new file mode 100644
index 0000000000..58fb3cc6b2
--- /dev/null
+++ b/modules/core/test/ref/test47.out
@@ -0,0 +1,8 @@
+# testing with conf/test47.conf
+[macro:warn] macro 'foo' (defined on line 3 of "./conf/test47.conf"): empty contents!
+[macro:warn] macro 'bla' (defined on line 8 of "./conf/test47.conf"): empty contents!
+[macro:warn] macro 'bof' (defined on line 11 of "./conf/test47.conf"): empty contents!
+[core:error] okay. on line 15 of ./conf/test47.conf
+AH00526: Syntax error on line 15 of ./conf/test47.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test48.out b/modules/core/test/ref/test48.out
new file mode 100644
index 0000000000..6ac5e993c3
--- /dev/null
+++ b/modules/core/test/ref/test48.out
@@ -0,0 +1,20 @@
+# testing with conf/test48.conf
+[core:warn] 1 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 7 of "./conf/test48.conf"
+[core:warn] 12 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 8 of "./conf/test48.conf"
+[core:warn] 123 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 9 of "./conf/test48.conf"
+[core:warn] 1234 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 10 of "./conf/test48.conf"
+[core:warn] 12345 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 11 of "./conf/test48.conf"
+[core:warn] 123456 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 12 of "./conf/test48.conf"
+[core:warn] 1234567 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 13 of "./conf/test48.conf"
+[core:warn] 12345678 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 14 of "./conf/test48.conf"
+[core:warn] 123456789 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 15 of "./conf/test48.conf"
+[core:warn] 1234567890 on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 16 of "./conf/test48.conf"
+[core:warn] 1234567890a on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 17 of "./conf/test48.conf"
+[core:warn] 1234567890ab on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 18 of "./conf/test48.conf"
+[core:warn] 1234567890abc on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 19 of "./conf/test48.conf"
+[core:warn] 1234567890abcd on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 20 of "./conf/test48.conf"
+[core:warn] 1234567890abcde on line 1 of macro 'm' (defined on line 3 of "./conf/test48.conf") used on line 21 of "./conf/test48.conf"
+[core:error] done line 23. on line 23 of ./conf/test48.conf
+AH00526: Syntax error on line 23 of ./conf/test48.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test49.out b/modules/core/test/ref/test49.out
new file mode 100644
index 0000000000..5e83e02e3e
--- /dev/null
+++ b/modules/core/test/ref/test49.out
@@ -0,0 +1,3 @@
+# testing with conf/test49.conf
+httpd: Syntax error on line 2 of ./conf/test49.conf: no macro defined before UndefMacro
+# exit: 1
diff --git a/modules/core/test/ref/test50.out b/modules/core/test/ref/test50.out
new file mode 100644
index 0000000000..477e8549d7
--- /dev/null
+++ b/modules/core/test/ref/test50.out
@@ -0,0 +1,3 @@
+# testing with conf/test50.conf
+httpd: Syntax error on line 5 of ./conf/test50.conf: cannot remove undefined macro 'bla'
+# exit: 1
diff --git a/modules/core/test/ref/test51.out b/modules/core/test/ref/test51.out
new file mode 100644
index 0000000000..be9cc17a1b
--- /dev/null
+++ b/modules/core/test/ref/test51.out
@@ -0,0 +1,3 @@
+# testing with conf/test51.conf
+httpd: Syntax error on line 9 of ./conf/test51.conf: macro 'foo' undefined
+# exit: 1
diff --git a/modules/core/test/ref/test52.out b/modules/core/test/ref/test52.out
new file mode 100644
index 0000000000..f41b7d6888
--- /dev/null
+++ b/modules/core/test/ref/test52.out
@@ -0,0 +1,6 @@
+# testing with conf/test52.conf
+[core:warn] foo macro contents line 1 on line 1 of macro 'foo' (defined on line 2 of "./conf/test52.conf") used on line 5 of "./conf/test52.conf"
+[core:error] done line 8. on line 8 of ./conf/test52.conf
+AH00526: Syntax error on line 8 of ./conf/test52.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test53.out b/modules/core/test/ref/test53.out
new file mode 100644
index 0000000000..2fb3852d84
--- /dev/null
+++ b/modules/core/test/ref/test53.out
@@ -0,0 +1,3 @@
+# testing with conf/test53.conf
+httpd: Syntax error on line 2 of ./conf/test53.conf: no macro defined before Use
+# exit: 1
diff --git a/modules/core/test/ref/test54.out b/modules/core/test/ref/test54.out
new file mode 100644
index 0000000000..814b491e6c
--- /dev/null
+++ b/modules/core/test/ref/test54.out
@@ -0,0 +1,6 @@
+# testing with conf/test54.conf
+[macro:warn] macro 'foo' (defined on line 2 of "./conf/test54.conf"): empty contents!
+[core:error] done line 6. on line 6 of ./conf/test54.conf
+AH00526: Syntax error on line 6 of ./conf/test54.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test55.out b/modules/core/test/ref/test55.out
new file mode 100644
index 0000000000..c3590f95de
--- /dev/null
+++ b/modules/core/test/ref/test55.out
@@ -0,0 +1,8 @@
+# testing with conf/test55.conf
+[core:warn] macro foo(:2) line 1 (file line 9) on line 1 of macro 'foo' (defined on line 2 of "./conf/test55.conf") used on line 9 of "./conf/test55.conf"
+[core:warn] macro bla(:5) line 1 (file line 10) on line 1 of macro 'bla' (defined on line 5 of "./conf/test55.conf") used on line 10 of "./conf/test55.conf"
+[core:warn] macro foo(:2) line 1 (bla line 2) on line 1 of macro 'foo' (defined on line 2 of "./conf/test55.conf") used on line 2 of "macro 'bla' (defined on line 5 of "./conf/test55.conf") used on line 10 of "./conf/test55.conf""
+[core:error] done line 11. on line 11 of ./conf/test55.conf
+AH00526: Syntax error on line 11 of ./conf/test55.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test56.out b/modules/core/test/ref/test56.out
new file mode 100644
index 0000000000..f2a0b6e2fc
--- /dev/null
+++ b/modules/core/test/ref/test56.out
@@ -0,0 +1,12 @@
+# testing with conf/test56.conf
+[macro:warn] bad cumulated nesting (+1) in macro 'open' (defined on line 2 of "./conf/test56.conf")
+[macro:warn] bad (negative) nesting on line 3 of macro 'close' (defined on line 6 of "./conf/test56.conf")
+[macro:warn] bad cumulated nesting (-1) in macro 'close' (defined on line 6 of "./conf/test56.conf")
+[core:warn] Open:2 /tmp on line 2 of macro 'open' (defined on line 2 of "./conf/test56.conf") used on line 12 of "./conf/test56.conf"
+[core:warn] Close:1 on line 1 of macro 'close' (defined on line 6 of "./conf/test56.conf") used on line 13 of "./conf/test56.conf"
+[core:warn] Open:2 /etc on line 2 of macro 'open' (defined on line 2 of "./conf/test56.conf") used on line 15 of "./conf/test56.conf"
+[core:warn] Close:1 on line 1 of macro 'close' (defined on line 6 of "./conf/test56.conf") used on line 16 of "./conf/test56.conf"
+[core:error] done line 18. on line 18 of ./conf/test56.conf
+AH00526: Syntax error on line 18 of ./conf/test56.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test57.out b/modules/core/test/ref/test57.out
new file mode 100644
index 0000000000..77a190111c
--- /dev/null
+++ b/modules/core/test/ref/test57.out
@@ -0,0 +1,3 @@
+# testing with conf/test57.conf
+httpd: Syntax error on line 2 of ./conf/test57.conf: macro 'foo' (defined on line 2 of "./conf/test57.conf"): empty argument #2 name
+# exit: 1
diff --git a/modules/core/test/ref/test58.out b/modules/core/test/ref/test58.out
new file mode 100644
index 0000000000..0ece028d41
--- /dev/null
+++ b/modules/core/test/ref/test58.out
@@ -0,0 +1,3 @@
+# testing with conf/test58.conf
+httpd: Syntax error on line 2 of ./conf/test58.conf: <Macro> directive missing closing '>'
+# exit: 1
diff --git a/modules/core/test/ref/test59.out b/modules/core/test/ref/test59.out
new file mode 100644
index 0000000000..7895917b48
--- /dev/null
+++ b/modules/core/test/ref/test59.out
@@ -0,0 +1,3 @@
+# testing with conf/test59.conf
+httpd: Syntax error on line 2 of ./conf/test59.conf: <Macro macro definition: name not found
+# exit: 1
diff --git a/modules/core/test/ref/test60.out b/modules/core/test/ref/test60.out
new file mode 100644
index 0000000000..cac7002861
--- /dev/null
+++ b/modules/core/test/ref/test60.out
@@ -0,0 +1,15 @@
+# testing with conf/test60.conf
+[core:warn] macro Foo arg 1: hello on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 14 of "./conf/test60.conf"
+[core:warn] macro Foo arg 2: world on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 14 of "./conf/test60.conf"
+[core:warn] Macro Bla arg 1: "hello world" on line 1 of macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf"
+[core:warn] Macro Bla arg 2: "thank you" on line 2 of macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf"
+[core:warn] macro Foo arg 1: hello world on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 3 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:warn] macro Foo arg 2: second on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 3 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:warn] macro Foo arg 1: first on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 4 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:warn] macro Foo arg 2: thank you on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 4 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:warn] macro Foo arg 1: hello world on line 1 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 5 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:warn] macro Foo arg 2: thank you on line 2 of macro 'foo' (defined on line 2 of "./conf/test60.conf") used on line 5 of "macro 'bla' (defined on line 6 of "./conf/test60.conf") used on line 15 of "./conf/test60.conf""
+[core:error] done on line 17. on line 17 of ./conf/test60.conf
+AH00526: Syntax error on line 17 of ./conf/test60.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test61.out b/modules/core/test/ref/test61.out
new file mode 100644
index 0000000000..59639c9750
--- /dev/null
+++ b/modules/core/test/ref/test61.out
@@ -0,0 +1,9 @@
+# testing with conf/test61.conf
+[core:warn] F4:1 x=line=17 on line 1 of macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf"
+[core:warn] F3:1 x=line=17 on line 1 of macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf""
+[core:warn] F2:1 x=line=17 on line 1 of macro 'f2' (defined on line 5 of "./conf/test61.conf") used on line 2 of "macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf"""
+[core:warn] F1:1 x=line=17 on line 1 of macro 'f1' (defined on line 2 of "./conf/test61.conf") used on line 2 of "macro 'f2' (defined on line 5 of "./conf/test61.conf") used on line 2 of "macro 'f3' (defined on line 9 of "./conf/test61.conf") used on line 2 of "macro 'f4' (defined on line 13 of "./conf/test61.conf") used on line 17 of "./conf/test61.conf""""
+[core:error] done line 18. on line 18 of ./conf/test61.conf
+AH00526: Syntax error on line 18 of ./conf/test61.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test62.out b/modules/core/test/ref/test62.out
new file mode 100644
index 0000000000..a956e7e7b8
--- /dev/null
+++ b/modules/core/test/ref/test62.out
@@ -0,0 +1,15 @@
+# testing with conf/test62.conf
+[core:warn] Line:1-2 start at 11 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 11 of "./conf/test62.conf"
+[core:warn] Line:3-4 stop at 11 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 11 of "./conf/test62.conf"
+[core:warn] Line:1-2 start at 12 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 13 of "./conf/test62.conf"
+[core:warn] Line:3-4 stop at 13 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 13 of "./conf/test62.conf"
+[core:warn] Line:1-2 start at 14 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 16 of "./conf/test62.conf"
+[core:warn] Line:3-4 stop at 16 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 16 of "./conf/test62.conf"
+[core:warn] Line:1-2 start at 17 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 18 of "./conf/test62.conf"
+[core:warn] Line:3-4 stop at 18 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 18 of "./conf/test62.conf"
+[core:warn] Line:1-2 start at 19 on line 1 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 23 of "./conf/test62.conf"
+[core:warn] Line:3-4 stop at 23 on line 2 of macro 'line' (defined on line 4 of "./conf/test62.conf") used on line 23 of "./conf/test62.conf"
+[core:error] done line 25. on line 25 of ./conf/test62.conf
+AH00526: Syntax error on line 25 of ./conf/test62.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test63.out b/modules/core/test/ref/test63.out
new file mode 100644
index 0000000000..985710dd40
--- /dev/null
+++ b/modules/core/test/ref/test63.out
@@ -0,0 +1,10 @@
+# testing with conf/test63.conf
+[core:warn] Foo macro at inc63_.conf:5 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 5 of "./conf/inc63_1.conf"
+[core:warn] Foo macro at test63.conf:3 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 3 of "./conf/test63.conf"
+[core:warn] Foo macro at inc63_2.conf:2 on line 1 of macro 'foo' (defined on line 2 of "./conf/inc63_1.conf") used on line 2 of "./conf/inc63_2.conf"
+[core:warn] Bla at inc63_2.conf:3 on line 1 of macro 'bla' (defined on line 4 of "./conf/test63.conf") used on line 3 of "./conf/inc63_2.conf"
+[core:warn] Bla at test63.conf:8 on line 1 of macro 'bla' (defined on line 4 of "./conf/test63.conf") used on line 8 of "./conf/test63.conf"
+[core:error] done at line 9. on line 9 of ./conf/test63.conf
+AH00526: Syntax error on line 9 of ./conf/test63.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test64.out b/modules/core/test/ref/test64.out
new file mode 100644
index 0000000000..99fec92d20
--- /dev/null
+++ b/modules/core/test/ref/test64.out
@@ -0,0 +1,7 @@
+# testing with conf/test64.conf
+[core:warn] on line 2 on line 2 of ./conf/test64.conf
+[core:warn] from line 3 to line 4 on line 4 of ./conf/test64.conf
+[core:error] done on line 5. on line 5 of ./conf/test64.conf
+AH00526: Syntax error on line 5 of ./conf/test64.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test65.out b/modules/core/test/ref/test65.out
new file mode 100644
index 0000000000..62882e28f1
--- /dev/null
+++ b/modules/core/test/ref/test65.out
@@ -0,0 +1,7 @@
+# testing with conf/test65.conf
+[core:warn] Line: on line 6-7 on line 1 of macro 'line' (defined on line 2 of "./conf/test65.conf") used on line 7 of "./conf/test65.conf"
+[core:warn] Line: on line 8-10 on line 1 of macro 'line' (defined on line 2 of "./conf/test65.conf") used on line 10 of "./conf/test65.conf"
+[core:error] done on line 11. on line 11 of ./conf/test65.conf
+AH00526: Syntax error on line 11 of ./conf/test65.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test66.out b/modules/core/test/ref/test66.out
new file mode 100644
index 0000000000..db8616a957
--- /dev/null
+++ b/modules/core/test/ref/test66.out
@@ -0,0 +1,7 @@
+# testing with conf/test66.conf
+[core:warn] Foo: x=X y=Y on line 1 of macro 'foo' (defined on line 2 of "./conf/test66.conf") used on line 5 of "./conf/test66.conf"
+[core:warn] Foo: x=$y y=$x on line 1 of macro 'foo' (defined on line 2 of "./conf/test66.conf") used on line 6 of "./conf/test66.conf"
+[core:error] done on line 7. on line 7 of ./conf/test66.conf
+AH00526: Syntax error on line 7 of ./conf/test66.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test67.out b/modules/core/test/ref/test67.out
new file mode 100644
index 0000000000..b83f074907
--- /dev/null
+++ b/modules/core/test/ref/test67.out
@@ -0,0 +1,5 @@
+# testing with conf/test67.conf
+[core:error] done at line 1 without LF. on line 1 of ./conf/test67.conf
+AH00526: Syntax error on line 1 of ./conf/test67.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test68.out b/modules/core/test/ref/test68.out
new file mode 100644
index 0000000000..0289127b26
--- /dev/null
+++ b/modules/core/test/ref/test68.out
@@ -0,0 +1,6 @@
+# testing with conf/test68.conf
+[core:warn] line 2-3 on line 3 of ./conf/test68.conf
+[core:error] done on line 4-5. on line 5 of ./conf/test68.conf
+AH00526: Syntax error on line 5 of ./conf/test68.conf:
+Configuration processing stopped by Error directive
+# exit: 1
diff --git a/modules/core/test/ref/test69.out b/modules/core/test/ref/test69.out
new file mode 100644
index 0000000000..ac0c1dbd8a
--- /dev/null
+++ b/modules/core/test/ref/test69.out
@@ -0,0 +1,10 @@
+# testing with conf/test69.conf
+[macro:warn] non blank chars found after <Macro closing '>' on line 2 of ./conf/test69.conf: this stuff is ignored...
+[macro:warn] non blank chars found after directive closing on line 4 of ./conf/test69.conf: this stuff is ignored as well...
+[core:warn] Foo on line 1 of macro 'foo' (defined on line 2 of "./conf/test69.conf") used on line 5 of "./conf/test69.conf"
+[core:warn] Bla on line 1 of macro 'bla' (defined on line 6 of "./conf/test69.conf") used on line 9 of "./conf/test69.conf"
+[core:warn] Comments on line 1 of macro 'comments' (defined on line 10 of "./conf/test69.conf") used on line 13 of "./conf/test69.conf"
+[core:error] done on line 14. on line 14 of ./conf/test69.conf
+AH00526: Syntax error on line 14 of ./conf/test69.conf:
+Configuration processing stopped by Error directive
+# exit: 1