1 /* echo.c - echo supporting -n and -e. 2 * 3 * Copyright 2007 Rob Landley <rob@landley.net> 4 * 5 * See http://opengroup.org/onlinepubs/9699919799/utilities/echo.html 6 7 USE_ECHO(NEWTOY(echo, "^?en", TOYFLAG_BIN)) 8 9 config ECHO 10 bool "echo" 11 default y 12 help 13 usage: echo [-ne] [args...] 14 15 Write each argument to stdout, with one space between each, followed 16 by a newline. 17 18 -n No trailing newline. 19 -e Process the following escape sequences: 20 \\ backslash 21 \0NNN octal values (1 to 3 digits) 22 \a alert (beep/flash) 23 \b backspace 24 \c stop output here (avoids trailing newline) 25 \f form feed 26 \n newline 27 \r carriage return 28 \t horizontal tab 29 \v vertical tab 30 \xHH hexadecimal values (1 to 2 digits) 31 */ 32 33 #define FOR_echo 34 #include "toys.h" 35 echo_main(void)36void echo_main(void) 37 { 38 int i = 0, out; 39 char *arg, *c; 40 41 for (;;) { 42 arg = toys.optargs[i]; 43 if (!arg) break; 44 if (i++) putchar(' '); 45 46 // Should we output arg verbatim? 47 48 if (!(toys.optflags & FLAG_e)) { 49 xprintf("%s", arg); 50 continue; 51 } 52 53 // Handle -e 54 55 for (c = arg;;) { 56 if (!(out = *(c++))) break; 57 58 // handle \escapes 59 if (out == '\\' && *c) { 60 int slash = *(c++), n = unescape(slash); 61 62 if (n) out = n; 63 else if (slash=='c') goto done; 64 else if (slash=='0') { 65 out = 0; 66 while (*c>='0' && *c<='7' && n++<3) out = (out*8)+*(c++)-'0'; 67 } else if (slash=='x') { 68 out = 0; 69 while (n++<2) { 70 if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0'; 71 else { 72 int temp = tolower(*c); 73 if (temp>='a' && temp<='f') { 74 out = (out*16)+temp-'a'+10; 75 c++; 76 } else break; 77 } 78 } 79 // Slash in front of unknown character, print literal. 80 } else c--; 81 } 82 putchar(out); 83 } 84 } 85 86 // Output "\n" if no -n 87 if (!(toys.optflags&FLAG_n)) putchar('\n'); 88 done: 89 xflush(); 90 } 91