home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / ld / bio.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  4KB  |  255 lines

  1.  
  2. /*
  3.  * Copyright (c) 1991 by Sozobon, Limited.  Author: Johann Ruegg
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #define MAXBF    5
  15. #define BSIZE    1000
  16.  
  17. struct buf {
  18.     struct buf *b_next;
  19.     char b_bufr[BSIZE];
  20. };
  21.  
  22. struct file {
  23.     char *f_name;
  24.     int f_fd;
  25.     int f_flags;
  26.     struct buf *f_first, *f_last;
  27.     long f_fcount, f_rdoffs;
  28.     int f_boffset;
  29.     char f_bufr[BSIZE];
  30. } f[MAXBF];
  31. int numf = 0;
  32. extern int vflag;
  33.  
  34. #define F_READING    1
  35. #define F_FILEIO    2
  36. #define F_LOCKED    4
  37.  
  38. t_open(s)
  39. char *s;
  40. {
  41.     int i;
  42.  
  43.     if (numf >= MAXBF) {
  44.         fatal("Too many b-files");
  45.     }
  46.     i = numf++;
  47.     f[i].f_name = s;
  48.     return i;
  49. }
  50.  
  51. t_exit()
  52. {
  53.     int i;
  54.     struct file *fp;
  55.  
  56.     for (i=0; i<numf; i++) {
  57.         fp = &f[i];
  58.         if (fp->f_flags & F_FILEIO)
  59. #ifdef TOS
  60.             remove(fp->f_name);
  61. #else
  62.             unlink(fp->f_name);
  63. #endif
  64.     }
  65.     numf = 0;
  66. }
  67.  
  68. t_frees()
  69. {
  70.     int i;
  71.     struct file *fp;
  72.  
  73.     for (i=0; i<numf; i++) {
  74.         fp = &f[i];
  75.         if ((fp->f_flags & F_FILEIO) == 0 && fp->f_first) {
  76.             t_freef(fp);
  77.             return 1;
  78.         }
  79.     }
  80.     return 0;
  81. }
  82.  
  83. t_freef(fp)
  84. struct file *fp;
  85. {
  86.     int fd;
  87.     struct buf *bp, *t_dequeue();
  88.  
  89.     if (vflag) {
  90.         printf("Using temp file for %s\n", fp->f_name);
  91.     }
  92.  
  93.     fp->f_flags |= F_FILEIO;
  94.     fd = open(fp->f_name, 2);
  95.     if (fd < 0)
  96.         fd = creat(fp->f_name, 0600);
  97.     if (fd < 0)
  98.         fatals("Cant open tmp file", fp->f_name);
  99.     fp->f_fd = fd;
  100.     while (fp->f_first) {
  101.         bp = t_dequeue(fp);
  102.         if (write(fd, bp->b_bufr, BSIZE) != BSIZE)
  103.             fatal("write error");
  104.         free(bp);
  105.     }
  106.     if (fp->f_flags & F_READING)
  107.         lseek(fd, 0L, 0);
  108. }
  109.  
  110. t_rewind(id)
  111. {
  112.     struct file *fp;
  113.     int n;
  114.  
  115.     fp = &f[id];
  116.     if (fp->f_flags & F_READING)
  117.         fatal("t_rewind called twice");
  118.     if (fp->f_boffset) {
  119.         t_wfull(fp);
  120.     }
  121.     if (fp->f_flags & F_FILEIO)
  122.         lseek(fp->f_fd, 0L, 0);
  123.     fp->f_flags |= F_READING;
  124.     if (fp->f_fcount)
  125.         t_rfill(fp);
  126. }
  127.  
  128. t_write(id, buf, cnt)
  129. char *buf;
  130. {
  131.     struct file *fp;
  132.  
  133.     fp = &f[id];
  134.     if (fp->f_flags & F_READING)
  135.         fatal("write called while READING");
  136.     while (cnt-- > 0)
  137.         t_putc(fp, *buf++);
  138. }
  139.  
  140. t_putc(fp, c)
  141. struct file *fp;
  142. char c;
  143. {
  144.     if (fp->f_boffset >= BSIZE)
  145.         t_wfull(fp);
  146.     fp->f_bufr[fp->f_boffset++] = c;
  147.     fp->f_fcount++;
  148. }
  149.  
  150. t_read(id, buf, cnt)
  151. char *buf;
  152. {
  153.     char c;
  154.     struct file *fp;
  155.  
  156.     fp = &f[id];
  157.     if ((fp->f_flags & F_READING) == 0)
  158.         fatal("read called while WRITING");
  159.     while (cnt-- > 0) {
  160.         c = t_getc(fp);
  161.         *buf++ = c;
  162.     }
  163. }
  164.  
  165. t_getc(fp)
  166. struct file *fp;
  167. {
  168.     if (fp->f_rdoffs >= fp->f_fcount)
  169.         fatal("b-file read past end");
  170.     if (fp->f_boffset >= BSIZE)
  171.         t_rfill(fp);
  172.     fp->f_rdoffs++;
  173.     return fp->f_bufr[fp->f_boffset++];
  174. }    
  175.  
  176. t_wfull(fp)
  177. struct file *fp;
  178. {
  179.     char *malloc();
  180.     int n;
  181.  
  182.     n = fp->f_boffset;
  183. again:
  184.     if (fp->f_flags & F_FILEIO) {
  185.         if (write(fp->f_fd, fp->f_bufr, n) != n)
  186.             fatal("write error");
  187.         fp->f_boffset = 0;
  188.     } else {
  189.         struct buf *bp;
  190.  
  191.         bp = (struct buf *)malloc(sizeof(struct buf));
  192.         if (!bp) {
  193.             if (t_frees())
  194.                 goto again;
  195.             fatal("out of memory");
  196.         }
  197.         bcopy(fp->f_bufr, bp->b_bufr, n);
  198.         t_enqueue(fp, bp);
  199.         fp->f_boffset = 0;
  200.     }
  201. }
  202.  
  203. t_enqueue(fp, bp)
  204. struct file *fp;
  205. struct buf *bp;
  206. {
  207.     bp->b_next = 0;
  208.     if (fp->f_last) {
  209.         fp->f_last->b_next = bp;
  210.         fp->f_last = bp;
  211.     } else {
  212.         fp->f_first = fp->f_last = bp;
  213.     }
  214. }
  215.  
  216. struct buf *
  217. t_dequeue(fp)
  218. struct file *fp;
  219. {
  220.     struct buf *bp;
  221.  
  222.     bp = fp->f_first;
  223.     if (!bp)
  224.         fatal("internal buffer list error");
  225.     fp->f_first = bp->b_next;
  226.     if (fp->f_first == 0)
  227.         fp->f_last = 0;
  228.     return bp;
  229. }
  230.  
  231. t_rfill(fp)
  232. struct file *fp;
  233. {
  234.     int n;
  235.     long l;
  236.  
  237.     if (fp->f_flags & F_FILEIO) {
  238.         l = fp->f_fcount - fp->f_rdoffs;
  239.         if (l > BSIZE)
  240.             n = BSIZE;
  241.         else
  242.             n = l;
  243.         if (read(fp->f_fd, fp->f_bufr, n) != n)
  244.             fatal("read error");
  245.         fp->f_boffset = 0;
  246.     } else {
  247.         struct buf *bp;
  248.  
  249.         bp = t_dequeue(fp);
  250.         bcopy(bp->b_bufr, fp->f_bufr, BSIZE);
  251.         free(bp);
  252.         fp->f_boffset = 0;
  253.     }
  254. }
  255.