home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / vfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  4.4 KB  |  257 lines

  1. /*
  2.  *  Copyright (c) 1992, 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <limits.h>
  8.  
  9.  
  10. #ifdef VMS
  11. #include <file.h>
  12. #endif
  13.  
  14. #ifdef unix
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/file.h>
  18. #ifdef SYSV
  19. #include <sys/fcntl.h>
  20. #endif
  21. #endif
  22.  
  23. #ifdef msdos
  24. #include <fcntl.h>
  25. #include <io.h>
  26. #include <sys/stat.h>
  27. #endif
  28.  
  29. #ifdef __os2__
  30. #include <fcntl.h>
  31. #include <io.h>
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #endif
  35.  
  36. #ifndef O_RDONLY
  37. #ifdef VMS
  38. #include <file.h>
  39. #else
  40. #include <fcntl.h>
  41. #endif
  42. #endif
  43.  
  44. #include "config.h"
  45. #include "slang.h"
  46. #include "vfile.h"
  47. #ifdef JED
  48. #include "misc.h"
  49. #endif
  50.  
  51.  
  52. unsigned int VFile_Mode = VFILE_TEXT;
  53.  
  54. VFILE *vopen(char *file, unsigned int size, unsigned int fmode)
  55. {
  56.    int fd;
  57.    unsigned int mode;
  58.  
  59. #ifdef O_BINARY
  60.    mode = O_BINARY;
  61. #else 
  62.    mode = 0;
  63. #endif
  64.       
  65.    if ((fd = open(file, mode | O_RDONLY, 0)) < 0) return(NULL);
  66.    return vstream(fd, size, fmode);
  67. }
  68.  
  69. void vclose(VFILE *v)
  70. {
  71.    close(v->fd);
  72.    if (v->buf != NULL) SLFREE(v->buf);
  73.    SLFREE(v);
  74. }
  75.  
  76.  
  77. VFILE *vstream(int fd, unsigned int size, unsigned int mode)
  78. {
  79.    VFILE *v;
  80.    
  81.    if (NULL == (v = (VFILE *) SLMALLOC(sizeof(VFILE)))) return(NULL);
  82.    v->bmax = v->bp = v->buf = NULL;
  83.    v->fd = fd;
  84.    v->eof = NULL;
  85.    v->size = size;
  86.    if (mode == 0) mode = VFile_Mode;
  87.    v->mode = mode;
  88.    v->cr_flag = 0;
  89.    return v;
  90. }
  91.  
  92. /* I malloc one extra so that I can always add a null character to last line */
  93. char *vgets(VFILE *vp, unsigned int *num)
  94. {
  95.    register char *bp, *bp1;
  96.    register char *bmax, *bpmax;
  97.    char *neew;
  98.    int fd = vp->fd;
  99.    unsigned int n, max, fmode = vp->mode;
  100.    int doread = 0;
  101.    n = vp->size;
  102.    
  103.    *num = 0;
  104.    if (NULL == vp->buf)
  105.      {
  106. #if defined (msdos) || defined (__os2_16__)
  107.     if (!n) n = 512;
  108. #else
  109.     if (!n) n = 64 * 1024;
  110. #endif
  111.     
  112.     if (NULL == (neew = (char *) SLMALLOC(n + 1)))
  113.       {
  114. #ifdef JED
  115.          msg_error("Unable to malloc space.");
  116. #endif
  117.          return(NULL);
  118.       }
  119.     
  120.     vp->bp = vp->buf = neew;
  121.     vp->bmax = neew + n;
  122.     doread = 1;
  123.      }
  124.  
  125.    bp = vp->bp;
  126.    if ((vp->eof != NULL) && (bp >= vp->eof)) return (NULL);
  127.    bp1 = vp->buf;
  128.    bmax = vp->bmax;
  129.    
  130.    while (1)
  131.      {    
  132.     if (doread)
  133.       {
  134.          max = (int) (vp->bmax - bp);
  135.          while ((n = read(fd, bp, max)) != 0)
  136.            {
  137.           max -= n;
  138.           bp += n;
  139.            }
  140.          if (max) vp->eof = bp;
  141.          if (bp == bp1)
  142.            {
  143.           return(NULL);
  144.            }
  145.          bp = bp1;
  146.       }
  147.     else bp1 = bp;
  148.        
  149.     /* extract a line */
  150.     if (vp->eof != NULL) bmax = vp->eof;
  151.     
  152.     n = (unsigned int) (bmax - bp);
  153. #if defined(msdos) && !defined(__WATCOMC__)
  154.     if (n)
  155.       {
  156.          bpmax = bp;
  157.          asm  {
  158.         mov bx, di
  159.         mov al, 10
  160.         mov cx, n
  161.         les di, bpmax
  162.         cld
  163.         repne scasb
  164.         inc cx
  165.         sub n, cx
  166.         mov di, bx
  167.          }
  168.          bp += n;
  169.          if (*bp != '\n') bp++;
  170.       }
  171.     
  172.     if (bp < bmax)
  173.       {
  174.          vp->bp = ++bp;
  175.          *num = (unsigned int) (bp - bp1);
  176.          
  177.          /* if it is text, replace the carriage return by a newline
  178.             and adjust the number read by 1 */
  179.          bp -= 2;
  180.          if ((fmode == VFILE_TEXT) && (*num > 1) && (*bp == '\r'))
  181.            {
  182.           *bp = '\n';
  183.           *num -= 1;
  184.           vp->cr_flag = 1;
  185.            }
  186.          return bp1;
  187.       }
  188. #else
  189.     if (NULL != (bpmax = MEMCHR(bp, '\n', n)))
  190.       {
  191.          bpmax++;
  192.          vp->bp = bpmax;
  193.          *num = (unsigned int) (bpmax - bp1);
  194.          
  195.          if ((fmode == VFILE_TEXT) && (*num > 1))
  196.            {
  197.           bpmax -= 2;
  198.           if (*bpmax == '\r') 
  199.             {
  200.                vp->cr_flag = 1;
  201.                *bpmax = '\n'; (*num)--;
  202.             }
  203.            }
  204.          return bp1;
  205.       }
  206.     bp = bp + n;
  207. #endif    /* msdos */
  208.     if (vp->eof != NULL)
  209.       {
  210.          *num = (unsigned int) (bp - bp1);
  211.          vp->bp = bp;
  212.          
  213.          
  214. #if defined(pc_system) || defined(__os2__)
  215.          /* kill ^Z at EOF if present */
  216.          if ((fmode == VFILE_TEXT) && (*num) && (26 == *(bp - 1))) 
  217.            {
  218.           *num -= 1;
  219.           if (!*num) bp1 = NULL;
  220.            }
  221. #endif
  222.          return(bp1);
  223.       }
  224.     
  225.     doread = 1;
  226.  
  227.     bp = bp1;
  228.     bp1 = vp->buf;
  229.     if (bp != bp1)
  230.       {
  231.          /* shift to beginning */
  232.          while (bp < bmax) *bp1++ = *bp++;
  233.          bp = bp1;
  234.          bp1 = vp->buf;
  235.       }
  236.     else 
  237.       {
  238.          bp = bmax;
  239.          vp->bmax += 2 * (int) (vp->bmax - vp->buf);
  240.          neew = (char *) SLREALLOC(vp->buf, vp->bmax - vp->buf + 1);
  241.          if (neew == NULL) 
  242.            {
  243. #ifdef JED
  244.           msg_error("Realloc Error.");
  245. #endif
  246.  
  247.           return(NULL);
  248.            }
  249.          
  250.          bp = neew + (int) (bmax - vp->buf);
  251.          bmax = vp->bmax = neew + (int) (vp->bmax - vp->buf);
  252.          bp1 = vp->buf = neew;
  253.       }
  254.      }
  255. }
  256.  
  257.