# HG changeset patch # User Rob Landley # Date 1413670452 18000 # Node ID 95cb37adb0244a03619b5d057489fc4f8e80c9c2 # Parent 2ce0f52103a9fa4a59d33d8107d82d0b77f4d212 Factor out printf-style escape parsing logic from echo.c. diff -r 2ce0f52103a9 -r 95cb37adb024 lib/lib.c --- a/lib/lib.c Thu Oct 16 05:58:35 2014 -0500 +++ b/lib/lib.c Sat Oct 18 17:14:12 2014 -0500 @@ -283,6 +283,14 @@ 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 -r 2ce0f52103a9 -r 95cb37adb024 lib/lib.h --- a/lib/lib.h Thu Oct 16 05:58:35 2014 -0500 +++ b/lib/lib.h Sat Oct 18 17:14:12 2014 -0500 @@ -152,6 +152,7 @@ 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 -r 2ce0f52103a9 -r 95cb37adb024 toys/posix/echo.c --- a/toys/posix/echo.c Thu Oct 16 05:58:35 2014 -0500 +++ b/toys/posix/echo.c Sat Oct 18 17:14:12 2014 -0500 @@ -36,12 +36,12 @@ 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 @@ // 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 @@ // 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(); }