home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
- * is provided to you without charge, and with no warranty. You may give *
- * away copies of JOVE, including sources, provided that this notice is *
- * included in all the files. *
- ***************************************************************************/
-
- #include "jove.h"
- #include "io.h"
- #include "ctype.h"
- #include "termcap.h"
-
- #ifdef MAC
- # include "mac.h"
- #else
- # include <sys/stat.h>
- # ifndef MSDOS
- # include <sys/file.h>
- # else /* MSDOS */
- # include <fcntl.h>
- # include <io.h>
- # endif /* MSDOS */
- #endif /* MAC */
-
- #include <errno.h>
-
- #ifdef MAC
- # undef private
- # define private
- #endif
-
- #ifdef LINT_ARGS
- private File * f_alloc(char *, int, int, char *, int);
- #ifdef RAINBOW
- private int rbwrite(int, char *, int);
- #endif
- #else
- private File * f_alloc();
- #ifdef RAINBOW
- private int rbwrite();
- #endif
- #endif /* LINT_ARGS */
-
- #ifdef MAC
- # undef private
- # define private static
- #endif
-
- #ifndef L_SET
- # define L_SET 0
- #endif
-
- #define MAXFILES 20 /* good enough for my purposes */
-
- private File _openfiles[MAXFILES] = {0};
-
- private File *
- f_alloc(name, flags, fd, buffer, buf_size)
- char *name,
- *buffer;
- {
- register File *fp;
- register int i;
-
- for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
- if (fp->f_flags == 0)
- break;
- if (i == MAXFILES)
- complain("[Too many open files!]");
- fp->f_bufsize = buf_size;
- fp->f_cnt = 0;
- fp->f_fd = fd;
- fp->f_flags = flags;
- if (buffer == 0) {
- buffer = emalloc(buf_size);
- fp->f_flags |= F_MYBUF;
- }
- fp->f_base = fp->f_ptr = buffer;
- fp->f_name = copystr(name);
-
- return fp;
- }
-
- void
- gc_openfiles()
- {
- register File *fp;
-
- for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
- if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
- f_close(fp);
- }
-
- File *
- fd_open(name, flags, fd, buffer, bsize)
- char *name,
- *buffer;
- {
- return f_alloc(name, flags, fd, buffer, bsize);
- }
-
- File *
- f_open(name, flags, buffer, buf_size)
- char *name,
- *buffer;
- {
- register int fd;
- int mode = F_MODE(flags);
-
- if (mode == F_READ)
- fd = open(name, 0);
- if (mode == F_APPEND) {
- fd = open(name, 1);
- if (fd == -1)
- mode = F_WRITE;
- else
- (void) lseek(fd, 0L, 2);
- }
- if (mode == F_WRITE)
- fd = creat(name, CreatMode);
- if (fd == -1)
- return NIL;
- #ifdef MSDOS
- else
- setmode(fd, 0x8000);
- #endif /* MSDOS */
- return f_alloc(name, flags, fd, buffer, buf_size);
- }
-
- void
- f_close(fp)
- File *fp;
- {
- flush(fp);
- #ifdef BSD4_2
- if (fp->f_flags & (F_WRITE|F_APPEND))
- (void) fsync(fp->f_fd);
- #endif
- (void) close(fp->f_fd);
- if (fp->f_flags & F_MYBUF)
- free(fp->f_base);
- free(fp->f_name);
- fp->f_flags = 0; /* indicates that we're available */
- }
-
- int
- filbuf(fp)
- File *fp;
- {
- if (fp->f_flags & (F_EOF|F_ERR))
- return EOF;
- fp->f_ptr = fp->f_base;
- #ifndef MSDOS
- do
- #endif /* MSDOS */
- fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
- #ifndef MSDOS
- while (fp->f_cnt == -1 && errno == EINTR);
- #endif /* MSDOS */
- if (fp->f_cnt == -1) {
- printf("[Read error %d]", errno);
- fp->f_flags |= F_ERR;
- }
- if (fp->f_cnt == 0) {
- fp->f_flags |= F_EOF;
- return EOF;
- }
- io_chars += fp->f_cnt;
- return getc(fp);
- }
-
- void
- putstr(s)
- register char *s;
- {
- #ifndef IBMPC
- register int c;
-
- while (c = *s++)
- putchar(c);
- #else /* IBMPC */
- write_emif(s);
- #endif /* IBMPC */
- }
-
- void
- fputnchar(s, n, fp)
- register char *s;
- register int n;
- register File *fp;
- {
- while (--n >= 0)
- putc(*s++, fp);
- }
-
- void
- flusho()
- {
- #ifndef IBMPC
- _flush(EOF, stdout);
- #endif /* IBMPC */
- }
-
- void
- flush(fp)
- File *fp;
- {
- _flush(EOF, fp);
- }
-
- void
- f_seek(fp, offset)
- register File *fp;
- off_t offset;
- {
- if (fp->f_flags & F_WRITE)
- flush(fp);
- fp->f_cnt = 0; /* next read will filbuf(), next write
- will flush() with no bad effects */
- lseek(fp->f_fd, (long) offset, L_SET);
- }
-
- int /* is void - but for lints sake */
- _flush(c, fp)
- register File *fp;
- {
- register int n;
-
- if (fp->f_flags & (F_READ | F_STRING | F_ERR))
- return EOF;
- if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
- #ifndef RAINBOW
- (write(fp->f_fd, fp->f_base, n) != n) &&
- #else
- (rbwrite(fp->f_fd, fp->f_base, n) != n) &&
- #endif
- (fp != stdout)) {
- fp->f_flags |= F_ERR;
- error("[I/O error(%d); file = %s, fd = %d]",
- errno, fp->f_name, fp->f_fd);
- }
-
- fp->f_cnt = fp->f_bufsize;
- fp->f_ptr = fp->f_base;
- if (c != EOF)
- return putc(c, fp);
- }
-
- int
- f_gets(fp, buf, max)
- register File *fp;
- char *buf;
- {
- register char *cp = buf;
- register int c;
- char *endp = buf + max - 1;
-
- if (fp->f_flags & F_EOF)
- return EOF;
- while (((c = getc(fp)) != EOF) && (c != '\n')) {
- if (c == '\0') /* possibly different from NULL */
- break; /* sorry we don't read nulls */
- #ifdef MSDOS
- if (c == '\r') {
- if ((c = getc(fp)) == '\n')
- break;
- else
- *cp++ = '\r';
- }
- #endif /* MSDOS */
- if (cp >= endp) {
- add_mess(" [Line too long]");
- rbell();
- return EOF;
- }
- *cp++ = c;
- }
- *cp = '\0';
- if (c == EOF) {
- if (cp != buf)
- add_mess(" [Incomplete last line]");
- fp->f_flags |= F_EOF;
- return EOF;
- }
- io_lines += 1;
- return 0; /* this means okay */
- }
-
- /* skip to beginning of next line, i.e., next read returns first
- character of new line */
-
- void
- f_toNL(fp)
- register File *fp;
- {
- register int c;
-
- if (fp->f_flags & F_EOF)
- return;
- while (((c = getc(fp)) != EOF) && (c != '\n'))
- ;
- if (c == EOF)
- fp->f_flags |= F_EOF;
- }
-
- void
- f_readn(fp, addr, n)
- register File *fp;
- register char *addr;
- register int n;
- {
- while (--n >= 0)
- *addr++ = getc(fp);
- }
-
- int
- f_getint(fp)
- File *fp;
- {
- int n = 0,
- c;
-
- while (isdigit(c = getc(fp)))
- n = (n * 10) + c;
- return n;
- }
-
- /* Deals with output to the terminal, setting up the amount of characters
- to be buffered depending on the output baud rate. Why it's in a
- separate file I don't know ... */
-
- private char one_buf;
-
- int BufSize = 1;
-
- private File _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
- File *stdout = &_stdout;
-
- /* put a string with padding */
-
- #ifndef IBMPC
- void
- tputc(c)
- {
- putchar(c);
- }
-
- #undef putchar /* for files which forget to include io.h,
- here's a real putchar procedure. */
- void
- putchar(c)
- {
- putc(c, stdout);
- }
-
- #endif /* IBMPC */
- #ifndef MAC
- void
- putpad(str, lines)
- char *str;
- {
- #ifndef IBMPC
- if (str)
- tputs(str, lines, tputc);
- #else /* IBMPC */
- write_emif(str);
- #endif /* IBMPC */
- }
- #endif
-
- /* Determine the number of characters to buffer at each baud rate. The
- lower the number, the quicker the response when new input arrives. Of
- course the lower the number, the more prone the program is to stop in
- output. Decide what matters most to you. This sets BufSize to the right
- number or chars, and initiaizes `stdout'. */
-
- void
- settout(ttbuf)
- char *ttbuf;
- {
- #ifndef MAC
- #ifndef MSDOS
- static int speeds[] = {
- 1, /* 0 */
- 1, /* 50 */
- 1, /* 75 */
- 1, /* 110 */
- 1, /* 134 */
- 1, /* 150 */
- 1, /* 200 */
- 2, /* 300 */
- 4, /* 600 */
- 8, /* 1200 */
- 16, /* 1800 */
- 32, /* 2400 */
- 128, /* 4800 */
- 256, /* 9600 */
- 512, /* EXTA */
- 1024 /* EXT */
- };
- flusho(); /* flush the one character buffer */
- BufSize = min(MAXTTYBUF, speeds[ospeed] * max(LI / 24, 1));
- stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
- #else /* MSDOS */
- #ifndef IBMPC
- flusho(); /* flush the one character buffer */
- BufSize = BUFSIZ;
- stdout = fd_open("con", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
- #endif /* IBMPC */
- #endif /* MSDOS */
- #endif /* MAC */
- }
-
- #ifdef RAINBOW
-
- /*
- * use the Rainbow's video output function
- */
-
- #include <dos.h>
-
- private int
- rbwrite(fd, buf, cnt)
- char *buf;
- {
- union REGS vr;
-
- if (fd != 1) {
- write(fd, buf, cnt);
- } else {
- while (cnt-- > 0) {
- vr.x.ax = *buf++;
- vr.x.di = 0;
- int86(0x18, &vr, &vr);
- }
- }
- }
- #endif /* RAINBOW */
-