httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fab...@apache.org
Subject svn commit: r1435811 [1/3] - in /httpd/httpd/trunk: docs/manual/mod/ modules/core/ modules/core/test/ modules/core/test/conf/ modules/core/test/ref/
Date Sun, 20 Jan 2013 10:07:47 GMT
Author: fabien
Date: Sun Jan 20 10:07:44 2013
New Revision: 1435811

URL: http://svn.apache.org/viewvc?rev=1435811&view=rev
Log:
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


Added:
    httpd/httpd/trunk/docs/manual/mod/mod_macro.xml   (with props)
    httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr   (with props)
    httpd/httpd/trunk/modules/core/mod_macro.c   (with props)
    httpd/httpd/trunk/modules/core/test/   (with props)
    httpd/httpd/trunk/modules/core/test/Makefile   (with props)
    httpd/httpd/trunk/modules/core/test/conf/
    httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test01.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test02.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test03.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test04.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test05.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test06.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test07.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test08.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test09.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test10.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test11.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test12.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test13.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test14.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test15.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test16.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test17.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test18.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test19.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test20.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test21.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test22.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test23.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test24.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test25.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test26.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test27.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test28.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test29.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test30.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test31.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test32.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test33.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test34.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test35.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test36.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test37.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test38.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test39.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test40.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test41.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test42.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test43.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test44.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test45.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test46.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test47.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test48.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test49.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test50.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test51.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test52.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test53.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test54.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test55.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test56.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test57.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test58.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test59.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test60.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test61.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test62.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test63.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test64.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test65.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test66.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test67.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test68.conf   (with props)
    httpd/httpd/trunk/modules/core/test/conf/test69.conf   (with props)
    httpd/httpd/trunk/modules/core/test/ref/
    httpd/httpd/trunk/modules/core/test/ref/test01.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test02.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test03.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test04.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test05.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test06.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test07.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test08.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test09.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test10.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test11.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test12.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test13.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test14.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test15.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test16.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test17.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test18.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test19.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test20.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test21.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test22.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test23.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test24.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test25.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test26.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test27.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test28.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test29.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test30.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test31.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test32.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test33.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test34.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test35.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test36.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test37.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test38.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test39.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test40.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test41.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test42.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test43.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test44.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test45.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test46.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test47.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test48.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test49.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test50.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test51.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test52.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test53.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test54.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test55.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test56.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test57.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test58.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test59.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test60.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test61.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test62.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test63.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test64.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test65.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test66.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test67.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test68.out   (with props)
    httpd/httpd/trunk/modules/core/test/ref/test69.out   (with props)
Modified:
    httpd/httpd/trunk/modules/core/config.m4

