aboutsummaryrefslogtreecommitdiff
path: root/coreutils/echo.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/echo.c')
-rw-r--r--coreutils/echo.c133
1 files changed, 73 insertions, 60 deletions
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 31c031528..b600a1fbd 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -22,94 +22,107 @@
22 * Original copyright notice is retained at the end of this file. 22 * Original copyright notice is retained at the end of this file.
23 */ 23 */
24 24
25/* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */
26/* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */
27
28/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
29 *
30 * Because of behavioral differences, implemented configureable SUSv3
31 * or 'fancy' gnu-ish behaviors. Also, reduced size and fixed bugs.
32 * 1) In handling '\c' escape, the previous version only suppressed the
33 * trailing newline. SUSv3 specifies _no_ output after '\c'.
34 * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
35 * The previous version version did not allow 4-digit octals.
36 */
37
25#include <stdio.h> 38#include <stdio.h>
26#include <string.h> 39#include <string.h>
27#include <stdlib.h> 40#include <stdlib.h>
28#include "busybox.h" 41#include "busybox.h"
29 42
30extern int 43extern int echo_main(int argc, char** argv)
31echo_main(int argc, char** argv)
32{ 44{
33 int nflag = 0; 45#ifndef CONFIG_FEATURE_FANCY_ECHO
46#define eflag '\\'
47 ++argv;
48#else
49 const char *p;
50 int nflag = 1;
34 int eflag = 0; 51 int eflag = 0;
35 52
36 /* Skip argv[0]. */ 53 while (*++argv && (**argv == '-')) {
37 argc--; 54 /* If it appears that we are handling options, then make sure
38 argv++;
39
40 while (argc > 0 && *argv[0] == '-')
41 {
42 register char *temp;
43 register int ix;
44
45 /*
46 * If it appears that we are handling options, then make sure
47 * that all of the options specified are actually valid. 55 * that all of the options specified are actually valid.
48 * Otherwise, the string should just be echoed. 56 * Otherwise, the string should just be echoed.
49 */ 57 */
50 temp = argv[0] + 1; 58
51 59 if (!*(p = *argv + 1)) { /* A single '-', so echo it. */
52 for (ix = 0; temp[ix]; ix++)
53 {
54 if (strrchr("neE", temp[ix]) == 0)
55 goto just_echo;
56 }
57
58 if (!*temp)
59 goto just_echo; 60 goto just_echo;
61 }
60 62
61 /* 63 do {
62 * All of the options in temp are valid options to echo. 64 if (strrchr("neE", *p) == 0) {
63 * Handle them.
64 */
65 while (*temp)
66 {
67 if (*temp == 'n')
68 nflag = 1;
69 else if (*temp == 'e')
70 eflag = 1;
71 else if (*temp == 'E')
72 eflag = 0;
73 else
74 goto just_echo; 65 goto just_echo;
66 }
67 } while (*++p);
75 68
76 temp++; 69 /* All of the options in this arg are valid, so handle them. */
77 } 70 p = *argv + 1;
78 argc--; 71 do {
79 argv++; 72 if (*p == 'n') {
73 nflag = 0;
74 } else if (*p == 'e') {
75 eflag = '\\';
76 } else {
77 eflag = 0;
78 }
79 } while (*++p);
80 } 80 }
81 81
82just_echo: 82just_echo:
83 while (argc > 0) { 83#endif
84 const char *arg = argv[0]; 84 while (*argv) {
85 register int c; 85 register int c;
86 86
87 while ((c = *arg++)) { 87 while ((c = *(*argv)++)) {
88 88 if (c == eflag) { /* Check for escape seq. */
89 /* Check for escape sequence. */ 89 if (**argv == 'c') {
90 if (c == '\\' && eflag && *arg) { 90 /* '\c' means cancel newline and
91 if (*arg == 'c') { 91 * ignore all subsequent chars. */
92 /* '\c' means cancel newline. */ 92 goto DONE;
93 nflag = 1; 93 }
94 arg++; 94#ifndef CONFIG_FEATURE_FANCY_ECHO
95 continue; 95 /* SUSv3 specifies that octal escapes must begin with '0'. */
96 } else { 96 if (((unsigned int)(**argv - '1')) >= 7)
97 c = process_escape_sequence(&arg); 97#endif
98 {
99 /* Since SUSv3 mandates a first digit of 0, 4-digit octals
100 * of the form \0### are accepted. */
101 if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) {
102 (*argv)++;
103 }
104 /* bb_process_escape_sequence can handle nul correctly */
105 c = bb_process_escape_sequence((const char **) argv);
98 } 106 }
99 } 107 }
100
101 putchar(c); 108 putchar(c);
102 } 109 }
103 argc--; 110
104 argv++; 111 if (*++argv) {
105 if (argc > 0)
106 putchar(' '); 112 putchar(' ');
113 }
107 } 114 }
108 if (!nflag) 115
116#ifdef CONFIG_FEATURE_FANCY_ECHO
117 if (nflag) {
109 putchar('\n'); 118 putchar('\n');
110 fflush(stdout); 119 }
120#else
121 putchar('\n');
122#endif
111 123
112 return EXIT_SUCCESS; 124DONE:
125 bb_fflush_stdout_and_exit(EXIT_SUCCESS);
113} 126}
114 127
115/*- 128/*-