/*
* dyngets.c (library) Matt Bishop January 15, 1994
*
* Entry point:
* char *dyngets(char *buf, int n, FILE *fp)
* Read the next line from the input and return a pointer to a buffer
* containing that line. If buf is non-NULL on entry, this call is
* identical to fgets(3S); if buf is NULL, the second argument n is
* ignored, and the pointer returned points to an allocated buffer
* with all of the next line of the file in it, REGARDLESS of length.
*
* Modification history:
* 1/10/94 Matt Bishop original
*/
#include <stdio.h>
#include <malloc.h>
/*
* macros
*/
#define INCREMENT 10 /* allocate this many chars, and */
/* increase space by this many */
/* chars when necessary */
#define NCHAR(n) ((n) * sizeof(char)) /* space for n chars */
/*
* chins: insert a character into an array, increasing the size of
* the array if necessary by INCREMENT characters
*
* arguments: int c character to be inserted
* int pos position in the array to insert character
* char **space points to pointer to array
* int *nspace points to integer representing size of array
* already allocated
*
* return: 0 attempt to increase size of array failed, so
* the character could not be inserted
* 1 character inserted successfully
*
* output: none
*
* exceptions: cannot allocate (reallocate) memory (no message, return 0)
*/
int chins(int c, int pos, char **space, int *nspace)
{
char *r; /* temp pointer to allocated space */
/*
* see if we need more space
*/
if (pos >= *nspace){
/* yes -- get size of the new allocation */
*nspace += INCREMENT;
/* do we allocate or make it grow? */
if (*space == NULL){
/* first time -- allocate */
if ((r = malloc(NCHAR(*nspace))) == NULL)
return(0);
}
else{
/* not the first time -- reallocate */
if ((r = realloc(*space, NCHAR(*nspace))) == NULL)
return(0);
}
/* now update the reserved space parameter */
*space = r;
}
/*
* we have enough space or
* we wouldn't be here -- add the char
*/
(*space)[pos] = c;
return(1);
}
/*
* dyngets: read a line from the given file, and return a pointer to
* a character array holding it
*
* arguments: char *buf buffer to put input characters in; if NULL,
* dyngets will use (and allocate if necessary)
* its own buffer
* int n size of array buf; ignored if buf is NULL
* FILE *fp pointer to file to be read
*
* return: char * points to array holding input line:
* if buf is non-NULL, this is the same as buf,
* and one line (or n-1 chars from that line,
* whichever is less) is stored inbuf
* if buf is NULL, one line is stored in
* allocated space
* NULL on EOF or error
*
* output: dyngets: ran out of room
* could not allocate enough space to hold input line
*
* exceptions: ran out of room (error message and return)
*/
char *dyngets(char *buf, int n, FILE *fp)
{
static char *space = NULL; /* internal buffer */
static int nspace = 0; /* size of internal buffer */
int c; /* input character */
int i; /* index of space to put char in */
/*
* if we're told where to put the input
* let someone else do the work for us!
*/
if (buf != NULL)
return(fgets(buf, n, fp));
/*
* read up to the next newline or EOF,
* and append it to the current line
*/
for(i = 0; (c = getc(fp)) != '\n' && c != EOF; i++)
if (chins(c, i, &space, &nspace) == 0){
fprintf(stderr, "dyngets: ran out of room\n");
return(NULL);
}
/*
* if EOF is the first character in the line,
* you're done; indicate this
*/
if (c == EOF && i == 0)
return(NULL);
/*
* tack on the newline, if present
*/
if (c == '\n' && chins('\n', i++, &space, &nspace) == 0){
fprintf(stderr, "dyngets: ran out of room\n");
return(NULL);
}
/*
* tack on the string terminator
*/
if (chins('\0', i, &space, &nspace) == 0){
fprintf(stderr, "dyngets: ran out of room\n");
return(NULL);
}
/*
* return pointer to internally allocated buffer
*/
return(space);
}
|
ECS 36A, Programming & Problem Solving Version of April 2, 2024 at 12:13PM
|
You can get the raw source code here. |