148069Sbostic /*-
2*62161Sbostic * Copyright (c) 1980, 1993
3*62161Sbostic * The Regents of the University of California. All rights reserved.
448069Sbostic *
548069Sbostic * %sccs.include.redist.c%
622560Sdist */
75544Slinton
822560Sdist #ifndef lint
9*62161Sbostic static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 06/06/93";
1048069Sbostic #endif /* not lint */
115544Slinton
125544Slinton /*
135544Slinton * Miscellaneous commands "edit" and "help".
145544Slinton * Also, output redirection routine "setout" and "unsetout".
155544Slinton */
165544Slinton
175544Slinton #include "defs.h"
185544Slinton #include "tree.h"
195544Slinton #include "command.h"
205544Slinton #include "object.h"
215544Slinton #include "mappings.h"
225544Slinton #include "sym.h"
235544Slinton #include "symtab.h"
245544Slinton
255544Slinton extern char *getenv();
265544Slinton
275544Slinton #define DEF_EDITOR "vi"
285544Slinton
295544Slinton /*
305544Slinton * Invoke an editor on the given file. Which editor to use might change
315544Slinton * installation to installation. For now, we use "vi". In any event,
325544Slinton * the environment variable "EDITOR" overrides any default.
335544Slinton */
345544Slinton
edit(filename)355544Slinton edit(filename)
365544Slinton char *filename;
375544Slinton {
385544Slinton char *ed;
395544Slinton FILE *fp;
405544Slinton SYM *s;
415544Slinton ADDRESS addr;
425544Slinton char buff[10];
435544Slinton
445544Slinton if ((ed = getenv("EDITOR")) == NIL) {
455544Slinton ed = DEF_EDITOR;
465544Slinton }
475544Slinton fp = fopen(filename, "r");
485544Slinton if (fp == NIL) {
495544Slinton s = st_lookup(symtab, filename);
505544Slinton if (s == NIL) {
515544Slinton error("can't read \"%s\"", filename);
525544Slinton }
535544Slinton s = which(s);
545544Slinton if (!isblock(s)) {
555544Slinton error("can't read \"%s\"", filename);
565544Slinton }
575544Slinton addr = firstline(s);
585544Slinton filename = srcfilename(addr);
595544Slinton sprintf(buff, "+%d", srcline(addr));
605544Slinton call(ed, stdin, stdout, buff, filename, NIL);
615544Slinton } else {
625544Slinton fclose(fp);
635544Slinton call(ed, stdin, stdout, filename, NIL);
645544Slinton }
655544Slinton }
665544Slinton
675544Slinton /*
685565Slinton * Send some nasty mail to the current pdx support person.
695565Slinton */
705565Slinton
gripe()715565Slinton gripe()
725565Slinton {
7330852Smckusick char *maintainer = "4bsd-bugs@Berkeley.EDU";
745565Slinton
755565Slinton puts("Type control-D to end your message. Be sure to include");
765565Slinton puts("your name and the name of the file you are debugging.");
775565Slinton putchar('\n');
785565Slinton call("Mail", stdin, stdout, maintainer, NIL);
795565Slinton puts("Thank you.");
805565Slinton }
815565Slinton
825565Slinton /*
835544Slinton * Give the user some help.
845544Slinton */
855544Slinton
help()865544Slinton help()
875544Slinton {
885544Slinton puts("pdx command subset summary:");
895544Slinton putchar('\n');
905544Slinton puts("run - begin execution of the program");
915544Slinton puts("cont - continue execution");
925544Slinton puts("step - single step one line");
935544Slinton puts("next - step to next line (skip over calls)");
945544Slinton puts("trace <line#> - trace execution of the line");
955544Slinton puts("trace <proc> - trace calls to the procedure");
965544Slinton puts("trace <var> - trace changes to the variable");
975544Slinton puts("trace <exp> at <line#> - print <exp> when <line> is reached");
985544Slinton puts("stop at <line> - suspend execution at the line");
995544Slinton puts("stop in <proc> - suspend execution when <proc> is called");
1005544Slinton puts("status - print trace/stop's in effect");
1015544Slinton puts("delete <number> - remove trace or stop of given number");
1025544Slinton puts("call <proc> - call the procedure");
1035544Slinton puts("where - print currently active procedures");
1045544Slinton puts("print <exp> - print the value of the expression");
1055544Slinton puts("whatis <name> - print the declaration of the name");
1065591Slinton puts("list <line>, <line> - list source lines");
1075591Slinton puts("edit <proc> - edit file containing <proc>");
1085565Slinton puts("gripe - send mail to the person in charge of pdx");
1095544Slinton puts("quit - exit pdx");
1105544Slinton }
1115544Slinton
1125544Slinton /*
1135544Slinton * Divert output to the given file name.
1145544Slinton * Cannot redirect to an existing file.
1155544Slinton */
1165544Slinton
1175544Slinton LOCAL int so_fd;
1185544Slinton LOCAL BOOLEAN notstdout;
1195544Slinton
setout(filename)1205544Slinton setout(filename)
1215544Slinton char *filename;
1225544Slinton {
1235544Slinton FILE *fp;
1245544Slinton
1255544Slinton if ((fp = fopen(filename, "r")) != NIL) {
1265544Slinton fclose(fp);
1275544Slinton error("%s: file already exists", filename);
1285544Slinton } else {
1295544Slinton so_fd = dup(1);
1305544Slinton close(1);
1315544Slinton if (creat(filename, 0666) == NIL) {
1325544Slinton unsetout();
1335544Slinton error("can't create %s", filename);
1345544Slinton }
1355544Slinton notstdout = TRUE;
1365544Slinton }
1375544Slinton }
1385544Slinton
1395544Slinton /*
1405544Slinton * Revert output to standard output.
1415544Slinton */
1425544Slinton
unsetout()1435544Slinton unsetout()
1445544Slinton {
1455544Slinton fflush(stdout);
1465544Slinton close(1);
1475544Slinton if (dup(so_fd) != 1) {
1485544Slinton panic("standard out dup failed");
1495544Slinton }
1505544Slinton close(so_fd);
1515544Slinton notstdout = FALSE;
1525544Slinton }
1535544Slinton
isredirected()1545544Slinton BOOLEAN isredirected()
1555544Slinton {
1565544Slinton return(notstdout);
1575544Slinton }
158