1 /* echo.c, derived from code echo.c in Bash.
2 Copyright (C) 87,89, 1991-1997, 1999-2005, 2007-2008 Free Software
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include <sys/types.h>
22 #include "long-options.h"
24 /* The official name of this program (e.g., no `g' prefix). */
25 #define PROGRAM_NAME "echo"
28 proper_name ("Brian Fox"), \
29 proper_name ("Chet Ramey")
31 /* If true, interpret backslash escapes by default. */
32 #ifndef DEFAULT_ECHO_TO_XPG
33 enum { DEFAULT_ECHO_TO_XPG = false };
39 if (status != EXIT_SUCCESS)
40 fprintf (stderr, _("Try `%s --help' for more information.\n"),
44 printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
46 Echo the STRING(s) to standard output.\n\
48 -n do not output the trailing newline\n\
50 fputs (_(DEFAULT_ECHO_TO_XPG
52 -e enable interpretation of backslash escapes (default)\n\
53 -E disable interpretation of backslash escapes\n")
55 -e enable interpretation of backslash escapes\n\
56 -E disable interpretation of backslash escapes (default)\n")),
58 fputs (HELP_OPTION_DESCRIPTION, stdout);
59 fputs (VERSION_OPTION_DESCRIPTION, stdout);
62 If -e is in effect, the following sequences are recognized:\n\
64 \\0NNN the character whose ASCII code is NNN (octal)\n\
70 \\c produce no further output\n\
73 \\r carriage return\n\
77 printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
78 emit_bug_reporting_address ();
83 /* Convert C from hexadecimal character to integer. */
85 hextobin (unsigned char c)
89 default: return c - '0';
90 case 'a': case 'A': return 10;
91 case 'b': case 'B': return 11;
92 case 'c': case 'C': return 12;
93 case 'd': case 'D': return 13;
94 case 'e': case 'E': return 14;
95 case 'f': case 'F': return 15;
99 /* Print the words in LIST to standard output. If the first word is
100 `-n', then don't print a trailing newline. We also support the
101 echo syntax from Version 9 unix systems. */
104 main (int argc, char **argv)
106 bool display_return = true;
108 (! getenv ("POSIXLY_CORRECT")
109 || (! DEFAULT_ECHO_TO_XPG && 1 < argc && STREQ (argv[1], "-n")));
111 /* System V machines already have a /bin/sh with a v9 behavior.
112 Use the identical behavior for these machines so that the
113 existing system shell scripts won't barf. */
114 bool do_v9 = DEFAULT_ECHO_TO_XPG;
116 initialize_main (&argc, &argv);
117 set_program_name (argv[0]);
118 setlocale (LC_ALL, "");
119 bindtextdomain (PACKAGE, LOCALEDIR);
120 textdomain (PACKAGE);
122 atexit (close_stdout);
125 parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
126 usage, AUTHORS, (char const *) NULL);
132 while (argc > 0 && *argv[0] == '-')
134 char const *temp = argv[0] + 1;
137 /* If it appears that we are handling options, then make sure that
138 all of the options specified are actually valid. Otherwise, the
139 string should just be echoed. */
141 for (i = 0; temp[i]; i++)
144 case 'e': case 'E': case 'n':
153 /* All of the options in TEMP are valid options to ECHO.
167 display_return = false;
181 char const *s = argv[0];
190 case 'a': c = '\a'; break;
191 case 'b': c = '\b'; break;
192 case 'c': exit (EXIT_SUCCESS);
193 case 'f': c = '\f'; break;
194 case 'n': c = '\n'; break;
195 case 'r': c = '\r'; break;
196 case 't': c = '\t'; break;
197 case 'v': c = '\v'; break;
200 unsigned char ch = *s;
209 c = c * 16 + hextobin (ch);
215 if (! ('0' <= *s && *s <= '7'))
219 case '1': case '2': case '3':
220 case '4': case '5': case '6': case '7':
222 if ('0' <= *s && *s <= '7')
223 c = c * 8 + (*s++ - '0');
224 if ('0' <= *s && *s <= '7')
225 c = c * 8 + (*s++ - '0');
230 default: putchar ('\\'); break;
245 fputs (argv[0], stdout);