From e8c4b477b982549caa79b3efb455b0e83d89700b Mon Sep 17 00:00:00 2001 From: Mid Favila Date: Sun, 14 Aug 2022 14:02:20 -0400 Subject: [PATCH] Rewrite cat to use pointer trickery instead of str* functions. --- src/cat.c | 49 +++++++++++++++++++++++-------------------------- src/common.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/cat.c b/src/cat.c index a391a6d..bb4752a 100644 --- a/src/cat.c +++ b/src/cat.c @@ -10,34 +10,32 @@ #include "common.h" /* If mode is set to zero, return a null pointer and print characters directly. Otherwise, return a pointer to a buffer containing */ -/* the contents of the file pointed to by fp. */ -char *cat(FILE *fp, const int mode) +/* the contents of the file pointed to by fp. The size of the new buffer is stored in the int pointed to by bufsize. */ +char *cat(FILE *fp, const int mode, long unsigned *bufsize) { char c; if(!mode) { - int i, buflen; + static long unsigned int i, buflen; buflen = 4096; - char *arr = malloc(4096); + char *arr = malloc(buflen); char *newarr = 0; for(i = 0; (c = fgetc(fp)) != EOF; i++) { - /* Rewrite using memcpy? */ if(i >= buflen) { buflen *= 2; newarr = malloc(buflen); - strcpy(newarr, arr); + memcpy(newarr, arr, buflen/2); free(arr); arr = newarr; } arr[i] = c; } - arr[i] = '\0'; - + *bufsize = buflen; return arr; } else @@ -54,13 +52,13 @@ char *cat(FILE *fp, const int mode) int main(int argc, char **argv) { char *buf, *newbuf, *tmpbuf; - int i, upresence, fppresence; + long unsigned int i, upresence, fppresence; i = upresence = fppresence = 0; - long unsigned int buflen; - buflen = 4096; + long unsigned int buflen, newbuflen; + buflen = newbuflen = 0; FILE *fp; fp = 0; - buf = malloc(buflen); + buf = newbuf = tmpbuf = 0; if((upresence = (getopt(argc, argv, ":u") == 'u'))) { @@ -72,12 +70,12 @@ int main(int argc, char **argv) if(!strcmp(argv[i], "-")) { fppresence++; - newbuf = cat(stdin, upresence); + newbuf = cat(stdin, upresence, &newbuflen); } else if((fp = fopen(argv[i], "r")) != NULL) { fppresence++; - newbuf = cat(fp, upresence); + newbuf = cat(fp, upresence, &newbuflen); } else { @@ -85,29 +83,28 @@ int main(int argc, char **argv) exit(1); } - if(!upresence and (2 * (strlen(buf) + strlen(newbuf)) >= buflen)) - { - /* Rewrite this bit to use realloc and/or memcpy? */ - tmpbuf = malloc(2 * (strlen(buf) + strlen(newbuf))); - strcpy(tmpbuf, buf); - free(buf); - buf = tmpbuf; - } - + /* This is where the actual magic happens. */ if(!upresence) { - strcat(buf, newbuf); + /* Here, we copy buf and newbuf end-to-end into a new buffer of size buflen+newbuflen, then store that in buflen and */ + /* return a pointer to the new buffer. */ + tmpbuf = arrccat(buf, newbuf, &buflen, newbuflen); + free(buf); + buf = tmpbuf; } } if(!fppresence) { - buf = cat(stdin, upresence); + buf = cat(stdin, upresence, &newbuflen); } if(!upresence) { - printf("%s", buf); + for(i = 0; i < buflen; i++) + { + putchar(buf[i]); + } } exit(0); diff --git a/src/common.h b/src/common.h index 69d1e20..f9b9d04 100644 --- a/src/common.h +++ b/src/common.h @@ -5,3 +5,39 @@ #include #include +/* arrconcat -- function to copy copy_n bytes from arr2 to arr1, starting at startpos (in arr1) */ +void arrconcat(char* arr1, char* arr2, unsigned int startpos, unsigned int copy_n) + { + unsigned int i, i2; + + + for(i = startpos, i2 = 0; i <= copy_n && arr2 != NULL; i++, i2++) + { + arr1[i] = arr2[i2]; + } + } + + +/* 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; + }