15544Slinton /* Copyright (c) 1982 Regents of the University of California */ 25544Slinton 3*5565Slinton static char sccsid[] = "@(#)misc.c 1.2 01/19/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 /* 61*5565Slinton * Send some nasty mail to the current pdx support person. 62*5565Slinton */ 63*5565Slinton 64*5565Slinton gripe() 65*5565Slinton { 66*5565Slinton char *maintainer = "csvax:linton"; 67*5565Slinton 68*5565Slinton puts("Type control-D to end your message. Be sure to include"); 69*5565Slinton puts("your name and the name of the file you are debugging."); 70*5565Slinton putchar('\n'); 71*5565Slinton call("Mail", stdin, stdout, maintainer, NIL); 72*5565Slinton puts("Thank you."); 73*5565Slinton } 74*5565Slinton 75*5565Slinton /* 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*5565Slinton puts("gripe - send mail to the person in charge of pdx"); 1005544Slinton puts("quit - exit pdx"); 1015544Slinton } 1025544Slinton 1035544Slinton /* 1045544Slinton * Divert output to the given file name. 1055544Slinton * Cannot redirect to an existing file. 1065544Slinton */ 1075544Slinton 1085544Slinton LOCAL int so_fd; 1095544Slinton LOCAL BOOLEAN notstdout; 1105544Slinton 1115544Slinton setout(filename) 1125544Slinton char *filename; 1135544Slinton { 1145544Slinton FILE *fp; 1155544Slinton 1165544Slinton if ((fp = fopen(filename, "r")) != NIL) { 1175544Slinton fclose(fp); 1185544Slinton error("%s: file already exists", filename); 1195544Slinton } else { 1205544Slinton so_fd = dup(1); 1215544Slinton close(1); 1225544Slinton if (creat(filename, 0666) == NIL) { 1235544Slinton unsetout(); 1245544Slinton error("can't create %s", filename); 1255544Slinton } 1265544Slinton notstdout = TRUE; 1275544Slinton } 1285544Slinton } 1295544Slinton 1305544Slinton /* 1315544Slinton * Revert output to standard output. 1325544Slinton */ 1335544Slinton 1345544Slinton unsetout() 1355544Slinton { 1365544Slinton fflush(stdout); 1375544Slinton close(1); 1385544Slinton if (dup(so_fd) != 1) { 1395544Slinton panic("standard out dup failed"); 1405544Slinton } 1415544Slinton close(so_fd); 1425544Slinton notstdout = FALSE; 1435544Slinton } 1445544Slinton 1455544Slinton BOOLEAN isredirected() 1465544Slinton { 1475544Slinton return(notstdout); 1485544Slinton } 149