File:  [MW Coherent from dump] / coherent / d / bin / db / trace3.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
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);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.