add some fd tests to head

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
I still need to add more tests from the mailing lists, but here is a group of 
tests that expose current shortfalls in handling closed fds.

2006-10-04  Eric Blake  <[email protected]>

	* tests/builtins.at: Alphabetize tests.
	* tests/testsuite.at (AT_CHECK_M4): Allow choosing stdin.
	* tests/generate.awk (new_test): Fix underquoting.
	* tests/others.at (maketemp): Rename from misc.
	(stdin closed, stdout closed, stderr closed): New tests.

Index: tests/builtins.at
===================================================================
RCS file: /sources/m4/m4/tests/builtins.at,v
retrieving revision 1.19
diff -u -r1.19 builtins.at
--- tests/builtins.at	18 Sep 2006 13:16:44 -0000	1.19
+++ tests/builtins.at	4 Oct 2006 23:26:49 -0000
@@ -19,6 +19,43 @@
 AT_BANNER([Torturing builtins.])
 
 
+## ----- ##
+## debug ##
+## ----- ##
+
+AT_SETUP([debug])
+
+AT_DATA([[debug.m4]],
+[[define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', 
`Liftoff')')
+debugmode(`aeqc')
+traceon(`countdown')
+countdown(2)
+]])
+
+AT_DATA([[expout]],
+[[
+
+
+2 1 0 Liftoff
+]])
+
+AT_DATA([[experr]],
+[[m4trace: -1- countdown ...
+m4trace: -1- countdown(`2') -> ???
+m4trace: -1- countdown(...) -> `2 ifelse(eval(2 > 0), 1, `countdown(decr(2))', 
`Liftoff')'
+m4trace: -1- countdown ...
+m4trace: -1- countdown(`1') -> ???
+m4trace: -1- countdown(...) -> `1 ifelse(eval(1 > 0), 1, `countdown(decr(1))', 
`Liftoff')'
+m4trace: -1- countdown ...
+m4trace: -1- countdown(`0') -> ???
+m4trace: -1- countdown(...) -> `0 ifelse(eval(0 > 0), 1, `countdown(decr(0))', 
`Liftoff')'
+]])
+
+AT_CHECK_M4([debug.m4], 0, expout, experr)
+
+AT_CLEANUP
+
+
 ## ------ ##
 ## define ##
 ## ------ ##
@@ -78,45 +115,6 @@
 AT_CLEANUP
 
 
-
-## ----- ##
-## debug ##
-## ----- ##
-
-AT_SETUP([debug])
-
-AT_DATA([[debug.m4]],
-[[define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', 
`Liftoff')')
-debugmode(`aeqc')
-traceon(`countdown')
-countdown(2)
-]])
-
-AT_DATA([[expout]],
-[[
-
-
-2 1 0 Liftoff
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- countdown ...
-m4trace: -1- countdown(`2') -> ???
-m4trace: -1- countdown(...) -> `2 ifelse(eval(2 > 0), 1, `countdown(decr(2))', 
`Liftoff')'
-m4trace: -1- countdown ...
-m4trace: -1- countdown(`1') -> ???
-m4trace: -1- countdown(...) -> `1 ifelse(eval(1 > 0), 1, `countdown(decr(1))', 
`Liftoff')'
-m4trace: -1- countdown ...
-m4trace: -1- countdown(`0') -> ???
-m4trace: -1- countdown(...) -> `0 ifelse(eval(0 > 0), 1, `countdown(decr(0))', 
`Liftoff')'
-]])
-
-AT_CHECK_M4([debug.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-
 ## ------- ##
 ## esyscmd ##
 ## ------- ##
Index: tests/generate.awk
===================================================================
RCS file: /sources/m4/m4/tests/generate.awk,v
retrieving revision 1.20
diff -u -r1.20 generate.awk
--- tests/generate.awk	4 Oct 2006 03:57:01 -0000	1.20
+++ tests/generate.awk	4 Oct 2006 23:26:49 -0000
@@ -175,7 +175,8 @@
   if (options ~ /-I/)
     {
       printf ("AT_DATA([expout1],\n[[%s]])\n", output);
-      printf ("sed -e \"s|\\.\\./examples|$abs_top_srcdir/examples|g\" \\\n");
+      printf ("sed -e \"s|\\\\.\\\\./examples|"\
+	      "$abs_top_srcdir/examples|g\" \\\n");
       printf ("  < expout1 > expout\n\n");
     }
 
Index: tests/others.at
===================================================================
RCS file: /sources/m4/m4/tests/others.at,v
retrieving revision 1.19
diff -u -r1.19 others.at
--- tests/others.at	5 Sep 2006 17:28:45 -0000	1.19
+++ tests/others.at	4 Oct 2006 23:26:49 -0000
@@ -286,11 +286,11 @@
 
 
 
-## ---- ##
-## misc ##
-## ---- ##
+## -------- ##
+## maketemp ##
+## -------- ##
 
-AT_SETUP([misc])
+AT_SETUP([maketemp])
 
 [cat >expout <<EOF
 different
@@ -338,6 +338,129 @@
 AT_CLEANUP
 
 
+## ------------- ##
+## stderr closed ##
+## ------------- ##
+
+AT_SETUP([stderr closed])
+
+dnl no error when stderr is not used
+AT_CHECK_M4([2>&-], [0])
+
+dnl no error when stderr is not used
+AT_DATA([in.m4], [[hello world
+]])
+AT_CHECK_M4([in.m4], [0], [[hello world
+]])
+
+dnl must exit nonzero when error issued
+AT_CHECK([--unknown], [1])
+
+dnl must exit nonzero if stderr used
+AT_DATA([in.m4], [[errprint(`hello world
+')dnl
+]])
+AT_CHECK_M4([in.m4 2>&-], [1])
+
+dnl must exit nonzero if stderr used
+AT_DATA([in.m4], [[dnl(`hello world')
+]])
+AT_CHECK_M4([in.m4 2>&-], [1])
+
+dnl must exit nonzero on error, in spite of m4exit
+AT_DATA([in.m4], [[errprint(`hello world
+')m4exit(`0')
+]])
+AT_CHECK_M4([in.m4 2>&-], [1])
+
+dnl trace file must not collide with closed stderr
+AT_DATA([in.m4], [[errprint(`hello world
+')dnl
+]])
+AT_CHECK_M4([--debugfile=trace -terrprint in.m4 2>&-], [1])
+AT_CHECK([cat trace], [0], [[m4trace: -1- errprint(`hello world
+')
+]])
+
+AT_CLEANUP
+
+
+## ------------ ##
+## stdin closed ##
+## ------------ ##
+
+AT_SETUP([stdin closed])
+
+dnl no error when stdin is not used due to early exit
+AT_CHECK_M4([--version], [0], [ignore], [], [-])
+
+dnl no error when stdin is not used due to supplied file
+AT_DATA([in.m4], [[hello world
+]])
+AT_CHECK_M4([in.m4], [0], [[hello world
+]], [], [-])
+
+dnl error when stdin must be read
+AT_CHECK_M4([], [1], [],
+[[m4:stdin:1: error reading file `stdin'
+]], [-])
+
+dnl error when stdin must be read
+AT_CHECK_M4([-], [1], [],
+[[m4:stdin:1: error reading file `stdin'
+]], [-])
+
+dnl only error once when stdin must be read
+AT_CHECK_M4([- in.m4 -], [1], [[hello world
+]], [[m4:stdin:1: error reading file `stdin'
+]], [-])
+
+AT_CLEANUP
+
+## ------------- ##
+## stdout closed ##
+## ------------- ##
+
+AT_SETUP([stdout closed])
+
+dnl error when stdout must be used
+AT_CHECK_M4([--version >&-], [1], [],
+[[m4: write error: Bad file descriptor
+]])
+
+dnl no error when stdout is not used
+AT_CHECK_M4([>&-], [0])
+
+dnl no error when stdout is not used
+AT_DATA([in.m4], [[errprint(`hello world
+')dnl
+]])
+AT_CHECK_M4([in.m4 >&-], [0], [], [[hello world
+]])
+
+dnl error when stdout must be used
+AT_CHECK_M4([-P in.m4 >&-], [1], [],
+[[m4: write error: Bad file descriptor
+]])
+
+dnl error must occur in spite of m4exit requesting 0
+AT_DATA([in.m4], [[hello world
+m4exit(`0')
+]])
+AT_CHECK_M4([in.m4 >&-], [1], [],
+[[m4: write error: Bad file descriptor
+]])
+
+dnl trace file must not collide with closed stdout
+AT_DATA([in.m4], [[hello world
+]])
+AT_CHECK_M4([--debugfile=trace in.m4 >&-], [1], [],
+[[m4: write error: Bad file descriptor
+]])
+AT_CHECK([cat trace])
+
+AT_CLEANUP
+
 
 ## --------- ##
 ## sysv-args ##
Index: tests/testsuite.at
===================================================================
RCS file: /sources/m4/m4/tests/testsuite.at,v
retrieving revision 1.23
diff -u -r1.23 testsuite.at
--- tests/testsuite.at	29 Sep 2006 18:20:13 -0000	1.23
+++ tests/testsuite.at	4 Oct 2006 23:26:49 -0000
@@ -21,11 +21,14 @@
 # We need a recent Autotest.
 m4_version_prereq([2.52e])
 
-# AT_CHECK_M4(ARGS, [EXIT-STATUS = 0], [STDOUT = `'], [STDERR = `'])
+# AT_CHECK_M4(ARGS, [EXIT-STATUS = 0], [STDOUT = `'], [STDERR = `'],
+#             [STDIN = `/dev/null'])
 # ------------------------------------------------------------------
-# Run m4 with ARGS, and stdin redirected from /dev/null.  Expect EXIT-STATUS,
-# with output matching STDOUT and STDERR as in AT_CHECK.  If stderr is
-# specified, normalize the observed error output.
+# Run m4 with ARGS, and stdin redirected from STDIN, or with stdin closed
+# if STDIN is `-'.  ARGS may redirect stdout and/or stderr, but should
+# not redirect stdin.  Expect EXIT-STATUS, with output matching STDOUT and
+# STDERR as in AT_CHECK.  If STDERR is specified, normalize the observed
+# error output.
 #
 # When testing an uninstalled wrapper, tests/m4 is on the path, but invokes
 # src/m4, which may itself be a libtool wrapper.  Also, some platforms
@@ -44,7 +47,9 @@
 # or m4:input.m4:7: cannot open module `no_such': can't open the module
 # to m4:input.m4:7: cannot open module `no_such'
 m4_define([AT_CHECK_M4],
-[AT_CHECK([m4 -b -d $1 < /dev/null], [$2], [$3], m4_ifval([$4], [stderr]))
+[AT_CHECK([m4 -b -d $1 m4_if([$5], [-], [<&-],
+			     [< m4_default([$5], [/dev/null])])],
+          [$2], [$3], m4_ifval([$4], [stderr]))
 m4_if([$4], [], [],
       [$4], [ignore], [],
 [AT_CHECK([[sed 's/^[^:]*[lt-]*m4[.ex]*:/m4:/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.