Clean up AS_MESSAGE_LOG_FD usage.

* lib/m4sugar/m4sh.m4 (AS_MESSAGE_FD, AS_MESSAGE_LOG_FD)
(AS_ORIGINAL_STDIN_FD): Provide default M4sh values.
(_AS_ECHO_LOG, AS_MESSAGE, _AS_ERROR_PREPARE, AS_ERROR): Simplify
usage.
(AS_INIT_GENERATED): Don't shuffle an unchanged AS_MESSAGE_FD.
* tests/m4sh.at (AS@&t@_INIT_GENERATED): Update test.
(AS@&t@_MESSAGE_FD): New test.
* doc/autoconf.texi (Initialization Macros) <AS_INIT_GENERATED>:
Give more details about fd manipulation.
(File Descriptor Macros): Describe M4sh defaults for the fds.

Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
Eric Blake 2008-11-21 15:50:37 -07:00
parent 48d8391ff3
commit 2cc7d57a17
4 changed files with 157 additions and 22 deletions

View File

@ -1,3 +1,17 @@
2008-11-21 Eric Blake <ebb9@byu.net>
Clean up AS_MESSAGE_LOG_FD usage.
* lib/m4sugar/m4sh.m4 (AS_MESSAGE_FD, AS_MESSAGE_LOG_FD)
(AS_ORIGINAL_STDIN_FD): Provide default M4sh values.
(_AS_ECHO_LOG, AS_MESSAGE, _AS_ERROR_PREPARE, AS_ERROR): Simplify
usage.
(AS_INIT_GENERATED): Don't shuffle an unchanged AS_MESSAGE_FD.
* tests/m4sh.at (AS@&t@_INIT_GENERATED): Update test.
(AS@&t@_MESSAGE_FD): New test.
* doc/autoconf.texi (Initialization Macros) <AS_INIT_GENERATED>:
Give more details about fd manipulation.
(File Descriptor Macros): Describe M4sh defaults for the fds.
2008-11-21 Eric Blake <ebb9@byu.net>
Use shell function for AS_ERROR.

View File