Added: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_macro.xml?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_macro.xml (added)
+++ httpd/httpd/trunk/docs/manual/mod/mod_macro.xml Sun Jan 20 10:07:44 2013
@@ -0,0 +1,203 @@
+<?xml version="1.0"?>
+<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
+
+<!--
+ 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.
+-->
+
+<modulesynopsis metafile="mod_macro.xml.meta">
+
+<name>mod_macro</name>
+<description>This module provides usage of macros within apache runtime configuration files</description>
+<status>Base</status>
+<sourcefile>mod_macro.c</sourcefile>
+<identifier>macro_module</identifier>
+
+<summary>
+
+    <p>This modules provides macros within apache runtime configuration files.
+    These macros have parameters.  They are expanded when used (parameters are
+    substituted by their values given as an argument), and the result is
+    processed normally.</p>
+</summary>
+
+<section id="features"><title>Features</title>
+
+    Definition of a macro:
+    <ul>
+    <li> macro definition within a &lt;Macro&gt; section, following
+         the apache style.</li>
+    <li> user defined names for the macro and its parameters.</li>
+    <li> macro names are case-insensitive, like apache directives.</li>
+    <li> macro parameter names are case sensitive.</li>
+    <li> macro parameters must have distinct names.</li>
+    <li> error on empty parameter names.</li>
+    <li> redefining a macro generates a warning.</li>
+    <li> macro definitions can be nested... (but what for?)</li>
+    <li> warn about unused macro parameters.</li>
+    <li> warn about macro parameter names which prefix one another.</li>
+    <li> warn if a parameter is not prefixed by any of '<code>$%@</code>'
+         (good practice).</li>
+    <li> the available prefixes help deal with interactions with other
+         directives such as <directive module="core">Define</directive>.</li>
+    <li> tip: it may be useful to define a macro parameter with surrounding
+         braces, say <code>${foo}</code> so that the name can appear with
+	 surrounding characters such as <code>bla${foo}bla</code>.</li>
+    <li> warn about empty macro contents.</li>
+    <li> warns if sections are not properly nested within a macro.
+         (if it is detected so).</li>
+    <li> the lexical scope of macro parameters is restricted to the macro text,
+         it is not forwarded to includes for instance.</li>
+    <li> arbitrary contents in macros.
+         <p>It means you can put perl sections or whatever you like in a macro.
+	 No assumption is made about the lexical structure (quotes, spaces or
+         whatever) within the macro contents but to expect a set of
+         backslash-continued independent lines.</p></li>
+    </ul>
+
+    Use of a macro:
+    <ul>
+    <li> number of arguments must match the definition.</li>
+    <li> all occurences of macro parameters are substituted by their values.</li>
+    <li> in case of conflicts, the longest parameter name is chosen.</li>
+    <li> macro expansion recursion is detected and stopped (error).</li>
+    <li> warn about empty arguments when used.</li>
+    <li> on errors, try to describe precisely where the error occured.</li>
+    <li> <code>$</code> and <code>%</code>-prefixed parameters are not
+          escaped.</li>
+    <li> <code>@</code>-prefixed parameters are escaped in quotes.</li>
+    </ul>
+
+   Removal of a macro definition:
+   <ul>
+   <li> the macro must be already defined.</li>
+   </ul>
+
+    <highlight language="config">
+&lt;Macro DirGroup $dir $group&gt;
+  &lt;Directory $dir&gt;
+    require group $group
+  &lt;/Directory&gt;
+&lt;/Macro&gt;
+
+Use DirGroup /www/apache/private private
+Use DirGroup /www/apache/server  admin
+
+UndefMacro DirGroup
+    </highlight>
+</section>
+
+<!-- Macro -->
+<directivesynopsis type="section">
+<name>Macro</name>
+<description>Define a configuration file macro</description>
+<syntax>
+&lt;Macro <var>name</var> [<var>par1</var> .. <var>parN</var>]&gt;
+... &lt;/Macro&gt;</syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p>The <directive>Macro</directive> directive controls the definition of
+    a macro within the server runtime configuration files.
+    The first argument is the name of the macro.
+    Other arguments are parameters to the macro. It is good practice to prefix
+    parameter names with any of '<code>$%@</code>', and not macro names
+    with such characters.
+    </p>
+
+    <highlight language="config">
+&lt;Macro LocalAccessPolicy&gt;
+  order deny,allow
+  deny from all
+  allow from 10.2.16.0/24
+&lt;/Macro&gt;
+
+&lt;Macro RestrictedAccessPolicy $ipnumbers&gt;
+   order deny,allow
+   deny from all
+   allow from $ipnumbers
+&lt;/Macro&gt;
+    </highlight>
+</usage>
+</directivesynopsis>
+
+<!-- Use -->
+<directivesynopsis>
+<name>Use</name>
+<description>Use a macro</description>
+<syntax>Use <var>name</var> [<var>value1</var> ... <var>valueN</var>]
+</syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p> The <directive>Use</directive> directive controls the use of a macro.
+    The specified macro is expanded. It must be given the same number of
+    arguments than in the  macro definition. The provided values are
+    associated to their corresponding initial parameters and are substituted
+    before processing.</p>
+
+    <highlight language="config">
+Use LocalAccessPolicy
+...
+Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24"
+    </highlight>
+
+    is equivalent, with the macros defined above, to:
+
+    <highlight language="config">
+order deny,allow
+deny from all
+allow from 10.2.16.0/24
+...
+order deny,allow
+deny from all
+allow from 192.54.172.0/24 192.54.148.0/24
+    </highlight>
+</usage>
+</directivesynopsis>
+
+<!-- UndefMacro -->
+<directivesynopsis>
+<name>undefMacro</name>
+<description>Undefine a macro</description>
+
+<syntax>UndefMacro <var>name</var></syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p>The <directive>UndefMacro</directive> directive undefines a macro
+    which has been defined before hand.</p>
+
+    <highlight language="config">
+UndefMacro LocalAccessPolicy
+UndefMacro RestrictedAccessPolicy
+    </highlight>
+</usage>
+</directivesynopsis>
+</modulesynopsis>

