/** * file: echo.c * command: echo * author: Tyler Murphy */ #include "command.h" #include "lslib.h" #include /** * Flags that are to be used with echo */ static struct { bool escape_codes; bool newline; } flags; /** * Prints a null terminated string to standard out and changes each char based on input flags * @param str the string to print */ static void print_with_escape_codes(const char* str) { size_t index = 0; /* current index in the string */ char c; /* current char being read */ char n; /* next char being read */ while (true) { c = str[index]; /* read current char */ index++; if (c == '\0') break; /* if we hit the NUL, break */ if (c != '\\') { /* if its not a escaped code, print and continue */ putchar(c); continue; } /* read next character */ n = str[index]; index++; /* check each char against the valid escape codes */ switch (n) { case '\\': putchar('\\'); break; case 'b': putchar('\b'); break; case 'c': exit(EXIT_SUCCESS); case 'n': putchar('\n'); break; case 'r': putchar('\r'); break; case 't': putchar('\t'); break; case 'v': putchar('\v'); break; default: /* if none found print both chars as is */ putchar(c); putchar(n); } } } /** * Takes in each argument that has a single - and parses it * @param c the character after the - * @param next the next argument in argv that hasnt been parsed * @reutrn if the next arg was used or if the arg was invalid */ static int short_arg(char c, char* next) { UNUSED(next); switch (c) { case 'e': flags.escape_codes = true; break; case 'E': flags.escape_codes = false; break; case 'n': flags.newline = false; break; default: flags.newline = true; flags.escape_codes = false; return ARG_IGNORE; }; return ARG_UNUSED; } /** * Prints data in each argument to stdout */ COMMAND(echo_main) { int start, i; /* if no arguments supplied exit */ if (argc < 1) { return EXIT_FAILURE; } /* set default flags */ flags.escape_codes = false; flags.newline = true; /* parse arguments, no help message */ start = parse_args(argc, argv, NULL, short_arg, NULL); /* for each argument either print as is or parse each character for escape codes */ for (i = start; i < argc; i++) { if (flags.escape_codes) { print_with_escape_codes(argv[i]); } else { printf("%s", argv[i]); } /* put a space seperator between arguments */ if (i + 1 != argc) { putchar(' '); } } /* if set to put a new line at the end (default), do so */ if (flags.newline) { putchar('\n'); } /* done */ return EXIT_SUCCESS; }