autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to do "$@"?


From: Paul Eggert
Subject: Re: how to do "$@"?
Date: Fri, 19 Apr 2002 12:18:46 -0700 (PDT)

> From: Akim Demaille <address@hidden>
> Date: 18 Apr 2002 14:33:03 +0200
> 
> This is the kind of obfuscation I'd like to avoid.

OK, I installed the following patch instead.  I think it reflects all
your comments.  It uses the obfuscated code only in places where the
ZSH_VERSION fixes don't apply.

In this patch I couldn't resist tuning the Zsh workaround slightly,
as follows:

  ${ZSH_VERSION-:} alias -g '${1+"$@"}'='"$@"'

(The code is total gibberish to the uninitiated anyway, so we might as
well make it short and sweet.)


2002-04-19  Paul Eggert  <address@hidden>

        Fix some bugs when using "$@" when there might be zero positional
        arguments in cases where this matters.

        * bin/autoconf.as: Rewrite so that the problem does not come up.
        * lib/autoconf/programs.m4 (AC_CHECK_PROG): Likewise.
        * lib/autoconf/status.m4 (AC_OUTPUT): Likewise.
        * lib/autotest/general.m4 (AT_INIT): Likewise.

        * bin/autoheader.in: Use 'case' statement to work around problem.
        * bin/auto4mte.in: Likewise.
        * bin/autoreconf.in: Likewise.
        * bin/autoscan.in: Likewise.
        * bin/autoupdate.in: Likewise.
        * bin/ifnames.in: Likewise.

        * doc/autoconf.texi (Shell Substitutions): Document the problem.

        * lib/autotest/general.m4 (AT_INIT):
        Use Zsh alias to work around problem.
        * tests/atgeneral.m4 (AT_INIT): Likewise.

        * tests/c.at: We can't have zero arguments, so remove workaround
        that is not portable to Zsh.

Index: bin/autoconf.as
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autoconf.as,v
retrieving revision 1.1
diff -p -u -r1.1 autoconf.as
--- bin/autoconf.as     10 Apr 2002 15:58:19 -0000      1.1
+++ bin/autoconf.as     19 Apr 2002 18:44:36 -0000
@@ -182,10 +182,7 @@ esac
 # Unless specified, the output is stdout.
 test -z "$outfile" && outfile=-
 
-# Running autom4te.
-run_autom4te="$AUTOM4TE --language=autoconf --output=$outfile"
-# Autom4te expansion.
-eval set dummy "$traces"
-shift
-$verbose "$me: running $run_autom4te "${1+"$@"}" $infile" >&2
-exec $run_autom4te ${1+"$@"} $infile
+# Run autom4te with expansion.
+eval set \$AUTOM4TE --language=autoconf --output=\$outfile "$traces" \$infile
+$verbose "$me: running $*" >&2
+exec "$@"
Index: bin/autoheader.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autoheader.in,v
retrieving revision 1.115
diff -p -u -r1.115 autoheader.in
--- bin/autoheader.in   8 Mar 2002 11:46:31 -0000       1.115
+++ bin/autoheader.in   19 Apr 2002 18:44:36 -0000
@@ -2,11 +2,11 @@
 # -*- Perl -*-
 # @configure_input@
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 # autoheader -- create `config.h.in' from `configure.ac'
-# Copyright 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001
+# Copyright (C) 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
Index: bin/autom4te.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autom4te.in,v
retrieving revision 1.59
diff -p -u -r1.59 autom4te.in
--- bin/autom4te.in     8 Mar 2002 12:01:23 -0000       1.59
+++ bin/autom4te.in     19 Apr 2002 18:44:36 -0000
@@ -2,11 +2,11 @@
 # -*- perl -*-
 # @configure_input@
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 # autom4te - Wrapper around M4 libraries.
-# Copyright 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
Index: bin/autoreconf.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autoreconf.in,v
retrieving revision 1.92
diff -p -u -r1.92 autoreconf.in
--- bin/autoreconf.in   5 Apr 2002 09:42:49 -0000       1.92
+++ bin/autoreconf.in   19 Apr 2002 18:44:37 -0000
@@ -2,11 +2,11 @@
 # -*- perl -*-
 # @configure_input@
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 # autoreconf - install the GNU Build System in a directory tree
-# Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
Index: bin/autoscan.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autoscan.in,v
retrieving revision 1.76
diff -p -u -r1.76 autoscan.in
--- bin/autoscan.in     19 Mar 2002 15:25:26 -0000      1.76
+++ bin/autoscan.in     19 Apr 2002 18:44:37 -0000
@@ -1,7 +1,7 @@
 #! @PERL@ -w
 # -*- perl -*-
 # autoscan - Create configure.scan (a preliminary configure.ac) for a package.
-# Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 # Written by David MacKenzie <address@hidden>.
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 BEGIN
Index: bin/autoupdate.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/autoupdate.in,v
retrieving revision 1.32
diff -p -u -r1.32 autoupdate.in
--- bin/autoupdate.in   19 Apr 2002 08:30:39 -0000      1.32
+++ bin/autoupdate.in   19 Apr 2002 18:44:37 -0000
@@ -1,7 +1,7 @@
 #! @PERL@ -w
 # -*- perl -*-
 # autoupdate - modernize an Autoconf file.
-# Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 # Originally written by David MacKenzie <address@hidden>.
 # Rewritten by Akim Demaille <address@hidden>.
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 BEGIN
Index: bin/ifnames.in
===================================================================
RCS file: /cvsroot/autoconf/autoconf/bin/ifnames.in,v
retrieving revision 1.25
diff -p -u -r1.25 ifnames.in
--- bin/ifnames.in      8 Mar 2002 11:46:31 -0000       1.25
+++ bin/ifnames.in      19 Apr 2002 18:44:37 -0000
@@ -2,11 +2,13 @@
 # -*- perl -*-
 # @configure_input@
 
-eval 'exec @PERL@ -S $0 ${1+"$@"}'
+eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
     if 0;
 
 # ifnames - print the identifiers used in C preprocessor conditionals
-# Copyright 1994, 1995, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# Copyright (C) 1994, 1995, 1999, 2000, 2001, 2002 Free Software
+# Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
Index: doc/autoconf.texi
===================================================================
RCS file: /cvsroot/autoconf/autoconf/doc/autoconf.texi,v
retrieving revision 1.612
diff -p -u -r1.612 autoconf.texi
--- doc/autoconf.texi   19 Apr 2002 15:23:25 -0000      1.612
+++ doc/autoconf.texi   19 Apr 2002 18:44:41 -0000
@@ -8457,13 +8457,16 @@ strings inside double-quoted backquoted 
 @item $@@
 @cindex @samp{"$@@"}
 One of the most famous shell-portability issues is related to
address@hidden"$@@"}: when there are no positional arguments, it is supposed to
-be equivalent to nothing.  But some shells, for instance under Digital
-Unix 4.0 and 5.0, will then replace it with an empty argument.  To be
-portable, use @address@hidden"$@@"@}}.
-
-But that's not the end of the story.  Zsh (3.x and 4.x), when emulating
-the Bourne shell, does perform word splitting on @address@hidden"$@@"@}}...
address@hidden"$@@"}.  When there are no positional arguments, @sc{posix} says
+that @samp{"$@@"} is supposed to be equivalent to nothing, but the
+original Unix Version 7 Bourne shell treated it as equivalent to
address@hidden""} instead, and this behavior survives in later implementations
+like Digital Unix 5.0.
+
+The traditional way to work around this portability problem is to use
address@hidden@{1+"$@@"@}}.  Unfortunately this method does not work with
+Zsh (3.x and 4.x), which is used on Mac OS X.  When emulating
+the Bourne shell, Zsh performs word splitting on @address@hidden"$@@"@}}:
 
 @example
 zsh $ @kbd{emulate sh}
@@ -8477,19 +8480,31 @@ World
 @end example
 
 @noindent
-It is not clear whether this is a violation of the Bourne shell
-standard, nevertheless, in this regard Zsh is different from all the
-other shells.  Of course Zsh handles @samp{"$@@"} properly, but we can't
-use it portably...
-
-Fortunately, there is a workaround which relies on Zsh's ``global
-aliases'': let it convert @address@hidden"$@@"@}} into @samp{"$@@"} by
-itself:
+Zsh handles plain @samp{"$@@"} properly, but we can't use plain
address@hidden"$@@"} because of the portability problems mentioned above.
+One workaround relies on Zsh's ``global aliases'' to convert
address@hidden@{1+"$@@"@}} into @samp{"$@@"} by itself:
+
address@hidden
address@hidden:@} alias -g 'address@hidden"$@@"@}'='"$@@"'
address@hidden example
+
+A more conservative workaround is to avoid @samp{"$@@"} if it is
+possible that there may be no positional arguments.  For example,
+instead of:
 
 @example
-test "address@hidden@}" = set && alias -g 'address@hidden"$@@"@}'='"$@@"'
+cat conftest.c "$@@"
 @end example
 
