aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c8
-rw-r--r--lib/lib.h1
-rw-r--r--toys/posix/echo.c22
3 files changed, 20 insertions, 11 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 19d28d2b..dc2de121 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -283,6 +283,14 @@ int stridx(char *haystack, char needle)
return off-haystack;
}
+int unescape(char c)
+{
+ char *from = "\\abefnrtv", *to = "\\\a\b\033\f\n\r\t\v";
+ int idx = stridx(from, c);
+
+ return (idx == -1) ? 0 : to[idx];
+}
+
// If *a starts with b, advance *a past it and return 1, else return 0;
int strstart(char **a, char *b)
{
diff --git a/lib/lib.h b/lib/lib.h
index 887c1d57..49b02bb5 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -152,6 +152,7 @@ long atolx(char *c);
long atolx_range(char *numstr, long low, long high);
int numlen(long l);
int stridx(char *haystack, char needle);
+int unescape(char c);
int strstart(char **a, char *b);
off_t fdlength(int fd);
void loopfiles_rw(char **argv, int flags, int permissions, int failok,
diff --git a/toys/posix/echo.c b/toys/posix/echo.c
index 28284bfb..45890dc4 100644
--- a/toys/posix/echo.c
+++ b/toys/posix/echo.c
@@ -36,12 +36,12 @@ config ECHO
void echo_main(void)
{
int i = 0, out;
- char *arg, *from = "\\abfnrtv", *to = "\\\a\b\f\n\r\t\v", *c;
+ char *arg, *c;
for (;;) {
arg = toys.optargs[i];
if (!arg) break;
- if (i++) xputc(' ');
+ if (i++) putchar(' ');
// Should we output arg verbatim?
@@ -52,19 +52,19 @@ void echo_main(void)
// Handle -e
- for (c=arg;;) {
+ 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') {
+ 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') {
+ } else if (slash=='x') {
out = 0;
while (n++<2) {
if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0';
@@ -79,12 +79,12 @@ void echo_main(void)
// Slash in front of unknown character, print literal.
} else c--;
}
- xputc(out);
+ putchar(out);
}
}
// Output "\n" if no -n
- if (!(toys.optflags&FLAG_n)) xputc('\n');
+ if (!(toys.optflags&FLAG_n)) putchar('\n');
done:
xflush();
}