.
[coreutils.git] / src / echo.c
blob340cad37c5fe6417547f4eaaa2c6f74920703a98
1 /* echo.c, derived from code echo.c in Bash.
2 Copyright (C) 87, 89, 91, 92, 93, 94, 95, 1996 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 /* echo [-neE] [arg ...]
25 Output the ARGs. If -n is specified, the trailing newline is
26 suppressed. If the -e option is given, interpretation of the
27 following backslash-escaped characters is turned on:
28 \a alert (bell)
29 \b backspace
30 \c suppress trailing newline
31 \f form feed
32 \n new line
33 \r carriage return
34 \t horizontal tab
35 \v vertical tab
36 \\ backslash
37 \num the character whose ASCII code is NUM (octal).
39 You can explicitly turn off the interpretation of the above characters
40 on System V systems with the -E option.
43 /* If defined, interpret backslash escapes if -e is given. */
44 #define V9_ECHO
46 /* If defined, interpret backslash escapes unless -E is given.
47 V9_ECHO must also be defined. */
48 #define V9_DEFAULT
50 #if defined (V9_ECHO)
51 # if defined (V9_DEFAULT)
52 # define VALID_ECHO_OPTIONS "neE"
53 # else
54 # define VALID_ECHO_OPTIONS "ne"
55 # endif /* !V9_DEFAULT */
56 #else /* !V9_ECHO */
57 # define VALID_ECHO_OPTIONS "n"
58 #endif /* !V9_ECHO */
60 /* The name this program was run with. */
61 char *program_name;
63 static void
64 usage (int status)
66 if (status != 0)
67 fprintf (stderr, _("Try `%s --help' for more information.\n"),
68 program_name);
69 else
71 printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
72 printf (_("\
73 Echo the STRING(s) to standard output.\n\
74 \n\
75 -n do not output the trailing newline\n\
76 -e (unused)\n\
77 -E disable interpolation of some sequences in STRINGs\n\
78 --help display this help and exit (should be alone)\n\
79 --version output version information and exit (should be alone)\n\
80 \n\
81 Without -E, the following sequences are recognized and interpolated:\n\
82 \n\
83 \\NNN the character whose ASCII code is NNN (octal)\n\
84 \\\\ backslash\n\
85 \\a alert (BEL)\n\
86 \\b backspace\n\
87 \\c suppress trailing newline\n\
88 \\f form feed\n\
89 \\n new line\n\
90 \\r carriage return\n\
91 \\t horizontal tab\n\
92 \\v vertical tab\n\
93 "));
94 puts (_("\nReport bugs to sh-utils-bugs@gnu.ai.mit.edu"));
96 exit (status);
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 int display_return = 1, do_v9 = 0;
108 program_name = argv[0];
109 setlocale (LC_ALL, "");
110 bindtextdomain (PACKAGE, LOCALEDIR);
111 textdomain (PACKAGE);
113 /* Don't recognize --help or --version if POSIXLY_CORRECT is set. */
114 if (getenv ("POSIXLY_CORRECT") == NULL)
115 parse_long_options (argc, argv, "echo", GNU_PACKAGE, VERSION, usage);
117 /* System V machines already have a /bin/sh with a v9 behaviour. We
118 use the identical behaviour for these machines so that the
119 existing system shell scripts won't barf. */
120 #if defined (V9_ECHO) && defined (V9_DEFAULT)
121 do_v9 = 1;
122 #endif
124 --argc;
125 ++argv;
127 while (argc > 0 && *argv[0] == '-')
129 register char *temp;
130 register int i;
132 /* If it appears that we are handling options, then make sure that
133 all of the options specified are actually valid. Otherwise, the
134 string should just be echoed. */
135 temp = argv[0] + 1;
137 for (i = 0; temp[i]; i++)
139 if (strrchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
140 goto just_echo;
143 if (!*temp)
144 goto just_echo;
146 /* All of the options in TEMP are valid options to ECHO.
147 Handle them. */
148 while (*temp)
150 if (*temp == 'n')
151 display_return = 0;
152 #if defined (V9_ECHO)
153 else if (*temp == 'e')
154 do_v9 = 1;
155 #if defined (V9_DEFAULT)
156 else if (*temp == 'E')
157 do_v9 = 0;
158 #endif /* V9_DEFAULT */
159 #endif /* V9_ECHO */
160 else
161 goto just_echo;
163 temp++;
165 argc--;
166 argv++;
169 just_echo:
171 if (argc > 0)
173 #if defined (V9_ECHO)
174 if (do_v9)
176 while (argc > 0)
178 register char *s = argv[0];
179 register int c;
181 while ((c = *s++))
183 if (c == '\\' && *s)
185 switch (c = *s++)
187 case 'a': c = '\007'; break;
188 case 'b': c = '\b'; break;
189 case 'c': display_return = 0; continue;
190 case 'f': c = '\f'; break;
191 case 'n': c = '\n'; break;
192 case 'r': c = '\r'; break;
193 case 't': c = '\t'; break;
194 case 'v': c = (int) 0x0B; break;
195 case '0': case '1': case '2': case '3':
196 case '4': case '5': case '6': case '7':
197 c -= '0';
198 if (*s >= '0' && *s <= '7')
199 c = c * 8 + (*s++ - '0');
200 if (*s >= '0' && *s <= '7')
201 c = c * 8 + (*s++ - '0');
202 break;
203 case '\\': break;
204 default: putchar ('\\'); break;
207 putchar(c);
209 argc--;
210 argv++;
211 if (argc > 0)
212 putchar(' ');
215 else
216 #endif /* V9_ECHO */
218 while (argc > 0)
220 fputs (argv[0], stdout);
221 argc--;
222 argv++;
223 if (argc > 0)
224 putchar (' ');
228 if (display_return)
229 putchar ('\n');
230 exit (0);