Rewrite cat to use pointer trickery instead of str* functions.
This commit is contained in:
parent
568cc5a802
commit
e8c4b477b9
49
src/cat.c
49
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);
|
||||
|
36
src/common.h
36
src/common.h
@ -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…
Reference in New Issue
Block a user