8270fc006190961ddd782f3ae18f7dd9acb5bda9
[platform/upstream/busybox.git] / coreutils / echo.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * echo implementation for busybox
4  *
5  * Copyright (c) 1991, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9  *
10  * Original copyright notice is retained at the end of this file.
11  */
12
13 /* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */
14 /* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */
15
16 /* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
17  *
18  * Because of behavioral differences, implemented configurable SUSv3
19  * or 'fancy' gnu-ish behaviors.  Also, reduced size and fixed bugs.
20  * 1) In handling '\c' escape, the previous version only suppressed the
21  *     trailing newline.  SUSv3 specifies _no_ output after '\c'.
22  * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
23  *    The previous version version did not allow 4-digit octals.
24  */
25
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include "busybox.h"
31
32 int bb_echo(char **argv)
33 {
34 #ifndef CONFIG_FEATURE_FANCY_ECHO
35 #define eflag '\\'
36         ++argv;
37 #else
38         const char *p;
39         int nflag = 1;
40         int eflag = 0;
41
42         while (*++argv && (**argv == '-')) {
43                 /* If it appears that we are handling options, then make sure
44                  * that all of the options specified are actually valid.
45                  * Otherwise, the string should just be echoed.
46                  */
47
48                 if (!*(p = *argv + 1)) {        /* A single '-', so echo it. */
49                         goto just_echo;
50                 }
51
52                 do {
53                         if (strrchr("neE", *p) == 0) {
54                                 goto just_echo;
55                         }
56                 } while (*++p);
57
58                 /* All of the options in this arg are valid, so handle them. */
59                 p = *argv + 1;
60                 do {
61                         if (*p == 'n') {
62                                 nflag = 0;
63                         } else if (*p == 'e') {
64                                 eflag = '\\';
65                         } else {
66                                 eflag = 0;
67                         }
68                 } while (*++p);
69         }
70
71 just_echo:
72 #endif
73         while (*argv) {
74                 int c;
75
76                 while ((c = *(*argv)++)) {
77                         if (c == eflag) {       /* Check for escape seq. */
78                                 if (**argv == 'c') {
79                                         /* '\c' means cancel newline and
80                                          * ignore all subsequent chars. */
81                                         return 0;
82                                 }
83 #ifndef CONFIG_FEATURE_FANCY_ECHO
84                                 /* SUSv3 specifies that octal escapes must begin with '0'. */
85                                 if (((unsigned int)(**argv - '1')) >= 7)
86 #endif
87                                 {
88                                         /* Since SUSv3 mandates a first digit of 0, 4-digit octals
89                                         * of the form \0### are accepted. */
90                                         if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) {
91                                                 (*argv)++;
92                                         }
93                                         /* bb_process_escape_sequence can handle nul correctly */
94                                         c = bb_process_escape_sequence((const char **) argv);
95                                 }
96                         }
97                         putchar(c);
98                 }
99
100                 if (*++argv) {
101                         putchar(' ');
102                 }
103         }
104
105 #ifdef CONFIG_FEATURE_FANCY_ECHO
106         if (nflag) {
107                 putchar('\n');
108         }
109 #else
110         putchar('\n');
111 #endif
112         return 0;
113 }
114
115 int echo_main(int argc, char** argv);
116 int echo_main(int argc, char** argv)
117 {
118         (void)bb_echo(argv);
119         fflush_stdout_and_exit(EXIT_SUCCESS);
120 }
121
122 /*-
123  * Copyright (c) 1991, 1993
124  *      The Regents of the University of California.  All rights reserved.
125  *
126  * This code is derived from software contributed to Berkeley by
127  * Kenneth Almquist.
128  *
129  * Redistribution and use in source and binary forms, with or without
130  * modification, are permitted provided that the following conditions
131  * are met:
132  * 1. Redistributions of source code must retain the above copyright
133  *    notice, this list of conditions and the following disclaimer.
134  * 2. Redistributions in binary form must reproduce the above copyright
135  *    notice, this list of conditions and the following disclaimer in the
136  *    documentation and/or other materials provided with the distribution.
137  *
138  * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
139  *              ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
140  *
141  *      California, Berkeley and its contributors.
142  * 4. Neither the name of the University nor the names of its contributors
143  *    may be used to endorse or promote products derived from this software
144  *    without specific prior written permission.
145  *
146  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
147  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
148  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
149  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
150  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
151  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
152  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
153  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
154  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
155  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
156  * SUCH DAMAGE.
157  *
158  *      @(#)echo.c      8.1 (Berkeley) 5/31/93
159  */