10f66f451Sopenharmony_ci/* echo.c - echo supporting -n and -e. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2007 Rob Landley <rob@landley.net> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/echo.html 60f66f451Sopenharmony_ci * 70f66f451Sopenharmony_ci * Deviations from posix: we parse command line options, as Linux has 80f66f451Sopenharmony_ci * consistently done since 1992. Posix defaults -e to on, we require -e. 90f66f451Sopenharmony_ci * We also honor -- to _stop_ option parsing (bash doesn't, we go with 100f66f451Sopenharmony_ci * consistency over compatibility here). 110f66f451Sopenharmony_ci 120f66f451Sopenharmony_ciUSE_ECHO(NEWTOY(echo, "^?Een[-eE]", TOYFLAG_BIN|TOYFLAG_MAYFORK)) 130f66f451Sopenharmony_ci 140f66f451Sopenharmony_ciconfig ECHO 150f66f451Sopenharmony_ci bool "echo" 160f66f451Sopenharmony_ci default y 170f66f451Sopenharmony_ci help 180f66f451Sopenharmony_ci usage: echo [-neE] [args...] 190f66f451Sopenharmony_ci 200f66f451Sopenharmony_ci Write each argument to stdout, with one space between each, followed 210f66f451Sopenharmony_ci by a newline. 220f66f451Sopenharmony_ci 230f66f451Sopenharmony_ci -n No trailing newline 240f66f451Sopenharmony_ci -E Print escape sequences literally (default) 250f66f451Sopenharmony_ci -e Process the following escape sequences: 260f66f451Sopenharmony_ci \\ Backslash 270f66f451Sopenharmony_ci \0NNN Octal values (1 to 3 digits) 280f66f451Sopenharmony_ci \a Alert (beep/flash) 290f66f451Sopenharmony_ci \b Backspace 300f66f451Sopenharmony_ci \c Stop output here (avoids trailing newline) 310f66f451Sopenharmony_ci \f Form feed 320f66f451Sopenharmony_ci \n Newline 330f66f451Sopenharmony_ci \r Carriage return 340f66f451Sopenharmony_ci \t Horizontal tab 350f66f451Sopenharmony_ci \v Vertical tab 360f66f451Sopenharmony_ci \xHH Hexadecimal values (1 to 2 digits) 370f66f451Sopenharmony_ci*/ 380f66f451Sopenharmony_ci 390f66f451Sopenharmony_ci#define FOR_echo 400f66f451Sopenharmony_ci#include "toys.h" 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_civoid echo_main(void) 430f66f451Sopenharmony_ci{ 440f66f451Sopenharmony_ci int i = 0, out; 450f66f451Sopenharmony_ci char *arg, *c; 460f66f451Sopenharmony_ci 470f66f451Sopenharmony_ci for (;;) { 480f66f451Sopenharmony_ci arg = toys.optargs[i]; 490f66f451Sopenharmony_ci if (!arg) break; 500f66f451Sopenharmony_ci if (i++) putchar(' '); 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_ci // Should we output arg verbatim? 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci if (!FLAG(e)) { 550f66f451Sopenharmony_ci xprintf("%s", arg); 560f66f451Sopenharmony_ci continue; 570f66f451Sopenharmony_ci } 580f66f451Sopenharmony_ci 590f66f451Sopenharmony_ci // Handle -e 600f66f451Sopenharmony_ci 610f66f451Sopenharmony_ci for (c = arg;;) { 620f66f451Sopenharmony_ci if (!(out = *(c++))) break; 630f66f451Sopenharmony_ci 640f66f451Sopenharmony_ci // handle \escapes 650f66f451Sopenharmony_ci if (out == '\\' && *c) { 660f66f451Sopenharmony_ci int slash = *(c++), n = unescape(slash); 670f66f451Sopenharmony_ci 680f66f451Sopenharmony_ci if (n) out = n; 690f66f451Sopenharmony_ci else if (slash=='c') return; 700f66f451Sopenharmony_ci else if (slash=='0') { 710f66f451Sopenharmony_ci out = 0; 720f66f451Sopenharmony_ci while (*c>='0' && *c<='7' && n++<3) out = (out*8)+*(c++)-'0'; 730f66f451Sopenharmony_ci } else if (slash=='x') { 740f66f451Sopenharmony_ci out = 0; 750f66f451Sopenharmony_ci while (n++<2) { 760f66f451Sopenharmony_ci if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0'; 770f66f451Sopenharmony_ci else { 780f66f451Sopenharmony_ci int temp = tolower(*c); 790f66f451Sopenharmony_ci if (temp>='a' && temp<='f') { 800f66f451Sopenharmony_ci out = (out*16)+temp-'a'+10; 810f66f451Sopenharmony_ci c++; 820f66f451Sopenharmony_ci } else { 830f66f451Sopenharmony_ci if (n==1) { 840f66f451Sopenharmony_ci --c; 850f66f451Sopenharmony_ci out = '\\'; 860f66f451Sopenharmony_ci } 870f66f451Sopenharmony_ci break; 880f66f451Sopenharmony_ci } 890f66f451Sopenharmony_ci } 900f66f451Sopenharmony_ci } 910f66f451Sopenharmony_ci // Slash in front of unknown character, print literal. 920f66f451Sopenharmony_ci } else c--; 930f66f451Sopenharmony_ci } 940f66f451Sopenharmony_ci putchar(out); 950f66f451Sopenharmony_ci } 960f66f451Sopenharmony_ci } 970f66f451Sopenharmony_ci 980f66f451Sopenharmony_ci // Output "\n" if no -n 990f66f451Sopenharmony_ci if (!FLAG(n)) putchar('\n'); 1000f66f451Sopenharmony_ci} 101