[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
AS_FOR [was: Faster AC_CHECK_{HEADERS,FUNCS}]
From: |
Eric Blake |
Subject: |
AS_FOR [was: Faster AC_CHECK_{HEADERS,FUNCS}] |
Date: |
Sat, 15 Nov 2008 10:46:15 -0700 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.17) Gecko/20080914 Thunderbird/2.0.0.17 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Paolo Bonzini on 11/14/2008 12:59 AM:
> Maybe a
>
> m4_defun([AS_FOREACH], [
> [m4_pushdef([_AS_VAR_$1], m4_quote(m4_tolower([$1]))
> m4_pushdef([$1], m4_if(m4_index(m4_translit([$2], [ ][
> $`], [ ]), [ ]), [-1], [[$2]], [[$_AS_VAR_$1])]]))]dnl
> for _AS_VAR_$1] in $2; do
> $3
> done
> _m4_popdef([_AS_VAR_$1])
>
> could help (untested and probably wrong)?
Like this? It also fixes some bugs in the earlier version (for example,
shell globs can expand to more than one word, or the quadrigraph @S|@ is a
synonym for $, so the filtering must exclude *, ?,...). I found it easier
to write the filter as the set of characters to allow rather than forbid
(thanks to [ and ]). I'll commit this Monday unless I get comments first.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkkfCucACgkQ84KuGfSFAYCBpACgs6hye0YIJs9M1B5VJr+p5sVR
a8YAoL+zV51SS5o2kvFMd9tDcPjN337o
=JmMK
-----END PGP SIGNATURE-----
>From fdcbe002e96ea0d2fa79ae88a4e08af5503a5913 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Sat, 15 Nov 2008 10:17:06 -0700
Subject: [PATCH] Add AS_FOR, undocumented for now.
* lib/m4sugar/m4sh.m4 (AS_FOR): New macro.
* tests/m4sh.at (AS@&address@hidden): New test.
Suggested by Paolo Bonzini.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 7 +++++
lib/m4sugar/m4sh.m4 | 27 +++++++++++++++++++++
tests/m4sh.at | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 31dd4f2..f99863f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-11-15 Eric Blake <address@hidden>
+
+ Add AS_FOR, undocumented for now.
+ * lib/m4sugar/m4sh.m4 (AS_FOR): New macro.
+ * tests/m4sh.at (AS@&address@hidden): New test.
+ Suggested by Paolo Bonzini.
+
2008-11-13 Eric Blake <address@hidden>
Optimize single-argument loop.
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index a39f702..f106e2d 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -533,6 +533,33 @@ m4_define([AS_EXIT],
[{ (exit m4_default([$1], 1)); exit m4_default([$1], 1); }])
+# AS_FOR(MACRO, SHELL-VAR, [LIST = "$@"], [BODY = :])
+# ---------------------------------------------------
+# Expand to a shell loop that assigns SHELL-VAR to each of the
+# whitespace-separated entries in LIST (or "$@" if LIST is empty),
+# then executes BODY. BODY may call break to abort the loop, or
+# continue to proceed with the next element of LIST. Requires that
+# IFS be set to the normal space-tab-newline. As an optimization,
+# BODY should access MACRO rather than $SHELL-VAR. Normally, MACRO
+# expands to $SHELL-VAR, but if LIST contains only a single element
+# that needs no additional shell quoting, then MACRO will expand to
+# that element, thus providing a direct value rather than a shell
+# variable indirection.
+#
+# Only use the optimization if LIST can be used without additional
+# shell quoting in either a literal or double-quoted context (that is,
+# we give up on default IFS chars, parameter expansion, command
+# substitution, shell quoting, globs, or quadrigraphs). Inline the
+# m4_defn for speed.
+m4_defun([AS_FOR],
+[m4_pushdef([$1], m4_if(m4_translit([$3], ]dnl
+m4_dquote(_m4_defn([m4_cr_symbols2]))[[%+=:,./-]), [], [[$3]], [[$$2]]))]dnl
+[for $2[]m4_ifval([$3], [ in $3])
+do
+ m4_default([$4], [:])
+done[]_m4_popdef([$1])])
+
+
# AS_IF(TEST1, [IF-TRUE1 = :]...[IF-FALSE = :])
# ---------------------------------------------
# Expand into
diff --git a/tests/m4sh.at b/tests/m4sh.at
index a8acf56..383d821 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -906,6 +906,72 @@ m4_popdef([limit])
AT_CLEANUP
+## -------- ##
+## AS_FOR. ##
+## -------- ##
+
+AT_SETUP([AS@&address@hidden)
+AT_KEYWORDS([m4sh])
+
+AT_DATA_M4SH([script.as], [[dnl
+AS_INIT
+
+# Simple checks.
+AS_FOR([m4var], [shvar], [a],
+[echo "m4var $shvar"])
+AS_FOR([m4var], [shvar], [b c],
+[echo "m4var $shvar"])
+list='d e'
+AS_FOR([m4var], [shvar], [$list],
+[echo "m4var $shvar"])
+AS_FOR([m4var], [shvar], ["$list"],
+[echo "m4var $shvar"])
+AS_FOR([m4var], [shvar], ['$list'],
+[echo "m4var $shvar"])
+AS_FOR([m4var], [shvar], [\'],
+[echo "m4var $shvar"])
+
+# Syntax checks: cope with empty arguments.
+set f g
+AS_FOR([], [shvar], [],
+[echo "$shvar"])
+rm -f file
+AS_FOR([], [shvar], [`touch file`])
+test -f file || exit 1
+
+# Check that break works.
+while :
+do
+ AS_FOR([m4var], [shvar], [h i],
+ [echo "m4var"; break 2])
+ exit 1
+done
+while :
+do
+ AS_FOR([m4var], [shvar], [j],
+ [echo "m4var"; break 2])
+ exit 1
+done
+]])
+
+AT_CHECK_M4SH
+AT_CHECK([./script], [0], [[a a
+b b
+c c
+d d
+e e
+d e d e
+$list $list
+' '
+f
+g
+h
+j
+]])
+
+AT_CLEANUP
+
+
## --------------- ##
## AS_LITERAL_IF. ##
## --------------- ##
--
1.6.0.2
>From cc854cd040b2e542f6a0365b28beefd30a2bd288 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Sat, 15 Nov 2008 10:36:22 -0700
Subject: [PATCH] Use the new AS_FOR function.
* lib/autoconf/functions.m4 (AC_CHECK_FUNCS): Use new
abstraction for cleaner code.
* lib/autoconf/headers.m4 (AC_CHECK_HEADERS): Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 5 +++++
lib/autoconf/functions.m4 | 14 +++++---------
lib/autoconf/headers.m4 | 15 +++++----------
3 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f99863f..81f28fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2008-11-15 Eric Blake <address@hidden>
+ Use the new AS_FOR function.
+ * lib/autoconf/functions.m4 (AC_CHECK_FUNCS): Use new
+ abstraction for cleaner code.
+ * lib/autoconf/headers.m4 (AC_CHECK_HEADERS): Likewise.
+
Add AS_FOR, undocumented for now.
* lib/m4sugar/m4sh.m4 (AS_FOR): New macro.
* tests/m4sh.at (AS@&address@hidden): New test.
diff --git a/lib/autoconf/functions.m4 b/lib/autoconf/functions.m4
index ebd7403..0e22efc 100644
--- a/lib/autoconf/functions.m4
+++ b/lib/autoconf/functions.m4
@@ -108,15 +108,11 @@ m4_define([_AH_CHECK_FUNC],
# `break' to stop the search.
AC_DEFUN([AC_CHECK_FUNCS],
[m4_map_args_w([$1], [_AH_CHECK_FUNC(], [)])]dnl
-[m4_pushdef([AC_func], m4_if(m4_index(m4_translit([$1], [ ][
-$`], [ ]), [ ]), [-1], [[$1]], [[$ac_func]]))]dnl
-[for ac_func in $1
-do
-AC_CHECK_FUNC(AC_func,
- [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]AC_func)) $2],
- [$3])dnl
-done
-_m4_popdef([AC_func])])
+[AS_FOR([AC_func], [ac_func], [$1],
+[AC_CHECK_FUNC(AC_func,
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]AC_func)) $2],
+ [$3])dnl])
+])# AC_CHECK_FUNCS
# _AC_CHECK_FUNC_ONCE(FUNCTION)
diff --git a/lib/autoconf/headers.m4 b/lib/autoconf/headers.m4
index bf2cb7a..56bbb39 100644
--- a/lib/autoconf/headers.m4
+++ b/lib/autoconf/headers.m4
@@ -245,16 +245,11 @@ m4_define([_AH_CHECK_HEADER],
# header. Either ACTION may include `break' to stop the search.
AC_DEFUN([AC_CHECK_HEADERS],
[m4_map_args_w([$1], [_AH_CHECK_HEADER(], [)])]dnl
-[m4_pushdef([AC_header], m4_if(m4_index(m4_translit([$1], [ ][
-$`], [ ]), [ ]), [-1], [[$1]], [[$ac_header]]))]dnl
-[for ac_header in $1
-do
-AC_CHECK_HEADER(AC_header,
- [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]AC_header)) $2],
- [$3],
- [$4])dnl
-done
-_m4_popdef([AC_header])])# AC_CHECK_HEADERS
+[AS_FOR([AC_header], [ac_header], [$1],
+[AC_CHECK_HEADER(AC_header,
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_]AC_header)) $2],
+ [$3], [$4])dnl])
+])# AC_CHECK_HEADERS
# _AC_CHECK_HEADER_ONCE(HEADER-FILE)
--
1.6.0.2