diff options
Diffstat (limited to 'commands/echo.c')
-rw-r--r-- | commands/echo.c | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/commands/echo.c b/commands/echo.c index 8853ee0a30..572b852ea3 100644 --- a/commands/echo.c +++ b/commands/echo.c @@ -1,21 +1,7 @@ -/* - * echo.c - echo arguments to stdout or into a file - * - * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: © 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + +/* echo.c - echo arguments to stdout or into a file */ #include <common.h> #include <command.h> @@ -24,6 +10,40 @@ #include <errno.h> #include <libbb.h> +static void echo_dputc(int fd, char c, bool wide) +{ + wchar_t wc; + int n; + + if (!wide || fd == 1 || fd == 2) { + dputc(fd, c); + return; + } + + n = mbtowc(&wc, &c, 1); + if (n < 0) + return; + + write(fd, &wc, sizeof(wchar_t)); +} + +static void echo_dputs(int fd, const char *s, bool wide) +{ + wchar_t *ws; + + if (!wide || fd == 1 || fd == 2) { + dputs(fd, s); + return; + } + + ws = strdup_char_to_wchar(s); + if (!ws) + return; + + write(fd, ws, wcslen(ws) * sizeof(wchar_t)); + free(ws); +} + static int do_echo(int argc, char *argv[]) { int i, optind = 1; @@ -32,6 +52,10 @@ static int do_echo(int argc, char *argv[]) int oflags = O_WRONLY | O_CREAT; char str[CONFIG_CBSIZE]; int process_escape = 0; + bool wide = false; + + if (IS_ENABLED(CONFIG_PRINTF_WCHAR) && *argv[0] == 'w') + wide = true; /* We can't use getopt() here because we want to * echo all things we don't understand. @@ -80,18 +104,22 @@ exit_parse: } for (i = optind; i < argc; i++) { + const char *out; + if (i > optind) - dputc(fd, ' '); + echo_dputc(fd, ' ', wide); if (process_escape) { process_escape_sequence(argv[i], str, CONFIG_CBSIZE); - dputs(fd, str); + out = str; } else { - dputs(fd, argv[i]); + out = argv[i]; } + + echo_dputs(fd, out, wide); } if (newline) - dputc(fd, '\n'); + echo_dputc(fd, '\n', wide); if (file) close(fd); @@ -113,8 +141,13 @@ BAREBOX_CMD_HELP_OPT ("-a FILE", "append to FILE instead of using stdout") BAREBOX_CMD_HELP_OPT ("-o FILE", "overwrite FILE instead of using stdout") BAREBOX_CMD_HELP_END +static __maybe_unused const char * const echo_aliases[] = { "wecho", NULL}; + BAREBOX_CMD_START(echo) .cmd = do_echo, +#ifdef CONFIG_PRINTF_WCHAR + .aliases = echo_aliases, +#endif BAREBOX_CMD_DESC("echo args to console") BAREBOX_CMD_OPTS("[-neao] STRING") BAREBOX_CMD_GROUP(CMD_GRP_CONSOLE) |