File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / cmd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

static char sccsid[] = "@(#)cmd.c	2.8";

#include <ctype.h>
#include <stdio.h>
#include "cdb.h"
#include <signal.h>

static char	vsbTarget[100];	/* used for string searches */
static char	vchSearch = '/';	/* contains either ? or / */

export CMDE	vcmdDef;
export char	*vsbCmd, *vsbCmdOld;
export long	vdot;
export TYR	vtyDot[cTyMax];
export int	viln, vslop;	/* line number & offset from true line number */
export char	vsbFileTemp[80]; /* name of vifdTemp file */


/* C A L L   S H E L L */

local void CallShell(sbCmd)
char	*sbCmd;
{
	char	stShell[20];

	if ((sbCmd == sbNil) OR (*sbCmd == chNull)) {
		sprintf(stShell, "%s -i", getenv("SHELL"));
		sbCmd = stShell;
	} /* if */
	system(sbCmd);
	printf("\nback in cdb, debugging %s\n", vsbSymfile);
} /* CallShell */


/* E A T   C M D   L I S T */

export char * EatCmdList()
{
	char	*sbCmd, *sbTemp;
	TKE		tk;

	sbCmd = vsbCmd;
	tk = TkPeek();
	if (tk == tkNil)
		return(sbNil);

	if (tk != tkLCB) {
		vsbCmd = sbNil; /* give caller the rest of line */
	} 
	else {
		tk = TkNext();	/* eat { */
		sbCmd = vsbCmd;
		sbTemp = SbFEob(vsbCmd) - 1;
		if (*sbTemp == '}')
			*sbTemp = chNull;
		vsbCmd = sbTemp + 1;
	} /* if */
	while (*sbCmd == ' ')
		sbCmd++;
	return(sbCmd);
} /* EatCmdList */


/* E A T   F I L E N A M E */

local void EatFilename(sbName, psbIn)
char	*sbName, **psbIn;
{
	int		cch;
	char	*sbIn;

	sbIn = *psbIn;
	while (*sbIn == '\t' OR *sbIn == ' ')
		sbIn++;
	cch = strcspn(sbIn, "\t ;}");
	strncpy(sbName, sbIn, cch);
	sbName[cch] = chNull;
	*psbIn = sbIn + cch;
} /* EatFilename */


/* S B   F   E O B */

export char *SbFEob(sb)
char	*sb;
{
	int		cNest;

	/* return pointer to AFTER '}', or to the chNull */
	cNest = (*sb == '{') ? 0 : 1;
	while (*sb) {
		if (*sb == '{')
			cNest++;
		else if (*sb == '}')
			if (--cNest == 0)
				return(sb+1);
		sb++;
	} /* while */
	return(sb);
} /* SbFEob */


/* F   D O   C O M M A N D */

