95 lines
2.2 KiB
C
95 lines
2.2 KiB
C
/* echo.c - echo supporting -n and -e.
|
|
*
|
|
* Copyright 2007 Rob Landley <rob@landley.net>
|
|
*
|
|
* See http://opengroup.org/onlinepubs/9699919799/utilities/echo.html
|
|
*
|
|
* Deviations from posix: we parse command line options, as Linux has
|
|
* consistently done since 1992. Posix defaults -e to on, we require -e.
|
|
* We also honor -- to _stop_ option parsing (bash doesn't, we go with
|
|
* consistency over compatibility here).
|
|
|
|
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 FOR_echo
|
|
#include "toys.h"
|
|
|
|
void echo_main(void)
|
|
{
|
|
int i = 0, out;
|
|
char *arg, *c;
|
|
|
|
for (;;) {
|
|
arg = toys.optargs[i];
|
|
if (!arg) break;
|
|
if (i++) putchar(' ');
|
|
|
|
// 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 slash = *(c++), n = unescape(slash);
|
|
|
|
if (n) out = n;
|
|
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--;
|
|
}
|
|
putchar(out);
|
|
}
|
|
}
|
|
|
|
// Output "\n" if no -n
|
|
if (!(toys.optflags&FLAG_n)) putchar('\n');
|
|
done:
|
|
xflush();
|
|
}
|