summaryrefslogtreecommitdiff
path: root/coreutils/echo.c
diff options
context:
space:
mode:
authorManuel Novoa III2003-03-19 09:13:01 +0000
committerManuel Novoa III2003-03-19 09:13:01 +0000
commitcad5364599eb5062d59e0c397ed638ddd61a8d5d (patch)
treea318d0f03aa076c74b576ea45dc543a5669e8e91 /coreutils/echo.c
parente01f9662a5bd5d91be4f6b3941b57fff73cd5af1 (diff)
downloadbusybox-cad5364599eb5062d59e0c397ed638ddd61a8d5d.zip
busybox-cad5364599eb5062d59e0c397ed638ddd61a8d5d.tar.gz
Major coreutils update.
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 31c0315..b600a1f 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -22,94 +22,107 @@
* Original copyright notice is retained at the end of this file.
*/
+/* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */
+
+/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ *
+ * Because of behavioral differences, implemented configureable SUSv3
+ * or 'fancy' gnu-ish behaviors. Also, reduced size and fixed bugs.
+ * 1) In handling '\c' escape, the previous version only suppressed the
+ * trailing newline. SUSv3 specifies _no_ output after '\c'.
+ * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
+ * The previous version version did not allow 4-digit octals.
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "busybox.h"
-extern int
-echo_main(int argc, char** argv)
+extern int echo_main(int argc, char** argv)
{
- int nflag = 0;
+#ifndef CONFIG_FEATURE_FANCY_ECHO
+#define eflag '\\'
+ ++argv;
+#else
+ const char *p;
+ int nflag = 1;
int eflag = 0;
- /* Skip argv[0]. */
- argc--;
- argv++;
-
- while (argc > 0 && *argv[0] == '-')
- {
- register char *temp;
- register int ix;
-
- /*
- * If it appears that we are handling options, then make sure
+ while (*++argv && (**argv == '-')) {
+ /* If it appears that we are handling options, then make sure
* that all of the options specified are actually valid.
* Otherwise, the string should just be echoed.
*/
- temp = argv[0] + 1;
-
- for (ix = 0; temp[ix]; ix++)
- {
- if (strrchr("neE", temp[ix]) == 0)
- goto just_echo;
- }
-
- if (!*temp)
+
+ if (!*(p = *argv + 1)) { /* A single '-', so echo it. */
goto just_echo;
+ }
- /*
- * All of the options in temp are valid options to echo.
- * Handle them.
- */
- while (*temp)
- {
- if (*temp == 'n')
- nflag = 1;
- else if (*temp == 'e')
- eflag = 1;
- else if (*temp == 'E')
- eflag = 0;
- else
+ do {
+ if (strrchr("neE", *p) == 0) {
goto just_echo;
+ }
+ } while (*++p);
- temp++;
- }
- argc--;
- argv++;
+ /* All of the options in this arg are valid, so handle them. */
+ p = *argv + 1;
+ do {
+ if (*p == 'n') {
+ nflag = 0;
+ } else if (*p == 'e') {
+ eflag = '\\';
+ } else {
+ eflag = 0;
+ }
+ } while (*++p);
}
just_echo:
- while (argc > 0) {
- const char *arg = argv[0];
+#endif
+ while (*argv) {
register int c;
- while ((c = *arg++)) {
-
- /* Check for escape sequence. */
- if (c == '\\' && eflag && *arg) {
- if (*arg == 'c') {
- /* '\c' means cancel newline. */
- nflag = 1;
- arg++;
- continue;
- } else {
- c = process_escape_sequence(&arg);
+ while ((c = *(*argv)++)) {
+ if (c == eflag) { /* Check for escape seq. */
+ if (**argv == 'c') {
+ /* '\c' means cancel newline and
+ * ignore all subsequent chars. */
+ goto DONE;
+ }
+#ifndef CONFIG_FEATURE_FANCY_ECHO
+ /* SUSv3 specifies that octal escapes must begin with '0'. */
+ if (((unsigned int)(**argv - '1')) >= 7)
+#endif
+ {
+ /* Since SUSv3 mandates a first digit of 0, 4-digit octals
+ * of the form \0### are accepted. */
+ if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) {
+ (*argv)++;
+ }
+ /* bb_process_escape_sequence can handle nul correctly */
+ c = bb_process_escape_sequence((const char **) argv);
}
}
-
putchar(c);
}
- argc--;
- argv++;
- if (argc > 0)
+
+ if (*++argv) {
putchar(' ');
+ }
}
- if (!nflag)
+
+#ifdef CONFIG_FEATURE_FANCY_ECHO
+ if (nflag) {
putchar('\n');
- fflush(stdout);
+ }
+#else
+ putchar('\n');
+#endif
- return EXIT_SUCCESS;
+DONE:
+ bb_fflush_stdout_and_exit(EXIT_SUCCESS);
}
/*-