export FLAGT FDoCommand(sbCmdIn, fTop)
char	*sbCmdIn;
FLAGT	fTop;
{
	int		valShort, ln, cLn, cnt, ifd, ipd;
	int		sig, ibp, i, ilnSave;
	FLAGT	fHaveValue, fDidit, fDoit, fCommand;
	char	ch, chBp, chCmd, chNext;
	char	*sbBp, *sbTemp, *sbCmds, *sbTwoChars;
	char	sbName[80];
	long	valExp, adrLong;
	ADRT	adr;
	TKE		tk, tkRet;
	ASE		as;
	pTYR	ty;
	TYR		rgTy[cTyMax];

	/* the commands */
	sbCmds = "\n<>-+?/^!~;{}AabBcCdDeEfFgiIklLMpqQrRsStTwWxzZ";
	sbTwoChars = "<bi";	/* commands of two or more characters */
	if (!fTop)
		PushCmd(vsbCmd);
	vsbCmd = vsbCmdOld = sbCmdIn;

	tk = TkNext();
	do {
		if ((tk == tkStr) AND (FSbCmp("help", vsbTok))) {
			Help();
			vcmdDef = cmdNil;
			return(fTop);
		} 
		else if (tk == tkStrConstant) {
			printf("%s", vsbTok);
			vcmdDef = cmdNil;
			tk = TkNext();
			continue;
		} /* if */

		/* we guess whether to parse an expression */
		/* this is a little weird because we try to do the `right' thing */
		adrLong = 0;
		chCmd = vsbTok[0];
		fHaveValue = false;
		fCommand = (tk == tkNil);
		if (strchr(sbCmds, chCmd) != NULL) {
			/* the first letter LOOKS like a command, keep going */
			fCommand = (vcbTok == 1);
			if ((vcbTok > 1) AND (tk == tkStr)) {
				/* it is longer than 1 character, might be a variable name */
				chNext = vsbTok[1];
				if ( (vcbTok == 2)
				    AND (strchr(sbTwoChars, chCmd) != NULL) ) {
					fCommand =   (chCmd == 'b' AND strchr("abBtTuUxX", chNext))
						OR (chCmd == 'i' AND chNext == 'f')
							OR (chCmd == '<' AND chNext == '<');
				} /* if */
			} /* if */
			/* a final chance to change our minds */
			TkPeek(); /* load peek token information */
			if (   (tk == tkStr)
			    AND (*vsbCmd != ' ')
			    AND (vsbTokPeek[0] != chNull)
			    AND !(strchr(";}", vsbTokPeek[0])) ) {
				fCommand = false;
			} /* if */
		} /* if */

		if (!fCommand) {
			/* assume it is a beginning expression */
			vipd = IpdFAdr(AdrFIfdLn(vifd, viln)); /* force things right */
			if ((tkRet = TkFExpr(&adrLong, rgTy)) != tkNil) {
				valExp = ValFAdr(adrLong, rgTy); /* many cmds just want value */
				valShort = valExp;
				fHaveValue = true;
			} 
			else {
				if (PrecFTk(tkRet))
					tk = TkNext();
				UError("Unknown variable - %s", vsbTok);
			} /* if */
		} /* if */

		cnt = 1;
		chCmd = vsbTok[0];
		switch (chCmd) {
		default:
			vcmdDef = cmdNil;
			UError("Unknown command `%c' (%#o)\n", chCmd, chCmd);
		case '\n':
		case '~':
		case chNull:		/* default command */
			if (!fHaveValue) {
				switch (vcmdDef) {
				case cmdPrint:
					viln++;
					PrintLine(viln, 1, true);
					break;
				case cmdUpArrow:
				case cmdDisplay:
					i = IncFTyMode(vtyDot, vmode);
					vdot += (vcmdDef == cmdUpArrow) ? -i : i;
					DispVal(vdot, vtyDot, vmode, true, true, true);
					printf("\n");
					break;
				case cmdLineSingle:
					printf("s: ");
					IbpFSingle(false, false);
					break;
				case cmdProcSingle:
					printf("S: ");
					IbpFSingle(true, false);
					break;
				} /* switch */
			} 
			else if (tkRet == tkNumber) {
				i = valShort;
				if (i > 0)
					viln = i;
				else viln += i;
				vslop = 0;
				PrintLine(viln, 1, true);
				vcmdDef = cmdPrint;
			} 
			else if (tkRet == tkAdr) {
				vdot = adrLong;
				CopyTy(vtyDot, rgTy);
				DispVal(vdot, vtyDot, modeNil, true, true, true);
				printf("\n");
				vcmdDef = cmdDisplay;
			} /* if */
			break;
		case '+':	/* go forward N (1) line and print it */
		case '-':	/* go backward N (1) line and print it */
			i = GetExpr(&ty, tkNil);
			if (ty == tyNil)
				i = 1;
			viln += (chCmd=='-') ? -abs(i) : abs(i);
			PrintLine(viln, 1, true);
			vcmdDef = cmdPrint;
			continue;
		case '!':
			CallShell(vsbCmd);	/* shell escape */
			vsbCmd = sbNil;
			break;
		case '^':	/* attempt to move backward, displaying memory */
			GetMode(vmode);
			vdot -= IncFTyMode(vtyDot, vmode);
			DispVal(vdot, vtyDot, vmode, true, true, true);
			printf("\n");
			vcmdDef = cmdUpArrow;
			break;
		case '/':	/* 2 commands:  'X/Y' == display *X in format Y
						 *		'/hi mom' == search FORWARDS and print
						*/
		case '?':	/* 2 commands:  'X?Y' == display X in format Y
						 *		'?hi mom' == search BACKWARDS and print
						*/
			if (!fHaveValue) {
				/* search for something */
				if (*vsbCmd != chNull) {
					strcpy(vsbTarget, vsbCmd);
					*vsbCmd = chNull;
				} /* if */
				vchSearch = chCmd;
				Find(vsbTarget, (chCmd=='?'));
				vcmdDef = cmdPrint;
			} 
			else {
				vdot = adrLong;
				CopyTy(vtyDot, rgTy);
				GetMode(vmode);
				if (chCmd == '/') {
					/* this prints the CONTENTS of an address */
					DispVal(vdot, vtyDot, vmode, true, true, true);
					vcmdDef = cmdDisplay;
				} 
				else {
					/* this prints an ADDRESS */
					vmode->cnt = 1;
					DispVal(vdot, vtyDot, vmode, true, false, false);
					vcmdDef = cmdNil;
				} /* if */
				printf("\n");
			} /* if */
			break;
		case '<':	/* playback commands */
			EatFilename(sbName, &vsbCmd);
			SetPlayback(sbName, (vsbTok[1] == '<'));
			break;
		case '>':	/* record commands */
			TkPeek();
			if (vsbTokPeek[1] == chNull) {
				if (  (vsbTokPeek[0] == 't')
				    OR (vsbTokPeek[0] == 'f')) {
					TkNext();	/* actually eat next token */
					StateRecord(vsbTok[0] == 't');
					break;
				} 
				else if (vsbTokPeek[0] == 'c') {
					TkNext();	/* actually eat next token */
					SetRecord(sbNil);
					break;
				} /* if */
				/* we fall through on other, 1 character filenames */
			} /* if */
			EatFilename(sbName, &vsbCmd);
			SetRecord(sbName);
			break;
		case ';':	/* just a command delimiter */
			vcmdDef = cmdNil;
			break;
		case 'A':	/* toggle main assertion state */
			if (viadMac > 0)
				vas = (vas==asSuspended) ? asActive : asSuspended;
			printf("Assertions are %s\n", (vas==asSuspended) ?
			"SUSPENDED" : "ACTIVE");
			vcmdDef = cmdNil;
			break;
		case 'a': /* maintain assertion list */
			if (fHaveValue) {
				TkNext();
				switch (vsbTok[0]) {
				case 'a':
					as = asActive;
					break;
				case 'd':
					as = asNil;
					break;
				case 's':
					as = asSuspended;
					break;
				default:
					UError("Invalid assertion maintenance command");
				} /* switch */
				ModAssert(valShort, as);
				break;
			} /* if */
			if ((sbTemp=EatCmdList()) != sbNil)
				AddAssert(sbTemp);
			break;
		case 'B': /* list all breakpoints */
			ListBp();
			break;
		case 'b':	/* set (set again) a break point */
			vipd = IpdFAdr(AdrFIfdLn(vifd, viln));
			chBp = vsbTok[1];
			sbBp = EatCmdList();
			ibp = ibpNil;
			if (chBp == 'a') {
				if (!fHaveValue)
					UError("correct form is `address ba [<cmds>]'");
				else
					adr = valShort;
				ibp = IbpFAdr(adr, 1, sbBp);
			} 
			else if (chBp == chNull) {
				/* vanilla breakpoint */
				i = (fHaveValue) ? valShort : viln;
				adr = AdrFIfdLn(vifd, i);
				ibp = IbpFAdr(adr, 1, sbBp);
			} 
			else {
				ch = (isupper(chBp)) ? tolower(chBp) : chBp;
				i = (fHaveValue) ? valShort : (ch=='u') ? 1 : -1;
				ibp = IbpFSet(chBp, i, sbBp);
			} /* if */
			if (ibp != ibpNil) {
				PrintPos(vrgBp[ibp].adr, fmtProc+fmtLn+fmtSave);
				printf(":b \n");
			} /* if */
			vcmdDef = cmdNil;
			break;
		case 'C':
		case 'c':
			vipd = IpdFAdr(AdrFIfdLn(vifd, viln));
			if (fHaveValue) {
				/* we have a continuance count */
				i = valShort;
				if (vibp != ibpNil)
					vrgBp[vibp].count = i;
			} /* if */
			i = GetExpr(&ty, tkNil);
			if (ty != tyNil) {
				adr = AdrFIfdLn(vifd, i);
				ibp = IbpFAdr(adr, -1, "");
			} /* if */
			if (chCmd == 'c')
				vsig = 0;	/* do not pass signal back to child */
			IbpFRun(ptResume);
			vcmdDef = cmdNil;
			continue;
		case 'D':
			ClearAll();
			vcmdDef = cmdNil;
			break;
		case 'd':
			adr = adrNil;
			if (!fHaveValue)
				adr = AdrFIfdLn(vifd, viln);
			else if (valShort > 0
			    AND valShort < vibpMac) /* make sure it is range */
				adr = vrgBp[valShort].adr;
			if ((adr == adrNil)
			    OR (!FClearBp(adr)) ) {
				printf("No such breakpoint\n");
				ListBp();
				break;
			} /* if */
			vcmdDef = cmdNil;
			break;
		case 'e':
			adr = AdrFIfdLn(vifd, viln);
			tk = TkPeek();
			if (tk == tkNil) {
				PrintPos(adr, fmtFile+fmtProc+fmtLn+fmtEol);
			} 
			else {
				fDidit = false;
				EatFilename(sbName, &vsbCmd);
				if (strchr(sbName, '.') == NULL) {
					if ((ipd = IpdFName(sbName)) != ipdNil) {
						OpenIpd(ipd, true);
						PrintPos(adrNil,fmtFile+fmtProc+fmtLn+fmtPrint);
						fDidit = true;
					} /* if */
				} /* if */
				if (!fDidit) {
					strcpy(vsbFileTemp, sbName);
					if ((ifd = IfdFName(vsbFileTemp)) == vifdNil)
						ifd = vifdTemp;
					ifd = IfdFOpen(ifd);
					if (ifd != vifdNil) {
						PrintPos(adrNil, fmtFile+fmtLn+fmtPrint);
						fDidit = true;
					} /* if */
				} /* if */
				if (!fDidit)
					UError("No such procedure or file name: %s",sbName);
			} /* if */
			vcmdDef = cmdPrint;
			break;
		case 'E':
			cnt = (fHaveValue) ? valShort : 0;
			OpenStack(cnt);
			vcmdDef = cmdPrint;
			break;
		case 'F':	/* find and fix bug */
			FindAndFix();
			break;
		case 'f':	/* set address display format */
			tk = TkNext();
			if (tk == tkStrConstant) {
				strncpy(vsbFmt, vsbTok, 20); /* snarf */
				vsbFmt[19] = chNull;	/* just to be safe */
			} 
			else if (tk == tkSemi) {
				vsbFmt[0] = chNull;
			} 
			else {
				UError("Bad argument to the 'f' command");
			} /* if */
			vcmdDef = cmdNil;
			break;
		case 'g':	/* 'goto' command (I'm SORRY!!!!!!!!) */
			adr = GetExpr(&ty, tkNil);
			if (ty == tyNil) {
				UError("I need a linenumber");
			} /* if */
			GotoLn(adr);
			break;
		case 'i':	/* conditional command */
			fDoit = GetExpr(&ty, tkNil);
			if (ty == tyNil)
				fDoit = false;
			tk = vtk;	/* look ahead by expression parser */
			if (tk != tkLCB)
				UError("Missing {");
			if (!fDoit) {
				vsbCmd = SbFEob(vsbCmd); /* eat the first block */
				tk = TkNext();
				if (tk != tkLCB)
					continue;	/* we ate first part of next command */
			} /* if */
			break;
		case '{':	/* beginning of block, eat block */
			vsbCmd = SbFEob(vsbCmd);  /* returns ptr to matching }+1 */
			break;
		case '}':	/* end of block */
			break;	/* we just throw it away */
		case 'I':	/* information about cdb's state */
			ShowState();
			vcmdDef = cmdNil;
			break;
		case 'k':
			if (vpid == pidNil)
				UError("No process to kill");
			if (!YesNo("Really kill child? "))
				break;	/* their finger slipped or something */
			KillChild();
			printf("process killed\n");
			vcmdDef = cmdNil;
			break;
		case 'l':
			ListSomething();
			break;
		case 'L':
			PrintPos(vpc, fmtFile+fmtProc+fmtLn+fmtPrint);
			/* which puts us at the break */
			vcmdDef = cmdPrint;
			break;
		case 'M':	/* print|set map values */
			DoMap();
			vcmdDef = cmdNil;
			break;
		case 'p':
			if (fHaveValue) {
				i = valShort;
				if (i < 0)
					viln += i;
				else viln = i;
				vslop = 0;
			} /* if */
			cnt = GetExpr(&ty, tkNil);
			if ((ty == tyNil) OR (cnt <= 0))
				cnt = 1;
			PrintLine(viln, cnt, true);
			vcmdDef = cmdPrint;
			continue;
		case 'q':
			if (!YesNo("Really quit? "))
				break;	/* their finger slipped or something */
			exit(0);
			/* NOTREACHED */
			break;
		case 'Q':	/* quiet command, just eat it */
			break;
		case 'r':
		case 'R':
			ibp = IbpFNewChild((chCmd == 'R') ? sbNil : vsbCmd);
			if (ibp == ibpNil)
				/* just fire it up */
				ibp = IbpFRun(ptResume);
			vcmdDef = cmdNil;
			break;
		case 'S':
		case 's':
			i = (fHaveValue) ? valShort : 1;
			vcmdDef = (chCmd=='s') ? cmdLineSingle : cmdProcSingle;
			while (i--)
				if (ibpNil != IbpFSingle(chCmd=='S', false))
					break;
			break;
		case 'T':
		case 't':
			i = (fHaveValue) ? valShort : 20; /* default to 20 deep */
			StackTrace(i, (chCmd=='T')); /* do locals, too, on T */
			vcmdDef = cmdNil;
			break;
		case 'W':
			cnt = 21;
		case 'w':
			viln = (fHaveValue) ? valShort : viln;
			vslop = 0;
			ilnSave = viln;
			if (cnt == 1)
				cnt = 11;	/* i.e. - we didn't come through W */
			i = GetExpr(&ty, tkNil);
			if ((ty != tyNil) AND (i >= 1))
				cnt = i;
			ln = Max(viln-cnt/2, 0);
			cLn = Min(cnt/2, viln-ln);
			PrintLine(ln, cLn, true);
			printf(">");	/* shows them which line they are on */
			viln++;
			cLn = Min(cnt-cLn, vrgFd[vifd].ilnMac-viln+1);
			PrintLine(viln, cLn, true);
			viln = ilnSave;
			vcmdDef = cmdPrint;
			continue;
		case 'x':	/* clear command line and exit current level */
			if ((!fHaveValue) OR (valShort == 0))
				vsbCmd = PopCmd();
			return(true);
		case 'z':
			sig = (fHaveValue) ? valShort : vsig;
			TkNext();
			if (sig == SIGTRAP)
				printf(
				"WARNING: You are modifying the breakpoint signal!\n");
			SaMaintain(sig, vsbTok);
			break;
		case 'Z':
			vcaseMod = (vcaseMod) ? 0 : 040;
			printf("Searches will %sbe case sensitive\n",
			(vcaseMod!=0) ? "NOT " : "");
			vcmdDef = cmdNil;
			break;
		} /* switch */
	} 
	while ((tk = TkNext()) != tkNil);

	return(fTop);
} /* FDoCommand */

unix.superglobalmegacorp.com

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