home *** CD-ROM | disk | FTP | other *** search
- /*
- * getline.c -- get a line into a variable-size cache. Otherwise the
- * behavior is identical to fgets.
- */
- #include <stdio.h>
-
- #define BADEXIT 3 /* Nonzero is sufficent. 3 implies badness. */
- #define INITIAL_CHUNK 60 /* Purely a heuristic value. */
- #define CHUNKSIZE 10
-
- /*
- * getline -- actually get the line. Behaves as expected on an eof
- * at the beginning of a line or at end of file. Dependant on
- * the behavior of fgets as to what happens when an EOF is entered
- * from a terminal in the middle of a line. Under Ultrix/Berkley
- * TTY handling, the ^D seems to disappear...
- */
- char *
- getline(fp) FILE *fp; {
- extern char *realloc(), *malloc();
- extern char *lastCharacter();
- extern void exit();
- static char *cache = NULL;
- static int cacheSize = 0;
-
- if (cache == NULL) {
- /* Its the first time... */
- if ((cache= malloc(INITIAL_CHUNK)) == NULL) {
- (void) fprintf(stderr,"getline ran out of space (can't happen)\n");
- exit(BADEXIT);
- }
- cacheSize = INITIAL_CHUNK;
- }
-
- /* For all cases... */
- if (fgets(cache,cacheSize,fp) == NULL) {
- /* We hit an eof in the last line. */
- return NULL;
- }
- while (*lastCharacter(cache) != '\n') {
- /* We have to read some more... */
- if ((cache= realloc(cache,(unsigned)cacheSize+CHUNKSIZE)) == NULL) {
- (void) fprintf(stderr,"getline ran out of space: line longer than available memory\n");
- exit(BADEXIT);
- }
- if (fgets(&cache[cacheSize-1],CHUNKSIZE+1,fp) == NULL) {
- cacheSize += CHUNKSIZE;
- return cache;
- }
- else {
- cacheSize += CHUNKSIZE;
- }
- }
- /* We've got a line ending in \n... */
- return cache;
- }
-
-
- static char *
- lastCharacter(p) char *p; {
- while (p[1] != '\0')
- p++;
- return p;
- }
-
- #ifdef TEST
- main() {
- char *p;
-
- while ((p=getline(stdin)) != NULL)
- fputs(p,stdout);
- }
- #endif
-
-