c-bootbox/sysutils/echo.c

172 lines
3.4 KiB
C

#include <stdio.h>
#include <string.h>
#include "utils.h"
int echo_main(int argc, char **argv)
{
// Init
int add_newline;
int escape;
int backup_add_newline;
int backup_escape;
const char *escape_from;
const char *escape_to;
int argv_pos;
int i;
int j;
int len;
int len2;
int break_outer;
int first;
unsigned char tmp_char;
add_newline = 1;
escape = 0;
escape_from = "\\abnrtvf";
escape_to = "\\\a\\\n\r\t\v\f";
len2 = strlen(escape_from);
argv_pos = 1;
// Check for options
break_outer = 0;
while((argv_pos < argc) && (break_outer == 0)) {
backup_add_newline = add_newline;
backup_escape = escape;
if(argv[argv_pos][0] != '-') {
break;
}
i = 1;
len = strlen(argv[argv_pos]);
while(i < len) {
if(argv[argv_pos][i] == 'e') {
escape = 1;
}
else if(argv[argv_pos][i] == 'E') {
escape = 0;
}
else if(argv[argv_pos][i] == 'n') {
add_newline = 0;
}
else {
escape = backup_escape;
add_newline = backup_add_newline;
break_outer = 1;
break;
}
i++;
}
argv_pos++;
}
// Output strings
first = 1;
while(argv_pos < argc) {
// Add spaces betwean arguments
if(first != 0) {
first = 0;
}
else {
if(fwrite(" ", 1, 1, stdout) != 1) {
return 1;
}
}
if(escape != 0) {
// Escaped output
i = 0;
len = strlen(argv[argv_pos]);
while(i < len) {
if(argv[argv_pos][i] == '\\') {
i++;
if(argv[argv_pos][i] == 'c') {
return 0;
}
else if(argv[argv_pos][i] == '0') {
tmp_char = 0;
i++;
if(is_octal_dig(argv[argv_pos][i]) != 0) {
tmp_char = (tmp_char << 3) | ((unsigned char)parse_octal_dig(argv[argv_pos][i]));
i++;
if(is_octal_dig(argv[argv_pos][i]) != 0) {
tmp_char = (tmp_char << 3) | ((unsigned char)parse_octal_dig(argv[argv_pos][i]));
i++;
if(is_octal_dig(argv[argv_pos][i]) != 0) {
tmp_char = (tmp_char << 3) | ((unsigned char)parse_octal_dig(argv[argv_pos][i]));
i++;
}
}
}
i--;
if(fwrite(&tmp_char, 1, 1, stdout) != 1) {
return 1;
}
}
else if(argv[argv_pos][i] == 'x') {
i++;
tmp_char = 0;
if(is_hex_dig(argv[argv_pos][i]) != 0) {
tmp_char = (tmp_char << 4) | ((unsigned char)parse_octal_dig(argv[argv_pos][i]));
i++;
if(is_hex_dig(argv[argv_pos][i]) != 0) {
tmp_char = (tmp_char << 4) | ((unsigned char)parse_octal_dig(argv[argv_pos][i]));
i++;
}
}
i--;
if(fwrite(&tmp_char, 1, 1, stdout) != 1) {
return 1;
}
}
else {
j = 0;
while(j < len2) {
if(escape_from[j] == argv[argv_pos][i]) {
if(fwrite(escape_to + j, 1, 1, stdout) != 1) {
return 1;
}
break;
}
j++;
}
if(j >= len2) {
if(fwrite(argv[argv_pos] + i - 1, 2, 1, stdout) != 1) {
return 1;
}
}
}
}
else {
if(fwrite(argv[argv_pos] + i, 1, 1, stdout) != 1) {
return 1;
}
}
i++;
}
}
else {
// Unescaped output
if(fwrite(argv[argv_pos], strlen(argv[argv_pos]), 1, stdout) != 1) {
return 1;
}
}
argv_pos++;
}
// Write final newline when required
if(add_newline != 0) {
if(fwrite("\n", 1, 1, stdout) != 1) {
return 1;
}
}
// Done
return 0;
}
#ifndef CBOOTBOX_INCLUDED_CALL
int main(int argc, char **argv)
{
return echo_main(argc, argv);
}
#endif