commit 0721d91734be7ea70e283fa84d5f3e5ce9ef4564 Author: Mid Favila Date: Tue Sep 6 15:18:34 2022 -0400 Add LICENSE. Add README. Add overwrite. Add strcmp. Add vis. diff --git a/README b/README new file mode 100644 index 0000000..4a511b0 --- /dev/null +++ b/README @@ -0,0 +1,15 @@ +******************************************************************************** +* Mid's Extended Utilities * +******************************************************************************** + + This is a package of supplementary Unix-style utilities. They're meant to be + highly portable and to cover common problems that can't be easily solved with + shell. + + -strcmp: Exits with 0 if the provided pair of strings differs. Otherwise, 1. + -vis: Replaces non-printing and non-ASCII characters with octal values. + -unfold: Exactly what it sounds like. unfold will attempt to merge lines + with fewer than the provided number of characters with the next + line, so long as it doesn't cause a word-split. + -overwrite: Reads stdin and writes it to the provided file. + diff --git a/src/overwrite.c b/src/overwrite.c new file mode 100644 index 0000000..14aa99a --- /dev/null +++ b/src/overwrite.c @@ -0,0 +1,61 @@ +/* overwrite.c -- program to exhaust stdin, then write it to a file */ + +#include +#include +#include +#include + +#include "support.h" + +int main(int argc, char **argv) + { + int buflen, strlen; + char *buf; + strlen = 0; + buflen = 0; + /* arbitrary */ + buflen = 4096; + + if(argc == 1) + { + throw(NEEDARG_FAIL, mastrcat(argv[0], " files")); + } + + if((buf = malloc(buflen))) + { + int c; + c = 0; + FILE *fp; + + for(;((c = getchar()) != EOF);) + { + if(strlen == buflen) + { + buf = realloc(buf, (buflen*=2)); + } + buf[strlen++] = c; + } + + if(!(fp = fopen(argv[1], "a"))) + { + throw(FOPEN_FAIL, argv[1]); + } + + for(c = 0; c <= strlen; c++) + { + if(fputc(buf[c], fp) == EOF) + { + throw(WRITE_FAIL, argv[1]); + } + } + + /* close the file and exit successfully */ + fclose(fp); + } + else + { + throw(MALLOC_FAIL, NULL); + } + + return 0; + } diff --git a/src/strcmp.c b/src/strcmp.c new file mode 100644 index 0000000..b6fba33 --- /dev/null +++ b/src/strcmp.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#include "support.h" + +int shortestword(const char* word1, const char* word2) + { + int len = 0; + + for(;;) + { + if(!word1[len]) + { + return 0; + } + else if(!word2[len++]) + { + return 1; + } + } + } + +int main(int argc, char **argv) + { + int swl = 0; + + /* modify the program to support comparison of an arbitrary number of strings */ + if(argc != 3) + { + throw(NEEDARG_FAIL, mastrcat(argv[0], " str1 str2")); + } + + if(!shortestword(argv[1], argv[2])) + { + swl = (int) strlen(argv[1]); + } + else + { + swl = (int) strlen(argv[2]); + } + + return(strncmp(argv[1], argv[2], swl)); + } diff --git a/src/support.h b/src/support.h new file mode 100644 index 0000000..b655b5e --- /dev/null +++ b/src/support.h @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + + +enum { + UNKNOWN_FAIL = 1, + MALLOC_FAIL, + NEEDARG_FAIL, + FOPEN_FAIL, + WRITE_FAIL + }; + + +/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */ +/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */ +char *arrccat(char *arr1, char *arr2, size_t *arr1len, size_t arr2len) + { + char *newarr; + unsigned int i, i2; + newarr = malloc(*arr1len+arr2len); + i = i2 = 0; + + for(i = 0; i < *arr1len; i++) + { + newarr[i] = arr1[i]; + } + + for(i2 = 0; i2 < arr2len; i2++, i++) + { + newarr[i] = arr2[i2]; + } + + *arr1len = *arr1len+arr2len; + + return newarr; + } + +/* Condition should be one of the above enum'd strings. Info is optional; it can just be NULL when irrelevant. */ +void throw(long unsigned int condition, void *info) + { + switch(condition) + { + case UNKNOWN_FAIL: printf("unknown failure\n"); + exit(UNKNOWN_FAIL); + case MALLOC_FAIL: printf("malloc failure\n"); + exit(MALLOC_FAIL); + case NEEDARG_FAIL: printf("usage: %s\n", (char *) info); + exit(NEEDARG_FAIL); + case FOPEN_FAIL: printf("failed to open: %s\n", (char *) info); + exit(FOPEN_FAIL); + case WRITE_FAIL: printf("failed to write: %s\n", (char *) info); + exit(WRITE_FAIL); + default: printf("You shouldn't be seeing this.\nSomething is very wrong.\n"); + exit(-256); + } + } + +/* mastrcat -- improved string concat function. returns a pointer to the first element in a buffer containing the strings str1 */ +/* and str2 joined end-to-end. */ +char *mastrcat(char *str1, char *str2) + { + unsigned long int nbi, stri, nbsize; + char *nbuf; + nbi = stri = 0; + nbsize = (strlen(str1) + strlen(str2)); + nbuf = malloc(nbsize); + + for(stri = 0; str1[stri] != '\0'; nbi++, stri++) + { + nbuf[nbi] = str1[stri]; + } + + for(stri = 0; str2[stri] != '\0'; nbi++, stri++) + { + nbuf[nbi] = str2[stri]; + } + + return nbuf; + } + diff --git a/src/unfold.c b/src/unfold.c new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/src/unfold.c @@ -0,0 +1 @@ +# diff --git a/src/vis.c b/src/vis.c new file mode 100644 index 0000000..bba16d3 --- /dev/null +++ b/src/vis.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +#include "support.h" + + +int main(int argc, char **argv) + { + int i, c; + FILE *fp; + i = c = 0; + + for(;(c = getchar()) != EOF; i++) + { + if(isascii(c) && (c != ' ' && c != '\n' && c != '\t')) + { + printf("%c", c); + } + else + { + printf("%.3o", c); + } + } + + return(0); + }