Subject: bug#32703: echo_man_error

From: Bernhard Voelker <[email-masked]>
Date: Mon, 24 Sep 2018 23:47:39 +0200

On 9/24/18 4:48 AM, Pádraig Brady wrote:
> I'll push the attached later.
> Interesting there were no echo tests until now.

Nice work, indeed.

Additionally to Eric's comment, I'd suggest to increase the coverage
for 'echo' to about 100% [1] with the attached patch:

*  src/echo.c (usage): Assert that STATUS is always EXIT_SUCCESS.
* tests/misc/echo.sh: Add further tests for all hex and escape and
escape characters.

You may simply squash it in.

[1] To get coverage statistic, run:
  make coverage -j 4 TESTS=tests/misc/echo.sh SUBDIRS=.
  xdg-open file:doc/coverage/src/echo.c.gcov.frameset.html

Have a nice day,
Berny
diff --git a/src/echo.c b/src/echo.c
index 2aee5acfb..062f9038c 100644
--- a/src/echo.c
+++ b/src/echo.c
@@ -16,6 +16,7 @@
 
 #include <config.h>
 #include <stdio.h>
+#include <assert.h>
 #include <sys/types.h>
 #include "system.h"
 
@@ -34,35 +35,35 @@ enum { DEFAULT_ECHO_TO_XPG = false };
 void
 usage (int status)
 {
-  if (status != EXIT_SUCCESS)
-    emit_try_help ();
-  else
-    {
-      printf (_("\
+  /* STATUS should always be EXIT_SUCCESS (unlike in most other
+     utilities which would call emit_try_help otherwise).  */
+  assert (status == EXIT_SUCCESS);
+
+  printf (_("\
 Usage: %s [SHORT-OPTION]... [STRING]...\n\
   or:  %s LONG-OPTION\n\
 "), program_name, program_name);
-      fputs (_("\
+  fputs (_("\
 Echo the STRING(s) to standard output.\n\
 \n\
   -n             do not output the trailing newline\n\
 "), stdout);
-      fputs (_(DEFAULT_ECHO_TO_XPG
-               ? N_("\
+  fputs (_(DEFAULT_ECHO_TO_XPG
+           ? N_("\
   -e             enable interpretation of backslash escapes (default)\n\
   -E             disable interpretation of backslash escapes\n")
-               : N_("\
+           : N_("\
   -e             enable interpretation of backslash escapes\n\
   -E             disable interpretation of backslash escapes (default)\n")),
-             stdout);
-      fputs (HELP_OPTION_DESCRIPTION, stdout);
-      fputs (VERSION_OPTION_DESCRIPTION, stdout);
-      fputs (_("\
+         stdout);
+  fputs (HELP_OPTION_DESCRIPTION, stdout);
+  fputs (VERSION_OPTION_DESCRIPTION, stdout);
+  fputs (_("\
 \n\
 If -e is in effect, the following sequences are recognized:\n\
 \n\
 "), stdout);
-      fputs (_("\
+  fputs (_("\
   \\\\      backslash\n\
   \\a      alert (BEL)\n\
   \\b      backspace\n\
@@ -74,13 +75,12 @@ If -e is in effect, the following sequences are recognized:\n\
   \\t      horizontal tab\n\
   \\v      vertical tab\n\
 "), stdout);
-      fputs (_("\
+  fputs (_("\
   \\0NNN   byte with octal value NNN (1 to 3 digits)\n\
   \\xHH    byte with hexadecimal value HH (1 to 2 digits)\n\
 "), stdout);
-      printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
-      emit_ancillary_info (PROGRAM_NAME);
-    }
+  printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
+  emit_ancillary_info (PROGRAM_NAME);
   exit (status);
 }
 
diff --git a/tests/misc/echo.sh b/tests/misc/echo.sh
index 133b52a35..c3d67cf1b 100755
--- a/tests/misc/echo.sh
+++ b/tests/misc/echo.sh
@@ -63,4 +63,37 @@ foo
 EOF
 compare exp out || fail=1
 
+# Further test coverage.
+# Output a literal '-' (on a line itself).
+$prog - > out || fail=1
+# Output a literal backslash '\', no newline.
+$prog -n -e '\\' >> out || fail=1
+# Output an empty line (merely to have a newline after the previous test).
+$prog >> out || fail=1
+# Test other characters escaped by a backslash:
+# \a  hex 07  alert, bell
+# \b  hex 08  backspace
+# \e  hex 1b  escape
+# \f  hex 0c  form feed
+# \n  hex 0a  new line
+# \r  hex 0d  carriage return
+# \t  hex 09  horizontal tab
+# \v  hex 0b  vertical tab
+# Convert output, yet checking the exit status of $prog.
+{ $prog -n -e '\a\b\e\f\n\r\t\v' || touch fail; } | od -tx1 >> out || fail=1
+test '!' -f fail || fail=1
+# Output hex values which contain hexadecimal characters to test hextobin().
+# Hex values 4a through 4f are ASCII "JKLMNO".
+$prog -n -e '\x4a\x4b\x4c\x4d\x4e\x4f\x4A\x4B\x4C\x4D\x4E\x4F' >> out || fail=1
+# Output another newline.
+$prog >> out || fail=1
+cat <<\EOF > exp
+-
+\
+0000000 07 08 1b 0c 0a 0d 09 0b
+0000010
+JKLMNOJKLMNO
+EOF
+compare exp out || fail=1
+
 Exit $fail