OSDN Git Service

"printf %x 64" wasn't working right on 32 bit because a variable type was wrong.
[android-x86/external-toybox.git] / toys / posix / echo.c
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
12 USE_ECHO(NEWTOY(echo, "^?en", TOYFLAG_BIN))
13
14 config ECHO
15   bool "echo"
16   default y
17   help
18     usage: echo [-ne] [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  Process the following escape sequences:
25         \\      backslash
26         \0NNN   octal values (1 to 3 digits)
27         \a      alert (beep/flash)
28         \b      backspace
29         \c      stop output here (avoids trailing newline)
30         \f      form feed
31         \n      newline
32         \r      carriage return
33         \t      horizontal tab
34         \v      vertical tab
35         \xHH    hexadecimal values (1 to 2 digits)
36 */
37
38 #define FOR_echo
39 #include "toys.h"
40
41 void echo_main(void)
42 {
43   int i = 0, out;
44   char *arg, *c;
45
46   for (;;) {
47     arg = toys.optargs[i];
48     if (!arg) break;
49     if (i++) putchar(' ');
50
51     // Should we output arg verbatim?
52
53     if (!(toys.optflags & FLAG_e)) {
54       xprintf("%s", arg);
55       continue;
56     }
57
58     // Handle -e
59
60     for (c = arg;;) {
61       if (!(out = *(c++))) break;
62
63       // handle \escapes
64       if (out == '\\' && *c) {
65         int slash = *(c++), n = unescape(slash);
66
67         if (n) out = n;
68         else if (slash=='c') goto done;
69         else if (slash=='0') {
70           out = 0;
71           while (*c>='0' && *c<='7' && n++<3) out = (out*8)+*(c++)-'0';
72         } else if (slash=='x') {
73           out = 0;
74           while (n++<2) {
75             if (*c>='0' && *c<='9') out = (out*16)+*(c++)-'0';
76             else {
77               int temp = tolower(*c);
78               if (temp>='a' && temp<='f') {
79                 out = (out*16)+temp-'a'+10;
80                 c++;
81               } else break;
82             }
83           }
84         // Slash in front of unknown character, print literal.
85         } else c--;
86       }
87       putchar(out);
88     }
89   }
90
91   // Output "\n" if no -n
92   if (!(toys.optflags&FLAG_n)) putchar('\n');
93 done:
94   xflush();
95 }