Discussion:
Using "m4_bpatsubst/patsubst" to remove a string from a variable
Manuel Bachmann
2016-06-06 09:17:11 UTC
Permalink
Hi folks,

I am trying to use the "m4_bpatsubst" and/or "patsubst" macros (which I
found documented here : [1] [2]), to remove a string from a variable in my "
configure.ac" ; and pass it to "Makefile.am", so it ends up in final
"Makefile".

I was able to get some kind of output, with this in "configure.ac" :

VAR="text1 text2"
VAR2=m4_bpatsubst("$VAR", "text1")
AC_SUBST(VAR2)

with the hope of obtaining "VAR2="text2"", but when running "autoreconf
--install; ./configure", and opening "Makefile", the final variable is
still :
VAR2="text1 text2"
no text was removed...

I've also tried only syntaxes, such as :
VAR2=m4_bpatsubst([VAR], [text1])
or :
AC_DEFINE(VAR2, m4_bpatsubst([VAR], [text1])
but they all issue errors or the resulting "VAR2" is empty.

Any ideas on this ?

[1] :
https://www.gnu.org/software/autoconf/manual/autoconf-2.68/html_node/Redefined-M4-Macros.html
[2] :
https://www.gnu.org/software/m4/manual/m4-1.4.15/html_node/Patsubst.html

Regards,

*Manuel Bachmann, Graphics & Multimedia Engineer www.iot.bzh
<http://iot.bzh> *
Zack Weinberg
2016-06-06 13:31:14 UTC
Permalink
Post by Manuel Bachmann
Hi folks,
I am trying to use the "m4_bpatsubst" and/or "patsubst" macros (which I
found documented here : [1] [2]), to remove a string from a variable in my "
configure.ac" ; and pass it to "Makefile.am", so it ends up in final
"Makefile".
VAR="text1 text2"
VAR2=m4_bpatsubst("$VAR", "text1")
AC_SUBST(VAR2)
This is an easy mistake to make. Remember that configure.ac is an M4
script, that generates a shell script, configure. When configure is
run, M4 is no longer around to help out. (This is an intentional
design decision; it was, many years ago, not considered appropriate to
require people to have M4 available when running configure.)

So you can't mix M4 and shell like the above. Instead, you can do it all in M4:

m4_define([VAR],[text1 text2])
m4_define([VAR2],[m4_bpatsubst([VAR1],[text1],)
[VAR2=]VAR2
AC_SUBST([VAR])

or you can do it all in shell:

VAR="text1 text2"
VAR2="`AS_ECHO("$VAR") | sed 's/text1//g'`" dnl yes, the nested double
quotes are correct
AC_SUBST([VAR2])

You probably want to do it all in shell. The only situation I can
think of where you would want the all-in-M4 version is if you were
implementing a new Autoconf macro, VAR came from one of its arguments,
and it was guaranteed to be literal text - not the result of any
configure-time processing - in the caller.

zw
Manuel Bachmann
2016-06-06 17:14:02 UTC
Permalink
Hi Zack, and many thanks for the thorough answer !
Post by Zack Weinberg
This is an easy mistake to make. Remember that configure.ac is an M4
script, that generates a shell script, configure. When configure is
run, M4 is no longer around to help out.
You're right ; shell variables are only available when running
"./configure", when it is far too late... it is so obvious now, that I'm
facepalming myself.
Post by Zack Weinberg
or you can do it all
Yes, since it is a ad-hoc solution and it is a lot easier to read, shell
syntax is definitely better for my usecase.

I've just implemented it by using AS_ECHO, and a grep/sed logic as you
suggested. Seems to work fine.

Thanks a lot Zack !

Regards,

*Manuel Bachmann, Graphics & Multimedia Engineer www.iot.bzh
<http://iot.bzh> *
Post by Zack Weinberg
Post by Manuel Bachmann
Hi folks,
I am trying to use the "m4_bpatsubst" and/or "patsubst" macros (which I
found documented here : [1] [2]), to remove a string from a variable in
my "
Post by Manuel Bachmann
configure.ac" ; and pass it to "Makefile.am", so it ends up in final
"Makefile".
VAR="text1 text2"
VAR2=m4_bpatsubst("$VAR", "text1")
AC_SUBST(VAR2)
This is an easy mistake to make. Remember that configure.ac is an M4
script, that generates a shell script, configure. When configure is
run, M4 is no longer around to help out. (This is an intentional
design decision; it was, many years ago, not considered appropriate to
require people to have M4 available when running configure.)
m4_define([VAR],[text1 text2])
m4_define([VAR2],[m4_bpatsubst([VAR1],[text1],)
[VAR2=]VAR2
AC_SUBST([VAR])
VAR="text1 text2"
VAR2="`AS_ECHO("$VAR") | sed 's/text1//g'`" dnl yes, the nested double
quotes are correct
AC_SUBST([VAR2])
You probably want to do it all in shell. The only situation I can
think of where you would want the all-in-M4 version is if you were
implementing a new Autoconf macro, VAR came from one of its arguments,
and it was guaranteed to be literal text - not the result of any
configure-time processing - in the caller.
zw
Eric Blake
2016-06-06 18:21:23 UTC
Permalink
Post by Manuel Bachmann
VAR="text1 text2"
VAR2="`AS_ECHO("$VAR") | sed 's/text1//g'`" dnl yes, the nested double
quotes are correct
Correct in a POSIX shell, but liable to misbehave on some older shells.
Better is:

VAR2=`AS_ECHO("$VAR") | sed 's/text1//g'`

Since it is in assignment context, you don't need the outer "" to
prevent word splitting, the `` is enough for the shell to know where the
assignment ends.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Zack Weinberg
2016-06-06 19:09:38 UTC
Permalink
Post by Eric Blake
Post by Zack Weinberg
VAR2="`AS_ECHO("$VAR") | sed 's/text1//g'`"
Correct in a POSIX shell, but liable to misbehave on some older shells.
VAR2=`AS_ECHO("$VAR") | sed 's/text1//g'`
Since it is in assignment context, you don't need the outer "" to
prevent word splitting, the `` is enough for the shell to know where the
assignment ends.
I am under the impression that there did once exist shells for which
the outer quotes *were* necessary to prevent word splitting (and
therefore misinterpretation of the overall statement as a
single-command environment variable override). I am also under the
impression that any shell new enough to implement $() will *not* do
word splitting in a variable assignment.

Both of these factoids come out of the same "bitter experience with
vendor /bin/sh circa 1996" box in my head, so they may be totally
wrong, or they may only apply to shells sufficiently ancient as to be
irrelevant nowadays -- does anyone know for sure?

zw

Loading...