toaruos/apps/echo.c

126 lines
2.3 KiB
C
Raw Normal View History

/**
* @brief echo - Print arguments to stdout.
2018-03-02 15:25:22 +03:00
*
2018-08-15 04:07:33 +03:00
* Prints arguments to stdout, possibly interpreting escape
* sequences in the arguments.
*
* @copyright
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2013-2018 K. Lange
2018-03-02 15:25:22 +03:00
*/
2018-10-05 13:15:08 +03:00
#include <ctype.h>
2018-03-02 15:25:22 +03:00
#include <stdio.h>
#include <string.h>
2018-08-15 04:07:33 +03:00
#include <unistd.h>
2018-03-02 15:25:22 +03:00
2018-08-15 04:07:33 +03:00
void show_usage(char * argv[]) {
printf(
"echo - print arguments\n"
"\n"
"usage: %s [-ne] ARG...\n"
"\n"
" -n \033[3mdo not output a new line at the end\033[0m\n"
" -e \033[3mprocess escape sequences\033[0m\n"
" -? \033[3mshow this help text\033[0m\n"
"\n", argv[0]);
2018-03-02 15:25:22 +03:00
}
int main(int argc, char ** argv) {
int use_newline = 1;
int process_escapes = 0;
2018-08-15 04:07:33 +03:00
int opt;
while ((opt = getopt(argc, argv, "enh?")) != -1) {
switch (opt) {
case '?':
case 'h':
show_usage(argv);
2018-03-02 15:25:22 +03:00
return 1;
2018-08-15 04:07:33 +03:00
case 'n':
2018-03-02 15:25:22 +03:00
use_newline = 0;
2018-08-15 04:07:33 +03:00
break;
case 'e':
2018-03-02 15:25:22 +03:00
process_escapes = 1;
2018-08-15 04:07:33 +03:00
break;
2018-03-02 15:25:22 +03:00
}
}
2018-08-15 04:07:33 +03:00
for (int i = optind; i < argc; ++i) {
2018-03-02 15:25:22 +03:00
if (process_escapes) {
2018-10-05 13:15:08 +03:00
char * c = argv[i];
while (*c) {
if (*c == '\\') {
c++;
switch (*c) {
case '\\':
putchar('\\');
break;
case 'a':
putchar('\a');
break;
case 'b':
putchar('\b');
break;
case 'c':
return 0;
case 'e':
putchar('\033');
break;
case 'f':
putchar('\f');
break;
case 'n':
putchar('\n');
break;
case 't':
putchar('\t');
break;
case 'v':
putchar('\v');
break;
case '0':
{
int i = 0;
if (!isdigit(*(c+1)) || *(c+1) > '7') {
break;
}
c++;
i = *c - '0';
if (isdigit(*(c+1)) && *(c+1) <= '7') {
c++;
i = (i << 3) | (*c - '0');
if (isdigit(*(c+1)) && *(c+1) <= '7') {
c++;
i = (i << 3) | (*c - '0');
}
}
putchar(i);
}
break;
default:
putchar('\\');
putchar(*c);
break;
2018-03-02 15:25:22 +03:00
}
2018-10-05 13:15:08 +03:00
} else {
putchar(*c);
2018-03-02 15:25:22 +03:00
}
2018-10-05 13:15:08 +03:00
c++;
2018-03-02 15:25:22 +03:00
}
2018-10-05 13:15:08 +03:00
} else {
printf("%s",argv[i]);
2018-03-02 15:25:22 +03:00
}
if (i != argc - 1) {
printf(" ");
}
}
if (use_newline) {
printf("\n");
}
fflush(stdout);
return 0;
}