]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Add AS_VAR_ARITH.
authorEric Blake <ebb9@byu.net>
Mon, 27 Oct 2008 20:26:57 +0000 (14:26 -0600)
committerEric Blake <ebb9@byu.net>
Mon, 27 Oct 2008 22:11:56 +0000 (16:11 -0600)
* lib/m4sugar/m4sh.m4 (_AS_VAR_ARITH_PREPARE, _AS_VAR_ARITH_WORKS)
(AS_VAR_ARITH): New macros.
(_AS_PREPARE, AS_PREPARE): Emit preparation.
* tests/m4sh.at (AS@&t@_VAR_ARITH): New test.
* doc/autoconf.texi (Polymorphic Variables) <AS_VAR_ARITH>:
Document new macro.
(Limitations of Usual Tools) <expr>: Mention portability problem
if first argument starts with -.
(Shell Substitutions) <$((expression))>: Mention it.
* NEWS: Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
NEWS
doc/autoconf.texi
lib/m4sugar/m4sh.m4
tests/m4sh.at

index 313124b970069abcb8b644b53cc277fc74daa482..d5b68adbbb52580e7b411bfe02dd7453571bffb9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-10-27  Eric Blake  <ebb9@byu.net>
+
+       Add AS_VAR_ARITH.
+       * lib/m4sugar/m4sh.m4 (_AS_VAR_ARITH_PREPARE, _AS_VAR_ARITH_WORKS)
+       (AS_VAR_ARITH): New macros.
+       (_AS_PREPARE, AS_PREPARE): Emit preparation.
+       * tests/m4sh.at (AS@&t@_VAR_ARITH): New test.
+       * doc/autoconf.texi (Polymorphic Variables) <AS_VAR_ARITH>:
+       Document new macro.
+       (Limitations of Usual Tools) <expr>: Mention portability problem
+       if first argument starts with -.
+       (Shell Substitutions) <$((expression))>: Mention it.
+       * NEWS: Likewise.
+
 2008-10-27  Eric Blake  <ebb9@byu.net>
 
        Use read, rather than `cat`, for safe one-line files.
@@ -6,7 +20,7 @@
        * lib/autoconf/general.m4 (_AC_COMPUTE_INT_RUN): Likewise.
 
 2008-10-27  Paolo Bonzini  <bonzini@gnu.org>
-    
+
        * lib/autoconf/general.m4 (_AC_COMPUTE_INT_COMPILE,
        _AC_COMPUTE_INT_RUN): Add IF-SUCCESS argument.
        (_AC_COMPUTE_INT_BODY): New.
diff --git a/NEWS b/NEWS
index 5bdff4860a16ceddcc683dada95321c8e41a07ad..1f969b13dd7cc95d113a3fb97f9cd7297d9b57d6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,7 +20,8 @@ GNU Autoconf NEWS - User visible changes.
    m4_copy  m4_rename
 
 ** The following documented m4sh macros are new:
-   AS_LINENO_PREPARE  AS_ME_PREPARE  AS_VAR_APPEND  AS_VAR_COPY
+   AS_LINENO_PREPARE  AS_ME_PREPARE  AS_VAR_APPEND  AS_VAR_ARITH
+   AS_VAR_COPY
 
 ** The following m4sh macros are documented now:
    AS_ECHO  AS_ECHO_N  AS_EXIT  AS_LITERAL_IF  AS_UNSET  AS_VAR_IF
index b89ce5b7acd0e5f6549e3824416362bb3c202b64..c1427a67d07cc6cd9c0c258f7a548e11d838c82d 100644 (file)
@@ -12121,6 +12121,27 @@ appends.  Note that unlike @code{AS_VAR_SET}, this macro requires that
 expansion.
 @end defmac
 
+@defmac AS_VAR_ARITH (@var{var}, @var{expression})
+@asindex{ARITH}
+Emit shell code to compute the arithmetic expansion of @var{expression},
+assigning the result as the contents of the polymorphic shell variable
+@var{var}.  The code takes advantage of shells that provide @samp{$(())}
+for fewer forks, but uses @command{expr} as a fallback.  Therefore, the
+syntax for a valid @var{expression} is rather limited: all operators
+must occur as separate shell arguments and with proper quoting, there is
+no portable equality operator, all variables containing numeric values
+must be expanded prior to the computation, all numeric values must be
+provided in decimal without leading zeroes, and the first shell argument
+should not be a negative number.  In the following example, this snippet
+will print @samp{(2+3)*4 == 20}.
+
+@example
+bar=3
+AS_VAR_ARITH([foo], [\( 2 + $bar \) \* 4])
+echo "(2+$bar)*4 == $foo"
+@end example
+@end defmac
+
 @defmac AS_VAR_COPY (@var{dest}, @var{source})
 @asindex{VAR_COPY}
 Emit shell code to assign the contents of the polymorphic shell variable
@@ -14034,10 +14055,10 @@ $ @kbd{pdksh -c 'echo $(( 010 ))'}
 
 When it is available, using arithmetic expansion provides a noticeable
 speedup in script execution; but testing for support requires
-@command{eval} to avoid syntax errors.  If shell function support can
-be assumed, then this construct can be used to assign @samp{foo}
-to an arithmetic result, provided all numeric arguments are provided in
-decimal and without a leading zero:
+@command{eval} to avoid syntax errors.  The following construct is used
+by @code{AS_VAR_ARITH} to provide arithmetic computation when all
+arguments are provided in decimal and without a leading zero, and all
+operators are properly quoted and appear as distinct arguments:
 
 @example
 if ( eval 'test $(( 1 + 1 )) = 2' ) 2>/dev/null; then
@@ -15880,6 +15901,14 @@ foo
 @item @command{expr}
 @c -----------------
 @prindex @command{expr}
