autoconf
[Top][All Lists]
Advanced

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

Re: iterating over arguments


From: Sam Steingold
Subject: Re: iterating over arguments
Date: Mon, 14 Sep 2009 15:18:11 -0400
User-agent: Thunderbird 2.0.0.22 (X11/20090625)

Eric Blake wrote:
Sam Steingold <sds <at> gnu.org> writes:

yes, now, with this patch:

+test $cl_cv_clisp_]cl_feat[ = no && AC_MSG_ERROR([no ]CL_FEAT[ in CLISP])

is converted to

test $cl_cv_clisp_cl_feat = no && { { $as_echo "$as_me:$LINENO: error: no FFI in CLISP" >&5

Ah. This one is a case of underquotation - cl_feat was expanded too early. (Both Ralf and I did say that our first attempts were untested, after all ;) So, the next try is this.

m4_foreach_w([cl_feat], [$1],
[m4_pushdef([CL_FEAT], m4_toupper(cl_feat))dnl
AC_CACHE_CHECK([for CL_FEAT in CLISP], [cl_cv_clisp_]cl_feat,
 [CLISP_SET([cl_cv_clisp_]cl_feat,
   [[#+]]cl_feat[[ "yes" #-]]cl_feat[[ "no"]])])
test $cl_cv_clisp_[]cl_feat = no && AC_MSG_ERROR([no ]CL_FEAT[ in CLISP])
m4_popdef([CL_FEAT])])

See the difference? "$cl_cv_clisp_]cl_feat[" said to expand cl_feat prior to the body of the m4_foreach_w (and cl_feat was not defined as a macro at that point); whereas the new "$cl_cv_clisp_[]cl_feat" says that cl_feat is still quoted as part of the m4_foreach_w body, but separated by empty quotes from the rest of the text of the body so as to expand at the right point in time.

thanks for the fix and especially for the explanation!
I committed it to clisp cvs now.

And if clisp ever comes up with a feature that resembles an m4 macro name, or contains (), ',', [], or $, (for example, if you added a "dnl" feature to clisp), then you should consider a more robust solution (again, untested, but hopefully this time I've learned from the thread what needs to happen). If you aren't willing to rely on m4_toupper having its quoting fix that I will be adding in autoconf 2.65, you can use a raw m4_translit instead of m4_toupper for safety across older autoconf:

m4_foreach_w([cl_feat], [$1],
[m4_pushdef([CL_FEAT], m4_translit(m4_dquote(m4_defn([cl_feat])),
  [a-z], [A-Z]))dnl
AC_CACHE_CHECK([for m4_defn([CL_FEAT]) in CLISP],
 [cl_cv_clisp_]m4_defn([cl_feat]),
 [CLISP_SET([cl_cv_clisp_]m4_defn([cl_feat]),
   [[#+]]m4_dquote(m4_defn([cl_feat]))[[ "yes" #-]]m4_dquote(
      m4_defn([cl_feat]))[[ "no"]])])
test $cl_cv_clisp_[]m4_defn([cl_feat]) = no \
  && AC_MSG_ERROR([no ]m4_defn([CL_FEAT])[ in CLISP])
m4_popdef([CL_FEAT])])

See how hairy it gets with all the extra m4_defn for safety? Which is why I like my m4_map_args_w interface better (using $1 instead of m4_defn([varname]) is less typing, and more efficient use of m4); too bad I wasn't developing autoconf back in the 2.59 days ;)


OH HORROR!!!

OK, if you are still with me, how about the following extra tweak:
as you probably know, the CL reader is (by default) case-converting (the
default case being upcase), so "#+FOO" and "#+foo" have the same meaning.
This makes me want to use upcase for both messages and variables names, so that
CL_CLISP([ffi]) and CL_CLISP([FFI]) will not define two separate variables
cl_cv_clisp_ffi and cl_cv_clisp_FFI which answer the same question.
So, I applied this patch:
(drop m4_popdef, replace m4_pushdef with m4_define)
===================================================================
RCS file: /cvsroot/clisp/clisp/src/m4/clisp.m4,v
retrieving revision 1.14
diff -u -w -p -F^(def -r1.14 clisp.m4
--- src/m4/clisp.m4     14 Sep 2009 19:07:18 -0000      1.14
+++ src/m4/clisp.m4     14 Sep 2009 19:15:35 -0000
@@ -78,8 +78,8 @@ if test "$cl_use_clisp" != "no"; then
   fi
 fi
 m4_foreach_w([cl_feat], [$1],
-[m4_pushdef([CL_FEAT], m4_toupper(cl_feat))dnl
-AC_CACHE_CHECK([for CL_FEAT in CLISP], [cl_cv_clisp_]cl_feat,
+[m4_define([cl_feat], m4_toupper(cl_feat))dnl
+AC_CACHE_CHECK([for cl_feat in CLISP], [cl_cv_clisp_]cl_feat,
 [CLISP_SET([cl_cv_clisp_]cl_feat,[[#+]]cl_feat[[ "yes" #-]]cl_feat[[ "no"]])])
-test $cl_cv_clisp_[]cl_feat = no && AC_MSG_ERROR([no ]CL_FEAT[ in CLISP])
-m4_popdef([CL_FEAT])])])
+test $cl_cv_clisp_[]cl_feat = no && AC_MSG_ERROR([no ]cl_feat[ in CLISP])
+])])
===================================================================
and it seems to be doing what I want.
is it OK?
Thanks.
Sam.




reply via email to

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