Propchange: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr (added)
+++ httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr Sun Jan 20 10:07:44 2013
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
+<!-- French translation: Fabien Coelho -->
+
+<!--
+ 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.
+-->
+
+<modulesynopsis metafile="mod_macro.xml.meta">
+
+<name>mod_macro</name>
+<description>Ce module permet d'utiliser des macros dans les fichiers
+de configuration Apache.</description>
+<status>Base</status>
+<sourcefile>mod_macro.c</sourcefile>
+<identifier>macro_module</identifier>
+
+<summary>
+
+    <p>Ce module permet de d&eacute;finir et d'utiliser des macros dans les fichiers
+    de configuration Apache. Ces macros peuvent avoir des param&egrave;tres qui sont
+    expans&eacute;s &agrave; l'utilisation (les param&egrave;tres sont remplac&eacute;s par la valeur
+    pass&eacute;e en argument), et le r&eacute;sultat de la substitution est trait&eacute;
+    normalement.</p>
+</summary>
+
+<section id="features"><title>Caract&eacute;ristiques</title>
+
+    D&eacute;finition d'une macro :
+    <ul>
+    <li> dans une section &lt;Macro&gt; au style homog&egrave;ne &agrave; la
+         syntaxe des fichiers de configuration Apache.</li>
+    <li> l'utilisateur choisit le nom de la macro et de ses param&egrave;tres.</li>
+    <li> les noms de macro sont insensibles &agrave; la casse, comme les directives Apache.</li>
+    <li> les noms de param&egrave;tres sont par contre sensibles &agrave; la casse.</li>
+    <li> les param&egrave;tres d'une macro doivent avoir des noms distincts.</li>
+    <li> il y a une erreur si un param&egrave;tre a un nom vide.</li>
+    <li> la red&eacute;finition d'une macro g&eacute;n&egrave;re un avertissement.</li>
+    <li> des d&eacute;finitions de macros peuvent &ecirc;tre nich&eacute;es les unes dans les autres...</li>
+    <li> les param&egrave;tres inutilis&eacute;s g&eacute;n&egrave;rent un avertissement.</li>
+    <li> les noms de param&egrave;tre en pr&eacute;fixe les uns des autres g&eacute;n&egrave;rent un avertissement.</li>
+    <li> les noms de param&egrave;tre non pr&eacute;fix&eacute;s par '<code>$%@</code>' g&eacute;n&egrave;rent un
+         avertissement pour encourager cette bonne pratique.</li>
+    <li> les diff&eacute;rents pr&eacute;fixes propos&eacute;s permettent de g&eacute;rer les interactions
+         avec d'autres directives comme <directive module="core">Define</directive>.</li>
+    <li> un conseil : il peut &ecirc;tre utile d'ajouter des accolades autour du nom d'un
+         param&egrave;tre, par exemple <code>${foo}</code>, de mani&egrave;re &agrave; ce que le
+         param&egrave;tre puisse &ecirc;tre utilis&eacute;e avec des caract&egrave;res coll&eacute;s autour,
+         par exemple <code>bla${foo}bla</code>.</li>
+    <li> g&eacute;n&egrave;re un avertissement si le contenu de la macro est vide.</li>
+    <li> g&eacute;n&egrave;re un avertissement si le syst&egrave;me d&eacute;tecte que les sections &agrave; l'int&eacute;rieur
+         d'une macro ne sont pas correctement nich&eacute;es.</li>
+    <li> la port&eacute;e lexicale des param&egrave;tres d'une macro est restreinte au texte
+         de la macro elle-m&ecirc;me... en particulier elle n'est pas propag&eacute;e aux inclusions.</li>
+    <li> il n'y a pas de contrainte sur le contenu d'une macro.
+         <p>Cela signifie que vous pouvez mettre une section perl ou n'importe
+         quoi d'autre dans une macro. Il n'y a pas d'autre hypoth&egrave;se sur la
+         structure lexicale et syntaxique de la macro (guillemets, espaces...)
+         que d'attendre une s&eacute;quence de ligne avec &eacute;ventuellement des
+         continuations.</p></li>
+    </ul>
+
+    Utilisation d'une macro:
+    <ul>
+    <li> le nombre d'argument doit &ecirc;tre coh&eacute;rent avec la d&eacute;finition.</li>
+    <li> toutes les occurences des param&egrave;tres sont substitu&eacute;s par leur valeur.</li>
+    <li> en cas de conflit, le nom le plus long est choisit.</li>
+    <li> une r&eacute;cursion dans l'expansion d'une macro est d&eacute;tect&eacute;e et arr&ecirc;t&eacute;e avec une erreur.</li>
+    <li> les arguments vides g&eacute;n&egrave;rent un avertissement si ils sont utilis&eacute;s.</li>
+    <li> le syst&egrave;me g&eacute;n&egrave;re une description tr&egrave;s pr&eacute;cise de la localisation des erreurs.</li>
+    <li> les valeurs des param&egrave;tres pr&eacute;fix&eacute;s par <code>$</code> et <code>%</code> ne sont pas prot&eacute;g&eacute;s.</li>
+    <li> les valeurs des param&egrave;tres pr&eacute;fix&eacute;s par <code>@</code> sont prot&eacute;g&eacute;s par des guillemets.</li>
+    </ul>
+
+    Effacement de la d&eacute;finition d'une macro :
+    <ul>
+    <li> la macro effac&eacute;e doit avoir &eacute;t&eacute; d&eacute;finie auparavant.</li>
+    </ul>
+
+    <highlight language="config">
+&lt;Macro DirGroup $dir $group&gt;
+  &lt;Directory $dir&gt;
+    require group $group
+  &lt;/Directory&gt;
+&lt;/Macro&gt;
+
+Use DirGroup /www/apache/private private
+Use DirGroup /www/apache/server  admin
+
+UndefMacro DirGroup
+    </highlight>
+</section>
+
+<!-- Macro -->
+<directivesynopsis type="section">
+<name>Macro</name>
+<description>D&eacute;finition d'une macro dans un fichier de configuration</description>
+<syntax>
+&lt;Macro <var>nom</var> [<var>par1</var> .. <var>parN</var>]&gt;
+... &lt;/Macro&gt;</syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p>La diretive <directive>Macro</directive> permet de d&eacute;finir une macro
+    dans un fichier de configuration Apache. Le premier argument est le nom
+    de la macro, et les arguments suivants sont les noms des param&egrave;tres. Il
+    est de bon aloi de pr&eacute;fixer les noms des param&egrave;tres d'une macro
+    avec un caract&egrave;re parmi '<code>$%@</code>'.
+    </p>
+
+    <highlight language="config">
+&lt;Macro LocalAccessPolicy&gt;
+  order deny,allow
+  deny from all
+  allow from 10.2.16.0/24
+&lt;/Macro&gt;
+
+&lt;Macro RestrictedAccessPolicy $ipnumbers&gt;
+   order deny,allow
+   deny from all
+   allow from $ipnumbers
+&lt;/Macro&gt;
+    </highlight>
+</usage>
+</directivesynopsis>
+
+<!-- Use -->
+<directivesynopsis>
+<name>Use</name>
+<description>Utilise une macro</description>
+<syntax>Use <var>nom</var> [<var>valeur1</var> ... <var>valeurN</var>]
+</syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p> La directive <directive>Use</directive> permet d'utiliser une macro.
+    La macro est expans&eacute;e. Elle doit avoir le m&ecirc;me nombre d'argument que le
+    nombre de param&egrave;tres pr&eacute;cis&eacute;s dans sa d&eacute;finition. Les valeurs pass&eacute;es en
+    argument sont substitu&eacute;es avant l'interpr&eacute;tation du texte de la macro.</p>
+
+    <highlight language="config">
+Use LocalAccessPolicy
+...
+Use RestrictedAccessPolicy "192.54.172.0/24 192.54.148.0/24"
+    </highlight>
+
+    est &eacute;quivalent, avec les macros d&eacute;finies au dessus, &agrave; :
+
+    <highlight language="config">
+order deny,allow
+deny from all
+allow from 10.2.16.0/24
+...
+order deny,allow
+deny from all
+allow from 192.54.172.0/24 192.54.148.0/24
+    </highlight>
+</usage>
+</directivesynopsis>
+
+<!-- UndefMacro -->
+<directivesynopsis>
+<name>undefMacro</name>
+<description>Efface une macro</description>
+
+<syntax>UndefMacro <var>nom</var></syntax>
+<contextlist>
+<context>server config</context>
+<context>virtual host</context>
+<context>directory</context>
+</contextlist>
+
+<usage>
+    <p>La directive <directive>UndefMacro</directive> efface la d&eacute;finition
+    d'une macro, qui doit avoir &eacute;t&eacute; d&eacute;finie auparavant.</p>
+
+    <highlight language="config">
+UndefMacro LocalAccessPolicy
+UndefMacro RestrictedAccessPolicy
+    </highlight>
+</usage>
+</directivesynopsis>
+</modulesynopsis>