+Not all implementations obey the Posix rule that @samp{--} separates
+options from arguments; likewise, not all implementations provide the
+extension to Posix that the first argument can be treated as part of a
+valid expression rather than an invalid option if it begins with
+@samp{-}.  When performing arithmetic, use @samp{expr 0 + $var} if
+@samp{$var} might be a negative number, to keep @command{expr} from
+interpreting it as an option.
+
 No @command{expr} keyword starts with @samp{X}, so use @samp{expr
 X"@var{word}" : 'X@var{regex}'} to keep @command{expr} from
 misinterpreting @var{word}.
index 612406566604114a7812ae0e0b560598c28180d3..300923a23b4ce6263c546ad3d5886f8b075bb426 100644 (file)
@@ -266,6 +266,7 @@ m4_defun([_AS_PREPARE],
 )]dnl
 [_AS_UNSET_PREPARE
 _AS_VAR_APPEND_PREPARE
+_AS_VAR_ARITH_PREPARE
 
 _AS_EXPR_PREPARE
 _AS_BASENAME_PREPARE
@@ -301,6 +302,7 @@ AS_REQUIRE([_AS_TR_CPP_PREPARE])
 AS_REQUIRE([_AS_TR_SH_PREPARE])
 AS_REQUIRE([_AS_UNSET_PREPARE])
 AS_REQUIRE([_AS_VAR_APPEND_PREPARE], [], [M4SH-INIT-FN])
+AS_REQUIRE([_AS_VAR_ARITH_PREPARE], [], [M4SH-INIT-FN])
 m4_divert_pop[]])
 
 
@@ -1642,14 +1644,12 @@ AS_IF([_AS_RUN(["AS_ESCAPE([_AS_VAR_APPEND_WORKS])"])],
   }]) # as_func_append
 ])
 
-
 # _AS_VAR_APPEND_WORKS
 # --------------------
 # Output a shell test to discover whether += works.
 m4_define([_AS_VAR_APPEND_WORKS],
 [as_var=1; as_var+=2; test x$as_var = x12])
 
-
 # AS_VAR_APPEND(VAR, VALUE)
 # -------------------------
 # Append the shell expansion of VALUE to the end of the existing
@@ -1666,6 +1666,49 @@ m4_defun_init([AS_VAR_APPEND],
 [as_func_append $1 $2])
 
 
+# _AS_VAR_ARITH_PREPARE
+# ---------------------
+# Define as_func_arith to the optimum definition for the current
+# shell (using POSIX $(()) where supported).
+m4_defun([_AS_VAR_ARITH_PREPARE],
+[AS_FUNCTION_DESCRIBE([as_func_arith], [ARG...],
+[Perform arithmetic evaluation on the ARGs, and store the result in
+the global $as_val.  Take advantage of shells that can avoid forks.
+The arguments must be portable across $(()) and expr.])
+AS_IF([_AS_RUN(["AS_ESCAPE([_AS_VAR_ARITH_WORKS])"])],
+[eval 'as_func_arith ()
+  {
+    as_val=$(( $[]* ))
+  }'],
+[as_func_arith ()
+  {
+    as_val=`expr "$[]@"`
+  }]) # as_func_arith
+])
+
+# _AS_VAR_ARITH_WORKS
+# -------------------
+# Output a shell test to discover whether $(()) works.
+m4_define([_AS_VAR_ARITH_WORKS],
+[test $(( 1 + 1 )) = 2])
+
+# AS_VAR_ARITH(VAR, EXPR)
+# -----------------------
+# Perform the arithmetic evaluation of the arguments in EXPR, and set
+# contents of the polymorphic shell variable VAR to the result, taking
+# advantage of any shell optimizations that perform arithmetic without
+# forks.  Note that numbers occuring within EXPR must be written in
+# decimal, and without leading zeroes; variables containing numbers
+# must be expanded prior to arithmetic evaluation; the first argument
+# must not be a negative number; there is no portable equality
+# operator; and operators must be given as separate arguments and
+# properly quoted.
+m4_defun_init([AS_VAR_ARITH],
+[_AS_DETECT_SUGGESTED([_AS_VAR_ARITH_WORKS])]dnl
+[AS_REQUIRE([_AS_VAR_ARITH_PREPARE], [], [M4SH-INIT-FN])],
+[as_func_arith $2 && AS_VAR_SET([$1], [$as_val])])
+
+
 # AS_VAR_COPY(DEST, SOURCE)
 # -------------------------
 # Set the polymorphic shell variable DEST to the contents of the polymorphic
index badc6681415b43a4cbf1ed609642ee8f4cf807f9..e90e23193cca6a5c1dcabb988860cd2e59bb68ab 100644 (file)
@@ -1070,6 +1070,37 @@ hello,  world
 AT_CLEANUP
 
 
+## -------------- ##
+## AS_VAR_ARITH.  ##
+## -------------- ##
+
+AT_SETUP([AS@&t@_VAR_ARITH])
+AT_KEYWORDS([m4sh AS@&t@_VAR])
+
+AT_DATA_M4SH([script.as], [[dnl
+AS_INIT
+# Literals.
+AS_VAR_ARITH([foo], [1 + 1])
+echo "$foo"
+# Indirects via shell vars.
+num=1
+AS_VAR_ARITH([foo$num], [\( 2 + 3 \) \* 4])
+echo "$foo1"
+# Indirects via command substitution.
+AS_VAR_ARITH([`echo foo2`], [0 + -2 + $foo1 / 2])
+echo "$foo2"
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([./script], [],
+[[2
+20
+8
+]])
+
+AT_CLEANUP
+
+
 ## ----------------- ##
 ## AS_INIT cleanup.  ##
 ## ----------------- ##