Using "m4_bpatsubst/patsubst" to remove a string from a variable

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Using "m4_bpatsubst/patsubst" to remove a string from a variable

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".

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> *
_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|

Re: Using "m4_bpatsubst/patsubst" to remove a string from a variable

Zack Weinberg-2
On Mon, Jun 6, 2016 at 5:17 AM, Manuel Bachmann <[hidden email]> wrote:

> 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)

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

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|

Re: Using "m4_bpatsubst/patsubst" to remove a string from a variable

Manuel Bachmann
Hi Zack, and many thanks for the thorough answer !

> 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.

> So you can't mix M4 and shell like the above.  Instead, you can do it all
in M4:
> 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> *


2016-06-06 15:31 GMT+02:00 Zack Weinberg <[hidden email]>:

> On Mon, Jun 6, 2016 at 5:17 AM, Manuel Bachmann <[hidden email]>
> wrote:
> > 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)
>
> 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
>
_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf
Reply | Threaded
Open this post in threaded view
|

Re: Using "m4_bpatsubst/patsubst" to remove a string from a variable

Eric Blake-3
In reply to this post by Zack Weinberg-2
On 06/06/2016 07:31 AM, Zack Weinberg wrote:

> 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

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


_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf

signature.asc (617 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Using "m4_bpatsubst/patsubst" to remove a string from a variable

Zack Weinberg-2
On Mon, Jun 6, 2016 at 2:21 PM, Eric Blake <[hidden email]> wrote:

> On 06/06/2016 07:31 AM, Zack Weinberg wrote:
>
>> VAR2="`AS_ECHO("$VAR") | sed 's/text1//g'`"
>
> 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.

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

_______________________________________________
Autoconf mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/autoconf