diff toys/posix/echo.c @ 653:2986aa63a021

Move commands into "posix", "lsb", and "other" menus/directories.
author Rob Landley <rob@landley.net>
date Sat, 25 Aug 2012 14:25:22 -0500
parents toys/echo.c@b24c4fe9f4fd
children 6df4ccc0acbe
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/posix/echo.c	Sat Aug 25 14:25:22 2012 -0500
@@ -0,0 +1,97 @@
+/* vi: set sw=4 ts=4:
+ *
+ * echo.c - echo supporting -n and -e.
+ *
+ * Copyright 2007 Rob Landley <rob@landley.net>
+ *
+ * See http://www.opengroup.org/onlinepubs/009695399/utilities/echo.html
+
+USE_ECHO(NEWTOY(echo, "^?en", TOYFLAG_BIN))
+
+config ECHO
+	bool "echo"
+	default y
+	help
+	  usage: echo [-ne] [args...]
+
+	  Write each argument to stdout, with one space between each, followed
+	  by a newline.
+
+	  -n	No trailing newline.
+	  -e	Process the following escape sequences:
+	   \\	 backslash
+	   \0NNN octal values (1 to 3 digits)
+	   \a	 alert (beep/flash)
+	   \b	 backspace
+	   \c	 stop output here (avoids trailing newline)
+	   \f	 form feed
+	   \n	 newline
+	   \r	 carriage return
+	   \t	 horizontal tab
+	   \v	 vertical tab
+	   \xHH	 hexadecimal values (1 to 2 digits)
+*/
+
+#define THIS echo
+#include "toys.h"
+
+#define FLAG_e (1<<1)
+#define FLAG_n (1<<0)
+
+void echo_main(void)
+{
+	int i = 0, out;
+	char *arg, *from = "\\abfnrtv", *to = "\\\a\b\f\n\r\t\v", *c;
+
+	for (;;) {
+		arg = toys.optargs[i];
+		if (!arg) break;
+		if (i++) xputc(' ');
+
+		// Should we output arg verbatim?
+
+		if (!(toys.optflags&FLAG_e)) {
+			xprintf("%s", arg);
+			continue;
+		}
+
+		// Handle -e
+
+		for (c=arg;;) {
+			if (!(out = *(c++))) break;
+
+			// handle \escapes
+			if (out == '\\' && *c) {
+				int n = 0, slash = *(c++);
+				char *found = strchr(from, slash);
+				if (found) out = to[found-from];
+				else if (slash == 'c') goto done;
+				else if (slash == '0') {
+					out = 0;
+					while (*c>='0' && *c<='7' && n++<3)
+						out = (out*8)+*(c++)-'0';
+				} else if (slash == 'x') {
+					out = 0;							
+					while (n++<2) {
+						if (*c>='0' && *c<='9')
+							out = (out*16)+*(c++)-'0';
+						else {
+							int temp = tolower(*c);
+							if (temp>='a' && temp<='f') {
+								out = (out*16)+temp-'a'+10;
+								c++;
+							} else break;
+						}
+					}
+				// Slash in front of unknown character, print literal.
+				} else c--;
+			}
+			xputc(out);
+		}
+	}
+
+	// Output "\n" if no -n
+	if (!(toys.optflags&FLAG_n)) xputc('\n');
+done:
+	xflush();
+}