merge with 1.8.1d
[coreutils.git] / src / echo.c
blobab0779eae0bf69500082c233e407fc04ff3c3e48
1 /* echo.c, taken from Bash.
2 Copyright (C) 1987, 1989, 1991, 1992 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 #ifdef HAVE_CONFIG_H
21 #if defined (CONFIG_BROKETS)
22 /* We use <config.h> instead of "config.h" so that a compilation
23 using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
24 (which it would do because it found this file in $srcdir). */
25 #include <config.h>
26 #else
27 #include "config.h"
28 #endif
29 #endif
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include "system.h"
35 /* echo [-neE] [arg ...]
36 Output the ARGs. If -n is specified, the trailing newline is
37 suppressed. If the -e option is given, interpretation of the
38 following backslash-escaped characters is turned on:
39 \a alert (bell)
40 \b backspace
41 \c suppress trailing newline
42 \f form feed
43 \n new line
44 \r carriage return
45 \t horizontal tab
46 \v vertical tab
47 \\ backslash
48 \num the character whose ASCII code is NUM (octal).
50 You can explicitly turn off the interpretation of the above characters
51 on System V systems with the -E option.
54 /* If defined, interpret backslash escapes if -e is given. */
55 #define V9_ECHO
57 /* If defined, interpret backslash escapes unless -E is given.
58 V9_ECHO must also be defined. */
59 #define V9_DEFAULT
61 #if defined (V9_ECHO)
62 # if defined (V9_DEFAULT)
63 # define VALID_ECHO_OPTIONS "neE"
64 # else
65 # define VALID_ECHO_OPTIONS "ne"
66 # endif /* !V9_DEFAULT */
67 #else /* !V9_ECHO */
68 # define VALID_ECHO_OPTIONS "n"
69 #endif /* !V9_ECHO */
71 /* The name this program was run with. */
72 char *program_name;
74 void parse_long_options ();
76 static void
77 usage ()
79 fprintf (stderr, "Usage: %s [{--help,--version}] [-ne] [string ...]\n",
80 program_name);
81 exit (1);
84 /* Print the words in LIST to standard output. If the first word is
85 `-n', then don't print a trailing newline. We also support the
86 echo syntax from Version 9 unix systems. */
87 void
88 main (argc, argv)
89 int argc;
90 char **argv;
92 int display_return = 1, do_v9 = 0;
94 program_name = argv[0];
96 parse_long_options (argc, argv, usage);
98 /* System V machines already have a /bin/sh with a v9 behaviour. We
99 use the identical behaviour for these machines so that the
100 existing system shell scripts won't barf. */
101 #if defined (V9_ECHO) && defined (V9_DEFAULT)
102 do_v9 = 1;
103 #endif
105 --argc;
106 ++argv;
108 while (argc > 0 && *argv[0] == '-')
110 register char *temp;
111 register int i;
113 /* If it appears that we are handling options, then make sure that
114 all of the options specified are actually valid. Otherwise, the
115 string should just be echoed. */
116 temp = argv[0] + 1;
118 for (i = 0; temp[i]; i++)
120 if (rindex (VALID_ECHO_OPTIONS, temp[i]) == 0)
121 goto just_echo;
124 if (!*temp)
125 goto just_echo;
127 /* All of the options in TEMP are valid options to ECHO.
128 Handle them. */
129 while (*temp)
131 if (*temp == 'n')
132 display_return = 0;
133 #if defined (V9_ECHO)
134 else if (*temp == 'e')
135 do_v9 = 1;
136 #if defined (V9_DEFAULT)
137 else if (*temp == 'E')
138 do_v9 = 0;
139 #endif /* V9_DEFAULT */
140 #endif /* V9_ECHO */
141 else
142 goto just_echo;
144 temp++;
146 argc--;
147 argv++;
150 just_echo:
152 if (argc > 0)
154 #if defined (V9_ECHO)
155 if (do_v9)
157 while (argc > 0)
159 register char *s = argv[0];
160 register int c;
162 while ((c = *s++))
164 if (c == '\\' && *s)
166 switch (c = *s++)
168 case 'a': c = '\007'; break;
169 case 'b': c = '\b'; break;
170 case 'c': display_return = 0; continue;
171 case 'f': c = '\f'; break;
172 case 'n': c = '\n'; break;
173 case 'r': c = '\r'; break;
174 case 't': c = '\t'; break;
175 case 'v': c = (int) 0x0B; break;
176 case '0': case '1': case '2': case '3':
177 case '4': case '5': case '6': case '7':
178 c -= '0';
179 if (*s >= '0' && *s <= '7')
180 c = c * 8 + (*s++ - '0');
181 if (*s >= '0' && *s <= '7')
182 c = c * 8 + (*s++ - '0');
183 break;
184 case '\\': break;
185 default: putchar ('\\'); break;
188 putchar(c);
190 argc--;
191 argv++;
192 if (argc > 0)
193 putchar(' ');
196 else
197 #endif /* V9_ECHO */
199 while (argc > 0)
201 fputs (argv[0], stdout);
202 argc--;
203 argv++;
204 if (argc > 0)
205 putchar (' ');
209 if (display_return)
210 putchar ('\n');
211 exit (0);