bug-autoconf
[Top][All Lists]
Advanced

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

m4sh -- BINSH diversion cannot be cleared


From: Roger Crew
Subject: m4sh -- BINSH diversion cannot be cleared
Date: Sat, 17 Sep 2022 17:24:07 -0700

[...there doesn't seem to be a separate M4SH list,
    apologies if this needs to go elsewhere...]

(problem I'm actually trying to solve in case this is an A/B thing):

    I have an m4sh script. (I want portable, but also care about it not
    being slower than it has to be)

    Some previous run of configure has already figured out the best
    shell to use, etc, and I just want ./configure to be writing that
    into the #! line so that we don't have to redo that test and fork
    every time my script runs, because my script is going to be run A
    LOT.  (... and that if we were worried about missing out on new
    and better shells being installed later, presumably one would want
    to be re-running configure on every change to the build
    environment anyway...)

The obvious thing to do and what I suspect was intended by the 
m4sh authors, otherwise why bother exposing the BINSH diversion?
is this (autom4te -l m4sh - | head) 

AS_INIT
m4_cleardivert([BINSH])dnl
m4_divert_text([BINSH],[@%:@!@BEST_SHELL@])dnl

the point of this being to put

#!@BEST_SHELL@

on the first line of myscript.in.  But instead (as of v.69),
I get this:

#!/bin/sh
#!@BEST_SHELL@

The problem, I believe, is that, under the hood, BINSH is
actually diversion 0, which M4 gives special treatment:
Everything sent there gets output immediately (because you can't
have negative diversions getting in front of it, so why not?),
so that once AS_INIT writes the #!/bin/sh line, it's a done deal.
The subsequent m4_cleardivert() call has nothing to clear.

workaround #1:

m4_divert()[@%:@!@BEST_SHELL@
@%:@   Please pretend this is not here:  ]m4_divert([KILL])dnl
AS_INIT

is annoying because of the superfluous #! line

workaround #2:

m4_copy_force([_m4_divert(KILL)], [_m4_divert(BINSH)])dnl
AS_INIT
m4_divert_text([],[@%:@!@BEST_SHELL@])dnl

to keep AS_INIT from writing that first line is probably venturing
into the realm of Asking For Trouble in its use of private/internal
stuff (even if _m4_divert is used pervasively enough in m4sugar|m4sh
to be unlikely to *ever* be repurposed...).

Suffice it to say, I'm not happy about either of these.

It seems to me, the fundamental mistake is that none of M4sugar, M4sh,
Autoconf, should EVER be using diversion 0 (there's no reason to;
everything sent to non-negative diversions is going to make it out the
door eventually) and that this patch:

--- m4sugar/m4sh.m4     2020-12-25 01:25:29.000000000 -0800
+++ -   2022-09-17 14:35:23.095083010 -0700
@@ -59,13 +59,13 @@
 # DIVERSION-NAME which is supposed to be an actual diversion number.
 # Of course it would be nicer to use m4_case here, instead of zillions
 # of little macros, but it then takes twice longer to run `autoconf'!
-m4_define([_m4_divert(BINSH)],             0)
-m4_define([_m4_divert(HEADER-REVISION)],   1)
-m4_define([_m4_divert(HEADER-COMMENT)],    2)
-m4_define([_m4_divert(HEADER-COPYRIGHT)],  3)
-m4_define([_m4_divert(M4SH-SANITIZE)],     4)
-m4_define([_m4_divert(M4SH-INIT-FN)],      5)
-m4_define([_m4_divert(M4SH-INIT)],         6)
+m4_define([_m4_divert(BINSH)],             1)
+m4_define([_m4_divert(HEADER-REVISION)],   3)
+m4_define([_m4_divert(HEADER-COMMENT)],    4)
+m4_define([_m4_divert(HEADER-COPYRIGHT)],  5)
+m4_define([_m4_divert(M4SH-SANITIZE)],     6)
+m4_define([_m4_divert(M4SH-INIT-FN)],      7)
+m4_define([_m4_divert(M4SH-INIT)],         8)
 m4_define([_m4_divert(BODY)],           1000)



is What You Want, leaves space after BINSH and before the first
Autoconf diversion (10) which are the most likely places that
Future You will want to add stuff, and, in theory, since nobody's
supposed be referring to diversion numbers directly anyway, if this
breaks anything it'll be Their Own Damn Fault.

On the other hand, unless I'm doing something horribly
wrong/misguided in wanting to change the shell, I find it hard to
believe this is the first time this problem has come up.

Meaning what do people actually do here?

Is there some common idiom already?  
If so, it would be worth mentioning this in the M4sh Manual.

Barring that, I suppose the safest way out of this box, given that
people out there probably *are* doing strange shit with diversions,
would be to give AS_INIT some kind of "Don't Write The #! Line" flag,
making the user responsible for writing to BINSH herself.  
But that might be deemed inelegant.

Or is there something else I'm missing?  (*)

If not, then please consider this a feature request,
(any of the above patch, the idiom-mention in the manual,
or the AS_INIT option,...)

Thanks.


(*) I know about AS_INIT_GENERATED for making shell scripts that
run after ./configure.  

However that seems to be tailored for creating config.status,
which I'm guessing is the only thing currently that uses it.  
If I do an AS_INIT_GENERATED as part of AC_CONFIG_COMMANDS, 
that seems to dump lots of autoconf baggage at the front 
of my script, e.g., preparations for every shell function 
that configure.ac/config.status needs that my script dosn't.  

And if I write my own configure-time script that initializes with
AS_INIT and then uses AS_INIT_GENERATED to generate the script I
care about, I seem to be get the exact same output as when I have 
my script do AS_INIT directly, i.e., all of the configure-time
testing (e.g., which shell? let's feed thousands of characters 
to echo and see if it breaks?  etc) that I want to skip in later
runs of my script ends up there anyway.

... also seems to me the Autotest folks should care about this
but they seem to have punted on this problem.


--
Roger Crew
crew@cs.stanford.edu, wrog@cpan.org
206.940.5732



reply via email to

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