blob: de4be54b5808906c2eaee2951a7db4511fb70643 [file] [log] [blame]
/* 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)
*/
#include "toys.h"
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&2)) {
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&1)) xputc('\n');
done:
xflush();
}