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)