FENIX_coreutils/echo.c
2022-10-09 11:35:42 -05:00

104 lines
2.6 KiB
C
Executable file

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
int ctoi(char c); /* A bit of a helper function */
int main(int argc, char ** argv) {
int i, j, oct_temp;
char char_temp;
/*
If /c is present in the text, we're not supposed to print a trailing
newline at the end. Otherwise, we do. Hence, we start with 1 (true)
for printing this and switch it to 0 if \c shows up
*/
int trailing_newline = 1;
/*
Outer loop handles each word passed in,
inner loop handles characters within each word.
*/
for(i = 1; i < argc; i++) {
for(j = 0; argv[i][j] != '\0'; j++) {
/* We need to handle escape sequences ourself. */
if(argv[i][j] == '\\') {
j++;
switch(argv[i][j]) {
case 'a': printf("\a"); break; /* alert */
case 'b': printf("\b"); break; /* backspace */
case 'c': trailing_newline = 0; break; /* suppress trailing newline */
case 'f': printf("\f"); break; /* form feed */
case 'n': printf("\n"); break; /* new line */
case 'r': printf("\r"); break; /* carriage return */
case 't': printf("\t"); break; /* horizontal tab */
case 'v': printf("\v"); break; /* vertical tab */
case '\\': printf("\\"); break; /* just print a backslash */
/* Octal sequences */
case '0': {
j++;
oct_temp = ctoi(argv[i][j]); /* 1 digit escape (e.g. 08) */
j++;
/* 2 digit escape (e.g. 063) */
if(ctoi(argv[i][j] != -1)) {
oct_temp *= 8;
oct_temp += ctoi(argv[i][j]);
j++;
/*
3 digit escape (e.g. 0127)
This is all the POSIX spec allows.
*/
if(ctoi(argv[i][j] != -1)) {
oct_temp *= 8;
oct_temp += ctoi(argv[i][j]);
}
else {
j--;
}
}
else {
j--;
}
printf("%c", (char)oct_temp);
}
break;
/* On unrecognized escape, just print it literal */
default: printf("\\%c", argv[i][j]);
break;
}
}
else {
printf("%c", argv[i][j]); /* Not a backslash? Print the character */
}
}
}
/* Print trailing newline */
if(trailing_newline) {
printf("\n");
}
return 0;
}
/*
I'm really not sure whether writing a ctoi function was ideal here.
Maybe I should have just used atoi? I dunno. But, at this point, I'm
just gonna leave it as is.
- Kat
*/
int ctoi(char c) {
switch(c) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
default: return -1;
}
}