home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / getline / getline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  1.7 KB  |  75 lines

  1. /*
  2.  * getline.c -- get a line into a variable-size cache. Otherwise the
  3.  *    behavior is identical to fgets.
  4.  */
  5. #include <stdio.h>
  6.  
  7. #define BADEXIT 3    /* Nonzero is sufficent. 3 implies badness. */
  8. #define INITIAL_CHUNK 60  /* Purely a heuristic value. */
  9. #define CHUNKSIZE 10
  10.  
  11. /* 
  12.  * getline -- actually get the line. Behaves as expected on an eof
  13.  *    at the beginning of a line or at end of file.  Dependant on
  14.  *    the behavior of fgets as to what happens when an EOF is entered 
  15.  *    from a terminal in the middle of a line.  Under Ultrix/Berkley
  16.  *    TTY handling, the ^D seems to disappear... 
  17.  */ 
  18.  char *
  19. getline(fp) FILE *fp; {
  20.     extern char *realloc(), *malloc();
  21.     extern char *lastCharacter();
  22.     extern void exit();
  23.     static char *cache = NULL;
  24.     static int cacheSize = 0;
  25.  
  26.     if (cache == NULL) {
  27.         /* Its the first time... */
  28.         if ((cache= malloc(INITIAL_CHUNK)) == NULL) {
  29.             (void) fprintf(stderr,"getline ran out of space (can't happen)\n");
  30.             exit(BADEXIT);
  31.         }
  32.         cacheSize = INITIAL_CHUNK;
  33.     }
  34.  
  35.     /* For all cases... */
  36.     if (fgets(cache,cacheSize,fp) == NULL) {
  37.         /* We hit an eof in the last line. */
  38.         return NULL;
  39.     }
  40.     while (*lastCharacter(cache) != '\n') {
  41.         /* We have to read some more... */
  42.         if ((cache= realloc(cache,(unsigned)cacheSize+CHUNKSIZE)) == NULL) {
  43.             (void) fprintf(stderr,"getline ran out of space: line longer than available memory\n");
  44.             exit(BADEXIT);
  45.         }
  46.         if (fgets(&cache[cacheSize-1],CHUNKSIZE+1,fp) == NULL) {
  47.             cacheSize += CHUNKSIZE;
  48.             return cache;
  49.         }
  50.         else {
  51.             cacheSize += CHUNKSIZE;
  52.         }
  53.     }
  54.     /* We've got a line ending in \n... */
  55.     return cache;
  56. }
  57.  
  58.  
  59.  static char *
  60. lastCharacter(p) char *p; {
  61.     while (p[1] != '\0')
  62.         p++;
  63.     return p;
  64.  }
  65.  
  66. #ifdef TEST
  67. main() {
  68.     char    *p;
  69.  
  70.     while ((p=getline(stdin)) != NULL)
  71.         fputs(p,stdout);
  72. }
  73. #endif
  74.  
  75.