Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/runtm.c
There are no other files named runtm.c in the archive.
#include <stdio.h>
/* **************************************************************** */
/* High-level Runtime Support for C (TOPS-20 & WAITS) */
/* */
/* k. chen Aug, 1981 */
/* */
/* - ch[file_descriptor] is a JFN (TOPS20) or channel # (WAITS) */
/* except 0 -> TTY input (unredirected) */
/* 1 -> TTY output (unredirected) */
/* */
/* - on WAITS, assume command line is of the form: */
/* */
/* .RUN FOO ; arg1 arg2 arg3 ... */
/* */
/* - for both WAITS and TOPS-20, arguments are separated by */
/* spaces, tabs or semicolons. */
/* **************************************************************** */
#define TOPS20 /* *************** TOPS20 ****************** */
#define MAXFILE 16 /* maximum opened files */
#define UNDEF -1
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
#define GJSHT 0000001
#define GJOLD 0100000
#define GJFOU 0400000
#define OFWR 0100000
#define OFRD 0200000
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
struct bufhead {
int system;
char *user;
int count;
};
struct filespec {
int name;
int extension;
int date;
int PPN;
};
#endif /* ****************** WAITS ********************* */
#define term(x) (x == ';')
#define blank(x) (x == ' ' || x == '\t')
typedef char string[32];
static int ch[MAXFILE],
ieof;
#ifdef WAITS /* ****************** WAITS ********************* */
static struct bufhead buffers[MAXFILE];
#endif /* ****************** WAITS ********************* */
runtm(n)
{
int argc,done;
char argbuf[256],*argv[32],*p;
string in,out,other;
argc = 0;
in[0] = out[0] = '\0';
if (n > 0) {
/* get command line into string */
p = argbuf;
while (--n)
if((*p++ = _getty()) == '\r') {
p--;
break;
}
_getty();
#ifdef WAITS /* ****************** WAITS ********************* */
p--;
#endif /* ****************** WAITS ********************* */
*p++ = '\0';
/* scan string, make up *argv[] */
p = argbuf;
done = 0;
while (!done) {
if blank(*p) while blank(*p) p++;
if term(*p) {
p++;
if blank(*p) while blank(*p) p++;
}
switch (*p) {
case '\0':
case '\r':
case '\n':
done = 1;
break;
case '<':
p++;
if (in[0]) abort("%stdin redirected more than once.");
p = getstr(p,in);
break;
case '>':
p++;
if (out[0]) abort("%stdout redirected more than once.");
p = getstr(p,out);
break;
default:
argv[argc++] = p;
p = getstr(p,other);
if (!*p) {
done = 1;
break;
}
*p++ = 0;
#ifdef WAITS /* ****************** WAITS ********************* */
if (argc == 1 && (caseall(argv[argc-1],"RUN")
|| caseall(argv[argc-1],"RU")
|| caseall(argv[argc-1],"R"))) argc--;
#endif /* ****************** WAITS ********************* */
}
}
}
setup(in,out); /* init I/O */
stdio();
main(argc,argv); /* call user program */
sexit();
exit(0);
}
/* ---------------------- */
/* set up files */
/* ---------------------- */
static setup(in,out)
char *in,*out;
{
int i;
for (i = 3; i < MAXFILE; i++) ch[i] = UNDEF;
ch[0] = (*in) ? creat(in,0) : 0;
ch[1] = (*out) ? creat(out,0) : 1;
ch[2] = 1;
ieof = 0;
}
/* -------------------------------------------- */
/* close all files and exit to monitor */
/* -------------------------------------------- */
exit(n)
{
int i;
for (i=0; i < MAXFILE; i++) {
if (ch[i] != UNDEF) close(i);
}
_exit(n);
}
/* -------------------------------- */
/* get a string from tty: */
/* -------------------------------- */
static char *getstr(p,s)
char *p,*s;
{
while (!term(*p) && !blank(*p) && *p != '\0') *s++ = *p++;
*s = '\0';
return p;
}
/* --------------------------------------- */
/* output error message and exit */
/* --------------------------------------- */
static abort(s)
char *s;
{
while (*s) _putty(*s++);
_putty('\n');
_exit(0);
}
/* --------------- */
/* write */
/* --------------- */
write(f,buf,n)
char *buf;
{
int chan,i;
char *c;
struct bufhead *p;
if ((chan=ch[f]) < 1 || n <= 0) return -1;
if (chan == 1) { /* tty output */
for (i = n; i-- ; ) _putty(*buf++);
return n;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return (_write(chan,buf,n))? n : -1;
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
c = p->user;
i = p->count;
while (n--) {
*++c = *buf++;
if (--i <= 0) {
if (!_out(chan)) return -1;
c = p->user;
i = p->count;
}
}
p->user = c;
p->count = i;
return n;
#endif /* ****************** WAITS ********************* */
}
/* -------------------- */
/* byte write */
/* -------------------- */
bwrite(f,buf,n)
char *buf;
{
int chan,i,save;
char *c;
struct bufhead *p;
if ((chan=ch[f]) < 1 || n < 0) return -1;
if (chan == 1) { /* tty output */
for (i = n; i-- ; ) _putty(*buf++);
return n;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return (_write(chan,buf,n))? n : -1;
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
save = p->user;
save++;
c = (save & 0777777) | (0341000<<18);
c--;
i = p->count*4;
while (n--) {
*++c = *buf++;
if (--i <= 0) {
if (!_out(chan)) return -1;
save = p->user;
c = (save & 0777777) | (0341000<<18);
i = p->count*4;
}
}
chan = c;
p->user = (chan & 0777777) | (save & (0777777<<18));
p->count = i/4;
return n;
#endif /* ****************** WAITS ********************* */
}
/* -------------------------- */
/* image mode write */
/* -------------------------- */
iwrite(f,buf,n)
char *buf;
{
int chan,i,save;
char *c;
struct bufhead *p;
if ((chan=ch[f]) < 1 || n < 0) return -1;
if (chan == 1) { /* tty output */
for (i = n; i-- ; ) _putty(*buf++);
return n;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return (_write(chan,buf,n))? n : -1;
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
c = p->user;
i = p->count;
while (n--) {
*++c = *buf++;
if (--i <= 0) {
if (!_out(chan)) return -1;
}
}
p->count = i;
p->user = c;
return n;
#endif /* ****************** WAITS ********************* */
}
/* -------------- */
/* read */
/* -------------- */
read(f,buf,n)
char *buf;
{
int chan,i,k,m;
char *c;
struct bufhead *p;
if ((chan=ch[f]) == 1 || n < 0) return -1;
if (!chan) { /* tty input */
if (ieof) return 0;
for (i = 0; n-- ; i++) {
#ifdef WAITS
*buf = _getln();
#endif
#ifdef TOPS20
*buf = _getty();
#endif
if (!*buf++) {
ieof = 1;
break;
}
}
return i;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return _read(chan,buf,n);
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
c = p->user;
i = p->count;
m = 0;
k = n;
while (n--) {
if (i <= 0) {
if (!_in(chan)) {
p->count = 0;
return m;
}
c = p->user;
i = p->count;
}
*buf++ = *++c;
i--;
m++;
}
p->user = c;
p->count = i;
return k;
#endif /* ****************** WAITS ********************* */
}
/* ------------------- */
/* byte read */
/* ------------------- */
bread(f,buf,n)
char *buf;
{
int chan,i,k,m, save, *addr;
char *c;
struct bufhead *p;
if ((chan=ch[f]) == 1 || n < 0) return -1;
if (!chan) { /* tty input */
if (ieof) return 0;
for (i = 0; n-- ; i++) {
*buf = _getty();
if (!*buf++) {
ieof = 1;
break;
}
}
return i;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return _read(chan,buf,n);
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
save = p->user;
save++;
c = (save & 0777777) | (0341000<<18);
c--;
i = p->count*4;
m = 0;
k = n;
while (n--) {
if (i <= 0) {
if (!_in(chan)) {
p->count = 0;
return m;
}
save = p->user;
save++;
c = (save & 0777777) | (0341000<<18);
c--;
i = p->count*4;
}
*buf++ = *++c;
i--;
m++;
}
chan = c;
p->user = (chan & 0777777) | (save & (0777777<<18));
p->count = i/4;
return k;
#endif /* ****************** WAITS ********************* */
}
/* ------------------------- */
/* image mode read */
/* ------------------------- */
iread(f,buf,n)
char *buf;
{
int chan,i,k,m, save, *addr;
char *c;
struct bufhead *p;
if ((chan=ch[f]) == 1 || n < 0) return -1;
if (!chan) { /* tty input */
if (ieof) return 0;
for (i = 0; n-- ; i++) {
*buf = _getty();
if (!*buf++) {
ieof = 1;
break;
}
}
return i;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
return _read(chan,buf,n);
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
p = &buffers[chan];
i = p->count;
m = 0;
k = n;
while (n--) {
if (i <= 0) {
if (!_in(chan)) {
p->count = 0;
return m;
}
i = p->count;
}
*buf++ = *++p->user;
i--;
m++;
}
p->count = i;
return k;
#endif /* ****************** WAITS ********************* */
}
/* ------------------- */
/* open file */
/* ------------------- */
open(name,mode) /* 7-bit ASCII files */
char *name;
{
_ofile(name,mode,7);
}
bopen(name,mode) /* 8-bit byte open */
char *name;
{
_ofile(name,mode,8);
}
iopen(name,mode) /* 36-bit byte open */
char *name;
{
_ofile(name,mode,36);
}
static _ofile(name,mode,omode)
char *name;
{
int channel,f,buf,device,disk;
struct filespec fs;
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
if ((mode = getmode(mode)) == -1) return -1;
do { /* get reasonable JFN # */
channel = _getchannel(name, GJOLD|GJSHT);
if (channel < 0) return -1;
} while (channel < 2);
if (!_open(channel,mode,omode)) return -1;
if (f = getfd()) {
ch[f] = channel;
return f;
}
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
if (*name == ':') {
name++;
device = sixbit(name);
disk = 0;
}
else {
disk = device = sixbit("DSK");
}
if (convert(name,&fs) && (f = getfd())) {
buf = getbuf(f);
switch (omode) {
case 7:
if (_open(f,buf,device)) break;
return -1;
case 8:
if (_bopen(f,buf,device)) break;
return -1;
case 36:
if (_iopen(f,buf,device)) break;
return -1;
}
if (disk) {
if (!_lookup(f,&fs)) return -1;
_in(f);
}
return ch[f] = f;
}
#endif /* ****************** WAITS ********************* */
return -1;
}
/* -------------------------------- */
/* create file */
/* ignore protection mode */
/* -------------------------------- */
creat(name,mode)
char *name;
{
int i;
if ((i = _cfile(name,mode,7)) < 0) return NULL;
return i;
}
bcreat(name,mode)
char *name;
{
return _cfile(name,mode,8);
}
icreat(name,mode)
char *name;
{
return _cfile(name,mode,8);
}
static _cfile(name,mode,omode)
char *name;
{
int channel,f,buf,device,disk;
struct filespec fs;
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
do {
channel = _getchannel(name, GJFOU|GJSHT);
if (channel < 0) return -1;
} while (channel < 2);
mode = getmode(2);
if (_open(channel,mode,omode) <= 0) return -2;
if (f = getfd()) {
ch[f] = channel;
return f;
}
#endif /* ****************** TOPS-20 ******************* */
#ifdef WAITS /* ****************** WAITS ********************* */
if (*name == ':') {
name++;
device = sixbit(name);
disk = 0;
}
else {
disk = device = sixbit("DSK");
}
if (convert(name,&fs) && (f = getfd())) {
buf = getbuf(f);
switch (omode) {
case 7:
if (_open(f,buf<<18,device)) break;
return -1;
case 8:
if (_bopen(f,buf<<18,device)) break;
return -1;
case 36:
if (_iopen(f,buf<<18,device)) break;
return -1;
}
if (disk) {
if (!_enter(f,&fs)) return -1;
}
_out(f);
return ch[f] = f;
}
#endif /* ****************** WAITS ********************* */
return -1;
}
#ifdef TOPS20 /* ****************** TOPS-20 ******************* */
static getmode(n)
{
switch (n) {
case 0:
return OFRD;
case 1:
return OFWR;
case 2:
return OFRD|OFWR;
default:
return -1;
}
}
#endif /* ****************** TOPS-20 ******************* */
/* -------------------- */
/* close file */
/* -------------------- */
close(f)
{
int chnl;
chnl = ch[f];
if (chnl == UNDEF) abort("File never opened.");
if (chnl < 2) return;
_close(chnl);
ch[f] = UNDEF;
}
/* ---------------------------------------- */
/* find an unused file descriptor */
/* ---------------------------------------- */
getfd()
{
int n;
n = 3;
while (n < MAXFILE && ch[n] != UNDEF) n++;
return (n < MAXFILE) ? n : 0;
}
#ifdef WAITS /* ****************** WAITS ********************* */
/* ---------------------------------------------- */
/* compare string with uppercase string */
/* ---------------------------------------------- */
static caseall(s,t)
char *s,*t;
{
while (up(*s) == *t++) {
if (!*s++) return 1;
}
return 0;
}
static up(c)
{
if (c >= 'a' && c <= 'z') return c - 'a' + 'A';
return c;
}
/* --------------------------------------------------- */
/* obtain a sixbit representation for string */
/* --------------------------------------------------- */
static sixbit(s)
char *s;
{
int n,w,t;
w = 0;
n = 30;
while (*s && n >= 0) {
t = *s++;
if (t & 0100) t = t | 040; else t = t & 0137;
w += (t&077) << n;
n -= 6;
}
return w;
}
/* ----------------------------------------------------------------------- */
/* convert a filename string to internal filespec representation */
/* ----------------------------------------------------------------------- */
static convert(s,t)
char *s; struct filespec *t;
{
char u[16],*v;
int state;
state = 1;
t->name = t->extension = t->date = t->PPN = 0;
while (state) {
v = u;
while (!fend(*s)) *v++ = *s++;
*v = 0;
switch (state) {
case 1:
t->name = sixbit(u);
switch (*s) {
case 0:
state = 0;
break;
case '.':
state = 2;
break;
case '[':
state = 3;
break;
default:
return 0;
}
s++;
break;
case 2:
t->extension = sixbit(u) & 0777777000000;
switch (*s) {
case 0:
state = 0;
break;
case '[':
state = 3;
break;
default:
return 0;
}
s++;
break;
case 3:
t->PPN = rightjust(sixbit(u));
switch (*s) {
case ',':
state = 4;
break;
default:
return 0;
}
s++;
break;
case 4:
t->PPN += (rightjust(sixbit(u)) >> 18);
state = 0;
break;
default:
return 0;
}
}
return 1;
}
static fend(c)
{
if (c == 0 || c == '.' || c == '[' || c == ',' || c == ']') return 1;
return 0;
}
static rightjust(n)
{
if (n = n & 0777777000000) {
while (!(n & 077000000)) n = n >> 6;
}
return n;
}
/* -------------------------------------------------------- */
/* create an integer that contains buffer address */
/* -------------------------------------------------------- */
static getbuf(f)
{
return &buffers[f];
}
#endif /* ****************** WAITS ********************* */
/* ---------------------------------------------- */
/* convert string of decimal to integer */
/* ---------------------------------------------- */
atoi(s) /* convert s to integer */
char s[];
{
int i,n;
n = 0;
for (i=0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10*n + s[i] - '0';
return n;
}
/* ------------------------------------------------------------ */
/* returns false if file fp has no characters waiting */
/* if fp is NULL, keyboard is assumed */
/* ------------------------------------------------------------ */
ttyskp(fp)
FILE *fp;
{
if (fp == NULL) return tskp(-1);
return tskp(ch[fp->_fd]);
}