.
[coreutils.git] / src / echo.c
blobf0b7cd076063614b6439214547d839698be5cccf
1 /* echo.c, taken from Bash.
2 Copyright (C) 87, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Bash, the Bourne Again SHell.
6 Bash is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License along
17 with Bash; see the file COPYING. If not, write to the Free Software
18 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include "system.h"
24 #include "version.h"
25 #include "long-options.h"
27 /* echo [-neE] [arg ...]
28 Output the ARGs. If -n is specified, the trailing newline is
29 suppressed. If the -e option is given, interpretation of the
30 following backslash-escaped characters is turned on:
31 \a alert (bell)
32 \b backspace
33 \c suppress trailing newline
34 \f form feed
35 \n new line
36 \r carriage return
37 \t horizontal tab
38 \v vertical tab
39 \\ backslash
40 \num the character whose ASCII code is NUM (octal).
42 You can explicitly turn off the interpretation of the above characters
43 on System V systems with the -E option.
46 /* If defined, interpret backslash escapes if -e is given. */
47 #define V9_ECHO
49 /* If defined, interpret backslash escapes unless -E is given.
50 V9_ECHO must also be defined. */
51 #define V9_DEFAULT
53 #if defined (V9_ECHO)
54 # if defined (V9_DEFAULT)
55 # define VALID_ECHO_OPTIONS "neE"
56 # else
57 # define VALID_ECHO_OPTIONS "ne"
58 # endif /* !V9_DEFAULT */
59 #else /* !V9_ECHO */
60 # define VALID_ECHO_OPTIONS "n"
61 #endif /* !V9_ECHO */
63 /* The name this program was run with. */
64 char *program_name;
66 static void
67 usage (status)
68 int status;
70 if (status != 0)
71 fprintf (stderr, _("Try `%s --help' for more information.\n"),
72 program_name);
73 else
75 printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name);
76 printf (_("\
77 Echo the STRING(s) to standard output.\n\
78 \n\
79 -n do not output the trailing newline\n\
80 -e (unused)\n\
81 -E disable interpolation of some sequences in STRINGs\n\
82 --help display this help and exit (should be alone)\n\
83 --version output version information and exit (should be alone)\n\
84 \n\
85 Without -E, the following sequences are recognized and interpolated:\n\
86 \n\
87 \\NNN the character whose ASCII code is NNN (octal)\n\
88 \\\\ backslash\n\
89 \\a alert (BEL)\n\
90 \\b backspace\n\
91 \\c suppress trailing newline\n\
92 \\f form feed\n\
93 \\n new line\n\
94 \\r carriage return\n\
95 \\t horizontal tab\n\
96 \\v vertical tab\n\
97 "));
99 exit (status);
102 /* Print the words in LIST to standard output. If the first word is
103 `-n', then don't print a trailing newline. We also support the
104 echo syntax from Version 9 unix systems. */
105 void
106 main (argc, argv)
107 int argc;
108 char **argv;
110 int display_return = 1, do_v9 = 0;
112 program_name = argv[0];
114 parse_long_options (argc, argv, "echo", version_string, usage);
116 /* System V machines already have a /bin/sh with a v9 behaviour. We
117 use the identical behaviour for these machines so that the
118 existing system shell scripts won't barf. */
119 #if defined (V9_ECHO) && defined (V9_DEFAULT)
120 do_v9 = 1;
121 #endif
123 --argc;
124 ++argv;
126 while (argc > 0 && *argv[0] == '-')
128 register char *temp;
129 register int i;
131 /* If it appears that we are handling options, then make sure that
132 all of the options specified are actually valid. Otherwise, the
133 string should just be echoed. */
134 temp = argv[0] + 1;
136 for (i = 0; temp[i]; i++)
138 if (strrchr (VALID_ECHO_OPTIONS, temp[i]) == 0)
139 goto just_echo;
142 if (!*temp)
143 goto just_echo;
145 /* All of the options in TEMP are valid options to ECHO.
146 Handle them. */
147 while (*temp)
149 if (*temp == 'n')
150 display_return = 0;
151 #if defined (V9_ECHO)
152 else if (*temp == 'e')
153 do_v9 = 1;
154 #if defined (V9_DEFAULT)
155 else if (*temp == 'E')
156 do_v9 = 0;
157 #endif /* V9_DEFAULT */
158 #endif /* V9_ECHO */
159 else
160 goto just_echo;
162 temp++;
164 argc--;
165 argv++;
168 just_echo:
170 if (argc > 0)
172 #if defined (V9_ECHO)
173 if (do_v9)
175 while (argc > 0)
177 register char *s = argv[0];
178 register int c;
180 while ((c = *s++))
182 if (c == '\\' && *s)
184 switch (c = *s++)
186 case 'a': c = '\007'; break;
187 case 'b': c = '\b'; break;
188 case 'c': display_return = 0; continue;
189 case 'f': c = '\f'; break;
190 case 'n': c = '\n'; break;
191 case 'r': c = '\r'; break;
192 case 't': c = '\t'; break;
193 case 'v': c = (int) 0x0B; break;
194 case '0': case '1': case '2': case '3':
195 case '4': case '5': case '6': case '7':
196 c -= '0';
197 if (*s >= '0' && *s <= '7')
198 c = c * 8 + (*s++ - '0');
199 if (*s >= '0' && *s <= '7')
200 c = c * 8 + (*s++ - '0');
201 break;
202 case '\\': break;
203 default: putchar ('\\'); break;
206 putchar(c);
208 argc--;
209 argv++;
210 if (argc > 0)
211 putchar(' ');
214 else
215 #endif /* V9_ECHO */
217 while (argc > 0)
219 fputs (argv[0], stdout);
220 argc--;
221 argv++;
222 if (argc > 0)
223 putchar (' ');
227 if (display_return)
228 putchar ('\n');
229 exit (0);