From 2b6598fb7489cfc6e967fe89158e15e524613314 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Wed, 28 Mar 1990 13:30:54 +0000 Subject: [PATCH] add LCC - a better C-Compiler for WEGA --- WEGA/contrib/lcc/h/mon.h | 17 ++ WEGA/contrib/lcc/lib/libc/port/stdio/flsbuf.c | 235 ++++++++++++++++++ WEGA/contrib/lcc/lib/libc/port/stdio/setbuf.c | 33 +++ 3 files changed, 285 insertions(+) create mode 100644 WEGA/contrib/lcc/h/mon.h create mode 100644 WEGA/contrib/lcc/lib/libc/port/stdio/flsbuf.c create mode 100644 WEGA/contrib/lcc/lib/libc/port/stdio/setbuf.c diff --git a/WEGA/contrib/lcc/h/mon.h b/WEGA/contrib/lcc/h/mon.h new file mode 100644 index 0000000..dc434e5 --- /dev/null +++ b/WEGA/contrib/lcc/h/mon.h @@ -0,0 +1,17 @@ +struct hdr { + char *lpc; + char *hpc; + int nfns; +}; + +struct cnt { + char *fnpc; + long mcnt; +}; + +typedef unsigned short WORD; + +#define MON_OUT "mon.out" +#define MPROGS0 600 +#define MSCALE0 4 +#define NULL 0 diff --git a/WEGA/contrib/lcc/lib/libc/port/stdio/flsbuf.c b/WEGA/contrib/lcc/lib/libc/port/stdio/flsbuf.c new file mode 100644 index 0000000..9e341ce --- /dev/null +++ b/WEGA/contrib/lcc/lib/libc/port/stdio/flsbuf.c @@ -0,0 +1,235 @@ +#include +#include "stdiom.h" +#include + +extern void free(); +extern int errno, write(), close(), isatty(); +extern char *malloc(); +extern FILE *_lastbuf; +extern unsigned char *_stdbuf[]; +extern unsigned char _smbuf[][_SBFSIZ]; + +/* + * Flush buffers on exit + */ + +void +_cleanup() +{ + register FILE *iop; + + for(iop = _iob; iop < _lastbuf; iop++) + (void) fclose(iop); +} +/* + fclose() will flush (output) buffers for a buffered open + FILE and then issue a system close on the _fileno. The + _base field will be reset to NULL for any but stdin and + stdout, the _ptr field will be set the same as the _base + field. The _flags and the _cnt field will be zeroed. + If buffers had been obtained via malloc(), the space will + be free()'d. In case the FILE was not open, or fflush() + or close() failed, an EOF will be returned, otherwise the + return value is 0. + */ + +int +fclose(iop) +register FILE *iop; +{ + register int rtn=EOF; + + if(iop == NULL) + return(rtn); + if(iop->_flag & (_IOREAD | _IOWRT | _IORW)) { + rtn = (iop->_flag & _IONBF)? 0: fflush(iop); + if(close(fileno(iop)) < 0) { + rtn = EOF; + errno = ENOENT; + } + } + if(iop->_flag & _IOMYBUF) { + free((char*)iop->_base); + iop->_base = NULL; + } + iop->_flag = 0; + iop->_cnt = 0; + iop->_ptr = iop->_base; + return(rtn); +} + +/* + The fflush() routine must take care because of the + possibility for recursion. The calling program might + do IO in an interupt catching routine that is likely + to interupt the write() call within fflush() + */ + +int +fflush(iop) +register FILE *iop; +{ + if (!(iop->_flag & _IOWRT)) { + iop->_cnt = 0; + return(0); + } + while(!(iop->_flag & _IONBF) && (iop->_flag & _IOWRT) && + (iop->_base != NULL) && (iop->_ptr > iop->_base) ) + (void) _xflsbuf(iop); + return(ferror(iop) ? EOF : 0); +} + +/* The routine _flsbuf may or may not actually flush the output buffer. If + * the file is line-buffered, the fact that iop->_cnt has run below zero + * is meaningless: it is always kept below zero so that invocations of putc + * will consistently give control to _flsbuf, even if the buffer is far from + * full. _flsbuf, on seeing the "line-buffered" flag, determines whether the + * buffer is actually full by comparing iop->_ptr to the end-of-buffer pointer + * _bufend(iop). If it is full, or if an output line is completed (with a + * newline), the buffer is flushed. (Note: the character argument to _flsbuf + * is not flushed with the current buffer if the buffer is actually full-- + * it goes into the buffer after flushing.) + */ + +int +_flsbuf(c, iop) +unsigned char c; +register FILE *iop; +{ + unsigned char c1; + + do { + if ( (iop->_flag & (_IOLBF | _IOWRT | _IOEOF)) == (_IOLBF | _IOWRT) ) { + if ( iop->_ptr >= _bufend(iop) ) /* if buffer full, */ + break; /* exit do-while, and flush buf. */ + if ( (*iop->_ptr++ = c) != '\n' ) + return(c); + return(_xflsbuf(iop) == EOF ? EOF : c); + } + if ( (iop->_flag & (_IONBF | _IOWRT | _IOEOF)) == (_IONBF | _IOWRT) ) { + c1 = c; + if (write(fileno(iop), (char *) &c1, 1) == 1) + return(c); + iop->_flag |= _IOERR; + return(EOF); + } + /* The _wrtchk call is here rather than at the top of _flsbuf to re- */ + /* duce overhead for line-buffered I/O under normal circumstances. */ + + if (_WRTCHK(iop)) /* is writing legitimate? */ + return(EOF); + } while ( (iop->_flag & (_IONBF | _IOLBF)) ); + + + (void) _xflsbuf(iop); /* full buffer: flush buffer */ + (void) putc((char) c, iop); /* then put "c" in newly emptied buf */ + /* (which, because of signals, may NOT be empty) */ + return( ferror(iop) ? EOF : c); +} + +/* The function _xflsbuf writes out the current contents of the output + * buffer delimited by iop->_base and iop->_ptr. + * iop->_cnt is reset appropriately, but its value on entry to _xflsbuf + * is ignored. + * + * The following code is not strictly correct. If a signal is raised, + * invoking a signal-handler which generates output into the same buffer + * being flushed, a peculiar output sequence may result (for example, + * the output generated by the signal-handler may appear twice). At + * present no means has been found to guarantee correct behavior without + * resorting to the disabling of signals, a means considered too expensive. + * For now the code has been written with the intent of reducing the + * probability of strange effects and, when they do occur, of confining + * the damage. Except under extremely pathological circumstances, this + * code should be expected to respect buffer boundaries even in the face + * of interrupts and other signals. + */ + +int +_xflsbuf(iop) +register FILE *iop; +{ + register unsigned char *base; + register int n; + + n = iop->_ptr - (base = iop->_base); + iop->_ptr = base; + iop->_cnt = (iop->_flag &(_IONBF | _IOLBF)) ? 0 : _bufsiz(iop); + _BUFSYNC(iop); + if (n > 0 && n != write(fileno(iop),(char*)base,(unsigned)n) ) { + iop->_flag |= _IOERR; + return(EOF); + } + return(0); +} + +/* The function _wrtchk checks to see whether it is legitimate to write + * to the specified device. If it is, _wrtchk sets flags in iop->_flag for + * writing, assures presence of a buffer, and returns 0. If writing is not + * legitimate, EOF is returned. + */ + +int +_wrtchk(iop) +register FILE *iop; +{ + if ( (iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT ) { + if (!(iop->_flag & (_IOWRT | _IORW))) + return(EOF); /* bogus call--read-only file */ + iop->_flag = iop->_flag & ~_IOEOF | _IOWRT; /* fix flags */ + } + if (iop->_base == NULL) /* this is first I/O to file--get buffer */ + _findbuf(iop); + if (iop->_ptr == iop->_base && !(iop->_flag & (_IONBF | _IOLBF)) ) { + iop->_cnt = _bufsiz(iop); /* first write since seek--set cnt */ + _BUFSYNC(iop); + } + return(0); +} + +/* + * _findbuf, called only when iop->_base == NULL, locates a predefined buffer + * or allocates a buffer using malloc. If a buffer is obtained from malloc, + * the _IOMYBUF flag is set in iop->_flag. + */ + +_findbuf(iop) +register FILE *iop; +{ + register int fno = fileno(iop); /* file number */ + + if (fno < 2) /* use existing bufs for stdin, stdout */ + _bufend(iop) = (iop->_base = _stdbuf[fno]) + BUFSIZ; + else + if ((iop->_base = (unsigned char *) malloc(BUFSIZ+8)) != NULL) { + iop->_flag |= _IOMYBUF; + _bufend(iop) = iop->_base + BUFSIZ; + } + else + _bufend(iop) = (iop->_base = _smbuf[fno]) + _SBFSIZ; + + iop->_ptr = iop->_base; + if ( isatty(fno) && !(iop->_flag & _IONBF) ) + iop->_flag |= _IOLBF; +} + +/* The function _bufsync is called because interrupts and other signals + * which occur in between the decrementing of iop->_cnt and the incrementing + * of iop->_ptr, or in other contexts as well, may upset the synchronization + * of iop->_cnt and iop->ptr. If this happens, calling _bufsync should + * resynchronize the two quantities (this is not always possible). Resyn- + * chronization guarantees that putc invocations will not write beyond + * the end of the buffer. Note that signals during _bufsync can cause + * _bufsync to do the wrong thing, but usually with benign effects. + */ + +_bufsync(iop) +register FILE *iop; +{ + register int spaceleft; + + if ((spaceleft = _bufend(iop) - iop->_ptr) < 0) + iop->_ptr = _bufend(iop); + else if (spaceleft < iop->_cnt) + iop->_cnt = spaceleft; +} diff --git a/WEGA/contrib/lcc/lib/libc/port/stdio/setbuf.c b/WEGA/contrib/lcc/lib/libc/port/stdio/setbuf.c new file mode 100644 index 0000000..50c858a --- /dev/null +++ b/WEGA/contrib/lcc/lib/libc/port/stdio/setbuf.c @@ -0,0 +1,33 @@ +#include + +extern void free(); +extern int isatty(); +extern unsigned char _smbuf[][_SBFSIZ]; +extern unsigned char *_stdbuf[]; + +void +setbuf(iop, buf) +register FILE *iop; +char *buf; +{ + register int fno = fileno(iop); /* file number */ + + if(iop->_base != NULL && iop->_flag & _IOMYBUF) + free((char*)iop->_base); + iop->_flag &= ~(_IOMYBUF | _IONBF | _IOLBF); + if((iop->_base = (unsigned char*)buf) == NULL) { + iop->_flag |= _IONBF; /* file unbuffered except in fastio */ + if (fno < 2) /* for stdin, stdout, use the existing bufs */ + _bufend(iop) = (iop->_base = _stdbuf[fno]) + BUFSIZ; + + else /* otherwise, use small buffers reserved for this */ + _bufend(iop) = (iop->_base = _smbuf[fno]) + _SBFSIZ; + } + else { /* regular buffered I/O, standard buffer size */ + _bufend(iop) = iop->_base + BUFSIZ; + if (isatty(fno)) + iop->_flag |= _IOLBF; + } + iop->_ptr = iop->_base; + iop->_cnt = 0; +}