@ -12500,15 +12500,21 @@ populates the child script with information learned from the parent
(thus, the emitted code is equivalent in effect, but more efficient,
than the code output by @code{AS_INIT}, @code{AS_BOURNE_COMPATIBLE}, and
@code{AS_SHELL_SANITIZE}). If present, @var{comment} is output near the
beginning of the child, prior to the shell initialization code. The
beginning of the child, prior to the shell initialization code, and is
subject to parameter expansion, command substitution, and backslash
quote removal. The
parent script should check the exit status after this macro, in case
@var{file} could not be properly created (for example, if the disk was
full). If successfully created, the parent script can then proceed to
append additional M4sh constructs into the child script.
Note that the child script starts life without a log file open, so you
Note that the child script starts life without a log file open, so if
the parent script uses logging (@pxref{AS_MESSAGE_LOG_FD}), you
must temporarily disable any attempts to use the log file until after
emitting code to open a log within the child. Currently, the suggested
emitting code to open a log within the child. On the other hand, if the
parent script has @code{AS_MESSAGE_FD} redirected somewhere besides
@samp{1}, then the child script already has code that copies stdout to
that descriptor. Currently, the suggested
idiom for writing a M4sh shell script from within another script is:
@example
@ -12583,27 +12589,36 @@ level macros as described below.
@defmac AS_MESSAGE_FD
@asindex{MESSAGE_FD}
The file descriptor for @samp{checking for...} messages and results.
Normally this directs messages to the standard output, however when
@command{configure} is run with the @option{-q} option, messages sent to
@code{AS_MESSAGE_FD} are discarded.
By default, @code{AS_INIT} sets this to @samp{1} for standalone M4sh
clients. However, @code{AC_INIT} shuffles things around to another file
descriptor, in order to allow the @option{-q} option of
@command{configure} to choose whether messages should go to the script's
standard output or be discarded.
If you want to display some messages, consider using one of the printing
macros (@pxref{Printing Messages}) instead. Copies of messages output
via these macros are also recorded in @file{config.log}.
@end defmac
@anchor{AS_MESSAGE_LOG_FD}
@defmac AS_MESSAGE_LOG_FD
@asindex{MESSAGE_LOG_FD}
The file descriptor for messages logged to @file{config.log}. Macros
that run tools, like @code{AC_COMPILE_IFELSE} (@pxref{Running the
This must either be empty, or expand to a file descriptor for log
messages. By default, @code{AS_INIT} sets this macro to the empty
string for standalone M4sh clients, thus disabling logging. However,
@code{AC_INIT} shuffles things around so that both @command{configure}
and @command{config.status} use @file{config.log} for log messages.
Macros that run tools, like @code{AC_COMPILE_IFELSE} (@pxref{Running the
Compiler}), redirect all output to this descriptor. You may want to do
so if you develop such a low-level macro.
@end defmac
@defmac AS_ORIGINAL_STDIN_FD
@asindex{ORIGINAL_STDIN_FD}
The file descriptor for the original standard input.
This must expand to a file descriptor for the original standard input.
By default, @code{AS_INIT} sets this macro to @samp{0} for standalone
M4sh clients. However, @code{AC_INIT} shuffles things around for
safety.
When @command{configure} runs, it may accidentally execute an
interactive command that has the same name as the non-interactive meant

View File

@ -658,8 +658,30 @@ m4_defun([AS_UNSET],
## 3. Error and warnings at the shell level. ##
## ------------------------------------------ ##
# If AS_MESSAGE_LOG_FD is defined, shell messages are duplicated there
# too.
# AS_MESSAGE_FD
# -------------
# Must expand to the fd where messages will be sent. Defaults to 1,
# although a script may reassign this value and use exec to either
# copy stdout to the new fd, or open the new fd on /dev/null.
m4_define([AS_MESSAGE_FD], [1])
# AS_MESSAGE_LOG_FD
# -----------------
# Must expand to either the empty string (when no logging is
# performed), or to the fd of a log file. Defaults to empty, although
# a script may reassign this value and use exec to open a log. When
# not empty, messages to AS_MESSAGE_FD are duplicated to the log,
# along with a LINENO reference.
m4_define([AS_MESSAGE_LOG_FD])
# AS_ORIGINAL_STDIN_FD
# --------------------
# Must expand to the fd of the script's original stdin. Defaults to
# 0, although the script may reassign this value and use exec to
# shuffle fd's.
m4_define([AS_ORIGINAL_STDIN_FD], [0])
# AS_ESCAPE(STRING, [CHARS = $"`\])
@ -730,7 +752,7 @@ m4_define([_AS_ECHO],
# Log the string to AS_MESSAGE_LOG_FD.
m4_defun_init([_AS_ECHO_LOG],
[AS_REQUIRE([_AS_LINENO_PREPARE])],
[_AS_ECHO([$as_me:${as_lineno-$LINENO}: $1], [AS_MESSAGE_LOG_FD])])
[_AS_ECHO([$as_me:${as_lineno-$LINENO}: $1], AS_MESSAGE_LOG_FD)])
# _AS_ECHO_N_PREPARE
@ -765,10 +787,11 @@ m4_define([_AS_ECHO_N],
# AS_MESSAGE(STRING, [FD = AS_MESSAGE_FD])
# ----------------------------------------
# Output "`basename $0`: "STRING to the open file FD.
# Output "`basename $0`: STRING" to the open file FD, and if logging
# is enabled, copy it to the log with a reference to LINENO.
m4_defun_init([AS_MESSAGE],
[AS_REQUIRE([_AS_ME_PREPARE])],
[m4_ifset([AS_MESSAGE_LOG_FD],
[m4_ifval(AS_MESSAGE_LOG_FD,
[{ _AS_ECHO_LOG([$1])
_AS_ECHO([$as_me: $1], [$2]);}],
[_AS_ECHO([$as_me: $1], [$2])])[]])
@ -792,15 +815,15 @@ m4_define([AS_WARN],
# otherwise, assume the entire script does not do logging.
m4_define([_AS_ERROR_PREPARE],
[AS_REQUIRE_SHELL_FN([as_fn_error],
[AS_FUNCTION_DESCRIBE([as_fn_error], [ERROR]m4_ifset([AS_MESSAGE_LOG_FD],
[AS_FUNCTION_DESCRIBE([as_fn_error], [ERROR]m4_ifval(AS_MESSAGE_LOG_FD,
[[ [[LINENO LOG_FD]]]]),
[Output "`basename @S|@0`: error: ERROR" to stderr.]
m4_ifset([AS_MESSAGE_LOG_FD],
m4_ifval(AS_MESSAGE_LOG_FD,
[[If LINENO and LOG_FD are provided, also output the error to LOG_FD,
referencing LINENO.]])
[Then exit the script with status $?, using 1 if that was 0.])],
[ as_status=$?; test $as_status -eq 0 && as_status=1
m4_ifset([AS_MESSAGE_LOG_FD],
m4_ifval(AS_MESSAGE_LOG_FD,
[m4_pushdef([AS_MESSAGE_LOG_FD], [$[3]])dnl
if test "$[3]"; then
AS_LINENO_PUSH([$[2]])
@ -819,7 +842,7 @@ m4_defun_init([AS_ERROR],
[m4_append_uniq([_AS_CLEANUP],
[m4_divert_text([M4SH-INIT-FN], [_AS_ERROR_PREPARE[]])])],
[m4_ifvaln([$2], [{ AS_SET_STATUS([$2])])]dnl
[as_fn_error "_AS_QUOTE([$1])"m4_ifset([AS_MESSAGE_LOG_FD],
[as_fn_error "_AS_QUOTE([$1])"m4_ifval([AS_MESSAGE_LOG_FD],
[ "$LINENO" AS_MESSAGE_LOG_FD])[]m4_ifval([$2], [; }])])
@ -1986,8 +2009,9 @@ _ASEOF
cat >>$1 <<\_ASEOF || as_write_fail=1
_AS_SHELL_SANITIZE
_AS_PREPARE
exec AS_MESSAGE_FD>&1
m4_text_box([Main body of $1 script.])
m4_if(AS_MESSAGE_FD, [1], [], [exec AS_MESSAGE_FD>&1
])]dnl
[m4_text_box([Main body of $1 script.])
_ASEOF
test $as_write_fail = 0 && chmod +x $1[]dnl
_m4_popdef([AS_MESSAGE_LOG_FD])])# AS_INIT_GENERATED

View File

@ -1259,9 +1259,10 @@ AT_CLEANUP
## ------------------- ##
AT_SETUP([AS@&t@_INIT_GENERATED])
AT_KEYWORDS([AS@&t@_MESSAGE AS@&t@_MESSAGE_LOG_FD])
dnl First run, no logging, tests shell selection
AT_DATA_M4SH([script.as], [[dnl
m4_define([AS_MESSAGE_FD], [1])
AS_INIT
AS_INIT_GENERATED([child], [echo hello from child])
cat >>child <<\EOF
@ -1286,4 +1287,85 @@ AT_CHECK([grep 'SHELL=.' stdout], [0], [ignore])
sed s/parent/child/ <stdout >expout
AT_CHECK([./child], [0], [expout])
dnl Second run, with logging from parent and child, tests fd handling
AT_DATA_M4SH([script.as], [[dnl
AS_INIT
child=${1-child}
m4_define([AS_MESSAGE_LOG_FD], [5])
exec AS_MESSAGE_LOG_FD>log
AS_INIT_GENERATED([$child], [echo hello1 from $child]) || AS_EXIT([1])
cat >>$child <<\EOF
m4_pushdef([AS_MESSAGE_LOG_FD])
AS_MESSAGE([hello2 from ${child}child])
m4_popdef([AS_MESSAGE_LOG_FD])
exec AS_MESSAGE_LOG_FD>>log
AS_MESSAGE([hello3 from child])
EOF
AS_MESSAGE([hello from parent])
dnl close log in parent before spawning child, for mingw
exec AS_MESSAGE_LOG_FD>-
./$child
]])
AT_CHECK_M4SH
AT_CHECK([./script], [0], [[script: hello from parent
hello1 from child
child: hello2 from child
child: hello3 from child
]])
AT_CHECK([[sed 's,:[0-9][0-9]*:,:0:,' log]], [0],
[[script:0: hello from parent
child:0: hello3 from child
]])
# Force write error creating a file on stdout
if test -w /dev/full && test -c /dev/full; then
AT_CHECK([./script /dev/full], [1], [ignore], [ignore])
fi
AT_CLEANUP
## --------------- ##
## AS_MESSAGE_FD. ##
## --------------- ##
AT_SETUP([AS@&t@_MESSAGE_FD])
AT_KEYWORDS([AS@&t@_MESSAGE AS@&t@_MESSAGE_LOG_FD AS@&t_ORIGINAL_STDIN_FD])
AT_KEYWORDS([AS@&t@_LINENO_PUSH])
AT_DATA_M4SH([script.as], [[dnl
AS_INIT
m4_define([AS_ORIGINAL_STDIN_FD], [5])
m4_define([AS_MESSAGE_LOG_FD], [6])
m4_define([AS_MESSAGE_FD], [7])
exec AS_ORIGINAL_STDIN_FD<&0 </dev/null AS_MESSAGE_LOG_FD>log
if test $[#] -gt 0; then
exec AS_MESSAGE_FD>/dev/null
else
exec AS_MESSAGE_FD>&1
fi
AS_LINENO_PUSH([100])
cat # tests that stdin is neutralized
AS_MESSAGE([hello world])
cat <&AS_ORIGINAL_STDIN_FD
]])
AT_CHECK_M4SH
AT_CHECK([echo goodbye | ./script], [0],
[[script: hello world
goodbye
]])
AT_CHECK([cat log], [0],
[[script:100: hello world
]])
rm log
AT_CHECK([echo goodbye | ./script silent], [0],
[[goodbye
]])
AT_CHECK([cat log], [0],
[[script:100: hello world
]])
AT_CLEANUP