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