home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / src / baseline / jove-4.14.6.lha / jove-4.14.6 / fp.c < prev    next >
C/C++ Source or Header  |  1992-01-10  |  7KB  |  355 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "fp.h"
  10. #include "ctype.h"
  11. #include "termcap.h"
  12. #include "disp.h"
  13.  
  14. #ifdef    MAC
  15. #    include "mac.h"
  16. #else    /* !MAC */
  17. #    include <sys/stat.h>
  18. #    ifndef    MSDOS
  19. #        include <sys/file.h>
  20. #    else    /* MSDOS */
  21. #        include <fcntl.h>
  22. #        include <io.h>
  23. #    endif    /* MSDOS */
  24. #endif    /* !MAC */
  25.  
  26. #include <errno.h>
  27.  
  28. #ifdef    RAINBOW
  29. private int rbwrite proto((int, char *, int));
  30. #endif
  31.  
  32. #ifndef    L_SET
  33. # define L_SET 0
  34. #endif
  35.  
  36. #define MAXFILES    20    /* good enough for my purposes */
  37.  
  38. private File    openfiles[MAXFILES];    /* must be zeroed initially */
  39.  
  40. File *
  41. fd_open(name, flags, fd, buffer, buf_size)
  42. char    *name,
  43.     *buffer;
  44. int    flags,
  45.     fd,
  46.     buf_size;
  47. {
  48.     register File    *fp;
  49.     register int    i;
  50.  
  51.     for (fp = openfiles, i = 0; i < MAXFILES; i++, fp++)
  52.         if (fp->f_flags == 0)
  53.             break;
  54.     if (i == MAXFILES)
  55.         complain("[Too many open files!]");
  56.     fp->f_bufsize = buf_size;
  57.     fp->f_cnt = 0;
  58.     fp->f_fd = fd;
  59.     fp->f_flags = flags;
  60.     if (buffer == NULL) {
  61.         buffer = emalloc((size_t)buf_size);
  62.         fp->f_flags |= F_MYBUF;
  63.     }
  64.     fp->f_base = fp->f_ptr = buffer;
  65.     fp->f_name = copystr(name);
  66.  
  67.     return fp;
  68. }
  69.  
  70. void
  71. gc_openfiles()
  72. {
  73.     register File    *fp;
  74.  
  75.     for (fp = openfiles; fp < &openfiles[MAXFILES]; fp++)
  76.         if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  77.             f_close(fp);
  78. }
  79.  
  80. File *
  81. f_open(name, flags, buffer, buf_size)
  82. char    *name,
  83.     *buffer;
  84. int    flags,
  85.     buf_size;
  86. {
  87.     register int    fd;
  88.  
  89.     switch (F_MODE(flags)) {
  90.     case F_READ:
  91.         fd = open(name, 0);
  92.         break;
  93.  
  94.     case F_APPEND:
  95.         fd = open(name, 1);
  96.         if (fd != -1) {
  97.             (void) lseek(fd, 0L, 2);
  98.             break;
  99.         }
  100.         /* FALLTHROUGH */
  101.     case F_WRITE:
  102.         fd = creat(name, CreatMode);
  103.         break;
  104.  
  105.     default:
  106.         error("invalid F_MODE");
  107.         /* NOTREACHED */
  108.     }
  109.     if (fd == -1)
  110.         return NULL;
  111. #ifdef    MSDOS
  112.     setmode(fd, 0x8000);
  113. #endif    /* MSDOS */
  114.     return fd_open(name, flags, fd, buffer, buf_size);
  115. }
  116.  
  117. void
  118. f_close(fp)
  119. File    *fp;
  120. {
  121.     if (fp->f_flags & (F_WRITE|F_APPEND)) {
  122.         flushout(fp);
  123. #ifdef    BSD4_2
  124.         (void) fsync(fp->f_fd);
  125. #endif
  126.     }
  127.     (void) close(fp->f_fd);
  128.     if (fp->f_flags & F_MYBUF)
  129.         free((UnivPtr) fp->f_base);
  130.     free((UnivPtr) fp->f_name);
  131.     fp->f_flags = 0;    /* indicates that we're available */
  132. }
  133.  
  134. int
  135. filbuf(fp)
  136. File    *fp;
  137. {
  138.     if (fp->f_flags & (F_EOF|F_ERR))
  139.         return EOF;
  140.     fp->f_ptr = fp->f_base;
  141. #ifndef    MSDOS
  142.     do {
  143. #endif    /* MSDOS */
  144.         fp->f_cnt = read(fp->f_fd, (UnivPtr) fp->f_base, (size_t) fp->f_bufsize);
  145. #ifndef    MSDOS
  146.     } while (fp->f_cnt == -1 && errno == EINTR);
  147. #endif    /* MSDOS */
  148.     if (fp->f_cnt == -1) {
  149.         /* I/O error -- treat as EOF */
  150.         writef("[Read error: %s]", strerror(errno));
  151.         fp->f_flags |= F_ERR | F_EOF;
  152.         return EOF;
  153.     }
  154.     if (fp->f_cnt == 0) {
  155.         fp->f_flags |= F_EOF;
  156.         return EOF;
  157.     }
  158.     io_chars += fp->f_cnt;
  159.     return jgetc(fp);
  160. }
  161.  
  162. void
  163. putstr(s)
  164. register char    *s;
  165. {
  166. #ifndef    IBMPC
  167.     register int    c;
  168.  
  169.     while ((c = *s++) != '\0')
  170.         jputchar(c);
  171. #else    /* IBMPC */
  172.     write_emif(s);
  173. #endif    /* IBMPC */
  174. }
  175.  
  176. void
  177. fputnchar(s, n, fp)
  178. register char    *s;
  179. register int    n;
  180. register File    *fp;
  181. {
  182.     while (--n >= 0)
  183.         jputc(*s++, fp);
  184. }
  185.  
  186. void
  187. flushscreen()
  188. {
  189. #ifndef    IBMPC
  190.     flushout(stdout);
  191. #endif    /* IBMPC */
  192. }
  193.  
  194. void
  195. f_seek(fp, offset)
  196. register File    *fp;
  197. off_t    offset;
  198. {
  199.     if (fp->f_flags & (F_WRITE|F_APPEND))
  200.         flushout(fp);
  201.     fp->f_cnt = 0;        /* next read will filbuf(), next write
  202.                    will flush() with no bad effects */
  203.     lseek(fp->f_fd, (long) offset, L_SET);
  204. }
  205.  
  206. void
  207. flushout(fp)
  208. register File    *fp;
  209. {
  210.     register int    n;
  211.  
  212.     if (fp->f_flags & (F_READ | F_STRING | F_ERR)) {
  213.         if (fp->f_flags != F_STRING)
  214.             abort();    /* IMPOSSIBLE */
  215.         /* We just banged into the end of a string.
  216.          * In the interests of continuing, we will cause
  217.          * the rest of the output to be be heaped in the
  218.          * last position.  Surely it will end up as a NUL. UGH!
  219.          */
  220.         fp->f_cnt = 1;
  221.         fp->f_ptr = &fp->f_base[fp->f_bufsize - 1];
  222.         return;
  223.     }
  224.     if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
  225. #ifndef    RAINBOW
  226.         (write(fp->f_fd, (UnivPtr) fp->f_base, (size_t)n) != n) &&
  227. #else
  228.         (rbwrite(fp->f_fd, fp->f_base, n) != n) &&
  229. #endif
  230.         (fp != stdout))
  231.     {
  232.         fp->f_flags |= F_ERR;
  233.         error("[I/O error(%s); file = %s, fd = %d]",
  234.             strerror(errno), fp->f_name, fp->f_fd);
  235.     }
  236.  
  237.     fp->f_cnt = fp->f_bufsize;
  238.     fp->f_ptr = fp->f_base;
  239. }
  240.  
  241. bool
  242. f_gets(fp, buf, max)
  243. register File    *fp;
  244. char    *buf;
  245. size_t    max;
  246. {
  247.     register char    *cp = buf;
  248.     register int    c;
  249.     char    *endp = buf + max - 1;
  250.  
  251.     if (fp->f_flags & F_EOF)
  252.         return YES;
  253.     while (((c = jgetc(fp)) != EOF) && (c != '\n')) {
  254.         if (c == '\0') {
  255.             /* We can't store NUL in our buffer, so ignore it.
  256.              * Of course, with a little ingenuity we could:
  257.              * NUL could be represented by \n!
  258.              */
  259.             continue;
  260.         }
  261.         if (cp >= endp) {
  262.             add_mess(" [Line too long]");
  263.             rbell();
  264.             return YES;
  265.         }
  266.         *cp++ = c;
  267.     }
  268.     *cp = '\0';
  269.     if (c == EOF) {
  270.         if (cp != buf)
  271.             add_mess(" [Incomplete last line]");
  272.         return YES;
  273.     }
  274. #ifdef    MSDOS
  275.     /* a CR followed by a LF is treated as a NL.
  276.      * Bug: the line-buffer is effectively shortened by one character.
  277.      */
  278.     if (cp != buf && cp[-1] == '\r')
  279.         *--cp = '\0';
  280. #endif    /* MSDOS */
  281.     io_lines += 1;
  282.     return NO;    /* this means okay */
  283. }
  284.  
  285. /* skip to beginning of next line, i.e., next read returns first
  286.    character of new line */
  287.  
  288. void
  289. f_toNL(fp)
  290. register File    *fp;
  291. {
  292.     register int    c;
  293.  
  294.     if (fp->f_flags & F_EOF)
  295.         return;
  296.     do ; while (((c = jgetc(fp)) != EOF) && (c != '\n'));
  297.     if (c == EOF)
  298.         fp->f_flags |= F_EOF;
  299. }
  300.  
  301. size_t
  302. f_readn(fp, addr, n)
  303. register File    *fp;
  304. register char    *addr;
  305. size_t    n;
  306. {
  307.     register size_t    nleft;
  308.  
  309.     for (nleft = n; nleft > 0; nleft--) {
  310.         int    c = jgetc(fp);
  311.  
  312.         if (f_eof(fp))
  313.             break;
  314.         *addr++ = c;
  315.     }
  316.     return n - nleft;
  317. }
  318.  
  319. /* Deals with output to the terminal, setting up the amount of characters
  320.    to be buffered depending on the output baud rate.  Why it's in a
  321.    separate file I don't know ... */
  322.  
  323. private char    one_buf;
  324.  
  325. int    BufSize = 1;
  326.  
  327. private File    stdout_File = {1, 1, 1, F_WRITE, &one_buf, &one_buf, (char *)NULL};
  328. File    *stdout = &stdout_File;
  329.  
  330. #ifdef    RAINBOW
  331.  
  332. /*
  333.  * use the Rainbow's video output function
  334.  */
  335.  
  336. #include <dos.h>
  337.  
  338. private int
  339. rbwrite(fd, buf, cnt)
  340. char *buf;
  341. {
  342.     union REGS vr;
  343.  
  344.     if (fd != 1) {
  345.         write(fd, buf, cnt);
  346.     } else {
  347.         while (cnt-- > 0) {
  348.             vr.x.ax = *buf++;
  349.             vr.x.di = 0;
  350.             int86(0x18, &vr, &vr);
  351.         }
  352.     }
  353. }
  354. #endif    /* RAINBOW */
  355.