| /* vi: set sw=4 ts=4: |
| * |
| * echo.c - echo supporting -n and -e. |
| * |
| * Copyright 2007 Rob Landley <rob@landley.net> |
| * |
| * See http://www.opengroup.org/onlinepubs/009695399/utilities/echo.html |
| |
| USE_ECHO(NEWTOY(echo, "^?en", TOYFLAG_BIN)) |
| |
| config ECHO |
| bool "echo" |
| default y |
| help |
| usage: echo [-ne] [args...] |
| |
| Write each argument to stdout, with one space between each, followed |
| by a newline. |
| |
| -n No trailing newline. |
| -e Process the following escape sequences: |
| \\ backslash |
| \0NNN octal values (1 to 3 digits) |
| \a alert (beep/flash) |
| \b backspace |
| \c stop output here (avoids trailing newline) |
| \f form feed |
| \n newline |
| \r carriage return |
| \t horizontal tab |
| \v vertical tab |
| \xHH hexadecimal values (1 to 2 digits) |
| */ |
| |
| #define THIS echo |
| #include "toys.h" |
| |
| #define FLAG_e (1<<1) |
| #define FLAG_n (1<<0) |
| |
| void echo_main(void) |
| { |
| int i = 0, out; |
| char *arg, *from = "\\abfnrtv", *to = "\\\a\b\f\n\r\t\v", *c; |
| |
| for (;;) { |
| arg = toys.optargs[i]; |
| if (!arg) break; |
| if (i++) xputc(' '); |
| |
| // Should we output arg verbatim? |
| |
| if (!(toys.optflags&FLAG_e)) { |
| xprintf("%s", arg); |
| continue; |
| } |
| |
| // Handle -e |
| |
| for (c=arg;;) { |
| if (!(out = *(c++))) break; |
| |
| // handle \escapes |
| if (out == '\\' && *c) { |
| int n = 0, slash = *(c++); |
| char *found = strchr(from, slash); |
| if (found) out = to[found-from]; |
| else if (slash == 'c') goto done; |
| else if (slash == '0') { |
| out = 0; |
| while (*c>='0' && *c<='7' && n++<3) |
| out = (out*8)+*(c++)-'0'; |
| } else if (slash == 'x') { |
| out = 0; |
| while (n++<2) { |
| if (*c>='0' && *c<='9') |
| out = (out*16)+*(c++)-'0'; |
| else { |
| int temp = tolower(*c); |
| if (temp>='a' && temp<='f') { |
| out = (out*16)+temp-'a'+10; |
| c++; |
| } else break; |
| } |
| } |
| // Slash in front of unknown character, print literal. |
| } else c--; |
| } |
| xputc(out); |
| } |
| } |
| |
| // Output "\n" if no -n |
| if (!(toys.optflags&FLAG_n)) xputc('\n'); |
| done: |
| xflush(); |
| } |