Added a mostly SUS-compliant echo.

This commit is contained in:
Mid Favila 2021-11-21 14:40:43 -04:00
parent ad186f06a9
commit fbe4f2b30c
5 changed files with 145 additions and 3 deletions

12
README Normal file
View File

@ -0,0 +1,12 @@
The mp-utils package includes a set of portable Unix utilities written by
me, Mid Favila. They attempt to comply with both the latest POSIX and SUS
specifications, whilst also implementing de facto standards such as sed's
-i option. The only time POSIX and SUS will not be obeyed is when doing
so requires relatively useless features to be implemented (that, or they
will be #ifdef'd).
They can be thought of as sitting somewhere between the Suckless tools and
Busybox - more sophisticated than Suckless' offerings, and less bloated
than Busybox.
I recommend compiling these statically.

View File

@ -1,3 +0,0 @@
# mp-utils
Mid's Portable Utilities are a set of (hopefully) POSIX and SUS-compliant Unix userland tools that are portable across many Unices.

3
src/common.h Normal file
View File

@ -0,0 +1,3 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

65
src/echo.c Normal file
View File

@ -0,0 +1,65 @@
#include "common.h"
int main(int argc, char **argv)
{
int i, i2;
char escape = 0;
if(argc > 1)
for(i = 1; i < argc; i++)
{
for(i2 = 0; argv[i][i2] != '\0'; i2++)
{
if(escape)
switch(argv[i][i2])
{
case 'a':
escape = 0;
putchar('\a');
break;
case 'b':
escape = 0;
putchar('\b');
break;
case 'c': // Immediately stop execution.
goto end;
case 'f':
escape = 0;
putchar('\f');
break;
case 'n':
escape = 0;
putchar('\n');
break;
case 'r':
escape = 0;
putchar('\r');
break;
case 't':
escape = 0;
putchar('\t');
break;
case 'v':
escape = 0;
putchar('\v');
break;
case '\\':
escape = 0;
putchar('\\');
break;
case '0': // This is for octal values.
break;
}
else if(argv[i][i2] == '\\')
escape++;
else
putchar(argv[i][i2]);
}
if(i < (argc-1))
putchar(' ');
}
putchar('\n');
end:
return 0;
}

65
src/echo.c~ Normal file
View File

@ -0,0 +1,65 @@
#include "common.h"
int main(int argc, char **argv)
{
int i, i2;
char escape = 0;
if(argc > 1)
for(i = 1; i < argc; i++)
{
for(i2 = 0; argv[i][i2] != '\0'; i2++)
{
if(escape)
switch(argv[i][i2])
{
case 'a':
escape = 0;
putchar('\a');
break;
case 'b':
escape = 0;
putchar('\b');
break;
case 'c': // Immediately stop echoing.
goto end;
case 'f':
escape = 0;
putchar('\f');
break;
case 'n':
escape = 0;
putchar('\n');
break;
case 'r':
escape = 0;
putchar('\r');
break;
case 't':
escape = 0;
putchar('\t');
break;
case 'v':
escape = 0;
putchar('\v');
break;
case '\\':
escape = 0;
putchar('\\');
break;
case '0': // This is for octal values
break;
}
else if(argv[i][i2] == '\\')
escape++;
else
putchar(argv[i][i2]);
}
if(i < (argc-1))
putchar(' ');
}
putchar('\n');
end:
return 0;
}