coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2020-07-08 15:01:28
Commit0b0be97cc31f21056a2cd77f84c5f98c812f95b9
Parent062c74fe54c9751eb57434f8ed40fba624ec42f6

echo: Add XSI escape sequence support

Diffstat

M src/echo.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------

1 files changed, 48 insertions, 6 deletions

diff --git a/src/echo.c b/src/echo.c
index 9a22e62..71b6f08 100644
--- a/src/echo.c
+++ b/src/echo.c
@@ -1,13 +1,29 @@
-// echo.c, version 1.0.0
+// echo.c, version 1.1.0
 // OMKOV coreutils implementation of POSIX echo
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
 /*
-OMKOV Public Domain Licence, version 1.0
+OMKOV Permissive Licence, version 1.0
 
-Permission is hereby granted to deal with this software and its associated
-documentation files without restriction.
+Copyright (C) 2020, Jakob Wakeling
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
@@ -18,9 +34,35 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
 #include <stdio.h>
+#include <stdlib.h>
+
+static inline void echo(const char *s);
 
 int main(int ac, char *av[]) { (void)ac;
-	register char **p = &av[1]; if (*p) { fputs(*p, stdout);
-		for (++p; *p; ++p) { fputc(' ', stdout); fputs(*p, stdout); }
+	register char **p = &av[1]; if (*p) { echo(*p);
+		for (++p; *p; ++p) { fputc(' ', stdout); echo(*p); }
 	} fputc('\n', stdout); return 0;
 }
+
+static inline void echo(const char *s) {
+	for (const char *p = s; *p; ++p) {
+		if (*p == '\\' && p[1]) switch (*++p) {
+		case 'a': { fputc('\a', stdout); continue; }
+		case 'b': { fputc('\b', stdout); continue; }
+		case 'c': { exit(0); }
+		case 'f': { fputc('\f', stdout); continue; }
+		case 'n': { fputc('\n', stdout); continue; }
+		case 'r': { fputc('\r', stdout); continue; }
+		case 't': { fputc('\t', stdout); continue; }
+		case 'v': { fputc('\v', stdout); continue; }
+		case '\\': { fputc('\\', stdout); continue; }
+		case '0': {
+			register int n = 0, d = 0;
+			for (++p; (*p >= '0' && *p <= '7') && d++ != 3; ++p) {
+				n <<= 3; n |= (*p - '0');
+			} fputc(n, stdout); --p; continue;
+		}
+		default: { fputc('\\', stdout); fputc(*p, stdout); }
+		} else { fputc(*p, stdout); continue; }
+	} return;
+}