home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / editor / j414src.arc / FP.C < prev    next >
C/C++ Source or Header  |  1989-10-10  |  7KB  |  376 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
  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. private File * f_alloc proto((char *, int, int, char *, int));
  29. #ifdef RAINBOW
  30. private int rbwrite proto((int, char *, int));
  31. #endif
  32.  
  33. #ifndef L_SET
  34. # define L_SET 0
  35. #endif
  36.  
  37. #define MAXFILES    20    /* good enough for my purposes */
  38.  
  39. private File    _openfiles[MAXFILES];    /* must be zeroed initially */
  40.  
  41. private File *
  42. f_alloc(name, flags, fd, buffer, buf_size)
  43. char    *name,
  44.     *buffer;
  45. int    flags,
  46.     fd,
  47.     buf_size;
  48. {
  49.     register File    *fp;
  50.     register int    i;
  51.  
  52.     for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
  53.         if (fp->f_flags == 0)
  54.             break;
  55.     if (i == MAXFILES)
  56.         complain("[Too many open files!]");
  57.     fp->f_bufsize = buf_size;
  58.     fp->f_cnt = 0;
  59.     fp->f_fd = fd;
  60.     fp->f_flags = flags;
  61.     if (buffer == 0) {
  62.         buffer = emalloc((size_t)buf_size);
  63.         fp->f_flags |= F_MYBUF;
  64.     }
  65.     fp->f_base = fp->f_ptr = buffer;
  66.     fp->f_name = copystr(name);
  67.  
  68.     return fp;
  69. }
  70.  
  71. void
  72. gc_openfiles()
  73. {
  74.     register File    *fp;
  75.  
  76.     for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
  77.         if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  78.             f_close(fp);
  79. }
  80.  
  81. File *
  82. fd_open(name, flags, fd, buffer, bsize)
  83. char    *name,
  84.     *buffer;
  85. int    flags,
  86.     fd,
  87.     bsize;
  88. {
  89.     return f_alloc(name, flags, fd, buffer, bsize);
  90. }
  91.  
  92. File *
  93. f_open(name, flags, buffer, buf_size)
  94. char    *name,
  95.     *buffer;
  96. int    flags,
  97.     buf_size;
  98. {
  99.     register int    fd;
  100.     int    mode = F_MODE(flags);
  101.  
  102.     if (mode == F_READ)
  103.         fd = open(name, 0);
  104.     if (mode == F_APPEND) {
  105.         fd = open(name, 1);
  106.         if (fd == -1)
  107.             mode = F_WRITE;
  108.         else
  109.             (void) lseek(fd, 0L, 2);
  110.     }
  111.     if (mode == F_WRITE)
  112.         fd = creat(name, CreatMode);
  113.     if (fd == -1)
  114.         return NIL;
  115. #ifdef MSDOS
  116.     else
  117.         setmode(fd, 0x8000);
  118. #endif /* MSDOS */
  119.     return f_alloc(name, flags, fd, buffer, buf_size);
  120. }
  121.  
  122. void
  123. f_close(fp)
  124. File    *fp;
  125. {
  126.     flush(fp);
  127. #ifdef BSD4_2
  128.     if (fp->f_flags & (F_WRITE|F_APPEND))
  129.         (void) fsync(fp->f_fd);
  130. #endif
  131.     (void) close(fp->f_fd);
  132.     if (fp->f_flags & F_MYBUF)
  133.         free(fp->f_base);
  134.     free(fp->f_name);
  135.     fp->f_flags = 0;    /* indicates that we're available */
  136. }
  137.  
  138. int
  139. filbuf(fp)
  140. File    *fp;
  141. {
  142.     if (fp->f_flags & (F_EOF|F_ERR))
  143.         return EOF;
  144.     fp->f_ptr = fp->f_base;
  145. #ifndef MSDOS
  146.     do
  147. #endif /* MSDOS */
  148.         fp->f_cnt = read(fp->f_fd, fp->f_base, (size_t) fp->f_bufsize);
  149. #ifndef MSDOS
  150.     while (fp->f_cnt == -1 && errno == EINTR);
  151. #endif /* MSDOS */
  152.     if (fp->f_cnt == -1) {
  153.         writef("[Read error %d]", errno);
  154.         fp->f_flags |= F_ERR;
  155.     }
  156.     if (fp->f_cnt == 0) {
  157.         fp->f_flags |= F_EOF;
  158.         return EOF;
  159.     }
  160.     io_chars += fp->f_cnt;
  161.     return jgetc(fp);
  162. }
  163.  
  164. void
  165. putstr(s)
  166. register char    *s;
  167. {
  168. #ifndef IBMPC
  169.     register int    c;
  170.  
  171.     while ((c = *s++) != '\0')
  172.         jputchar(c);
  173. #else /* IBMPC */
  174.     write_emif(s);
  175. #endif /* IBMPC */
  176. }
  177.  
  178. void
  179. fputnchar(s, n, fp)
  180. register char    *s;
  181. register int    n;
  182. register File    *fp;
  183. {
  184.     while (--n >= 0)
  185.         jputc(*s++, fp);
  186. }
  187.  
  188. void
  189. flusho()
  190. {
  191. #ifndef IBMPC
  192.     _flush(EOF, stdout);
  193. #endif /* IBMPC */
  194. }
  195.  
  196. void
  197. flush(fp)
  198. File    *fp;
  199. {
  200.     _flush(EOF, fp);
  201. }
  202.  
  203. void
  204. f_seek(fp, offset)
  205. register File    *fp;
  206. off_t    offset;
  207. {
  208.     if (fp->f_flags & F_WRITE)
  209.         flush(fp);
  210.     fp->f_cnt = 0;        /* next read will filbuf(), next write
  211.                    will flush() with no bad effects */
  212.     lseek(fp->f_fd, (long) offset, L_SET);
  213. }
  214.  
  215. int        /* is void - but for lints sake */
  216. _flush(c, fp)
  217. int    c;
  218. register File    *fp;
  219. {
  220.     register int    n;
  221.  
  222.     if (fp->f_flags & (F_READ | F_STRING | F_ERR))
  223.         return EOF;
  224.     if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
  225. #ifndef RAINBOW
  226.         (write(fp->f_fd, 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.         fp->f_flags |= F_ERR;
  232.         error("[I/O error(%d); file = %s, fd = %d]",
  233.             errno, fp->f_name, fp->f_fd);
  234.     }
  235.  
  236.     fp->f_cnt = fp->f_bufsize;
  237.     fp->f_ptr = fp->f_base;
  238.     if (c != EOF)
  239.         return jputc(c, fp);
  240.     return EOF;
  241. }
  242.  
  243. int
  244. f_gets(fp, buf, max)
  245. register File    *fp;
  246. char    *buf;
  247. size_t    max;
  248. {
  249.     register char    *cp = buf;
  250.     register int    c;
  251.     char    *endp = buf + max - 1;
  252.  
  253.     if (fp->f_flags & F_EOF)
  254.         return EOF;
  255.     while (((c = jgetc(fp)) != EOF) && (c != '\n')) {
  256.         if (c == '\0')  /* possibly different from NULL */
  257.             break;        /* sorry we don't read nulls */
  258. #ifdef MSDOS
  259.         if (c == '\r') {
  260.             if ((c = jgetc(fp)) == '\n')
  261.                break;
  262.             else
  263.                *cp++ = '\r';
  264.         }
  265. #endif /* MSDOS */
  266.         if (cp >= endp) {
  267.             add_mess(" [Line too long]");
  268.             rbell();
  269.             return EOF;
  270.         }
  271.         *cp++ = c;
  272.     }
  273.     *cp = '\0';
  274.     if (c == EOF) {
  275.         if (cp != buf)
  276.             add_mess(" [Incomplete last line]");
  277.         fp->f_flags |= F_EOF;
  278.         return EOF;
  279.     }
  280.     io_lines += 1;
  281.     return 0;    /* this means okay */
  282. }
  283.  
  284. /* skip to beginning of next line, i.e., next read returns first
  285.    character of new line */
  286.  
  287. void
  288. f_toNL(fp)
  289. register File    *fp;
  290. {
  291.     register int    c;
  292.  
  293.     if (fp->f_flags & F_EOF)
  294.         return;
  295.     while (((c = jgetc(fp)) != EOF) && (c != '\n'))
  296.         ;
  297.     if (c == EOF)
  298.         fp->f_flags |= F_EOF;
  299. }
  300.  
  301. int
  302. f_readn(fp, addr, n)
  303. register File    *fp;
  304. register char    *addr;
  305. register int    n;
  306. {
  307.     int    c,
  308.         nbytes = n;
  309.  
  310.     while (--n >= 0) {
  311.         c = jgetc(fp);
  312.         if (f_eof(fp))
  313.             break;
  314.         *addr++ = c;
  315.     }
  316.     return (nbytes - (n + 1));
  317. }
  318.  
  319. int
  320. f_getint(fp)
  321. File    *fp;
  322. {
  323.     int    n = 0,
  324.         c;
  325.  
  326.     while (isdigit(c = jgetc(fp)))
  327.         n = (n * 10) + c;
  328.     return n;
  329. }
  330.  
  331. /* Deals with output to the terminal, setting up the amount of characters
  332.    to be buffered depending on the output baud rate.  Why it's in a
  333.    separate file I don't know ... */
  334.  
  335. private char    one_buf;
  336.  
  337. int    BufSize = 1;
  338.  
  339. private File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf, (char *) NIL};
  340. File    *stdout = &_stdout;
  341.  
  342. #undef jputchar        /* for files which forget to include fp.h,
  343.                here's a real jputchar procedure. */
  344. void
  345. jputchar(c)
  346. int    c;
  347. {
  348.     jputc(c, stdout);
  349. }
  350.  
  351. #ifdef RAINBOW
  352.  
  353. /*
  354.  * use the Rainbow's video output function
  355.  */
  356.  
  357. #include <dos.h>
  358.  
  359. private int
  360. rbwrite(fd, buf, cnt)
  361. char *buf;
  362. {
  363.     union REGS vr;
  364.  
  365.     if (fd != 1) {
  366.         write(fd, buf, cnt);
  367.     } else {
  368.         while (cnt-- > 0) {
  369.             vr.x.ax = *buf++;
  370.             vr.x.di = 0;
  371.             int86(0x18, &vr, &vr);
  372.         }
  373.     }
  374. }
  375. #endif /* RAINBOW */
  376.