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 "io.h"
  10: #include "ctype.h"
  11: #include "termcap.h"
  12: 
  13: #ifdef MAC
  14: #	include "mac.h"
  15: #else
  16: #	include <sys/stat.h>
  17: #	ifndef MSDOS
  18: #		include <sys/file.h>
  19: #	else /* MSDOS */
  20: #		include <fcntl.h>
  21: #		include <io.h>
  22: #	endif /* MSDOS */
  23: #endif /* MAC */
  24: 
  25: #include <errno.h>
  26: 
  27: #ifdef MAC
  28: #	undef private
  29: #	define private
  30: #endif
  31: 
  32: #ifdef  LINT_ARGS
  33: private File * f_alloc(char *, int, int, char *, int);
  34: #ifdef RAINBOW
  35: private int rbwrite(int, char *, int);
  36: #endif
  37: #else
  38: private File * f_alloc();
  39: #ifdef RAINBOW
  40: private int rbwrite();
  41: #endif
  42: #endif	/* LINT_ARGS */
  43: 
  44: #ifdef MAC
  45: #	undef private
  46: #	define private static
  47: #endif
  48: 
  49: #ifndef L_SET
  50: #	define L_SET 0
  51: #endif
  52: 
  53: #define MAXFILES    20  /* good enough for my purposes */
  54: 
  55: private File    _openfiles[MAXFILES] = {0};
  56: 
  57: private File *
  58: f_alloc(name, flags, fd, buffer, buf_size)
  59: char    *name,
  60:     *buffer;
  61: {
  62:     register File   *fp;
  63:     register int    i;
  64: 
  65:     for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
  66:         if (fp->f_flags == 0)
  67:             break;
  68:     if (i == MAXFILES)
  69:         complain("[Too many open files!]");
  70:     fp->f_bufsize = buf_size;
  71:     fp->f_cnt = 0;
  72:     fp->f_fd = fd;
  73:     fp->f_flags = flags;
  74:     if (buffer == 0) {
  75:         buffer = emalloc(buf_size);
  76:         fp->f_flags |= F_MYBUF;
  77:     }
  78:     fp->f_base = fp->f_ptr = buffer;
  79:     fp->f_name = copystr(name);
  80: 
  81:     return fp;
  82: }
  83: 
  84: void
  85: gc_openfiles()
  86: {
  87:     register File   *fp;
  88: 
  89:     for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
  90:         if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  91:             f_close(fp);
  92: }
  93: 
  94: File *
  95: fd_open(name, flags, fd, buffer, bsize)
  96: char    *name,
  97:     *buffer;
  98: {
  99:     return f_alloc(name, flags, fd, buffer, bsize);
 100: }
 101: 
 102: File *
 103: f_open(name, flags, buffer, buf_size)
 104: char    *name,
 105:     *buffer;
 106: {
 107:     register int    fd;
 108:     int mode = F_MODE(flags);
 109: 
 110:     if (mode == F_READ)
 111:         fd = open(name, 0);
 112:     if (mode == F_APPEND) {
 113:         fd = open(name, 1);
 114:         if (fd == -1)
 115:             mode = F_WRITE;
 116:         else
 117:             (void) lseek(fd, 0L, 2);
 118:     }
 119:     if (mode == F_WRITE)
 120:         fd = creat(name, CreatMode);
 121:     if (fd == -1)
 122:         return NIL;
 123: #ifdef MSDOS
 124:     else
 125:         setmode(fd, 0x8000);
 126: #endif /* MSDOS */
 127:     return f_alloc(name, flags, fd, buffer, buf_size);
 128: }
 129: 
 130: void
 131: f_close(fp)
 132: File    *fp;
 133: {
 134:     flush(fp);
 135: #ifdef BSD4_2
 136:     if (fp->f_flags & (F_WRITE|F_APPEND))
 137:         (void) fsync(fp->f_fd);
 138: #endif
 139:     (void) close(fp->f_fd);
 140:     if (fp->f_flags & F_MYBUF)
 141:         free(fp->f_base);
 142:     free(fp->f_name);
 143:     fp->f_flags = 0;    /* indicates that we're available */
 144: }
 145: 
 146: int
 147: filbuf(fp)
 148: File    *fp;
 149: {
 150:     if (fp->f_flags & (F_EOF|F_ERR))
 151:         return EOF;
 152:     fp->f_ptr = fp->f_base;
 153: #ifndef MSDOS
 154:     do
 155: #endif /* MSDOS */
 156:         fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
 157: #ifndef MSDOS
 158:     while (fp->f_cnt == -1 && errno == EINTR);
 159: #endif /* MSDOS */
 160:     if (fp->f_cnt == -1) {
 161:         printf("[Read error %d]", errno);
 162:         fp->f_flags |= F_ERR;
 163:     }
 164:     if (fp->f_cnt == 0) {
 165:         fp->f_flags |= F_EOF;
 166:         return EOF;
 167:     }
 168:     io_chars += fp->f_cnt;
 169:     return getc(fp);
 170: }
 171: 
 172: void
 173: putstr(s)
 174: register char   *s;
 175: {
 176: #ifndef IBMPC
 177:     register int    c;
 178: 
 179:     while (c = *s++)
 180:         putchar(c);
 181: #else /* IBMPC */
 182:     write_emif(s);
 183: #endif /* IBMPC */
 184: }
 185: 
 186: void
 187: fputnchar(s, n, fp)
 188: register char   *s;
 189: register int    n;
 190: register File   *fp;
 191: {
 192:     while (--n >= 0)
 193:         putc(*s++, fp);
 194: }
 195: 
 196: void
 197: flusho()
 198: {
 199: #ifndef IBMPC
 200:     _flush(EOF, stdout);
 201: #endif /* IBMPC */
 202: }
 203: 
 204: void
 205: flush(fp)
 206: File    *fp;
 207: {
 208:     _flush(EOF, fp);
 209: }
 210: 
 211: void
 212: f_seek(fp, offset)
 213: register File   *fp;
 214: off_t   offset;
 215: {
 216:     if (fp->f_flags & F_WRITE)
 217:         flush(fp);
 218:     fp->f_cnt = 0;      /* next read will filbuf(), next write
 219: 				   will flush() with no bad effects */
 220:     lseek(fp->f_fd, (long) offset, L_SET);
 221: }
 222: 
 223: int     /* is void - but for lints sake */
 224: _flush(c, fp)
 225: register File   *fp;
 226: {
 227:     register int    n;
 228: 
 229:     if (fp->f_flags & (F_READ | F_STRING | F_ERR))
 230:         return EOF;
 231:     if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
 232: #ifndef RAINBOW
 233:         (write(fp->f_fd, fp->f_base, n) != n) &&
 234: #else
 235:         (rbwrite(fp->f_fd, fp->f_base, n) != n) &&
 236: #endif
 237:         (fp != stdout)) {
 238:             fp->f_flags |= F_ERR;
 239:         error("[I/O error(%d); file = %s, fd = %d]",
 240:             errno, fp->f_name, fp->f_fd);
 241:     }
 242: 
 243:     fp->f_cnt = fp->f_bufsize;
 244:     fp->f_ptr = fp->f_base;
 245:     if (c != EOF)
 246:         return putc(c, fp);
 247: }
 248: 
 249: int
 250: f_gets(fp, buf, max)
 251: register File   *fp;
 252: char    *buf;
 253: {
 254:     register char   *cp = buf;
 255:     register int    c;
 256:     char    *endp = buf + max - 1;
 257: 
 258:     if (fp->f_flags & F_EOF)
 259:         return EOF;
 260:     while (((c = getc(fp)) != EOF) && (c != '\n')) {
 261:         if (c == '\0')  /* possibly different from NULL */
 262:             break;      /* sorry we don't read nulls */
 263: #ifdef MSDOS
 264:         if (c == '\r') {
 265:             if ((c = getc(fp)) == '\n')
 266:                break;
 267:             else
 268:                *cp++ = '\r';
 269:         }
 270: #endif /* MSDOS */
 271:         if (cp >= endp) {
 272:             add_mess(" [Line too long]");
 273:             rbell();
 274:             return EOF;
 275:         }
 276:         *cp++ = c;
 277:     }
 278:     *cp = '\0';
 279:     if (c == EOF) {
 280:         if (cp != buf)
 281:             add_mess(" [Incomplete last line]");
 282:         fp->f_flags |= F_EOF;
 283:         return EOF;
 284:     }
 285:     io_lines += 1;
 286:     return 0;   /* this means okay */
 287: }
 288: 
 289: /* skip to beginning of next line, i.e., next read returns first
 290:    character of new line */
 291: 
 292: void
 293: f_toNL(fp)
 294: register File   *fp;
 295: {
 296:     register int    c;
 297: 
 298:     if (fp->f_flags & F_EOF)
 299:         return;
 300:     while (((c = getc(fp)) != EOF) && (c != '\n'))
 301:         ;
 302:     if (c == EOF)
 303:         fp->f_flags |= F_EOF;
 304: }
 305: 
 306: void
 307: f_readn(fp, addr, n)
 308: register File   *fp;
 309: register char   *addr;
 310: register int    n;
 311: {
 312:     while (--n >= 0)
 313:         *addr++ = getc(fp);
 314: }
 315: 
 316: int
 317: f_getint(fp)
 318: File    *fp;
 319: {
 320:     int n = 0,
 321:         c;
 322: 
 323:     while (isdigit(c = getc(fp)))
 324:         n = (n * 10) + c;
 325:     return n;
 326: }
 327: 
 328: /* Deals with output to the terminal, setting up the amount of characters
 329:    to be buffered depending on the output baud rate.  Why it's in a
 330:    separate file I don't know ... */
 331: 
 332: private char    one_buf;
 333: 
 334: int BufSize = 1;
 335: 
 336: private File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
 337: File    *stdout = &_stdout;
 338: 
 339: /* put a string with padding */
 340: 
 341: #ifndef IBMPC
 342: void
 343: tputc(c)
 344: {
 345:     putchar(c);
 346: }
 347: 
 348: #undef putchar      /* for files which forget to include io.h,
 349: 					   here's a real putchar procedure. */
 350: void
 351: putchar(c)
 352: {
 353:     putc(c, stdout);
 354: }
 355: 
 356: #endif /* IBMPC */
 357: #ifndef MAC
 358: void
 359: putpad(str, lines)
 360: char    *str;
 361: {
 362: #ifndef IBMPC
 363:     if (str)
 364:         tputs(str, lines, tputc);
 365: #else /* IBMPC */
 366:     write_emif(str);
 367: #endif /* IBMPC */
 368: }
 369: #endif
 370: 
 371: /* Determine the number of characters to buffer at each baud rate.  The
 372:    lower the number, the quicker the response when new input arrives.  Of
 373:    course the lower the number, the more prone the program is to stop in
 374:    output.  Decide what matters most to you. This sets BufSize to the right
 375:    number or chars, and initiaizes `stdout'.  */
 376: 
 377: void
 378: settout(ttbuf)
 379: char    *ttbuf;
 380: {
 381: #ifndef MAC
 382: #ifndef MSDOS
 383:     static int speeds[] = {
 384:         1,  /* 0	*/
 385:         1,  /* 50	*/
 386:         1,  /* 75	*/
 387:         1,  /* 110	*/
 388:         1,  /* 134	*/
 389:         1,  /* 150	*/
 390:         1,  /* 200	*/
 391:         2,  /* 300	*/
 392:         4,  /* 600	*/
 393:         8,  /* 1200 */
 394:         16, /* 1800	*/
 395:         32, /* 2400	*/
 396:         128,    /* 4800	*/
 397:         256,    /* 9600	*/
 398:         512,    /* EXTA	*/
 399:         1024    /* EXT	*/
 400:     };
 401:     flusho();       /* flush the one character buffer */
 402:     BufSize = min(MAXTTYBUF, speeds[ospeed] * max(LI / 24, 1));
 403:     stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
 404: #else /* MSDOS */
 405: #ifndef IBMPC
 406:     flusho();       /* flush the one character buffer */
 407:     BufSize = BUFSIZ;
 408:     stdout = fd_open("con", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
 409: #endif	/* IBMPC */
 410: #endif /* MSDOS */
 411: #endif /* MAC */
 412: }
 413: 
 414: #ifdef RAINBOW
 415: 
 416: /*
 417:  * use the Rainbow's video output function
 418:  */
 419: 
 420: #include <dos.h>
 421: 
 422: private int
 423: rbwrite(fd, buf, cnt)
 424: char *buf;
 425: {
 426:     union REGS vr;
 427: 
 428:     if (fd != 1) {
 429:         write(fd, buf, cnt);
 430:     } else {
 431:         while (cnt-- > 0) {
 432:             vr.x.ax = *buf++;
 433:             vr.x.di = 0;
 434:             int86(0x18, &vr, &vr);
 435:         }
 436:     }
 437: }
 438: #endif /* RAINBOW */

Defined functions

_flush defined in line 223; used 5 times
f_alloc defined in line 57; used 4 times
f_getint defined in line 316; used 2 times
f_open defined in line 102; used 4 times
f_readn defined in line 306; used 2 times
f_seek defined in line 211; used 4 times
f_toNL defined in line 292; used 4 times
fd_open defined in line 94; used 9 times
filbuf defined in line 146; used 3 times
flush defined in line 204; used 6 times
fputnchar defined in line 186; used 3 times
gc_openfiles defined in line 84; used 3 times
putchar defined in line 350; used 2 times
rbwrite defined in line 422; used 3 times
settout defined in line 377; used 3 times
tputc defined in line 342; used 1 times

Defined variables

BufSize defined in line 334; used 8 times
_openfiles defined in line 55; used 3 times
_stdout defined in line 336; used 1 times
one_buf defined in line 332; used 2 times
  • in line 336(2)
stdout defined in line 337; used 5 times

Defined macros

L_SET defined in line 50; used 2 times
MAXFILES defined in line 53; used 4 times
private defined in line 46; used 11 times
Last modified: 1988-03-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3670
Valid CSS Valid XHTML 1.0 Strict