Add system util echo

master
Marko Semet 2021-02-16 23:53:52 +01:00
parent 97a9ca5bc7
commit 90843713f4
3 changed files with 243 additions and 0 deletions

View File

@ -1,2 +1,9 @@
# c-bootbox
Standalone libraries and tools to bootstrap a system when you have a running c compiler
## System utils
Basic commands for a system can be found at `/sysutils`.
Current supported: `echo`

172
sysutils/echo.c 100644
View File

@ -0,0 +1,172 @@
#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

64
sysutils/utils.h 100644
View File

@ -0,0 +1,64 @@
#ifndef _SYSUTILS_UTILS_H
// Number parsing
static inline int parse_num_dig(char dig)
{
if((dig >= '0') && (dig <= '9')) {
return dig - '0';
}
else if((dig >= 'a') && (dig <= 'z')) {
return dig - 'a';
}
else if((dig >= 'A') && (dig <= 'Z')) {
return dig - 'A';
}
else {
return -1;
}
}
static inline int is_octal_dig(char dig)
{
int tmp;
tmp = parse_num_dig(dig);
if((tmp >= 0) && (tmp <= 7)) {
return 1;
}
else {
return 0;
}
}
static inline int is_hex_dig(char dig)
{
int tmp;
tmp = parse_num_dig(dig);
if((tmp >= 0) && (tmp <= 15)) {
return 1;
}
else {
return 0;
}
}
static inline int parse_octal_dig(char dig)
{
int tmp;
tmp = parse_num_dig(dig);
if((tmp >= 0) && (tmp <= 7)) {
return tmp;
}
else {
return -1;
}
}
static inline int parse_hex_dig(char dig)
{
int tmp;
tmp = parse_num_dig(dig);
if((tmp >= 0) && (tmp <= 15)) {
return tmp;
}
else {
return -1;
}
}
#endif