X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fecho.c;h=539640fb0052eb3d42f05324d8d05f706db86a15;hb=5cfa5ef6f358bb979b76f8927899b920074f698d;hp=6890d95e0b87a967ecb6c63f9d1b48deefe45b20;hpb=3570a34de46b1f7dedd16999bb1687e2d6b55d40;p=oweals%2Fbusybox.git diff --git a/coreutils/echo.c b/coreutils/echo.c index 6890d95e0..539640fb0 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c @@ -22,53 +22,107 @@ * Original copyright notice is retained at the end of this file. */ -#include "busybox.h" +/* 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 configurable 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 +#include +#include +#include "busybox.h" -extern int -echo_main(int argc, char** argv) +extern int echo_main(int argc, char** argv) { - register char **ap; - char *p; - int c; - int nflag = 0; +#ifndef CONFIG_FEATURE_FANCY_ECHO +#define eflag '\\' + ++argv; +#else + const char *p; + int nflag = 1; int eflag = 0; + 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. + */ - while ((c = getopt(argc, argv, "neE")) != EOF) { - switch (c) { - case 'n': - nflag = 1; - break; - case 'e': - eflag = 1; - break; - case 'E': - eflag = 0; - break; - default: - usage(echo_usage); + if (!*(p = *argv + 1)) { /* A single '-', so echo it. */ + goto just_echo; } + + do { + if (strrchr("neE", *p) == 0) { + goto just_echo; + } + } while (*++p); + + /* 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); } - ap = &argv[optind]; - while ((p = *ap++) != NULL) { - while ((c = *p++) != '\0') { - if (c == '\\' && eflag) { - if (*p == 'c') - exit(0); - else - c = process_escape_sequence(&p); +just_echo: +#endif + while (*argv) { + register int c; + + 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); } - if (*ap) + + if (*++argv) { putchar(' '); + } } - if (! nflag) + +#ifdef CONFIG_FEATURE_FANCY_ECHO + if (nflag) { putchar('\n'); - fflush(stdout); - return( 0); + } +#else + putchar('\n'); +#endif + +DONE: + bb_fflush_stdout_and_exit(EXIT_SUCCESS); } /*- @@ -86,9 +140,10 @@ echo_main(int argc, char** argv) * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of + * + * 3. + * * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software @@ -108,5 +163,3 @@ echo_main(int argc, char** argv) * * @(#)echo.c 8.1 (Berkeley) 5/31/93 */ - -