172 lines
3.4 KiB
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 |