[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: m4 brackets question
From: |
Gary V. Vaughan |
Subject: |
Re: m4 brackets question |
Date: |
Sun, 11 Sep 2011 15:41:00 +0700 |
Hi Bruno,
On 10 Sep 2011, at 16:23, Bruno Haible wrote:
> Again, I've stumbled across a behaviour of brackets in autoconf macros that
> I don't understand.
It's just the number of nested quotation levels, with m4 processing always
removing
the outer level whenever text is passed through it.
There must be an additional '[' above here somewhere, to preserve inner quotes
between
there and the next closing ']' at the matching nesting level. I've annotated
all the
matching outer pairs that are stripped below (where anything inside is
preserved when
passed through m4 processing once):
> case "$host_os" in
> mingw*)
> dnl For the sake of native Windows compilers (excluding
> gcc), treat
> dnl backslash as a directory separator, like /. Actually,
> these
> dnl compilers use a double-backslash as directory
> separator, inside the
> dnl # line "filename"
> dnl directives.
> gl_absolute_header_sed='\#[/\\]]m4_defn([gl_HEADER_NAME])[#{
...outermost quoting finishes here ->] [... ...]
[...
> s#.*"\(.*[/\\]]m4_defn([gl_HEADER_NAME])[\)".*#\1#
...] [... ...] [...
> s#^/[^/]#//&#
> p
> q
> }'
> ;;
> *)
> gl_absolute_header_sed='\#/]m4_defn([gl_HEADER_NAME])[#{
...] [... ...] [...
> s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1#
...] [... ...] [...
> s#^/[^/]#//&#
> p
> q
> }'
> ;;
> esac
somewhere beyond this is the next matching closing outer ']' quote. This text
must be being
requoted and processed again though, because the 'dnl' invocations are missing
from the output
even though they are inside an outer level of quoting above.
> [[snip]]
This time, we must be NOT inside an opening outer '[' at this point, because...
> case "$host_os" in
> mingw*)
> dnl For the sake of native Windows compilers (excluding
> gcc),
> dnl treat backslash as a directory separator, like /.
> dnl Actually, these compilers use a double-backslash as
> dnl directory separator, inside the
> dnl # line "filename"
> dnl directives.
> gl_dirsep_regex='[/\\]'
[...] <- this pair are being stripped as
outer quotes
> ;;
> *)
> gl_dirsep_regex='/'
> ;;
> esac
>
> gl_absolute_header_sed='\#'"${gl_dirsep_regex}"']m4_defn([gl_HEADER_NAME])[#{
this one is missing from the expanded output -> ...] [...
...] [...
>
> s#.*"\(.*'"${gl_dirsep_regex}"']m4_defn([gl_HEADER_NAME])[\)".*#\1#
...] [... ...]
[...
> s#^/[^/]#//&#
> p
> q
> }'
Followed by a closing outer ']' below here somewhere.
> Note that the brackets around /\\ have been removed. Why??
With the stray closing ']' I point at above, I deduce that the code you are
showing is
part of a macro that the autoconf machinery must be wrapping up inside quoting
for multiple
expansions, since only one layer of quoting is removed on each pass, and that
stray is not
present in the final output. That points to a quoting mismatch in one of the
macros between
the definition you have shown above, and the final expanded code I've elided.
The proof is here:
$ cat foo.m4
case "$host_os" in
mingw*)
X dnl For the sake of native Windows compilers (excluding gcc),
X dnl treat backslash as a directory separator, like /.
X dnl Actually, these compilers use a double-backslash as
X dnl directory separator, inside the
X dnl # line "filename"
X dnl directives.
X gl_dirsep_regex='[/\\]'
;;
*)
gl_dirsep_regex='/'
;;
esac
gl_absolute_header_sed='\#'"${gl_dirsep_regex}"']m4_defn([gl_HEADER_NAME])[#{
s#.*"\(.*'"${gl_dirsep_regex}"']m4_defn([gl_HEADER_NAME])[\)".*#\1#
s#^/[^/]#//&#
p
q
}'
$ { echo 'm4_changecom(,)m4_changequote([,])m4_define([dnl],
m4_defn([m4_dnl]))dnl'
> echo 'm4_define([gl_HEADER_NAME], [math.h])dnl'
> echo '['
> cat foo.m4
> echo ']' } |m4 -P
case "$host_os" in
mingw*)
X dnl For the sake of native Windows compilers (excluding gcc),
X dnl treat backslash as a directory separator, like /.
X dnl Actually, these compilers use a double-backslash as
X dnl directory separator, inside the
X dnl # line "filename"
X dnl directives.
X gl_dirsep_regex='[/\\]'
;;
*)
gl_dirsep_regex='/'
;;
esac
gl_absolute_header_sed='\#'"${gl_dirsep_regex}"'math.h#{
s#.*"\(.*'"${gl_dirsep_regex}"'math.h\)".*#\1#
s#^/[^/]#//&#
p
q
}'
$ { echo 'm4_changecom(,)m4_changequote([,])m4_define([dnl],
m4_defn([m4_dnl]))dnl'
> echo 'm4_define([gl_HEADER_NAME], [math.h])dnl
> cat foo.m4 } |m4 -P
case "$host_os" in
mingw*)
X X X X X
X X gl_dirsep_regex='/\\'
;;
*)
gl_dirsep_regex='/'
;;
esac
gl_absolute_header_sed='\#'"${gl_dirsep_regex}"']math.h#{
s#.*"\(.*'"${gl_dirsep_regex}"'math.hm4:stdin:18: ERROR: end
of file in string
Unfortunately, the solution will be to chase the multiple requotes and
expansions around with
trace to try to find where the misquoting is hiding.
Cheers,
--
Gary V. Vaughan (gary AT gnu DOT org)