From: Akim Demaille Date: Tue, 8 Feb 2000 11:20:57 +0000 (+0000) Subject: Introduce name spaces in libm4. X-Git-Tag: autoconf-2.50~1209 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a9da0e05e8d9c187ae33005b1a3f770a294348d;p=thirdparty%2Fautoconf.git Introduce name spaces in libm4. * libm4.m4 (m4_namespace_push, m4_namespace_pop, m4_namespace_define, define, m4_disable, m4_enable, m4_rename): New macros. (_m4_foreach, _m4_for, m4_wrap): Use m4_define for temporaries. (m4_split): Don't mess with the quotes. * acgeneral.m4 (AC_OUTPUT_MAKE_DEFS, AC_OUTPUT_HEADERS): Quote `define'. --- diff --git a/ChangeLog b/ChangeLog index 412740a4d..7399a0491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2000-02-08 Akim Demaille + + Introduce name spaces in libm4. + + * libm4.m4 (m4_namespace_push, m4_namespace_pop, + m4_namespace_define, define, m4_disable, m4_enable, m4_rename): + New macros. + (_m4_foreach, _m4_for, m4_wrap): Use m4_define for temporaries. + (m4_split): Don't mess with the quotes. + + * acgeneral.m4 (AC_OUTPUT_MAKE_DEFS, AC_OUTPUT_HEADERS): Quote + `define'. + 2000-02-08 Akim Demaille * doc/autoconf.texi (Introduction): m4 1.4 is now required. diff --git a/acgeneral.m4 b/acgeneral.m4 index 9786d50ed..1ceb10eeb 100644 --- a/acgeneral.m4 +++ b/acgeneral.m4 @@ -3378,9 +3378,9 @@ dnl Using a here document instead of a string reduces the quoting nightmare. # look for a macro that doesn't take arguments. cat >$ac_cs_root.defs <<\EOF changequote(<<, >>)dnl -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g t cleanup -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g : cleanup s%[ `~<<#>>$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g @@ -3605,7 +3605,7 @@ changequote(<<, >>)dnl # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dA='s%^\([ ]*\)#\([ ]*<>[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%;t t' @@ -3671,9 +3671,9 @@ s/[\\&%]/\\&/g s%[\\$`]%\\&%g t clear : clear -s%^[ ]*<<#>>[ ]*define[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$%${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD}%gp +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$%${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD}%gp t cleanup -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp : cleanup changequote([, ])dnl EOF diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4 index 9786d50ed..1ceb10eeb 100644 --- a/lib/autoconf/general.m4 +++ b/lib/autoconf/general.m4 @@ -3378,9 +3378,9 @@ dnl Using a here document instead of a string reduces the quoting nightmare. # look for a macro that doesn't take arguments. cat >$ac_cs_root.defs <<\EOF changequote(<<, >>)dnl -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g t cleanup -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g : cleanup s%[ `~<<#>>$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g @@ -3605,7 +3605,7 @@ changequote(<<, >>)dnl # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dA='s%^\([ ]*\)#\([ ]*<>[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%;t t' @@ -3671,9 +3671,9 @@ s/[\\&%]/\\&/g s%[\\$`]%\\&%g t clear : clear -s%^[ ]*<<#>>[ ]*define[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$%${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD}%gp +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\(\([^ (][^ (]*\)([^)]*)\)[ ]*\(.*\)$%${ac_dA}\2${ac_dB}\1${ac_dC}\3${ac_dD}%gp t cleanup -s%^[ ]*<<#>>[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp +s%^[ ]*<<#>>[ ]*<>[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp : cleanup changequote([, ])dnl EOF diff --git a/libm4.m4 b/libm4.m4 index 71c1a7e9a..17cc0cf87 100644 --- a/libm4.m4 +++ b/libm4.m4 @@ -59,6 +59,107 @@ ifdef([__gnu__], , set the M4 environment variable to its path name.) m4exit(2)]) + + +## ---------------------------------------------- ## +## Defining macros and disabling/enabling libm4. ## +## ---------------------------------------------- ## + +# Private copies of the macros we used in disabling/enabling libm4. +# It is much more convenient than fighting with the renamed version +# of define etc. + +define([m4_dnl], defn([dnl])) +define([m4_define], defn([define])) +define([m4_undefine], defn([undefine])) +define([m4_defn], defn([defn])) + +# Name spaces. + +# Sometimes we want to disable some *set* of macros, and restore them +# later. We provide support for this via name spaces. + +# There are basically three characters playing this scene: defining a +# macro in a namespace, disabling a namespace, and restoring a namespace +# (i.e., all the definitions it holds). + +# Technically, to define a MACRO in NAMESPACE means to define the +# macro named `m4_defn(NAMESPACE, MACRO)' to the VALUE. At the same +# time, we append `undefine(NAME)' in the macro named +# `m4_disable(NAMESPACE)', and similarly a binding of NAME to the +# value of `m4_defn(NAMESPACE, MACRO)' in `m4_enable(NAMESPACE)'. +# These mechanisms allow to bind the macro of NAMESPACE and to unbind +# them at will. + +# Of course this implementation is not really efficient: m4 has to +# grow strings which can become quickly huge, which slows it +# significantly. A better implementation should be a list of the +# symbols associated to the name space, and m4_enable?m4_disable +# would just loop over this list. Unfortunately loops of active +# symbols are extremely delicate in m4, and I'm still unsure of the +# implementation I want. So, until we reach a perfect agreement on +# foreach loops implementation, I prefer to use the brute force. + +# It should be noted that one should avoid as much as possible to use +# `define' for temporaries. Now that `define' as quite a complex +# meaning, it is an expensive operations that should be limited to +# macros. Use `m4_define' for temporaries. + +m4_define([m4_namespace_push], [pushdef([m4_namespace], [$1])]) +m4_define([m4_namespace_pop], [popdef([m4_namespace])]) + +m4_namespace_push([libm4]) + + +# m4_namespace_define(NAMESPACE, NAME, VALUE) +# ------------------------------------------- +# +# Assign VALUE to NAME in NAMESPACE, and append the binding/unbinding +# in `m4_disable(NAMESPACE)'/`m4_enable(NAMESPACE)'. +m4_define([m4_namespace_define], +[m4_define([m4_defn([$1], [$2])], [$3])dnl +m4_define([m4_disable($1)], +defn([m4_disable($1)])dnl +[m4_undefine([$2])])dnl +m4_define([m4_enable($1)], +defn([m4_enable(]m4_namespace[)])dnl +[m4_define([$2], defn([m4_defn([$1], [$2])]))])dnl +]) + + +# define(NAME, VALUE) +# ------------------- +# +# Assign VALUE to NAME in the current name space, and bind it at top level. +m4_define([define], +[m4_namespace_define(m4_namespace, [$1], [$2])dnl +m4_define([$1], [$2])dnl +]) + + +# m4_disable(NAMESPACE) +# --------------------- +# +# Undefine all the macros of NAMESPACE. +m4_define([m4_disable], [indir([m4_disable($1)])]) + + +# m4_enable(NAMESPACE) +# -------------------- +# +# Restore all the macros of NAMESPACE. +m4_define([m4_enable], [indir([m4_enable($1)])]) + + +# m4_rename(SRC, DST) +# ------------------- +# +# Rename the macro SRC as DST. +define([m4_rename], +[m4_define([$2], m4_defn([$1]))m4_undefine([$1])]) + + + ## --------------------------------------------- ## ## Move some m4 builtins to a safer name space. ## ## --------------------------------------------- ## @@ -84,16 +185,6 @@ define(m4_fatal, m4exit(ifelse([$2],, 1, [$2]))]) -# Some m4 internals have names colliding with tokens we might use. -# Rename them a` la `m4 --prefix-builtins'. -define([m4_prefix], -[define([m4_$1], defn([$1])) -undefine([$1])]) - -m4_prefix([eval]) -m4_prefix([shift]) -m4_prefix([format]) - # We also want to neutralize include (and sinclude for symmetry), # but we want to extend them slightly: warn when a file is included @@ -106,7 +197,6 @@ m4_prefix([format]) # define(bar, [bar]) # which is certainly not what was meant. - # m4_include_unique(FILE) # ----------------------- # Declare that the FILE was loading; and warn if it has already @@ -240,9 +330,11 @@ define(m4_match, define([m4_for], [pushdef([$1], [$2])_m4_for([$1], [$2], [$3], [$4])popdef([$1])]) +# Low level macros used to define m4_for. +# Use m4_define for temporaries. define([_m4_for], [$4[]ifelse($1, [$3], [], - [define([$1], incr($1))_m4_for([$1], [$2], [$3], [$4])])]) + [m4_define([$1], incr($1))_m4_for([$1], [$2], [$3], [$4])])]) @@ -309,13 +401,14 @@ define([_m4_for], define(m4_foreach, [pushdef([$1], [])_m4_foreach($@)popdef([$1])]) -# Low level macros used to define m4_foreach +# Low level macros used to define m4_foreach. +# Use m4_define for temporaries. define(m4_car, [[$1]]) define(_m4_foreach, [ifelse($2, [()], , - [define([$1], [m4_car$2])$3[]_m4_foreach([$1], - [(m4_shift$2)], - [$3])])]) + [m4_define([$1], [m4_car$2])$3[]_m4_foreach([$1], + [(m4_shift$2)], + [$3])])]) ## ----------------------- ## @@ -340,7 +433,6 @@ define([m4_quote], [[$@]]) # Use m4_strip to remove them. # # REGEXP specifies where to split. Default is [\t ]+. -# # Pay attention to the changequotes. Inner changequotes exist for # obvious reasons (we want to insert square brackets). Outer # changequotes are needed because otherwise the m4 parser, when it @@ -355,16 +447,22 @@ define([m4_quote], [[$@]]) # define(active, ACTIVE) # m4_split([active active ])end # => [active], [active], []end -changequote(<<, >>) -define(<>, -<>) -changequote([, ]) +#changequote(<<, >>) +#define(m4_split, +#<>) +#changequote([, ]) +#changequote(<<, >>) + +define(m4_split, +[patsubst([[$1]], + ifelse([$2],, [[[ ]+]], [[$2]]), + [,])]) # m4_join(STRING) @@ -457,9 +555,9 @@ ifdef([$1], [defn([$1]), ])[$2])]) -## --------------------------------- ## -## Helping macros to display strings ## -## --------------------------------- ## +## ----------------------------------- ## +## Helping macros to display strings. ## +## ----------------------------------- ## # m4_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH]) @@ -510,7 +608,7 @@ ifelse(m4_eval(m4_Cursor > len(m4_Prefix)), 1, [define([m4_Cursor], len(m4_Prefix)) m4_Prefix])[]dnl m4_foreach([m4_Word], (m4_split(m4_strip(m4_join([$1])))), -[define([m4_Cursor], m4_eval(m4_Cursor + len(m4_Word) + 1))dnl +[m4_define([m4_Cursor], m4_eval(m4_Cursor + len(m4_Word) + 1))dnl dnl New line if too long, else insert a space unless it is the first dnl of the words. ifelse(m4_eval(m4_Cursor > m4_Width), @@ -518,10 +616,16 @@ ifelse(m4_eval(m4_Cursor > m4_Width), m4_Prefix, [m4_Separator])[]dnl m4_Word[]dnl -define([m4_Separator], [ ])])dnl +m4_define([m4_Separator], [ ])])dnl popdef([m4_Separator])dnl popdef([m4_Cursor])dnl popdef([m4_Width])dnl popdef([m4_Prefix1])dnl popdef([m4_Prefix])dnl ]) + +# Some m4 internals have names colliding with tokens we might use. +# Rename them a` la `m4 --prefix-builtins'. +m4_rename([eval], [m4_eval]) +m4_rename([shift], [m4_shift]) +m4_rename([format], [m4_format])