+you can use this instead:
+
address@hidden
+case $# in
+0) cat conftest.c;;
+*) cat conftest.c "$@@";;
+esac
address@hidden example
 
 @item address@hidden@var{var}:address@hidden@}
 @c Info cannot handle `:' in index entries.
Index: lib/autoconf/programs.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autoconf/programs.m4,v
retrieving revision 1.9
diff -p -u -r1.9 programs.m4
--- lib/autoconf/programs.m4    2 Mar 2002 15:19:48 -0000       1.9
+++ lib/autoconf/programs.m4    19 Apr 2002 18:44:41 -0000
@@ -1,6 +1,6 @@
 # This file is part of Autoconf.                       -*- Autoconf -*-
 # Checking for programs.
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -92,9 +92,7 @@ m4_ifvaln([$6],
     # However, it has the same basename, so the bogon will be chosen
     # first if we set $1 to just the basename; use the full file name.
     shift
-    set dummy "$as_dir/$ac_word" ${1+"address@hidden"}
-    shift
-    ac_cv_prog_$1="address@hidden"
+    ac_cv_prog_$1="$as_dir/$ac_word${1+' 'address@hidden"
 m4_if([$2], [$4],
 [  else
     # Default is a loser.
Index: lib/autoconf/status.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autoconf/status.m4,v
retrieving revision 1.22
diff -p -u -r1.22 status.m4
--- lib/autoconf/status.m4      10 Apr 2002 15:58:20 -0000      1.22
+++ lib/autoconf/status.m4      19 Apr 2002 18:44:41 -0000
@@ -1382,17 +1382,20 @@ do
   --*=*)
     ac_option=`expr "x$[1]" : 'x\([[^=]]*\)='`
     ac_optarg=`expr "x$[1]" : 'x[[^=]]*=\(.*\)'`
-    shift
-    set dummy "$ac_option" "$ac_optarg" ${1+"address@hidden"}
-    shift
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$[1]
+    ac_optarg=$[2]
+    ac_shift=shift
     ;;
-  -*);;
   *) # This is not an option, so the user has probably given explicit
      # arguments.
+     ac_option=$[1]
      ac_need_defaults=false;;
   esac
 
-  case $[1] in
+  case $ac_option in
   # Handling of the options.
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
@@ -1412,12 +1415,12 @@ Try `$[0] --help' for more information.]
   --debug | --d* | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
-    shift
-    CONFIG_FILES="$CONFIG_FILES $[1]"
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
     ac_need_defaults=false;;
   --header | --heade | --head | --hea )
-    shift
-    CONFIG_HEADERS="$CONFIG_HEADERS $[1]"
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
     ac_need_defaults=false;;
 
   # This is an error.
Index: lib/autotest/general.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autotest/general.m4,v
retrieving revision 1.130
diff -p -u -r1.130 general.m4
--- lib/autotest/general.m4     10 Apr 2002 15:58:20 -0000      1.130
+++ lib/autotest/general.m4     19 Apr 2002 18:44:42 -0000
@@ -1,6 +1,6 @@
 # This file is part of Autoconf.                          -*- Autoconf -*-
 # M4 macros used in building test suites.
-# Copyright 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -101,7 +101,7 @@ AS_PREPARE
 SHELL=${CONFIG_SHELL-/bin/sh}
 
 # How were we run?
-at_cli_args=${1+"address@hidden"}
+at_cli_args="address@hidden"
 
 # Load the config file.
 for at_file in atconfig atlocal
@@ -569,6 +569,7 @@ _ATEOF
             # Create the debugging script.
             {
               echo "#! /bin/sh"
+              echo '${ZSH_VERSION-:} alias -g '\''${1+"$@"}'\''='\''"$@"'\'''
               echo "cd $at_dir"
               echo 'exec ${CONFIG_SHELL-'"$SHELL"'}' "$[0]" \
                    '-v -d' "$at_debug_args" "$at_group" '${1+"address@hidden"}'
Index: tests/atgeneral.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/tests/atgeneral.m4,v
retrieving revision 1.70
diff -p -u -r1.70 atgeneral.m4
--- tests/atgeneral.m4  25 Nov 2001 15:13:04 -0000      1.70
+++ tests/atgeneral.m4  19 Apr 2002 18:44:42 -0000
@@ -1,6 +1,6 @@
 include(m4sh.m4)                                           -*- Autoconf -*-
 # M4 macros used in building test suites.
-# Copyright 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -318,6 +318,7 @@ elif test $at_debug = false; then
   for at_group in $at_fail_list; do
     echo $at_n " $at_group$at_c"
     ( echo "#! /bin/sh"
+      echo '${ZSH_VERSION-:} alias -g '\''${1+"$@"}'\''='\''"$@"'\'''
       echo 'exec ${CONFIG_SHELL-'"$SHELL"'} '"$[0]"' -v -d '"$at_group"' 
${1+"address@hidden"}'
       echo 'exit 1'
     ) >debug-$at_group.sh
Index: tests/c.at
===================================================================
RCS file: /cvsroot/autoconf/autoconf/tests/c.at,v
retrieving revision 1.1
diff -p -u -r1.1 c.at
--- tests/c.at  27 Sep 2001 13:28:15 -0000      1.1
+++ tests/c.at  19 Apr 2002 18:44:42 -0000
@@ -2,7 +2,7 @@
 
 AT_BANNER([C low level compiling/preprocessing macros.])
 
-# Copyright 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -113,7 +113,7 @@ AT_SETUP([AC_PROG_CPP with warnings])
 AT_DATA([mycpp],
 [[#! /bin/sh
 echo noise >&2
-exec ${1+"$@"}
+exec "$@"
 ]])
 
 chmod +x mycpp
@@ -146,7 +146,7 @@ AT_CHECK([/lib/cpp </dev/null || exit 77
 # A cpp which exit status is meaningless.
 AT_DATA([mycpp],
 [[#! /bin/sh
-/lib/cpp ${1+"$@"}
+/lib/cpp "$@"
 exit 0
 ]])
 



reply via email to

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