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 * Deviations from posix: we parse command line options, as Linux has 8 * consistently done since 1992. Posix defaults -e to on, we require -e. 9 * We also honor -- to _stop_ option parsing (bash doesn't, we go with 10 * consistency over compatibility here). 11 12USE_ECHO(NEWTOY(echo, "^?Een[-eE]", TOYFLAG_BIN)) 13 14config ECHO 15 bool "echo" 16 default y 17 help 18 usage: echo [-neE] [args...] 19 20 Write each argument to stdout, with one space between each, followed 21 by a newline. 22 23 -n No trailing newline 24 -E Print escape sequences literally (default) 25 -e Process the following escape sequences: 26 \\ Backslash 27 \0NNN Octal values (1 to 3 digits) 28 \a Alert (beep/flash) 29 \b Backspace 30 \c Stop output here (avoids trailing newline) 31 \f Form feed 32 \n Newline 33 \r Carriage return 34 \t Horizontal tab 35 \v Vertical tab 36 \xHH Hexadecimal values (1 to 2 digits) 37*/ 38 39#define FOR_echo 40#include "toys.h" 41 42void echo_main(void) 43{ 44 int i = 0, out; 45 char *arg, *c; 46 47 for (;;) { 48 arg = toys.optargs[i]; 49 if (!arg) break; 50 if (i++) putchar(' '); 51 52 // Should we output arg verbatim? 53 54 if (!(toys.optflags & FLAG_e)) { 55 xprintf("%s", arg); 56 continue; 57 } 58 59 // Handle -e 60 61 for (c = arg;;) { 62 if (!(out = *(c++))) break; 63 64 // handle \escapes 65 if (out == '\\' && *c) { 66 int slash = *(c++), n = unescape(slash); 67 68 if (n) out = n; 69 else if (slash=='c') return; 70 else if (slash=='0') { 71 out = 0; 72 while (*c>='0' && *c<='7' && n++<3) out = (out*8)+*(c++)-'0'; 73 } else if (slash=='x') { 74 out = 0; 75 while (n++<2) { 76 if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0'; 77 else { 78 int temp = tolower(*c); 79 if (temp>='a' && temp<='f') { 80 out = (out*16)+temp-'a'+10; 81 c++; 82 } else break; 83 } 84 } 85 // Slash in front of unknown character, print literal. 86 } else c--; 87 } 88 putchar(out); 89 } 90 } 91 92 // Output "\n" if no -n 93 if (!(toys.optflags&FLAG_n)) putchar('\n'); 94} 95