|
|
1.1 ! root 1: static char sccsid[] = "@(#)cmd.c 2.8"; ! 2: ! 3: #include <ctype.h> ! 4: #include <stdio.h> ! 5: #include "cdb.h" ! 6: #include <signal.h> ! 7: ! 8: static char vsbTarget[100]; /* used for string searches */ ! 9: static char vchSearch = '/'; /* contains either ? or / */ ! 10: ! 11: export CMDE vcmdDef; ! 12: export char *vsbCmd, *vsbCmdOld; ! 13: export long vdot; ! 14: export TYR vtyDot[cTyMax]; ! 15: export int viln, vslop; /* line number & offset from true line number */ ! 16: export char vsbFileTemp[80]; /* name of vifdTemp file */ ! 17: ! 18: ! 19: /* C A L L S H E L L */ ! 20: ! 21: local void CallShell(sbCmd) ! 22: char *sbCmd; ! 23: { ! 24: char stShell[20]; ! 25: ! 26: if ((sbCmd == sbNil) OR (*sbCmd == chNull)) { ! 27: sprintf(stShell, "%s -i", getenv("SHELL")); ! 28: sbCmd = stShell; ! 29: } /* if */ ! 30: system(sbCmd); ! 31: printf("\nback in cdb, debugging %s\n", vsbSymfile); ! 32: } /* CallShell */ ! 33: ! 34: ! 35: /* E A T C M D L I S T */ ! 36: ! 37: export char * EatCmdList() ! 38: { ! 39: char *sbCmd, *sbTemp; ! 40: TKE tk; ! 41: ! 42: sbCmd = vsbCmd; ! 43: tk = TkPeek(); ! 44: if (tk == tkNil) ! 45: return(sbNil); ! 46: ! 47: if (tk != tkLCB) { ! 48: vsbCmd = sbNil; /* give caller the rest of line */ ! 49: } ! 50: else { ! 51: tk = TkNext(); /* eat { */ ! 52: sbCmd = vsbCmd; ! 53: sbTemp = SbFEob(vsbCmd) - 1; ! 54: if (*sbTemp == '}') ! 55: *sbTemp = chNull; ! 56: vsbCmd = sbTemp + 1; ! 57: } /* if */ ! 58: while (*sbCmd == ' ') ! 59: sbCmd++; ! 60: return(sbCmd); ! 61: } /* EatCmdList */ ! 62: ! 63: ! 64: /* E A T F I L E N A M E */ ! 65: ! 66: local void EatFilename(sbName, psbIn) ! 67: char *sbName, **psbIn; ! 68: { ! 69: int cch; ! 70: char *sbIn; ! 71: ! 72: sbIn = *psbIn; ! 73: while (*sbIn == '\t' OR *sbIn == ' ') ! 74: sbIn++; ! 75: cch = strcspn(sbIn, "\t ;}"); ! 76: strncpy(sbName, sbIn, cch); ! 77: sbName[cch] = chNull; ! 78: *psbIn = sbIn + cch; ! 79: } /* EatFilename */ ! 80: ! 81: ! 82: /* S B F E O B */ ! 83: ! 84: export char *SbFEob(sb) ! 85: char *sb; ! 86: { ! 87: int cNest; ! 88: ! 89: /* return pointer to AFTER '}', or to the chNull */ ! 90: cNest = (*sb == '{') ? 0 : 1; ! 91: while (*sb) { ! 92: if (*sb == '{') ! 93: cNest++; ! 94: else if (*sb == '}') ! 95: if (--cNest == 0) ! 96: return(sb+1); ! 97: sb++; ! 98: } /* while */ ! 99: return(sb); ! 100: } /* SbFEob */ ! 101: ! 102: ! 103: /* F D O C O M M A N D */ ! 104: ! 105: export FLAGT FDoCommand(sbCmdIn, fTop) ! 106: char *sbCmdIn; ! 107: FLAGT fTop; ! 108: { ! 109: int valShort, ln, cLn, cnt, ifd, ipd; ! 110: int sig, ibp, i, ilnSave; ! 111: FLAGT fHaveValue, fDidit, fDoit, fCommand; ! 112: char ch, chBp, chCmd, chNext; ! 113: char *sbBp, *sbTemp, *sbCmds, *sbTwoChars; ! 114: char sbName[80]; ! 115: long valExp, adrLong; ! 116: ADRT adr; ! 117: TKE tk, tkRet; ! 118: ASE as; ! 119: pTYR ty; ! 120: TYR rgTy[cTyMax]; ! 121: ! 122: /* the commands */ ! 123: sbCmds = "\n<>-+?/^!~;{}AabBcCdDeEfFgiIklLMpqQrRsStTwWxzZ"; ! 124: sbTwoChars = "<bi"; /* commands of two or more characters */ ! 125: if (!fTop) ! 126: PushCmd(vsbCmd); ! 127: vsbCmd = vsbCmdOld = sbCmdIn; ! 128: ! 129: tk = TkNext(); ! 130: do { ! 131: if ((tk == tkStr) AND (FSbCmp("help", vsbTok))) { ! 132: Help(); ! 133: vcmdDef = cmdNil; ! 134: return(fTop); ! 135: } ! 136: else if (tk == tkStrConstant) { ! 137: printf("%s", vsbTok); ! 138: vcmdDef = cmdNil; ! 139: tk = TkNext(); ! 140: continue; ! 141: } /* if */ ! 142: ! 143: /* we guess whether to parse an expression */ ! 144: /* this is a little weird because we try to do the `right' thing */ ! 145: adrLong = 0; ! 146: chCmd = vsbTok[0]; ! 147: fHaveValue = false; ! 148: fCommand = (tk == tkNil); ! 149: if (strchr(sbCmds, chCmd) != NULL) { ! 150: /* the first letter LOOKS like a command, keep going */ ! 151: fCommand = (vcbTok == 1); ! 152: if ((vcbTok > 1) AND (tk == tkStr)) { ! 153: /* it is longer than 1 character, might be a variable name */ ! 154: chNext = vsbTok[1]; ! 155: if ( (vcbTok == 2) ! 156: AND (strchr(sbTwoChars, chCmd) != NULL) ) { ! 157: fCommand = (chCmd == 'b' AND strchr("abBtTuUxX", chNext)) ! 158: OR (chCmd == 'i' AND chNext == 'f') ! 159: OR (chCmd == '<' AND chNext == '<'); ! 160: } /* if */ ! 161: } /* if */ ! 162: /* a final chance to change our minds */ ! 163: TkPeek(); /* load peek token information */ ! 164: if ( (tk == tkStr) ! 165: AND (*vsbCmd != ' ') ! 166: AND (vsbTokPeek[0] != chNull) ! 167: AND !(strchr(";}", vsbTokPeek[0])) ) { ! 168: fCommand = false; ! 169: } /* if */ ! 170: } /* if */ ! 171: ! 172: if (!fCommand) { ! 173: /* assume it is a beginning expression */ ! 174: vipd = IpdFAdr(AdrFIfdLn(vifd, viln)); /* force things right */ ! 175: if ((tkRet = TkFExpr(&adrLong, rgTy)) != tkNil) { ! 176: valExp = ValFAdr(adrLong, rgTy); /* many cmds just want value */ ! 177: valShort = valExp; ! 178: fHaveValue = true; ! 179: } ! 180: else { ! 181: if (PrecFTk(tkRet)) ! 182: tk = TkNext(); ! 183: UError("Unknown variable - %s", vsbTok); ! 184: } /* if */ ! 185: } /* if */ ! 186: ! 187: cnt = 1; ! 188: chCmd = vsbTok[0]; ! 189: switch (chCmd) { ! 190: default: ! 191: vcmdDef = cmdNil; ! 192: UError("Unknown command `%c' (%#o)\n", chCmd, chCmd); ! 193: case '\n': ! 194: case '~': ! 195: case chNull: /* default command */ ! 196: if (!fHaveValue) { ! 197: switch (vcmdDef) { ! 198: case cmdPrint: ! 199: viln++; ! 200: PrintLine(viln, 1, true); ! 201: break; ! 202: case cmdUpArrow: ! 203: case cmdDisplay: ! 204: i = IncFTyMode(vtyDot, vmode); ! 205: vdot += (vcmdDef == cmdUpArrow) ? -i : i; ! 206: DispVal(vdot, vtyDot, vmode, true, true, true); ! 207: printf("\n"); ! 208: break; ! 209: case cmdLineSingle: ! 210: printf("s: "); ! 211: IbpFSingle(false, false); ! 212: break; ! 213: case cmdProcSingle: ! 214: printf("S: "); ! 215: IbpFSingle(true, false); ! 216: break; ! 217: } /* switch */ ! 218: } ! 219: else if (tkRet == tkNumber) { ! 220: i = valShort; ! 221: if (i > 0) ! 222: viln = i; ! 223: else viln += i; ! 224: vslop = 0; ! 225: PrintLine(viln, 1, true); ! 226: vcmdDef = cmdPrint; ! 227: } ! 228: else if (tkRet == tkAdr) { ! 229: vdot = adrLong; ! 230: CopyTy(vtyDot, rgTy); ! 231: DispVal(vdot, vtyDot, modeNil, true, true, true); ! 232: printf("\n"); ! 233: vcmdDef = cmdDisplay; ! 234: } /* if */ ! 235: break; ! 236: case '+': /* go forward N (1) line and print it */ ! 237: case '-': /* go backward N (1) line and print it */ ! 238: i = GetExpr(&ty, tkNil); ! 239: if (ty == tyNil) ! 240: i = 1; ! 241: viln += (chCmd=='-') ? -abs(i) : abs(i); ! 242: PrintLine(viln, 1, true); ! 243: vcmdDef = cmdPrint; ! 244: continue; ! 245: case '!': ! 246: CallShell(vsbCmd); /* shell escape */ ! 247: vsbCmd = sbNil; ! 248: break; ! 249: case '^': /* attempt to move backward, displaying memory */ ! 250: GetMode(vmode); ! 251: vdot -= IncFTyMode(vtyDot, vmode); ! 252: DispVal(vdot, vtyDot, vmode, true, true, true); ! 253: printf("\n"); ! 254: vcmdDef = cmdUpArrow; ! 255: break; ! 256: case '/': /* 2 commands: 'X/Y' == display *X in format Y ! 257: * '/hi mom' == search FORWARDS and print ! 258: */ ! 259: case '?': /* 2 commands: 'X?Y' == display X in format Y ! 260: * '?hi mom' == search BACKWARDS and print ! 261: */ ! 262: if (!fHaveValue) { ! 263: /* search for something */ ! 264: if (*vsbCmd != chNull) { ! 265: strcpy(vsbTarget, vsbCmd); ! 266: *vsbCmd = chNull; ! 267: } /* if */ ! 268: vchSearch = chCmd; ! 269: Find(vsbTarget, (chCmd=='?')); ! 270: vcmdDef = cmdPrint; ! 271: } ! 272: else { ! 273: vdot = adrLong; ! 274: CopyTy(vtyDot, rgTy); ! 275: GetMode(vmode); ! 276: if (chCmd == '/') { ! 277: /* this prints the CONTENTS of an address */ ! 278: DispVal(vdot, vtyDot, vmode, true, true, true); ! 279: vcmdDef = cmdDisplay; ! 280: } ! 281: else { ! 282: /* this prints an ADDRESS */ ! 283: vmode->cnt = 1; ! 284: DispVal(vdot, vtyDot, vmode, true, false, false); ! 285: vcmdDef = cmdNil; ! 286: } /* if */ ! 287: printf("\n"); ! 288: } /* if */ ! 289: break; ! 290: case '<': /* playback commands */ ! 291: EatFilename(sbName, &vsbCmd); ! 292: SetPlayback(sbName, (vsbTok[1] == '<')); ! 293: break; ! 294: case '>': /* record commands */ ! 295: TkPeek(); ! 296: if (vsbTokPeek[1] == chNull) { ! 297: if ( (vsbTokPeek[0] == 't') ! 298: OR (vsbTokPeek[0] == 'f')) { ! 299: TkNext(); /* actually eat next token */ ! 300: StateRecord(vsbTok[0] == 't'); ! 301: break; ! 302: } ! 303: else if (vsbTokPeek[0] == 'c') { ! 304: TkNext(); /* actually eat next token */ ! 305: SetRecord(sbNil); ! 306: break; ! 307: } /* if */ ! 308: /* we fall through on other, 1 character filenames */ ! 309: } /* if */ ! 310: EatFilename(sbName, &vsbCmd); ! 311: SetRecord(sbName); ! 312: break; ! 313: case ';': /* just a command delimiter */ ! 314: vcmdDef = cmdNil; ! 315: break; ! 316: case 'A': /* toggle main assertion state */ ! 317: if (viadMac > 0) ! 318: vas = (vas==asSuspended) ? asActive : asSuspended; ! 319: printf("Assertions are %s\n", (vas==asSuspended) ? ! 320: "SUSPENDED" : "ACTIVE"); ! 321: vcmdDef = cmdNil; ! 322: break; ! 323: case 'a': /* maintain assertion list */ ! 324: if (fHaveValue) { ! 325: TkNext(); ! 326: switch (vsbTok[0]) { ! 327: case 'a': ! 328: as = asActive; ! 329: break; ! 330: case 'd': ! 331: as = asNil; ! 332: break; ! 333: case 's': ! 334: as = asSuspended; ! 335: break; ! 336: default: ! 337: UError("Invalid assertion maintenance command"); ! 338: } /* switch */ ! 339: ModAssert(valShort, as); ! 340: break; ! 341: } /* if */ ! 342: if ((sbTemp=EatCmdList()) != sbNil) ! 343: AddAssert(sbTemp); ! 344: break; ! 345: case 'B': /* list all breakpoints */ ! 346: ListBp(); ! 347: break; ! 348: case 'b': /* set (set again) a break point */ ! 349: vipd = IpdFAdr(AdrFIfdLn(vifd, viln)); ! 350: chBp = vsbTok[1]; ! 351: sbBp = EatCmdList(); ! 352: ibp = ibpNil; ! 353: if (chBp == 'a') { ! 354: if (!fHaveValue) ! 355: UError("correct form is `address ba [<cmds>]'"); ! 356: else ! 357: adr = valShort; ! 358: ibp = IbpFAdr(adr, 1, sbBp); ! 359: } ! 360: else if (chBp == chNull) { ! 361: /* vanilla breakpoint */ ! 362: i = (fHaveValue) ? valShort : viln; ! 363: adr = AdrFIfdLn(vifd, i); ! 364: ibp = IbpFAdr(adr, 1, sbBp); ! 365: } ! 366: else { ! 367: ch = (isupper(chBp)) ? tolower(chBp) : chBp; ! 368: i = (fHaveValue) ? valShort : (ch=='u') ? 1 : -1; ! 369: ibp = IbpFSet(chBp, i, sbBp); ! 370: } /* if */ ! 371: if (ibp != ibpNil) { ! 372: PrintPos(vrgBp[ibp].adr, fmtProc+fmtLn+fmtSave); ! 373: printf(":b \n"); ! 374: } /* if */ ! 375: vcmdDef = cmdNil; ! 376: break; ! 377: case 'C': ! 378: case 'c': ! 379: vipd = IpdFAdr(AdrFIfdLn(vifd, viln)); ! 380: if (fHaveValue) { ! 381: /* we have a continuance count */ ! 382: i = valShort; ! 383: if (vibp != ibpNil) ! 384: vrgBp[vibp].count = i; ! 385: } /* if */ ! 386: i = GetExpr(&ty, tkNil); ! 387: if (ty != tyNil) { ! 388: adr = AdrFIfdLn(vifd, i); ! 389: ibp = IbpFAdr(adr, -1, ""); ! 390: } /* if */ ! 391: if (chCmd == 'c') ! 392: vsig = 0; /* do not pass signal back to child */ ! 393: IbpFRun(ptResume); ! 394: vcmdDef = cmdNil; ! 395: continue; ! 396: case 'D': ! 397: ClearAll(); ! 398: vcmdDef = cmdNil; ! 399: break; ! 400: case 'd': ! 401: adr = adrNil; ! 402: if (!fHaveValue) ! 403: adr = AdrFIfdLn(vifd, viln); ! 404: else if (valShort > 0 ! 405: AND valShort < vibpMac) /* make sure it is range */ ! 406: adr = vrgBp[valShort].adr; ! 407: if ((adr == adrNil) ! 408: OR (!FClearBp(adr)) ) { ! 409: printf("No such breakpoint\n"); ! 410: ListBp(); ! 411: break; ! 412: } /* if */ ! 413: vcmdDef = cmdNil; ! 414: break; ! 415: case 'e': ! 416: adr = AdrFIfdLn(vifd, viln); ! 417: tk = TkPeek(); ! 418: if (tk == tkNil) { ! 419: PrintPos(adr, fmtFile+fmtProc+fmtLn+fmtEol); ! 420: } ! 421: else { ! 422: fDidit = false; ! 423: EatFilename(sbName, &vsbCmd); ! 424: if (strchr(sbName, '.') == NULL) { ! 425: if ((ipd = IpdFName(sbName)) != ipdNil) { ! 426: OpenIpd(ipd, true); ! 427: PrintPos(adrNil,fmtFile+fmtProc+fmtLn+fmtPrint); ! 428: fDidit = true; ! 429: } /* if */ ! 430: } /* if */ ! 431: if (!fDidit) { ! 432: strcpy(vsbFileTemp, sbName); ! 433: if ((ifd = IfdFName(vsbFileTemp)) == vifdNil) ! 434: ifd = vifdTemp; ! 435: ifd = IfdFOpen(ifd); ! 436: if (ifd != vifdNil) { ! 437: PrintPos(adrNil, fmtFile+fmtLn+fmtPrint); ! 438: fDidit = true; ! 439: } /* if */ ! 440: } /* if */ ! 441: if (!fDidit) ! 442: UError("No such procedure or file name: %s",sbName); ! 443: } /* if */ ! 444: vcmdDef = cmdPrint; ! 445: break; ! 446: case 'E': ! 447: cnt = (fHaveValue) ? valShort : 0; ! 448: OpenStack(cnt); ! 449: vcmdDef = cmdPrint; ! 450: break; ! 451: case 'F': /* find and fix bug */ ! 452: FindAndFix(); ! 453: break; ! 454: case 'f': /* set address display format */ ! 455: tk = TkNext(); ! 456: if (tk == tkStrConstant) { ! 457: strncpy(vsbFmt, vsbTok, 20); /* snarf */ ! 458: vsbFmt[19] = chNull; /* just to be safe */ ! 459: } ! 460: else if (tk == tkSemi) { ! 461: vsbFmt[0] = chNull; ! 462: } ! 463: else { ! 464: UError("Bad argument to the 'f' command"); ! 465: } /* if */ ! 466: vcmdDef = cmdNil; ! 467: break; ! 468: case 'g': /* 'goto' command (I'm SORRY!!!!!!!!) */ ! 469: adr = GetExpr(&ty, tkNil); ! 470: if (ty == tyNil) { ! 471: UError("I need a linenumber"); ! 472: } /* if */ ! 473: GotoLn(adr); ! 474: break; ! 475: case 'i': /* conditional command */ ! 476: fDoit = GetExpr(&ty, tkNil); ! 477: if (ty == tyNil) ! 478: fDoit = false; ! 479: tk = vtk; /* look ahead by expression parser */ ! 480: if (tk != tkLCB) ! 481: UError("Missing {"); ! 482: if (!fDoit) { ! 483: vsbCmd = SbFEob(vsbCmd); /* eat the first block */ ! 484: tk = TkNext(); ! 485: if (tk != tkLCB) ! 486: continue; /* we ate first part of next command */ ! 487: } /* if */ ! 488: break; ! 489: case '{': /* beginning of block, eat block */ ! 490: vsbCmd = SbFEob(vsbCmd); /* returns ptr to matching }+1 */ ! 491: break; ! 492: case '}': /* end of block */ ! 493: break; /* we just throw it away */ ! 494: case 'I': /* information about cdb's state */ ! 495: ShowState(); ! 496: vcmdDef = cmdNil; ! 497: break; ! 498: case 'k': ! 499: if (vpid == pidNil) ! 500: UError("No process to kill"); ! 501: if (!YesNo("Really kill child? ")) ! 502: break; /* their finger slipped or something */ ! 503: KillChild(); ! 504: printf("process killed\n"); ! 505: vcmdDef = cmdNil; ! 506: break; ! 507: case 'l': ! 508: ListSomething(); ! 509: break; ! 510: case 'L': ! 511: PrintPos(vpc, fmtFile+fmtProc+fmtLn+fmtPrint); ! 512: /* which puts us at the break */ ! 513: vcmdDef = cmdPrint; ! 514: break; ! 515: case 'M': /* print|set map values */ ! 516: DoMap(); ! 517: vcmdDef = cmdNil; ! 518: break; ! 519: case 'p': ! 520: if (fHaveValue) { ! 521: i = valShort; ! 522: if (i < 0) ! 523: viln += i; ! 524: else viln = i; ! 525: vslop = 0; ! 526: } /* if */ ! 527: cnt = GetExpr(&ty, tkNil); ! 528: if ((ty == tyNil) OR (cnt <= 0)) ! 529: cnt = 1; ! 530: PrintLine(viln, cnt, true); ! 531: vcmdDef = cmdPrint; ! 532: continue; ! 533: case 'q': ! 534: if (!YesNo("Really quit? ")) ! 535: break; /* their finger slipped or something */ ! 536: exit(0); ! 537: /* NOTREACHED */ ! 538: break; ! 539: case 'Q': /* quiet command, just eat it */ ! 540: break; ! 541: case 'r': ! 542: case 'R': ! 543: ibp = IbpFNewChild((chCmd == 'R') ? sbNil : vsbCmd); ! 544: if (ibp == ibpNil) ! 545: /* just fire it up */ ! 546: ibp = IbpFRun(ptResume); ! 547: vcmdDef = cmdNil; ! 548: break; ! 549: case 'S': ! 550: case 's': ! 551: i = (fHaveValue) ? valShort : 1; ! 552: vcmdDef = (chCmd=='s') ? cmdLineSingle : cmdProcSingle; ! 553: while (i--) ! 554: if (ibpNil != IbpFSingle(chCmd=='S', false)) ! 555: break; ! 556: break; ! 557: case 'T': ! 558: case 't': ! 559: i = (fHaveValue) ? valShort : 20; /* default to 20 deep */ ! 560: StackTrace(i, (chCmd=='T')); /* do locals, too, on T */ ! 561: vcmdDef = cmdNil; ! 562: break; ! 563: case 'W': ! 564: cnt = 21; ! 565: case 'w': ! 566: viln = (fHaveValue) ? valShort : viln; ! 567: vslop = 0; ! 568: ilnSave = viln; ! 569: if (cnt == 1) ! 570: cnt = 11; /* i.e. - we didn't come through W */ ! 571: i = GetExpr(&ty, tkNil); ! 572: if ((ty != tyNil) AND (i >= 1)) ! 573: cnt = i; ! 574: ln = Max(viln-cnt/2, 0); ! 575: cLn = Min(cnt/2, viln-ln); ! 576: PrintLine(ln, cLn, true); ! 577: printf(">"); /* shows them which line they are on */ ! 578: viln++; ! 579: cLn = Min(cnt-cLn, vrgFd[vifd].ilnMac-viln+1); ! 580: PrintLine(viln, cLn, true); ! 581: viln = ilnSave; ! 582: vcmdDef = cmdPrint; ! 583: continue; ! 584: case 'x': /* clear command line and exit current level */ ! 585: if ((!fHaveValue) OR (valShort == 0)) ! 586: vsbCmd = PopCmd(); ! 587: return(true); ! 588: case 'z': ! 589: sig = (fHaveValue) ? valShort : vsig; ! 590: TkNext(); ! 591: if (sig == SIGTRAP) ! 592: printf( ! 593: "WARNING: You are modifying the breakpoint signal!\n"); ! 594: SaMaintain(sig, vsbTok); ! 595: break; ! 596: case 'Z': ! 597: vcaseMod = (vcaseMod) ? 0 : 040; ! 598: printf("Searches will %sbe case sensitive\n", ! 599: (vcaseMod!=0) ? "NOT " : ""); ! 600: vcmdDef = cmdNil; ! 601: break; ! 602: } /* switch */ ! 603: } ! 604: while ((tk = TkNext()) != tkNil); ! 605: ! 606: return(fTop); ! 607: } /* FDoCommand */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.