📄 fp.c
字号:
/*************************************************************************** * 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 "fp.h"#include "ctype.h"#include "termcap.h"#include "disp.h"#ifdef MAC# include "mac.h"#else /* !MAC */# 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 RAINBOWprivate int rbwrite proto((int, char *, int));#endif#ifndef L_SET# define L_SET 0#endif#define MAXFILES 20 /* good enough for my purposes */private File openfiles[MAXFILES]; /* must be zeroed initially */File *fd_open(name, flags, fd, buffer, buf_size)char *name, *buffer;int flags, fd, buf_size;{ 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 == NULL) { buffer = emalloc((size_t)buf_size); fp->f_flags |= F_MYBUF; } fp->f_base = fp->f_ptr = buffer; fp->f_name = copystr(name); return fp;}voidgc_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 *f_open(name, flags, buffer, buf_size)char *name, *buffer;int flags, buf_size;{ register int fd; switch (F_MODE(flags)) { case F_READ: fd = open(name, 0); break; case F_APPEND: fd = open(name, 1); if (fd != -1) { (void) lseek(fd, 0L, 2); break; } /* FALLTHROUGH */ case F_WRITE: fd = creat(name, CreatMode); break; default: error("invalid F_MODE"); /* NOTREACHED */ } if (fd == -1) return NULL;#ifdef MSDOS setmode(fd, 0x8000);#endif /* MSDOS */ return fd_open(name, flags, fd, buffer, buf_size);}voidf_close(fp)File *fp;{ if (fp->f_flags & (F_WRITE|F_APPEND)) { flushout(fp);#ifdef BSD4_2 (void) fsync(fp->f_fd);#endif } (void) close(fp->f_fd); if (fp->f_flags & F_MYBUF) free((UnivPtr) fp->f_base); free((UnivPtr) fp->f_name); fp->f_flags = 0; /* indicates that we're available */}intfilbuf(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, (UnivPtr) fp->f_base, (size_t) fp->f_bufsize);#ifndef MSDOS } while (fp->f_cnt == -1 && errno == EINTR);#endif /* MSDOS */ if (fp->f_cnt == -1) { /* I/O error -- treat as EOF */ writef("[Read error: %s]", strerror(errno)); fp->f_flags |= F_ERR | F_EOF; return EOF; } if (fp->f_cnt == 0) { fp->f_flags |= F_EOF; return EOF; } io_chars += fp->f_cnt; return jgetc(fp);}voidputstr(s)register char *s;{#ifndef IBMPC register int c; while ((c = *s++) != '\0') jputchar(c);#else /* IBMPC */ write_emif(s);#endif /* IBMPC */}voidfputnchar(s, n, fp)register char *s;register int n;register File *fp;{ while (--n >= 0) jputc(*s++, fp);}voidflushscreen(){#ifndef IBMPC flushout(stdout);#endif /* IBMPC */}voidf_seek(fp, offset)register File *fp;off_t offset;{ if (fp->f_flags & (F_WRITE|F_APPEND)) flushout(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);}voidflushout(fp)register File *fp;{ register int n; if (fp->f_flags & (F_READ | F_STRING | F_ERR)) { if (fp->f_flags != F_STRING) abort(); /* IMPOSSIBLE */ /* We just banged into the end of a string. * In the interests of continuing, we will cause * the rest of the output to be be heaped in the * last position. Surely it will end up as a NUL. UGH! */ fp->f_cnt = 1; fp->f_ptr = &fp->f_base[fp->f_bufsize - 1]; return; } if (((n = (fp->f_ptr - fp->f_base)) > 0) &&#ifndef RAINBOW (write(fp->f_fd, (UnivPtr) fp->f_base, (size_t)n) != n) &&#else (rbwrite(fp->f_fd, fp->f_base, n) != n) &&#endif (fp != stdout)) { fp->f_flags |= F_ERR; error("[I/O error(%s); file = %s, fd = %d]", strerror(errno), fp->f_name, fp->f_fd); } fp->f_cnt = fp->f_bufsize; fp->f_ptr = fp->f_base;}boolf_gets(fp, buf, max)register File *fp;char *buf;size_t max;{ register char *cp = buf; register int c; char *endp = buf + max - 1; if (fp->f_flags & F_EOF) return YES; while (((c = jgetc(fp)) != EOF) && (c != '\n')) { if (c == '\0') { /* We can't store NUL in our buffer, so ignore it. * Of course, with a little ingenuity we could: * NUL could be represented by \n! */ continue; } if (cp >= endp) { add_mess(" [Line too long]"); rbell(); return YES; } *cp++ = c; } *cp = '\0'; if (c == EOF) { if (cp != buf) add_mess(" [Incomplete last line]"); return YES; }#ifdef MSDOS /* a CR followed by a LF is treated as a NL. * Bug: the line-buffer is effectively shortened by one character. */ if (cp != buf && cp[-1] == '\r') *--cp = '\0';#endif /* MSDOS */ io_lines += 1; return NO; /* this means okay */}/* skip to beginning of next line, i.e., next read returns first character of new line */voidf_toNL(fp)register File *fp;{ register int c; if (fp->f_flags & F_EOF) return; do ; while (((c = jgetc(fp)) != EOF) && (c != '\n')); if (c == EOF) fp->f_flags |= F_EOF;}size_tf_readn(fp, addr, n)register File *fp;register char *addr;size_t n;{ register size_t nleft; for (nleft = n; nleft > 0; nleft--) { int c = jgetc(fp); if (f_eof(fp)) break; *addr++ = c; } return n - nleft;}/* 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_File = {1, 1, 1, F_WRITE, &one_buf, &one_buf, (char *)NULL};File *stdout = &stdout_File;#ifdef RAINBOW/* * use the Rainbow's video output function */#include <dos.h>private intrbwrite(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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -