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 \a Alert (beep/flash) 280f66f451Sopenharmony_ci \b Backspace 290f66f451Sopenharmony_ci \c Stop output here (avoids trailing newline) 300f66f451Sopenharmony_ci \f Form feed 310f66f451Sopenharmony_ci \n Newline 320f66f451Sopenharmony_ci \r Carriage return 330f66f451Sopenharmony_ci \t Horizontal tab 340f66f451Sopenharmony_ci \v Vertical tab 350f66f451Sopenharmony_ci*/ 360f66f451Sopenharmony_ci 370f66f451Sopenharmony_ci#define FOR_echo 380f66f451Sopenharmony_ci#include "toys.h" 390f66f451Sopenharmony_ci 400f66f451Sopenharmony_civoid echo_main(void) 410f66f451Sopenharmony_ci{ 420f66f451Sopenharmony_ci int i = 0, out; 430f66f451Sopenharmony_ci char *arg, *c; 440f66f451Sopenharmony_ci 450f66f451Sopenharmony_ci for (;;) { 460f66f451Sopenharmony_ci arg = toys.optargs[i]; 470f66f451Sopenharmony_ci if (!arg) break; 480f66f451Sopenharmony_ci if (i++) putchar(' '); 490f66f451Sopenharmony_ci 500f66f451Sopenharmony_ci // Should we output arg verbatim? 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_ci if (!FLAG(e)) { 530f66f451Sopenharmony_ci xprintf("%s", arg); 540f66f451Sopenharmony_ci continue; 550f66f451Sopenharmony_ci } 560f66f451Sopenharmony_ci 570f66f451Sopenharmony_ci // Handle -e 580f66f451Sopenharmony_ci 590f66f451Sopenharmony_ci for (c = arg;;) { 600f66f451Sopenharmony_ci if (!(out = *(c++))) break; 610f66f451Sopenharmony_ci 620f66f451Sopenharmony_ci // handle \escapes 630f66f451Sopenharmony_ci if (out == '\\' && *c) { 640f66f451Sopenharmony_ci int slash = *(c++), n = unescape(slash); 650f66f451Sopenharmony_ci 660f66f451Sopenharmony_ci if (n) out = n; 670f66f451Sopenharmony_ci else if (slash=='c') return; 680f66f451Sopenharmony_ci else if (slash=='0') { 690f66f451Sopenharmony_ci out = 0; 700f66f451Sopenharmony_ci while (*c>='0' && *c<='7' && n++<3) out = (out*8)+*(c++)-'0'; 710f66f451Sopenharmony_ci } else if (slash=='x') { 720f66f451Sopenharmony_ci out = 0; 730f66f451Sopenharmony_ci while (n++<2) { 740f66f451Sopenharmony_ci if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0'; 750f66f451Sopenharmony_ci else { 760f66f451Sopenharmony_ci int temp = tolower(*c); 770f66f451Sopenharmony_ci if (temp>='a' && temp<='f') { 780f66f451Sopenharmony_ci out = (out*16)+temp-'a'+10; 790f66f451Sopenharmony_ci c++; 800f66f451Sopenharmony_ci } else { 810f66f451Sopenharmony_ci if (n==1) { 820f66f451Sopenharmony_ci --c; 830f66f451Sopenharmony_ci out = '\\'; 840f66f451Sopenharmony_ci } 850f66f451Sopenharmony_ci break; 860f66f451Sopenharmony_ci } 870f66f451Sopenharmony_ci } 880f66f451Sopenharmony_ci } 890f66f451Sopenharmony_ci // Slash in front of unknown character, print literal. 900f66f451Sopenharmony_ci } else c--; 910f66f451Sopenharmony_ci } 920f66f451Sopenharmony_ci putchar(out); 930f66f451Sopenharmony_ci } 940f66f451Sopenharmony_ci } 950f66f451Sopenharmony_ci 960f66f451Sopenharmony_ci // Output "\n" if no -n 970f66f451Sopenharmony_ci if (!FLAG(n)) putchar('\n'); 980f66f451Sopenharmony_ci} 99