Propchange: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/docs/manual/mod/mod_macro.xml.fr
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Modified: httpd/httpd/trunk/modules/core/config.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/config.m4?rev=1435811&r1=1435810&r2=1435811&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/core/config.m4 (original)
+++ httpd/httpd/trunk/modules/core/config.m4 Sun Jan 20 10:07:44 2013
@@ -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

Added: httpd/httpd/trunk/modules/core/mod_macro.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/mod_macro.c?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/mod_macro.c (added)
+++ httpd/httpd/trunk/modules/core/mod_macro.c Sun Jan 20 10:07:44 2013
@@ -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 */
+};

Propchange: httpd/httpd/trunk/modules/core/mod_macro.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/mod_macro.c
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/mod_macro.c
------------------------------------------------------------------------------
    svn:mime-type = text/x-c

Propchange: httpd/httpd/trunk/modules/core/test/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sun Jan 20 10:07:44 2013
@@ -0,0 +1 @@
+out

Added: httpd/httpd/trunk/modules/core/test/Makefile
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/Makefile?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/Makefile (added)
+++ httpd/httpd/trunk/modules/core/test/Makefile Sun Jan 20 10:07:44 2013
@@ -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

Propchange: httpd/httpd/trunk/modules/core/test/Makefile
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/Makefile
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/Makefile
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/Makefile
------------------------------------------------------------------------------
    svn:mime-type = text/x-make

