From a1824752a0606ec1a4c4d995624133128cbac61a Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Sun, 23 Aug 2020 20:09:42 +0200 Subject: Added echo --- src/echo.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/echo.c (limited to 'src') diff --git a/src/echo.c b/src/echo.c new file mode 100644 index 0000000..fbf74bd --- /dev/null +++ b/src/echo.c @@ -0,0 +1,105 @@ +#define _POSIX_C_SOURCE 2 +#include +#include +#include +#include +#include +#include +#include + +bool isodigit(char c) +{ + return c >= '0' && c < '8'; +} + +int main(int argc, char **argv) +{ + int option; + bool escape = false; + bool newline = true; + + while ((option = getopt(argc, argv, "neE")) != -1) + { + switch (option) + { + case 'e': escape = true; break; + case 'E': escape = false; break; + case 'n': newline = false; break; + } + } + for (; optind < argc; optind++) + { + char *str = argv[optind]; + if (escape) + { + for (size_t i = 0; str[i] != '\0'; i++) + { + if (str[i] == '\\') + { + uint8_t c = 0; + int shift = 1; + + switch (str[i + 1]) + { + case '\\': c = '\\'; break; + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'e': c = '\033'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + case '0': + c = 0; + for (int j = 0; isodigit(str[i + 2 + j]) && j < 3; j++) + { + c *= 8; + c += str[i + 2 + j] - '0'; + shift++; + } + break; + + case 'x': + c = 0; + for (int j = 0; isxdigit(str[i + 2 + j]) && j < 2; j++) + { + c *= 16; + if (islower(str[i + 2 + j])) + c += 10 + str[i + 2 + j] - 'a'; + else if (isupper(str[i + 2 + j])) + c += 10 + str[i + 2 + j] - 'A'; + else + c += str[i + 2 + j] - '0'; + shift++; + } + break; + + case 'c': + str[i] = '\0'; + fputs(str, stdout); + fflush(stdout); + exit(EXIT_SUCCESS); + break; + + default: + shift = -1; + break; + } + if (shift != -1) + { + str[i] = c; + memmove(&str[i + 1], &str[i + 1 + shift], strlen(&str[i + 1 + shift]) + 1); + } + } + } + } + fputs(str, stdout); + if (optind + 1 != argc) + putchar(' '); + } + if (newline) + putchar('\n'); + return EXIT_SUCCESS; +} -- cgit