15544Slinton /* Copyright (c) 1982 Regents of the University of California */ 25544Slinton 3*5591Slinton static char sccsid[] = "@(#)misc.c 1.3 01/20/82"; 45544Slinton 55544Slinton /* 65544Slinton * Miscellaneous commands "edit" and "help". 75544Slinton * Also, output redirection routine "setout" and "unsetout". 85544Slinton */ 95544Slinton 105544Slinton #include "defs.h" 115544Slinton #include "tree.h" 125544Slinton #include "command.h" 135544Slinton #include "object.h" 145544Slinton #include "mappings.h" 155544Slinton #include "sym.h" 165544Slinton #include "symtab.h" 175544Slinton 185544Slinton extern char *getenv(); 195544Slinton 205544Slinton #define DEF_EDITOR "vi" 215544Slinton 225544Slinton /* 235544Slinton * Invoke an editor on the given file. Which editor to use might change 245544Slinton * installation to installation. For now, we use "vi". In any event, 255544Slinton * the environment variable "EDITOR" overrides any default. 265544Slinton */ 275544Slinton 285544Slinton edit(filename) 295544Slinton char *filename; 305544Slinton { 315544Slinton char *ed; 325544Slinton FILE *fp; 335544Slinton SYM *s; 345544Slinton ADDRESS addr; 355544Slinton char buff[10]; 365544Slinton 375544Slinton if ((ed = getenv("EDITOR")) == NIL) { 385544Slinton ed = DEF_EDITOR; 395544Slinton } 405544Slinton fp = fopen(filename, "r"); 415544Slinton if (fp == NIL) { 425544Slinton s = st_lookup(symtab, filename); 435544Slinton if (s == NIL) { 445544Slinton error("can't read \"%s\"", filename); 455544Slinton } 465544Slinton s = which(s); 475544Slinton if (!isblock(s)) { 485544Slinton error("can't read \"%s\"", filename); 495544Slinton } 505544Slinton addr = firstline(s); 515544Slinton filename = srcfilename(addr); 525544Slinton sprintf(buff, "+%d", srcline(addr)); 535544Slinton call(ed, stdin, stdout, buff, filename, NIL); 545544Slinton } else { 555544Slinton fclose(fp); 565544Slinton call(ed, stdin, stdout, filename, NIL); 575544Slinton } 585544Slinton } 595544Slinton 605544Slinton /* 615565Slinton * Send some nasty mail to the current pdx support person. 625565Slinton */ 635565Slinton 645565Slinton gripe() 655565Slinton { 665565Slinton char *maintainer = "csvax:linton"; 675565Slinton 685565Slinton puts("Type control-D to end your message. Be sure to include"); 695565Slinton puts("your name and the name of the file you are debugging."); 705565Slinton putchar('\n'); 715565Slinton call("Mail", stdin, stdout, maintainer, NIL); 725565Slinton puts("Thank you."); 735565Slinton } 745565Slinton 755565Slinton /* 765544Slinton * Give the user some help. 775544Slinton */ 785544Slinton 795544Slinton help() 805544Slinton { 815544Slinton puts("pdx command subset summary:"); 825544Slinton putchar('\n'); 835544Slinton puts("run - begin execution of the program"); 845544Slinton puts("cont - continue execution"); 855544Slinton puts("step - single step one line"); 865544Slinton puts("next - step to next line (skip over calls)"); 875544Slinton puts("trace <line#> - trace execution of the line"); 885544Slinton puts("trace <proc> - trace calls to the procedure"); 895544Slinton puts("trace <var> - trace changes to the variable"); 905544Slinton puts("trace <exp> at <line#> - print <exp> when <line> is reached"); 915544Slinton puts("stop at <line> - suspend execution at the line"); 925544Slinton puts("stop in <proc> - suspend execution when <proc> is called"); 935544Slinton puts("status - print trace/stop's in effect"); 945544Slinton puts("delete <number> - remove trace or stop of given number"); 955544Slinton puts("call <proc> - call the procedure"); 965544Slinton puts("where - print currently active procedures"); 975544Slinton puts("print <exp> - print the value of the expression"); 985544Slinton puts("whatis <name> - print the declaration of the name"); 99*5591Slinton puts("list <line>, <line> - list source lines"); 100*5591Slinton puts("edit <proc> - edit file containing <proc>"); 1015565Slinton puts("gripe - send mail to the person in charge of pdx"); 1025544Slinton puts("quit - exit pdx"); 1035544Slinton } 1045544Slinton 1055544Slinton /* 1065544Slinton * Divert output to the given file name. 1075544Slinton * Cannot redirect to an existing file. 1085544Slinton */ 1095544Slinton 1105544Slinton LOCAL int so_fd; 1115544Slinton LOCAL BOOLEAN notstdout; 1125544Slinton 1135544Slinton setout(filename) 1145544Slinton char *filename; 1155544Slinton { 1165544Slinton FILE *fp; 1175544Slinton 1185544Slinton if ((fp = fopen(filename, "r")) != NIL) { 1195544Slinton fclose(fp); 1205544Slinton error("%s: file already exists", filename); 1215544Slinton } else { 1225544Slinton so_fd = dup(1); 1235544Slinton close(1); 1245544Slinton if (creat(filename, 0666) == NIL) { 1255544Slinton unsetout(); 1265544Slinton error("can't create %s", filename); 1275544Slinton } 1285544Slinton notstdout = TRUE; 1295544Slinton } 1305544Slinton } 1315544Slinton 1325544Slinton /* 1335544Slinton * Revert output to standard output. 1345544Slinton */ 1355544Slinton 1365544Slinton unsetout() 1375544Slinton { 1385544Slinton fflush(stdout); 1395544Slinton close(1); 1405544Slinton if (dup(so_fd) != 1) { 1415544Slinton panic("standard out dup failed"); 1425544Slinton } 1435544Slinton close(so_fd); 1445544Slinton notstdout = FALSE; 1455544Slinton } 1465544Slinton 1475544Slinton BOOLEAN isredirected() 1485544Slinton { 1495544Slinton return(notstdout); 1505544Slinton } 151