Added: httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,5 @@
+# macro for include
+<Macro Foo $where>
+  Warning "Foo macro at $where"
+</Macro>
+Use Foo "inc63_.conf:5"

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_1.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,3 @@
+# use macro defined elsewhere
+Use Foo "inc63_2.conf:2"
+Use Bla "inc63_2.conf:3"

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/inc63_2.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test01.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test01.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test01.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test01.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,3 @@
+# no macro name
+<Macro>
+</Macro>

Propchange: httpd/httpd/trunk/modules/core/test/conf/test01.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test01.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test01.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test01.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test02.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test02.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test02.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test02.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,3 @@
+# no macro name and spaces
+<Macro       >
+</Macro>

Propchange: httpd/httpd/trunk/modules/core/test/conf/test02.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test02.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test02.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test02.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test03.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test03.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test03.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test03.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,5 @@
+# use undefined macro
+<Macro foo>
+  Warning "macro foo"
+</Macro>
+Use bla

Propchange: httpd/httpd/trunk/modules/core/test/conf/test03.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test03.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test03.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test03.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test04.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test04.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test04.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test04.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,5 @@
+# wrong args
+<Macro foo>
+  Warning "macro foo"
+</Macro>
+Use foo hello

Propchange: httpd/httpd/trunk/modules/core/test/conf/test04.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test04.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test04.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test04.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test05.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test05.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test05.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test05.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,5 @@
+# wrong args
+<Macro foo $premier>
+  Warning "macro foo $premier"
+</Macro>
+Use foo

