From 6b7218e1ae606329bf2e45b08e2e46cb9f0fc998 Mon Sep 17 00:00:00 2001
From: Eric Gillespie <epg@pretzelnet.org>
Date: Thu, 14 Aug 2008 01:50:45 +0000
Subject: [PATCH] 	* sbr/ambigsw.c: Send print_sw output to stderr.  This
 avoids 	strange problems with scan `pick -bogus`, not to mention being
 	nicer anyway.

	* sbr/getans.c, sbr/print_help.c, uip/msh.c: Send print_sw output
	to stdout.

	* h/prototypes.h, sbr/print_sw.c (print_sw): Add FILE * argument
	and send output there rather than to stdout.

	* test/tests/pick/test-stderr: Add test that error messages don't
	end up going to stdout.
---
 ChangeLog                   | 15 +++++++++++++++
 h/prototypes.h              |  2 +-
 sbr/ambigsw.c               |  2 +-
 sbr/getans.c                |  2 +-
 sbr/print_help.c            |  2 +-
 sbr/print_sw.c              |  7 ++++---
 test/tests/pick/test-stderr | 24 ++++++++++++++++++++++++
 uip/msh.c                   |  4 ++--
 8 files changed, 49 insertions(+), 9 deletions(-)
 create mode 100644 test/tests/pick/test-stderr

diff --git a/ChangeLog b/ChangeLog
index f3eb541b..60587481 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-08-13  Eric Gillespie  <epg@pretzelnet.org>
+
+	* sbr/ambigsw.c: Send print_sw output to stderr.  This avoids
+	strange problems with scan `pick -bogus`, not to mention being
+	nicer anyway.
+
+	* sbr/getans.c, sbr/print_help.c, uip/msh.c: Send print_sw output
+	to stdout.
+
+	* h/prototypes.h, sbr/print_sw.c (print_sw): Add FILE * argument
+	and send output there rather than to stdout.
+
+	* test/tests/pick/test-stderr: Add test that error messages don't
+	end up going to stdout.
+
 2008-08-13  Eric Gillespie  <epg@pretzelnet.org>
 
 	* uip/pick.c: Print matching messages immediately, instead of
diff --git a/h/prototypes.h b/h/prototypes.h
index d10346f3..1de40677 100644
--- a/h/prototypes.h
+++ b/h/prototypes.h
@@ -91,7 +91,7 @@ int pidwait (pid_t, int);
 int pidstatus (int, FILE *, char *);
 char *pluspath(char *);
 void print_help (char *, struct swit *, int);
-void print_sw (char *, struct swit *, char *);
+void print_sw (char *, struct swit *, char *, FILE *);
 void print_version (char *);
 void push (void);
 char *pwd (void);
diff --git a/sbr/ambigsw.c b/sbr/ambigsw.c
index 53c8da1a..42796b34 100644
--- a/sbr/ambigsw.c
+++ b/sbr/ambigsw.c
@@ -16,5 +16,5 @@ void
 ambigsw (char *arg, struct swit *swp)
 {
     advise (NULL, "-%s ambiguous.  It matches", arg);
-    print_sw (arg, swp, "-");
+    print_sw (arg, swp, "-", stderr);
 }
diff --git a/sbr/getans.c b/sbr/getans.c
index 4feb3b90..deb884e1 100644
--- a/sbr/getans.c
+++ b/sbr/getans.c
@@ -50,7 +50,7 @@ getans (char *prompt, struct swit *ansp)
 	*cp = '\0';
 	if (ansbuf[0] == '?' || cp == ansbuf) {
 	    printf ("Options are:\n");
-	    print_sw (ALL, ansp, "");
+	    print_sw (ALL, ansp, "", stdout);
 	    continue;
 	}
 	cpp = brkstring (ansbuf, " ", NULL);
diff --git a/sbr/print_help.c b/sbr/print_help.c
index 17744559..a7bc7e53 100644
--- a/sbr/print_help.c
+++ b/sbr/print_help.c
@@ -23,7 +23,7 @@ print_help (char *str, struct swit *swp, int print_context)
 
     /* print all the switches */
     printf ("  switches are:\n");
-    print_sw (ALL, swp, "-");
+    print_sw (ALL, swp, "-", stdout);
 
     /*
      * check if we should print any profile entries
diff --git a/sbr/print_sw.c b/sbr/print_sw.c
index 426724b4..bd7b5aa2 100644
--- a/sbr/print_sw.c
+++ b/sbr/print_sw.c
@@ -13,7 +13,7 @@
 
 
 void
-print_sw (char *substr, struct swit *swp, char *prefix)
+print_sw (char *substr, struct swit *swp, char *prefix, FILE *fp)
 {
     int len, optno;
     register int i;
@@ -45,10 +45,11 @@ print_sw (char *substr, struct swit *swp, char *prefix)
 		    *cp++ = *cp1++;
 		*cp++ = ')';
 		while ((*cp++ = *cp1++));
-		printf ("  %s%s\n", prefix, buf);
+		fprintf (fp, "  %s%s\n", prefix, buf);
 	    } else {
 		if (!swp->minchars)
-		    printf(optno ? "  %s[no]%s\n" : "  %s%s\n", prefix, swp->sw);
+		    fprintf(fp, optno ? "  %s[no]%s\n" : "  %s%s\n",
+                            prefix, swp->sw);
 	    }
 	    if (optno)
 		swp++;	/* skip -noswitch */
diff --git a/test/tests/pick/test-stderr b/test/tests/pick/test-stderr
new file mode 100644
index 00000000..35a64efb
--- /dev/null
+++ b/test/tests/pick/test-stderr
@@ -0,0 +1,24 @@
+#!/bin/sh
+######################################################
+#
+# Test that errors are not written to stdout.
+#
+######################################################
+
+expected_err=$MH_TEST_DIR/$$.expected_err
+expected_out=$MH_TEST_DIR/$$.expected_out
+actual_err=$MH_TEST_DIR/$$.actual_err
+actual_out=$MH_TEST_DIR/$$.actual_out
+
+# Error message should go to stderr.
+cat > $expected_err <<EOF
+pick: -a ambiguous.  It matches
+  -and
+  -after date
+EOF
+# Nothing should to go stdout.
+cat /dev/null > $expected_out
+
+pick -a > $actual_out 2> $actual_err
+diff -u $expected_err $actual_err
+diff -u $expected_out $actual_out
diff --git a/uip/msh.c b/uip/msh.c
index 6d6fbca2..d87f92ea 100644
--- a/uip/msh.c
+++ b/uip/msh.c
@@ -1475,7 +1475,7 @@ getargs (char *prompt, struct swit *sw, struct Cmd *cmdp)
 	    continue;
 	if (buffer[0] == '?') {
 	    printf ("commands:\n");
-	    print_sw (ALL, sw, "");
+	    print_sw (ALL, sw, "", stdout);
 	    printf ("type CTRL-D or use ``quit'' to leave %s\n",
 		    invo_name);
 	    continue;
@@ -2142,7 +2142,7 @@ pCMD (char *str, struct swit *sw, struct Cmd *cmdp)
 
 	    case OK: 
 		printf ("commands:\n");
-		print_sw (ALL, sw, "");
+		print_sw (ALL, sw, "", stdout);
 		printf ("type ``quit'' to leave %s\n", invo_name);
 		fflush (stdout);
 		fflush (stderr);
-- 
2.39.5