[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: m4: use AC_SUBST with two arguments when applicable
From: |
Bruno Haible |
Subject: |
Re: m4: use AC_SUBST with two arguments when applicable |
Date: |
Sat, 09 May 2020 17:25:58 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-177-generic; KDE/5.18.0; x86_64; ; ) |
Hi Akim,
> AC_SUBST([GNULIB_ISWBLANK], [0])
> AC_SUBST([GNULIB_ISWDIGIT], [0])
> AC_SUBST([GNULIB_ISWXDIGIT], [0])
> AC_SUBST([GNULIB_WCTYPE], [0])
> AC_SUBST([GNULIB_ISWCTYPE], [0])
> AC_SUBST([GNULIB_WCTRANS], [0])
> AC_SUBST([GNULIB_TOWCTRANS], [0])
No, no, noooooo!! This would make the *.m4 code even harder to maintain.
> gl_SUBSTS(
> [[GNULIB_ISWBLANK], [0]],
> [[GNULIB_ISWDIGIT], [0]],
> [[GNULIB_ISWXDIGIT], [0]],
> [[GNULIB_WCTYPE], [0]],
> [[GNULIB_ISWCTYPE], [0]],
> [[GNULIB_WCTRANS], [0]],
> [[GNULIB_TOWCTRANS], [0]]
> )
Eeek! This is even worse!!!
Really, you need to consider two things when proposing new coding patterns:
1) The semantics.
2) The way a programmer works with the code on a daily basis.
1) Let's take an example: HAVE_OPENDIR. See how it's referenced in the *.m4
files:
$ grep -rw HAVE_OPENDIR m4 modules
m4/opendir.m4: HAVE_OPENDIR=0
m4/opendir.m4: if test $HAVE_OPENDIR = 1; then
m4/opendir.m4: case $host_os,$HAVE_OPENDIR in
m4/dirent_h.m4: HAVE_OPENDIR=1; AC_SUBST([HAVE_OPENDIR])
modules/opendir:filename [test $HAVE_OPENDIR = 0 || test
$REPLACE_OPENDIR = 1]
modules/opendir:unistd [test $HAVE_OPENDIR = 0 || test
$REPLACE_OPENDIR = 1]
modules/opendir:closedir [test $HAVE_OPENDIR = 0 || test
$REPLACE_OPENDIR = 1]
modules/opendir:dirfd [test $HAVE_OPENDIR = 0 || test
$REPLACE_OPENDIR = 1]
modules/opendir:if test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1; then
modules/dirent: -e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \
What you see is:
- 2 assignments, at different places (even in different files),
- 2 references as shell variables in *.m4 files,
- more references as shell variables in the modules description,
- 1 AC_SUBST, so it becomes usable as @HAVE_OPENDIR@ in *.h files.
What you propose is
- arbitrary, because it selects one out of several assignments, to
combine them with AC_SUBST,
- counter-maintainable, because it hides the fact that one of these
is a variable assignment. When I have a shell variable, I want to
have *all* assignments done through the VAR=... syntax and *all*
references through $VAR syntax.
2) I work with this code on a daily basis. Often I need to locate all
assignments. A 'grep -rw HAVE_OPENDIR=' does the job. What you
propose, would force me to search for
1. the 'HAVE_OPENDIR=' pattern,
2. the 'AC_SUBST([HAVE_OPENDIR]' pattern,
thus effectively doubling the time I need to make such a search.
And finally, your proposal with gl_SUBSTS groups things together that
are semantically unrelated. There is no relation between GNULIB_ISWBLANK
and GNULIB_WCTYPE. Therefore it is wrong to group them together.
--- --- --- ---
Most probably, you wanted to reduce the complexity of the *.m4 code by
making it smaller?
A laudible goal, but unfortunately you have a totally wrong complexity
measure. The complexity comes from the fact that there are different
assignment in different files. But you can't reduce that complexity
(or at least, I see no way of doing that).
--- --- --- ---
IF you want to reduce complexity in relation to AC_SUBST, then add
a variant AC_SUBST_CONST in such a way that
- AC_SUBST_CONST(VAR) registers a substitution of VAR, like AC_SUBST
does,
- AC_SUBST_CONST(VAR) asserts that VAR has already its value at this
point,
- assignments to VAR that occur later are forbidden (like with 'const'
variables in C).
This would reduce complexity, because it guarantees that the value is
already known, which - by the way AC_REQUIRE works - means that no other
file can modify the value.
For the maintainer, in those cases where AC_SUBST_CONST is applicable
(e.g. HAVE_GLOB_H), it would greatly reduce the scope in which I have to
look for assignments to the variable.
That's how you reduce complexity: Take away irrelevant freedoms, and
make things more "functional" or "declarative" instead of "procedural".
Bruno