Rewrite cat to use pointer trickery instead of str* functions.

master
Mid Favila 4 months ago
parent 568cc5a802
commit e8c4b477b9
  1. 47
      src/cat.c
  2. 36
      src/common.h

@ -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))
/* This is where the actual magic happens. */
if(!upresence)
{
/* Rewrite this bit to use realloc and/or memcpy? */
tmpbuf = malloc(2 * (strlen(buf) + strlen(newbuf)));
strcpy(tmpbuf, buf);
/* 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(!upresence)
{
strcat(buf, newbuf);
}
}
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);

@ -5,3 +5,39 @@
#include <unistd.h>
#include <sys/stat.h>
/* 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;
}

Loading…
Cancel
Save