summaryrefslogtreecommitdiff
path: root/src/echo.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-01-20 10:55:18 +0000
commit70e9163c9c18e995515598085cb824e554eb7ae7 (patch)
treea42dc8b2a6c031354bf31472de888bfc8a060132 /src/echo.c
parentcbf5993c43f49281173f185863577d86bfac6eae (diff)
downloadcoreutils-tarball-master.tar.gz
Diffstat (limited to 'src/echo.c')
-rw-r--r--src/echo.c320
1 files changed, 158 insertions, 162 deletions
diff --git a/src/echo.c b/src/echo.c
index 5f8582c..977bd5f 100644
--- a/src/echo.c
+++ b/src/echo.c
@@ -1,10 +1,10 @@
/* echo.c, derived from code echo.c in Bash.
- Copyright (C) 87,89, 1991-1997, 1999-2005 Free Software Foundation, Inc.
+ Copyright (C) 1987-2016 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,90 +12,74 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include "system.h"
-#include "long-options.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "echo"
-#define AUTHORS "FIXME unknown"
-
-/* echo [-neE] [arg ...]
-Output the ARGs. If -n is specified, the trailing newline is
-suppressed. If the -e option is given, interpretation of the
-following backslash-escaped characters is turned on:
- \a alert (bell)
- \b backspace
- \c suppress trailing newline
- \f form feed
- \n new line
- \r carriage return
- \t horizontal tab
- \v vertical tab
- \\ backslash
- \0NNN the character whose ASCII code is NNN (octal).
-
-You can explicitly turn off the interpretation of the above characters
-on System V systems with the -E option.
-*/
+#define AUTHORS \
+ proper_name ("Brian Fox"), \
+ proper_name ("Chet Ramey")
/* If true, interpret backslash escapes by default. */
#ifndef DEFAULT_ECHO_TO_XPG
enum { DEFAULT_ECHO_TO_XPG = false };
#endif
-/* The name this program was run with. */
-char *program_name;
-
void
usage (int status)
{
if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ emit_try_help ();
else
{
- printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
+ printf (_("\
+Usage: %s [SHORT-OPTION]... [STRING]...\n\
+ or: %s LONG-OPTION\n\
+"), program_name, program_name);
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_("\
-e enable interpretation of backslash escapes (default)\n\
- -E disable interpretation of backslash escapes\n"
- : "\
+ -E disable interpretation of backslash escapes\n")
+ : N_("\
-e enable interpretation of backslash escapes\n\
- -E disable interpretation of backslash escapes (default)\n"),
- stdout);
+ -E disable interpretation of backslash escapes (default)\n")),
+ 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\
- \\0NNN the character whose ASCII code is NNN (octal)\n\
- \\\\ backslash\n\
- \\a alert (BEL)\n\
- \\b backspace\n\
"), stdout);
fputs (_("\
- \\c suppress trailing newline\n\
- \\f form feed\n\
- \\n new line\n\
- \\r carriage return\n\
- \\t horizontal tab\n\
- \\v vertical tab\n\
+ \\\\ backslash\n\
+ \\a alert (BEL)\n\
+ \\b backspace\n\
+ \\c produce no further output\n\
+ \\e escape\n\
+ \\f form feed\n\
+ \\n new line\n\
+ \\r carriage return\n\
+ \\t horizontal tab\n\
+ \\v vertical tab\n\
+"), stdout);
+ 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);
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
@@ -117,7 +101,7 @@ hextobin (unsigned char c)
}
/* Print the words in LIST to standard output. If the first word is
- `-n', then don't print a trailing newline. We also support the
+ '-n', then don't print a trailing newline. We also support the
echo syntax from Version 9 unix systems. */
int
@@ -134,16 +118,27 @@ main (int argc, char **argv)
bool do_v9 = DEFAULT_ECHO_TO_XPG;
initialize_main (&argc, &argv);
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
- if (allow_options)
- parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
- usage, AUTHORS, (char const *) NULL);
+ /* We directly parse options, rather than use parse_long_options, in
+ order to avoid accepting abbreviations. */
+ if (allow_options && argc == 2)
+ {
+ if (STREQ (argv[1], "--help"))
+ usage (EXIT_SUCCESS);
+
+ if (STREQ (argv[1], "--version"))
+ {
+ version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
+ (char *) NULL);
+ return EXIT_SUCCESS;
+ }
+ }
--argc;
++argv;
@@ -151,45 +146,45 @@ main (int argc, char **argv)
if (allow_options)
while (argc > 0 && *argv[0] == '-')
{
- char const *temp = argv[0] + 1;
- size_t i;
-
- /* If it appears that we are handling options, then make sure that
- all of the options specified are actually valid. Otherwise, the
- string should just be echoed. */
-
- for (i = 0; temp[i]; i++)
- switch (temp[i])
- {
- case 'e': case 'E': case 'n':
- break;
- default:
- goto just_echo;
- }
-
- if (i == 0)
- goto just_echo;
-
- /* All of the options in TEMP are valid options to ECHO.
- Handle them. */
- while (*temp)
- switch (*temp++)
- {
- case 'e':
- do_v9 = true;
- break;
-
- case 'E':
- do_v9 = false;
- break;
-
- case 'n':
- display_return = false;
- break;
- }
-
- argc--;
- argv++;
+ char const *temp = argv[0] + 1;
+ size_t i;
+
+ /* If it appears that we are handling options, then make sure that
+ all of the options specified are actually valid. Otherwise, the
+ string should just be echoed. */
+
+ for (i = 0; temp[i]; i++)
+ switch (temp[i])
+ {
+ case 'e': case 'E': case 'n':
+ break;
+ default:
+ goto just_echo;
+ }
+
+ if (i == 0)
+ goto just_echo;
+
+ /* All of the options in TEMP are valid options to ECHO.
+ Handle them. */
+ while (*temp)
+ switch (*temp++)
+ {
+ case 'e':
+ do_v9 = true;
+ break;
+
+ case 'E':
+ do_v9 = false;
+ break;
+
+ case 'n':
+ display_return = false;
+ break;
+ }
+
+ argc--;
+ argv++;
}
just_echo:
@@ -197,80 +192,81 @@ just_echo:
if (do_v9)
{
while (argc > 0)
- {
- char const *s = argv[0];
- unsigned char c;
-
- while ((c = *s++))
- {
- if (c == '\\' && *s)
- {
- switch (c = *s++)
- {
- case 'a': c = '\a'; break;
- case 'b': c = '\b'; break;
- case 'c': exit (EXIT_SUCCESS);
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'v': c = '\v'; break;
- case 'x':
- {
- unsigned char ch = *s;
- if (! isxdigit (ch))
- goto not_an_escape;
- s++;
- c = hextobin (ch);
- ch = *s;
- if (isxdigit (ch))
- {
- s++;
- c = c * 16 + hextobin (ch);
- }
- }
- break;
- case '0':
- c = 0;
- if (! ('0' <= *s && *s <= '7'))
- break;
- c = *s++;
- /* Fall through. */
- case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- c -= '0';
- if ('0' <= *s && *s <= '7')
- c = c * 8 + (*s++ - '0');
- if ('0' <= *s && *s <= '7')
- c = c * 8 + (*s++ - '0');
- break;
- case '\\': break;
-
- not_an_escape:
- default: putchar ('\\'); break;
- }
- }
- putchar (c);
- }
- argc--;
- argv++;
- if (argc > 0)
- putchar (' ');
- }
+ {
+ char const *s = argv[0];
+ unsigned char c;
+
+ while ((c = *s++))
+ {
+ if (c == '\\' && *s)
+ {
+ switch (c = *s++)
+ {
+ case 'a': c = '\a'; break;
+ case 'b': c = '\b'; break;
+ case 'c': return EXIT_SUCCESS;
+ case 'e': c = '\x1B'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
+ case 'x':
+ {
+ unsigned char ch = *s;
+ if (! isxdigit (ch))
+ goto not_an_escape;
+ s++;
+ c = hextobin (ch);
+ ch = *s;
+ if (isxdigit (ch))
+ {
+ s++;
+ c = c * 16 + hextobin (ch);
+ }
+ }
+ break;
+ case '0':
+ c = 0;
+ if (! ('0' <= *s && *s <= '7'))
+ break;
+ c = *s++;
+ /* Fall through. */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c -= '0';
+ if ('0' <= *s && *s <= '7')
+ c = c * 8 + (*s++ - '0');
+ if ('0' <= *s && *s <= '7')
+ c = c * 8 + (*s++ - '0');
+ break;
+ case '\\': break;
+
+ not_an_escape:
+ default: putchar ('\\'); break;
+ }
+ }
+ putchar (c);
+ }
+ argc--;
+ argv++;
+ if (argc > 0)
+ putchar (' ');
+ }
}
else
{
while (argc > 0)
- {
- fputs (argv[0], stdout);
- argc--;
- argv++;
- if (argc > 0)
- putchar (' ');
- }
+ {
+ fputs (argv[0], stdout);
+ argc--;
+ argv++;
+ if (argc > 0)
+ putchar (' ');
+ }
}
if (display_return)
putchar ('\n');
- exit (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}