*** empty log message ***
[coreutils.git] / src / echo.c
blob8dbe53b757694dbbead013a58f62ee6e9cd1e460
1 /* echo.c, derived from code echo.c in Bash.
2 Copyright (C) 87,89, 1991-1997, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 #include <config.h>
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include "system.h"
22 #include "closeout.h"
23 #include "long-options.h"
25 /* The official name of this program (e.g., no `g' prefix). */
26 #define PROGRAM_NAME "echo"
28 #define AUTHORS "FIXME unknown"
30 /* echo [-neE] [arg ...]
31 Output the ARGs. If -n is specified, the trailing newline is
32 suppressed. If the -e option is given, interpretation of the
33 following backslash-escaped characters is turned on:
34 \a alert (bell)
35 \b backspace
36 \c suppress trailing newline
37 \f form feed
38 \n new line
39 \r carriage return
40 \t horizontal tab
41 \v vertical tab
42 \\ backslash
43 \num the character whose ASCII code is NUM (octal).
45 You can explicitly turn off the interpretation of the above characters
46 on System V systems with the -E option.
49 /* If defined, interpret backslash escapes if -e is given. */
50 #define V9_ECHO
52 /* If defined, interpret backslash escapes unless -E is given.
53 V9_ECHO must also be defined. */
54 /* #define V9_DEFAULT */
56 #if defined (V9_ECHO)
57 # if defined (V9_DEFAULT)
58 # define VALID_ECHO_OPTIONS "neE"
59 # else
60 # define VALID_ECHO_OPTIONS "ne"
61 # endif /* !V9_DEFAULT */
62 #else /* !V9_ECHO */
63 # define VALID_ECHO_OPTIONS "n"
64 #endif /* !V9_ECHO */
66 /* The name this program was run with. */
67 char *program_name;
69 void
70 usage (int status)
72 if (status != 0)
73 fprintf (stderr, _("Try `%s --help' for more information.\n"),
74 program_name);
75 else
77 printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
78 fputs (_("\
79 Echo the STRING(s) to standard output.\n\
80 \n\
81 -n do not output the trailing newline\n\
82 -e enable interpretation of the backslash-escaped characters\n\
83 listed below\n\
84 -E disable interpretation of those sequences in STRINGs\n\
85 "), stdout);
86 fputs (HELP_OPTION_DESCRIPTION, stdout);
87 fputs (VERSION_OPTION_DESCRIPTION, stdout);
88 fputs (_("\
89 \n\
90 Without -E, the following sequences are recognized and interpolated:\n\
91 \n\
92 \\NNN the character whose ASCII code is NNN (octal)\n\
93 \\\\ backslash\n\
94 \\a alert (BEL)\n\
95 \\b backspace\n\
96 "), stdout);
97 fputs (_("\
98 \\c suppress trailing newline\n\
99 \\f form feed\n\
100 \\n new line\n\
101 \\r carriage return\n\
102 \\t horizontal tab\n\
103 \\v vertical tab\n\
104 "), stdout);
105 puts (_("\nReport bugs to <bug-sh-utils@gnu.org>."));
107 exit (status);
110 /* Print the words in LIST to standard output. If the first word is
111 `-n', then don't print a trailing newline. We also support the
112 echo syntax from Version 9 unix systems. */
115 main (int argc, char **argv)
117 int display_return = 1, do_v9 = 0;
118 int allow_options = 1;
120 program_name = argv[0];
121 setlocale (LC_ALL, "");
122 bindtextdomain (PACKAGE, LOCALEDIR);
123 textdomain (PACKAGE);
125 atexit (close_stdout);
127 /* Don't recognize --help or --version if POSIXLY_CORRECT is set. */
128 if (getenv ("POSIXLY_CORRECT") == NULL)
129 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
130 AUTHORS, usage);
131 else
132 allow_options = 0;
134 /* System V machines already have a /bin/sh with a v9 behaviour. We
135 use the identical behaviour for these machines so that the
136 existing system shell scripts won't barf. */
137 #if defined (V9_ECHO) && defined (V9_DEFAULT)
138 do_v9 = allow_options;
139 #endif
141 --argc;
142 ++argv;
144 while (argc > 0 && *argv[0] == '-')
146 register char *temp;
147 register int i;
149 /* If it appears that we are handling options, then make sure that
150 all of the options specified are actually valid. Otherwise, the
151 string should just be echoed. */
152 temp = argv[0] + 1;
154 for (i = 0; temp[i]; i++)
156 if (strrchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
157 goto just_echo;
160 if (!*temp)
161 goto just_echo;
163 /* All of the options in TEMP are valid options to ECHO.
164 Handle them. */
165 while (*temp)
167 if (allow_options && *temp == 'n')
168 display_return = 0;
169 #if defined (V9_ECHO)
170 else if (allow_options && *temp == 'e')
171 do_v9 = 1;
172 # if defined (V9_DEFAULT)
173 else if (allow_options && *temp == 'E')
174 do_v9 = 0;
175 # endif /* V9_DEFAULT */
176 #endif /* V9_ECHO */
177 else
178 goto just_echo;
180 temp++;
182 argc--;
183 argv++;
186 just_echo:
188 if (argc > 0)
190 #if defined (V9_ECHO)
191 if (do_v9)
193 while (argc > 0)
195 register char *s = argv[0];
196 register int c;
198 while ((c = *s++))
200 if (c == '\\' && *s)
202 switch (c = *s++)
204 case 'a': c = '\007'; break;
205 case 'b': c = '\b'; break;
206 case 'c': display_return = 0; continue;
207 case 'f': c = '\f'; break;
208 case 'n': c = '\n'; break;
209 case 'r': c = '\r'; break;
210 case 't': c = '\t'; break;
211 case 'v': c = (int) 0x0B; break;
212 case '0': case '1': case '2': case '3':
213 case '4': case '5': case '6': case '7':
214 c -= '0';
215 if (*s >= '0' && *s <= '7')
216 c = c * 8 + (*s++ - '0');
217 if (*s >= '0' && *s <= '7')
218 c = c * 8 + (*s++ - '0');
219 break;
220 case '\\': break;
221 default: putchar ('\\'); break;
224 putchar(c);
226 argc--;
227 argv++;
228 if (argc > 0)
229 putchar(' ');
232 else
233 #endif /* V9_ECHO */
235 while (argc > 0)
237 fputs (argv[0], stdout);
238 argc--;
239 argv++;
240 if (argc > 0)
241 putchar (' ');
245 if (display_return)
246 putchar ('\n');
247 exit (0);