|
|
coherent
/*
* A debugger.
* Display.
*/
#include <stdio.h>
#include <ctype.h>
#include "trace.h"
/*
* Execute a command string.
*/
execute(cp)
char *cp;
{
register INP *ip;
while ((ip=inpp) != NULL) {
inpp = ip->i_next;
nfree(ip);
}
modsize = sizeof(int);
sincmod = SNULL;
dot = getpc();
lastc = '\0';
addstrp(cp);
request();
testint();
}
/*
* Parse requests and execute them.
*/
request()
{
register int c;
register char *cp;
register unsigned segn;
register long l;
register long d;
VAL val[VALSIZE];
while ((c=getn()) != EOF) {
if (c == '!') {
syscall();
continue;
}
if (c == '?') {
if ((c=getn()) != '\n') {
printe("Syntax error");
goto next;
}
if (errrstr == NULL)
printx("No error\n");
else
printx("%s\n", errrstr);
continue;
}
ungetn(c);
if (explist(val) == 0)
goto next;
switch (c=getn()) {
case ':':
sincmod = SNULL;
if (command(val) == 0)
return;
continue;
case '\n':
if (nvalue(&val[0]) && sincmod!=SNULL) {
if (excflag == 0) {
sincmod = SNULL;
printe("Cannot single step");
continue;
}
sinmode = sincmod;
sindecr = rvalue(&val[1], (long)1);
return;
}
case '=':
ungetn(c);
case '?':
sincmod = SNULL;
segn = vsegno(&val[0], cseg);
if ((c=getn()) == '=') {
l = lvalue(&val[0], (long)dot);
if ((c=getn()) == '\n') {
putaddnum( l);
printx("\n");
continue;
}
ungetn(c);
if (setdata(segn, l) == 0)
break;
continue;
}
if (c != '\n') {
cp = &segform[segn][0];
while (c != '\n') {
*cp++ = c;
c = getn();
}
*cp++ = '\0';
}
d = dot;
l = lad;
dot = lvalue(&val[0], (long)lad);
dispfmt(segn, segform[segn],
(int)rvalue(&val[1], (long)1));
if (segn != 2)
cseg = segn;
else {
dot = d;
lad = l;
}
continue;
default:
sincmod = SNULL;
printe("Syntax error");
break;
}
next:
while ((c=getn()) != '\n')
;
}
}
/*
* Change the value of a location.
*/
setdata(segn, a)
long a;
{
register char *cp;
register int n;
register int c;
char b[1];
char l3[3];
int i[1];
long l[1];
VAL val[VALSIZE];
if (explist(val) == 0)
return (0);
if ((c=getn()) != '\n')
return (0);
for (n=0; n<VALSIZE; n++, a+=modsize) {
if (nvalue(&val[n]))
continue;
l[0] = rvalue(&val[n], (long)0);
switch (modsize) {
case (sizeof(char)):
b[0] = l[0];
cp = b;
break;
case (sizeof(int)):
i[0] = l[0];
cp = i;
break;
case (sizeof(l3)):
ltol3(l3, l, 1);
cp = l3;
break;
case (sizeof(long)):
cp = l;
break;
default:
printe("Bad change type");
return (1);
}
add = a;
if (putb(segn, cp, modsize) == 0) {
printe("Cannot change value");
return (1);
}
}
if (segn == 2)
setregs();
return (1);
}
/*
* Send a command to the shell.
*/
syscall()
{
register int c;
register char *cp;
cp = miscbuf;
while ((c=getn()) != '\n')
*cp++ = c;
*cp++ = '\0';
system(miscbuf);
testint();
printf("!\n");
}
/*
* Print out data according to a format string. `n' is the number
* of times this is done.
*/
static int addfmt = 32767;
dispfmt(s, fs, n)
char *fs;
{
register char *sp1;
register char *sp2;
register int c;
register int r;
register int t1;
register int t2;
register char *sp3;
register char *fp;
register long nad;
register long pad;
register long uad;
r = 1;
t2 = '\0';
add = dot;
nad = dot;
pad = dot;
uad = dot;
sp1 = miscbuf;
sp3 = &sp1[DISSIZE];
while (n--) {
fp = fs;
for (;;) {
c = *fp++;
if (isascii(c) && isdigit(c)) {
r = 0;
do {
r = r*10 + c-'0';
c = *fp++;
} while (isascii(c) && isdigit(c));
--fp;
continue;
}
switch (c) {
case '^':
add = uad;
continue;
case '+':
add += r;
r = 1;
continue;
case '-':
add -= r;
r = 1;
continue;
case 'n':
*sp1 = '\0';
flushb((long)nad);
sp1 = miscbuf;
nad = add;
continue;
case 'd':
case 'o':
case 'u':
case 'x':
t2 = c;
continue;
case 'a':
addfmt = 32767;
continue;
case 'A':
addfmt = -1;
continue;
default:
t1 = c;
if (t1=='\0' && t2=='\0')
break;
if (t1 == '\0')
t1 = 'w';
if (t2 == '\0')
t2 = DDCHR;
uad = add;
while (r--) {
if (testint())
return (1);
*sp1++ = ' ';
pad = add;
sp2 = conform(sp1, s, t1, t2, getb);
if (sp2 == NULL) {
*--sp1 = '\0';
if (sp1 != miscbuf)
flushb((long)nad);
printe("Addressing error");
return (0);
}
if (sp2 <= sp3)
sp1 = sp2;
else {
*--sp1 = '\0';
flushb((long)nad);
*sp2 = '\0';
*sp1 = ' ';
sp2 = sp1;
sp1 = miscbuf;
while (*sp2)
*sp1++ = *sp2++;
nad = pad;
}
if (c == 'i') {
*sp1++ = '\0';
flushb((long)nad);
sp1 = miscbuf;
nad = add;
}
}
r = 1;
t2 = '\0';
if (c != '\0')
continue;
}
break;
}
lad = add;
}
if (sp1 != miscbuf) {
*sp1 = '\0';
flushb((long)nad);
}
return (1);
}
/*
* Flush the output buffer. The given address `a' is printed before the
* contents of the buffer and dot is set to it.
*/
flushb(a)
register long a;
{
char buf[40];
dot = a;
if( fflag)
printx( "%lx", a);
else {
conaddr( buf, -1, a, addfmt);
printx( "%s", buf);
}
printx("\t%s\n", miscbuf);
}
/*
* Given a format character `f' and a function `func', print out
* data according to the given format. The function `get' is
* called to read characters.
*/
char *
conform(sp, s, t1, t2, get)
register char *sp;
int (*get)();
{
register char *lp;
unsigned char c[1];
unsigned char v[3];
unsigned short h[1];
char *p[1];
int i[1];
long l[1];
#ifndef NFP
float f[1];
double d[1];
#endif
switch (t1) {
case 'b':
if ((*get)(s, c, sizeof(c)) == 0)
return (NULL);
modsize = sizeof(c);
/*
* There should be a better way to do this.
*/
if (t2 != 'd')
i[0] = c[0];
else {
char x[1];
x[0] = c[0];
i[0] = x[0];
}
sprintf(sp, getform(t1, t2), i[0]);
break;
case 'c':
if ((*get)(s, c, sizeof(c)) == 0)
return (NULL);
modsize = sizeof(c);
sp = conescs(sp, c[0]);
return (sp);
case 'C':
if ((*get)(s, c, sizeof(c)) == 0)
return (NULL);
modsize = sizeof(c);
*sp++ = (c[0]>=040&&c[0]<0177) ? c[0] : '.';
return (sp);
#ifndef NFP
case 'f':
if ((*get)(s, (char *)f, sizeof(f)) == 0)
return (NULL);
modsize = sizeof(f);
sprintf(sp, getform(t1, t2), f[0]);
break;
case 'F':
if ((*get)(s, (char *)d, sizeof(d)) == 0)
return (NULL);
modsize = sizeof(d);
sprintf(sp, getform(t1, t2), d[0]);
break;
#endif
case 'h':
if ((*get)(s, h, sizeof(h)) == 0)
return (NULL);
modsize = sizeof(h);
/*
* Oh well.
*/
if (t2 != 'd')
i[0] = h[0];
else {
short x[1];
x[0] = h[0];
i[0] = x[0];
}
sprintf(sp, getform(t1, t2), i[0]);
break;
case 'i':
sp = coninst(sp, s);
modsize = INLEN;
return (sp);
case 'l':
if ((*get)(s, (char *)l, sizeof(l)) == 0)
return (NULL);
modsize = sizeof(l);
sprintf(sp, getform(t1, t2), l[0]);
break;
case 'p':
if ((*get)(s, (char *)p, sizeof(p)) == 0)
return (NULL);
modsize = sizeof(p);
sp = conaddr(sp, -1, (long)p[0], I);
return (sp);
case 's':
case 'S':
lp = &sp[DISSIZE];
c[0] = '\0';
for (;;) {
if ((*get)(s, c, sizeof(c)) == 0)
return (NULL);
if (c[0] == '\0')
break;
if (t1 == 's')
sp = conescs(sp, c[0]);
else
*sp++ = c[0];
if (sp > lp)
return (NULL);
}
modsize = sizeof(i);
return (sp);
case 'v':
if ((*get)(s, (char *)v, sizeof(v)) == 0)
return (NULL);
modsize = sizeof(v);
l3tol(l, v, 1);
sprintf(sp, getform(t1, t2), l[0]);
break;
case 'w':
if ((*get)(s, (char *)i, sizeof(i)) == 0)
return (NULL);
modsize = sizeof(i);
sprintf(sp, getform(t1, t2), i[0]);
break;
case 'Y':
sp = gettime(sp, cseg, get);
modsize = sizeof(i);
return (sp);
default:
return (NULL);
}
while (*sp)
sp++;
return (sp);
}
/*
* If the given character is unprintable, convert it into
* an escape sequence.
*/
char *
conescs(sp, c)
register char *sp;
register int c;
{
*sp++ = '\\';
switch (c) {
case '\0':
*sp++ = '0';
break;
case '\b':
*sp++ = 'b';
break;
case '\n':
*sp++ = 'n';
break;
case '\f':
*sp++ = 'f';
break;
case '\r':
*sp++ = 'r';
break;
case '\\':
*sp++ = '\\';
break;
default:
if (c<040 || c>=0177) {
sprintf(sp, "%03o", c);
while (*sp)
sp++;
break;
}
sp[-1] = c;
}
return (sp);
}
/*
* Get the current time.
*/
char *
gettime(sp, s, get)
register char *sp;
int (*get)();
{
long l;
register int n;
register char *cp;
if ((*get)(s, (char *) &l, sizeof(l)) == 0)
return (NULL);
cp = ctime(&l);
n = 24;
do {
*sp++ = *cp++;
} while (--n);
return (sp);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.