Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/stdio.c
There is 1 other file named stdio.c in the archive. Click here to see a list.
/* -------------------------------------------- */
/* stdio.c (TOPS-20 & WAITS) */
/* */
/* reference: */
/* Kernighan,B.W., D.M.Ritchie, */
/* "The C Programming Language", */
/* Prentice-Hall, 1978 */
/* */
/* stdio (initializations) */
/* fopen, fclose */
/* getc, putc, ungetc, fgets, fputs */
/* sprintf, fprintf, printf */
/* _flushbuf, _fillbuf, __findbuf, _bin */
/* -------------------------------------------- */
#define TOPS20 /* **************** TOPS20 ******************** */
#define _BUFSIZE 512
#define _NFILE 10
#define _NBUFF 16
#define _MAXJFN 0105
#define PMODE 0644
#define _READ 01 /* file opened for reading */
#define _WRITE 02 /* file opened for writing */
#define _UNBUF 04 /* file is unbuffered */
#define _BIGBUF 010 /* big buffer allocated */
#define _BINARY 020 /* 8-bit image mode file */
#define _IMAGE 040 /* 36-bit image mode file */
#define _FIRST 0100 /* first read of file, for WAITS E files */
#define _BYTE 0200 /* 8-bit files */
#define _EFILE 0400 /* E editor file */
#define _EOF 01000 /* EOF occured */
#define _ERR 02000 /* error occured */
#define NULL 0
#define EOF (-1)
/* ------------------------------------- */
/* file structure [ref. p.165] */
/* ------------------------------------- */
typedef struct _iobuf {
char *_ptr; /* next character position */
int _cnt; /* number of characters left */
char *_base; /* location of buffer */
int _flag; /* file access mode */
int _fd; /* file descriptor */
} FILE;
FILE _iob[_NFILE] = {
NULL, 0, NULL, _READ|_UNBUF, 0, /* stdin */
NULL, 0, NULL, _WRITE, 1, /* stdout */
NULL, 0, NULL, _WRITE|_UNBUF, 2 /* stderr */
};
FILE *stdin,
*stdout,
*stderr;
static struct { char body[_BUFSIZE];
int use;
} _bigbuf[_NBUFF];
static char _smallbuf[_MAXJFN];
/* ----------------------------------------------- */
/* stdio called at runtime initialization */
/* ----------------------------------------------- */
stdio ()
{
int i;
for (i = 0 ; i < _NBUFF ; i++) _bigbuf[i].use = 0;
for (i = 3 ; i < _NFILE ; i++) _iob[i]._flag = 0;
stdin = &_iob[0];
stdout = &_iob[1]; stdout->_cnt = 0;
stderr = &_iob[2]; stderr->_cnt = 0;
}
/* ------------------------------ */
/* open buffered file */
/* [ref. p.151] */
/* ------------------------------ */
FILE *fopen (name, mode)
char *name, *mode;
{
int i, m, n, fd, flag;
FILE *fp;
m = *mode++;
n = *mode;
if (n ||
(m != 'r' && m != 'w' && m != 'a' &&
m != 'R' && m != 'W' &&
m != 'i' && m != 'o')) {
fputs ("illegal mode ", stderr);
fputs (mode, stderr);
fputs (" opening ", stderr);
fputs (name, stderr);
putc ('\n', stderr);
sexit (1);
}
for (i=3 ; i < _NFILE ; i++)
if (!(_iob[i]._flag & (_READ|_WRITE))) break;
if (i >= _NFILE) {
fputs ("No I/O buffer left.\n", stderr);
return NULL;
}
fp = &_iob[i];
switch (m) {
case 'r':
fd = open (name, 0);
flag = _READ | _FIRST;
break;
case 'R':
fd = bopen (name, 0);
flag = _READ | _BYTE;
break;
case 'i':
fd = iopen (name, 0);
flag = _READ | _IMAGE;
break;
case 'w':
fd = creat (name, PMODE);
flag = _WRITE;
break;
case 'W':
fd = bcreat (name, PMODE);
flag = _WRITE | _BYTE;
break;
case 'o':
fd = icreat (name, PMODE);
flag = _WRITE | _IMAGE;
break;
}
if (fd < 0) return NULL;
fp->_fd = fd;
fp->_cnt = 0;
fp->_base = NULL;
fp->_flag = flag;
return (fp);
}
/* ---------------------------------------- */
/* open unbuffered file */
/* same as fopen but unbuffered */
/* ---------------------------------------- */
FILE *uopen (name, mode)
char *name, *mode;
{
int i, m, n, fd, flag;
FILE *fp;
m = *mode++;
n = *mode;
if (n ||
(m != 'r' && m != 'w' && m != 'a' &&
m != 'R' && m != 'W' &&
m != 'i' && m != 'o')) {
fputs ("illegal mode ", stderr);
fputs (mode, stderr);
fputs (" opening ", stderr);
fputs (name, stderr);
putc ('\n', stderr);
sexit (1);
}
for (i=3 ; i < _NFILE ; i++)
if (!(_iob[i]._flag & (_READ|_WRITE))) break;
if (i >= _NFILE) {
fputs ("No I/O buffer left.\n", stderr);
return NULL;
}
fp = &_iob[i];
switch (m) {
case 'r':
fd = open (name, 0);
flag = _READ | _FIRST | _UNBUF;
break;
case 'R':
fd = bopen (name, 0);
flag = _READ | _BYTE | _UNBUF;
break;
case 'i':
fd = iopen (name, 0);
flag = _READ | _IMAGE | _UNBUF;
break;
case 'w':
fd = creat (name, PMODE);
flag = _WRITE | _UNBUF;
break;
case 'W':
fd = bcreat (name, PMODE);
flag = _WRITE | _BYTE | _UNBUF;
break;
case 'o':
fd = icreat (name, PMODE);
flag = _WRITE | _IMAGE | _UNBUF;
break;
}
if (fd < 0) return NULL;
fp->_fd = fd;
fp->_cnt = 0;
fp->_base = NULL;
fp->_flag = flag;
return (fp);
}
/* ---------------------------- */
/* close buffered file */
/* [ref. p.153] */
/* ---------------------------- */
fclose (fp)
FILE *fp;
{
char *p;
int i;
if (fp->_flag & _WRITE) _flushbuf (0, fp);
p = fp->_base;
for (i=0 ; i < _NFILE ; i++) {
if (_bigbuf[i].body == p) {
_bigbuf[i].use = 0;
break;
}
}
close (fp->_fd);
fp->_flag = 0;
}
/* ------------------------------ */
/* close files and exit */
/* ------------------------------ */
sexit (n)
{
int i;
_flushbuf (0, stdout);
_flushbuf (0, stderr);
for (i=3 ; i < _NFILE ; i++) {
if (_iob[i]._flag) {
fclose (&_iob[i]);
_iob[i]._ptr = NULL;
_iob[i]._cnt = 0;
_iob[i]._base = NULL;
}
}
}
/* ------------------------------------ */
/* get character from buffer */
/* [ref. p.166] */
/* ------------------------------------ */
getc (fp)
FILE *fp;
{
int i;
if (--fp->_cnt >= 0) {
i = *fp->_ptr++;
if (i == '\r' && !(fp->_flag&_BYTE)) {
i = getc (fp);
if (i != '\n') {
ungetc (i, fp);
return '\r';
}
}
#ifdef WAITS
if (i == 0 && (fp->_flag & _EFILE)) {
while (!*fp->_ptr && --fp->_cnt >= 0) fp->_ptr++;
return getc(fp);
}
#endif
return i;
}
else {
if ((i = _fillbuf (fp)) == EOF) return EOF;
ungetc(i, fp);
return getc(fp);
}
}
/* ------------------------------- */
/* pushback a character */
/* ------------------------------- */
ungetc (x, fp)
FILE *fp;
{
fp->_cnt++;
fp->_ptr--;
*fp->_ptr = x;
}
/* ------------------------------------ */
/* output character to buffer */
/* ------------------------------------ */
putc (x, fp)
FILE *fp;
{
int i;
if (x == '\n' && !(fp->_flag&_BYTE)) putc ('\r', fp);
if (fp->_cnt-- > 0) {
if ((fp == stdout || fp == stderr) && x == '\n') {
*fp->_ptr++ = '\n';
_flushbuf (0, fp);
return;
}
*fp->_ptr++ = x;
}
else {
if ((fp == stdout || fp == stderr) && x == '\n') {
*fp->_ptr++ = '\n';
fp->_cnt = 1;
_flushbuf (0, fp);
}
else {
if (fp->_flag & _UNBUF) {
fp->_cnt = 1;
_flushbuf (x, fp);
}
else {
fp->_cnt++;
_flushbuf (x, fp);
}
}
}
}
/* -------------------------------- */
/* putc with no \r for compiler */
/* -------------------------------- */
_putc (x, fp)
FILE *fp;
{
if (fp->_cnt-- > 0) {
*fp->_ptr++ = x;
if ((fp == stdout || fp == stderr) && x == '\n') {
_flushbuf (0, fp);
}
}
else {
fp->_cnt++;
_flushbuf (x, fp);
}
}
/* -------------------- */
/* get line */
/* [ref. p.155] */
/* -------------------- */
char *fgets (line, maxline, fp)
FILE *fp; char *line;
{
int i, c;
char *l;
l = line;
for (i=1 ; i < maxline ; i++) {
if ((c=getc (fp)) == EOF) {
line = NULL;
break;
}
if ((*l++ = c) == '\n') break;
}
*l = 0;
return line;
}
/* ----------------------- */
/* output string */
/* [ref. p.155] */
/* ----------------------- */
fputs (s, fp)
char *s;
FILE *fp;
{
while (*s) putc (*s++, fp);
}
/* ------------------------------------ */
/* flush buffered file output */
/* [ref. p.166] */
/* ------------------------------------ */
_flushbuf (x, fp)
FILE *fp;
{
int n, flag, cnt, unbuf;
char *s;
if (!(fp->_flag & _WRITE)) return;
unbuf = fp->_flag & _UNBUF;
if (unbuf && !x && !fp->_cnt) return;
if (fp->_base == NULL) {
__findbuf (fp);
fp->_ptr = fp->_base;
fp->_cnt = _BUFSIZE ;
}
if (unbuf && x) {
*fp->_base = x;
write (fp->_fd, fp->_base, 1);
fp->_ptr = fp->_base;
fp->_cnt = 0;
return;
}
if (n = (unbuf) ? 1 : _BUFSIZE - fp->_cnt) {
if (fp->_flag & _BYTE) {
bwrite (fp->_fd, fp->_base, n);
}
else if (fp->_flag & _IMAGE) {
iwrite (fp->_fd, fp->_base, n);
}
else write (fp->_fd, fp->_base, n);
fp->_ptr = fp->_base;
fp->_cnt = (unbuf) ? 0 :_BUFSIZE;
}
if (x) {
*fp->_ptr++ = x;
fp->_cnt--;
}
}
/* ------------------------------------------ */
/* fill buffer and return character */
/* ------------------------------------------ */
_fillbuf (fp)
FILE *fp;
{
int i, flag, c, cnt;
char *s;
flag = fp->_flag;
if (!(flag & _READ) || (flag & (_EOF|_ERR))) return EOF;
if (fp->_base == NULL) __findbuf (fp);
fp->_ptr = fp->_base;
flag = fp->_flag;
if ((flag & _BYTE) && !(flag & _UNBUF)) {
cnt = bread (fp->_fd, fp->_base, _BUFSIZE);
}
else if (flag & _IMAGE) {
cnt = iread (fp->_fd, fp->_base, (flag & _UNBUF) ? 1 : _BUFSIZE);
}
else {
cnt = read (fp->_fd, fp->_base, (flag & _UNBUF) ? 1 : _BUFSIZE);
}
/* ******************************************************************* */
#ifdef WAITS /* check for E directory page */
if (fp->_flag & _FIRST) {
fp->_flag = fp->_flag & (~_FIRST);
if (cnt >= 9) {
if (check("COMMENT ",fp->_base)) {
s = fp->_base;
while (*s != 014) {
if (--cnt <= 0) {
cnt = read(fp->_fd, fp->_base, _BUFSIZE);
if (cnt <= 0) { /* error of some sort */
fp->_flag = fp->_flag | _ERR;
fp->_cnt = 0;
return EOF;
}
s = fp->_base;
}
else s++;
}
fp->_ptr = ++s;
fp->_cnt = cnt;
c = getc(fp);
fp->_flag = fp->_flag | _EFILE;
return c;
}
}
}
#endif
/* ******************************************************************* */
fp->_cnt = cnt;
if (fp->_cnt <= 0) {
fp->_flag = fp->_flag | (cnt == -1) ? _EOF : _ERR ;
fp->_cnt = 0;
return EOF;
}
i = getc(fp);
return i;
}
#ifdef WAITS /* ******************** WAITS ******************** */
static check(s,t)
char *s,*t;
{
while (*s++ == *t) t++ ;
return (*t == 026);
}
#endif
/* ----------------------------- */
/* find buffer for I/O */
/* ----------------------------- */
__findbuf (fp)
FILE *fp;
{
int flag, i;
flag = fp->_flag;
if (flag & _UNBUF) {
fp->_base = &_smallbuf[fp->_fd]; /* unbuffered */
return;
}
for (i=3 ; i < _NBUFF ; i++)
if (_bigbuf[i].use == 0) break;
if (i < _NBUFF) {
fp->_flag = flag | _BIGBUF;
fp->_base = _bigbuf[i].body;
_bigbuf[i].use = 1;
}
else {
fp->_flag = flag | _UNBUF;
fp->_base = &_smallbuf[fp->_fd]; /* unbuffered */
}
}
/* ------------------------------------------- */
/* in-memory conversion [ref. p. 150] */
/* ------------------------------------------- */
sprintf (str, control, a, b, c, d, e, f, g, h)
char *str, *control;
{
int sign, value, def, i;
while (1) {
switch (*control) {
case 0:
*str = 0;
return;
case '%':
control++;
if (sign=(*control == '-')) control++;
value = 0;
while (*control >= '0' && *control <= '9') {
value = value*10 + *control++ - '0';
}
if (sign) value = -value;
def = 1;
switch (*control) {
case 'c':
*str++ = a;
break;
case 'd':
__pn (&str, a, value, 10);
break;
case 'o':
__pn (&str, a, value, 8);
break;
case 's':
__ps (&str, a, value);
break;
case 'x':
__pn (&str, a, value, 16);
break;
default:
def = 0;
}
if (def) {
sprintf (str, ++control, b, c, d, e, f, g, h);
return;
}
default:
*str++ = *control++;
}
}
}
/* --------------------------------------- */
/* formatted output [ref. p. 145] */
/* --------------------------------------- */
printf (control, a, b, c, d, e, f, g, h)
char *control;
{
char str[132];
sprintf (str, control, a, b, c, d, e, f, g, h);
fputs (str, stdout);
}
/* -------------------------------------------- */
/* file formatted output [ref. p. 152] */
/* -------------------------------------------- */
fprintf (fp, control, a, b, c, d, e, f, g, h)
FILE *fp;
char *control;
{
char str[132];
sprintf (str, control, a, b, c, d, e, f, g, h);
fputs (str, fp);
}
/* ---------------------- */
/* print string */
/* ---------------------- */
__ps (s, t, n) /* string */
char **s, *t;
{
int i, field;
char *u;
field = (n < 0) ? (-n) : n;
i = field - _ps_(t);
u = *s;
if (n < 0) {
while (*t) *u++ = *t++;
while (i-- > 0) *u++ = ' ';
}
else {
while (i-- > 0) *u++ = ' ';
while (*t) *u++ = *t++;
}
*s = u;
}
_ps_ (s)
char *s;
{
int n;
n = 0;
while (*s++) n++;
return n;
}
/* ---------------------- */
/* print number */
/* ---------------------- */
__pn (s, t, n, base)
char **s;
{
int i, field;
char *u, *v, str[132];
field = (n < 0) ? (-n) : n;
v = str;
switch (base) {
case 8:
i = _po_(&v, t);
break;
case 10:
i = _pd_(&v, t);
break;
case 16:
i = _px_(&v, t);
break;
}
i = field - i;
*v = '\0';
u = *s;
v = str;
if (n < 0) {
while (*v) *u++ = *v++;
while (i-- > 0) *u++ = ' ';
}
else {
while (i-- > 0) *u++ = ' ';
while (*v) *u++ = *v++;
}
*s = u;
}
/* ---------------------- */
/* print decimal */
/* ---------------------- */
_pd_ (s,t)
char **s;
{
char *u;
int i,n;
if (t < 0) {
t = -t;
u = *s;
*u++ = '-';
*s = u;
n = 2;
}
else n = 1;
if (i=t/10)
n = _pd_ (s, i) + n;
u = *s;
*u++ = t%10 + '0';
*s = u;
return n;
}
/* --------------------- */
/* print octal */
/* --------------------- */
_po_ (s,t)
char **s;
{
char *u;
int i,n;
if (i=t>>3) /* assume logical shift */
n = _po_ (s, i) + 1;
else
n = 1;
u = *s;
*u++ = (t&07) + '0';
*s = u;
return n;
}
/* --------------------------- */
/* print hexadecimal */
/* --------------------------- */
_px_ (s,t)
char **s;
{
char *u;
int i,n;
if (i=t>>4) /* assume logical shift */
n = _px_ (s, i) + 1;
else
n = 1;
i = (t&0xF);
u = *s;
*u++ = (i < 10) ? i + '0' : i + 'A' - 10;
*s = u;
return n;
}