bug-gnulib
[Top][All Lists]
Advanced

[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)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]