xref: /aosp_15_r20/external/toybox/toys/posix/echo.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1*cf5a6c84SAndroid Build Coastguard Worker /* echo.c - echo supporting -n and -e.
2*cf5a6c84SAndroid Build Coastguard Worker  *
3*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2007 Rob Landley <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker  *
5*cf5a6c84SAndroid Build Coastguard Worker  * See http://opengroup.org/onlinepubs/9699919799/utilities/echo.html
6*cf5a6c84SAndroid Build Coastguard Worker  *
7*cf5a6c84SAndroid Build Coastguard Worker  * Deviations from posix: we parse command line options, as Linux has
8*cf5a6c84SAndroid Build Coastguard Worker  * consistently done since 1992. Posix defaults -e to on, we require -e.
9*cf5a6c84SAndroid Build Coastguard Worker  * We also honor -- to _stop_ option parsing (bash doesn't, we go with
10*cf5a6c84SAndroid Build Coastguard Worker  * consistency over compatibility here).
11*cf5a6c84SAndroid Build Coastguard Worker 
12*cf5a6c84SAndroid Build Coastguard Worker USE_ECHO(NEWTOY(echo, "^?Een[-eE]", TOYFLAG_BIN|TOYFLAG_MAYFORK|TOYFLAG_LINEBUF))
13*cf5a6c84SAndroid Build Coastguard Worker 
14*cf5a6c84SAndroid Build Coastguard Worker config ECHO
15*cf5a6c84SAndroid Build Coastguard Worker   bool "echo"
16*cf5a6c84SAndroid Build Coastguard Worker   default y
17*cf5a6c84SAndroid Build Coastguard Worker   help
18*cf5a6c84SAndroid Build Coastguard Worker     usage: echo [-Een] [ARG...]
19*cf5a6c84SAndroid Build Coastguard Worker 
20*cf5a6c84SAndroid Build Coastguard Worker     Write each argument to stdout, one space between each, followed by a newline.
21*cf5a6c84SAndroid Build Coastguard Worker 
22*cf5a6c84SAndroid Build Coastguard Worker     -E	Print escape sequences literally (default)
23*cf5a6c84SAndroid Build Coastguard Worker     -e	Process the following escape sequences:
24*cf5a6c84SAndroid Build Coastguard Worker     	\\  Backslash		\0NNN Octal (1-3 digit)	\xHH Hex (1-2 digit)
25*cf5a6c84SAndroid Build Coastguard Worker     	\a  Alert (beep/flash)	\b  Backspace		\c  Stop here (no \n)
26*cf5a6c84SAndroid Build Coastguard Worker     	\f  Form feed		\n  Newline		\r  Carriage return
27*cf5a6c84SAndroid Build Coastguard Worker     	\t  Horizontal tab	\v  Vertical tab
28*cf5a6c84SAndroid Build Coastguard Worker     -n	No trailing newline
29*cf5a6c84SAndroid Build Coastguard Worker */
30*cf5a6c84SAndroid Build Coastguard Worker 
31*cf5a6c84SAndroid Build Coastguard Worker #define FOR_echo
32*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
33*cf5a6c84SAndroid Build Coastguard Worker 
echo_main(void)34*cf5a6c84SAndroid Build Coastguard Worker void echo_main(void)
35*cf5a6c84SAndroid Build Coastguard Worker {
36*cf5a6c84SAndroid Build Coastguard Worker   int i = 0;
37*cf5a6c84SAndroid Build Coastguard Worker   char *arg, *c, out[8];
38*cf5a6c84SAndroid Build Coastguard Worker 
39*cf5a6c84SAndroid Build Coastguard Worker   while ((arg = toys.optargs[i])) {
40*cf5a6c84SAndroid Build Coastguard Worker     if (i++) putchar(' ');
41*cf5a6c84SAndroid Build Coastguard Worker 
42*cf5a6c84SAndroid Build Coastguard Worker     // Should we output arg verbatim?
43*cf5a6c84SAndroid Build Coastguard Worker 
44*cf5a6c84SAndroid Build Coastguard Worker     if (!FLAG(e)) {
45*cf5a6c84SAndroid Build Coastguard Worker       xprintf("%s", arg);
46*cf5a6c84SAndroid Build Coastguard Worker       continue;
47*cf5a6c84SAndroid Build Coastguard Worker     }
48*cf5a6c84SAndroid Build Coastguard Worker 
49*cf5a6c84SAndroid Build Coastguard Worker     // Handle -e
50*cf5a6c84SAndroid Build Coastguard Worker 
51*cf5a6c84SAndroid Build Coastguard Worker     for (c = arg; *c; ) {
52*cf5a6c84SAndroid Build Coastguard Worker       unsigned u;
53*cf5a6c84SAndroid Build Coastguard Worker 
54*cf5a6c84SAndroid Build Coastguard Worker       if (*c == '\\' && c[1] == 'c') return;
55*cf5a6c84SAndroid Build Coastguard Worker       if ((u = unescape2(&c, 1))<128) putchar(u);
56*cf5a6c84SAndroid Build Coastguard Worker       else printf("%.*s", (int)wcrtomb(out, u, 0), out);
57*cf5a6c84SAndroid Build Coastguard Worker     }
58*cf5a6c84SAndroid Build Coastguard Worker   }
59*cf5a6c84SAndroid Build Coastguard Worker 
60*cf5a6c84SAndroid Build Coastguard Worker   // Output "\n" if no -n
61*cf5a6c84SAndroid Build Coastguard Worker   if (!FLAG(n)) putchar('\n');
62*cf5a6c84SAndroid Build Coastguard Worker }
63