Propchange: httpd/httpd/trunk/modules/core/test/conf/test05.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test05.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test05.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test05.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test06.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test06.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test06.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test06.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,6 @@
+# wrong args
+<Macro foo $premier>
+  Warning "macro foo $premier"
+</Macro>
+Use foo one two
+

Propchange: httpd/httpd/trunk/modules/core/test/conf/test06.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test06.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test06.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test06.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test07.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test07.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test07.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test07.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,3 @@
+# missing end macro
+<Macro foo $premier>
+hello

Propchange: httpd/httpd/trunk/modules/core/test/conf/test07.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test07.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test07.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test07.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test08.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test08.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test08.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test08.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,3 @@
+# missing begin macro
+ServerName hello
+</Macro>

Propchange: httpd/httpd/trunk/modules/core/test/conf/test08.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test08.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test08.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test08.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test09.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test09.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test09.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test09.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,6 @@
+# recursion is bad
+<Macro foo>
+Use foo
+</Macro>
+
+Use foo

Propchange: httpd/httpd/trunk/modules/core/test/conf/test09.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test09.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test09.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test09.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test10.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test10.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test10.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test10.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,10 @@
+# indirect recursion is bad
+<Macro foo>
+Use bla
+</Macro>
+
+<Macro bla>
+Use foo
+</Macro>
+
+Use foo

Propchange: httpd/httpd/trunk/modules/core/test/conf/test10.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test10.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test10.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test10.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test11.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test11.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test11.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test11.conf Sun Jan 20 10:07:44 2013
@@ -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."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test11.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test11.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test11.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test11.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test12.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test12.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test12.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test12.conf Sun Jan 20 10:07:44 2013
@@ -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."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test12.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test12.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test12.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test12.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test13.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test13.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test13.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test13.conf Sun Jan 20 10:07:44 2013
@@ -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."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test13.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test13.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test13.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test13.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test14.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test14.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test14.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test14.conf Sun Jan 20 10:07:44 2013
@@ -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."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test14.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test14.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test14.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test14.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test15.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test15.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test15.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test15.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,9 @@
+# non nested...
+<macro test>
+<directory /tmp>
+</macro>
+
+use test
+</directory>
+
+Error should not reach this point.

Propchange: httpd/httpd/trunk/modules/core/test/conf/test15.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test15.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test15.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test15.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test16.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test16.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test16.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test16.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,11 @@
+# bad nesting
+
+<Macro foo>
+</Limit>
+</Macro>
+
+<Limit GET>
+Use foo
+</Limit>
+
+stop

Propchange: httpd/httpd/trunk/modules/core/test/conf/test16.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test16.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test16.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test16.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test17.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test17.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test17.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test17.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,10 @@
+# bad but good nesting
+
+<Macro foo>
+</Directory>
+</Macro>
+
+<Directory /tmp>
+Use foo
+
+Error "done on line 10."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test17.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test17.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test17.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test17.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test18.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test18.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test18.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test18.conf Sun Jan 20 10:07:44 2013
@@ -0,0 +1,10 @@
+# bad but good nesting
+
+<Macro foo>
+</Location>
+</Macro>
+
+<Location /intranet>
+Use foo
+
+Error "done on line 10."

Propchange: httpd/httpd/trunk/modules/core/test/conf/test18.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/httpd/trunk/modules/core/test/conf/test18.conf
------------------------------------------------------------------------------
    svn:executable = *

Propchange: httpd/httpd/trunk/modules/core/test/conf/test18.conf
------------------------------------------------------------------------------
    svn:keywords = Id URL

Propchange: httpd/httpd/trunk/modules/core/test/conf/test18.conf
------------------------------------------------------------------------------
    svn:mime-type = text/x-httpd

Added: httpd/httpd/trunk/modules/core/test/conf/test19.conf
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/core/test/conf/test19.conf?rev=1435811&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/core/test/conf/test19.conf (added)
+++ httpd/httpd/trunk/modules/core/test/conf/test19.conf Sun Jan 20 10:07:44 2013
@@ -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."



Mime
View raw message