.
[coreutils.git] / src / echo.c
blobbd79cc96cf77b06a80dbc1c95caaee0b6e365c5c
1 /* echo.c, derived from code echo.c in Bash.
2 Copyright (C) 87,89, 1991-1997, 1999-2003 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 "long-options.h"
24 /* The official name of this program (e.g., no `g' prefix). */
25 #define PROGRAM_NAME "echo"
27 #define AUTHORS "FIXME unknown"
29 /* echo [-neE] [arg ...]
30 Output the ARGs. If -n is specified, the trailing newline is
31 suppressed. If the -e option is given, interpretation of the
32 following backslash-escaped characters is turned on:
33 \a alert (bell)
34 \b backspace
35 \c suppress trailing newline
36 \f form feed
37 \n new line
38 \r carriage return
39 \t horizontal tab
40 \v vertical tab
41 \\ backslash
42 \num the character whose ASCII code is NUM (octal).
44 You can explicitly turn off the interpretation of the above characters
45 on System V systems with the -E option.
48 /* If defined, interpret backslash escapes if -e is given. */
49 #define V9_ECHO
51 /* If defined, interpret backslash escapes unless -E is given.
52 V9_ECHO must also be defined. */
53 /* #define V9_DEFAULT */
55 #if defined (V9_ECHO)
56 # if defined (V9_DEFAULT)
57 # define VALID_ECHO_OPTIONS "neE"
58 # else
59 # define VALID_ECHO_OPTIONS "ne"
60 # endif /* !V9_DEFAULT */
61 #else /* !V9_ECHO */
62 # define VALID_ECHO_OPTIONS "n"
63 #endif /* !V9_ECHO */
65 /* The name this program was run with. */
66 char *program_name;
68 void
69 usage (int status)
71 if (status != 0)
72 fprintf (stderr, _("Try `%s --help' for more information.\n"),
73 program_name);
74 else
76 printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
77 fputs (_("\
78 Echo the STRING(s) to standard output.\n\
79 \n\
80 -n do not output the trailing newline\n\
81 -e enable interpretation of the backslash-escaped characters\n\
82 listed below\n\
83 -E disable interpretation of those sequences in STRINGs\n\
84 "), stdout);
85 fputs (HELP_OPTION_DESCRIPTION, stdout);
86 fputs (VERSION_OPTION_DESCRIPTION, stdout);
87 fputs (_("\
88 \n\
89 Without -E, the following sequences are recognized and interpolated:\n\
90 \n\
91 \\NNN the character whose ASCII code is NNN (octal)\n\
92 \\\\ backslash\n\
93 \\a alert (BEL)\n\
94 \\b backspace\n\
95 "), stdout);
96 fputs (_("\
97 \\c suppress trailing newline\n\
98 \\f form feed\n\
99 \\n new line\n\
100 \\r carriage return\n\
101 \\t horizontal tab\n\
102 \\v vertical tab\n\
103 "), stdout);
104 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
106 exit (status);
109 /* Print the words in LIST to standard output. If the first word is
110 `-n', then don't print a trailing newline. We also support the
111 echo syntax from Version 9 unix systems. */
114 main (int argc, char **argv)
116 int display_return = 1, do_v9 = 0;
117 int allow_options = 1;
119 initialize_main (&argc, &argv);
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 usage, AUTHORS, (char const *) NULL, NULL);
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 (EXIT_SUCCESS);