fix structure arguments. don't map OREG to REG for STASG (match fails)
[unix-history] / usr / src / old / dbx / main.c
CommitLineData
00102538
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
11d84b8e 3static char sccsid[] = "@(#)main.c 1.6 %G%";
00102538
ML
4
5/*
6 * Debugger main routine.
7 */
8
9#include "defs.h"
10#include <setjmp.h>
11#include <signal.h>
12#include <errno.h>
13#include "main.h"
1c5b15ac 14#include "symbols.h"
00102538
ML
15#include "scanner.h"
16#include "process.h"
17#include "source.h"
18#include "object.h"
1c5b15ac 19#include "mappings.h"
00102538
ML
20
21#ifndef public
22
23#define isterm(file) (interactive or isatty(fileno(file)))
24
39144fe1
ML
25#include <sgtty.h>
26
27typedef struct sgttyb Ttyinfo;
28
00102538
ML
29#endif
30
31public Boolean coredump; /* true if using a core dump */
32public Boolean runfirst; /* run program immediately */
33public Boolean interactive; /* standard input IS a terminal */
34public Boolean lexdebug; /* trace yylex return values */
35public Boolean tracebpts; /* trace create/delete breakpoints */
36public Boolean traceexec; /* trace process execution */
37public Boolean tracesyms; /* print symbols as their read */
38
39public File corefile; /* File id of core dump */
40
41#define FIRST_TIME 0 /* initial value setjmp returns */
42
43private Boolean initdone = false; /* true if initialization done */
44private jmp_buf env; /* setjmp/longjmp data */
45private char outbuf[BUFSIZ]; /* standard output buffer */
46private char namebuf[512]; /* possible name of object file */
47private int firstarg; /* first program argument (for -r) */
48
39144fe1
ML
49private Ttyinfo ttyinfo;
50
00102538
ML
51private catchintr();
52
53/*
54 * Main program.
55 */
56
57main(argc, argv)
58int argc;
59String argv[];
60{
61 register Integer i;
39144fe1 62 extern String date;
00102538
ML
63
64 cmdname = argv[0];
65 catcherrs();
66 onsyserr(EINTR, nil);
67 setbuf(stdout, outbuf);
39144fe1
ML
68 printf("dbx version of %s.\nType 'help' for help.\n", date);
69 fflush(stdout);
00102538
ML
70 scanargs(argc, argv);
71 language_init();
11d84b8e 72 symbols_init();
00102538
ML
73 process_init();
74 if (runfirst) {
75 if (setjmp(env) == FIRST_TIME) {
76 arginit();
77 for (i = firstarg; i < argc; i++) {
78 newarg(argv[i]);
79 }
80 run();
81 /* NOTREACHED */
82 } else {
83 runfirst = false;
84 }
85 } else {
86 init();
87 }
88 setjmp(env);
39144fe1 89 restoretty(stdout, &ttyinfo);
00102538
ML
90 signal(SIGINT, catchintr);
91 yyparse();
92 putchar('\n');
93 quit(0);
94}
95
96/*
97 * Initialize the world, including setting initial input file
98 * if the file exists.
99 */
100
101public init()
102{
103 File f;
104 String home;
105 char buf[100];
106 extern String getenv();
107
39144fe1 108 savetty(stdout, &ttyinfo);
00102538
ML
109 enterkeywords();
110 scanner_init();
111 if (not coredump and not runfirst) {
112 start(nil, nil, nil);
113 }
39144fe1
ML
114 printf("reading symbolic information ...");
115 fflush(stdout);
00102538 116 readobj(objname);
39144fe1
ML
117 printf("\n");
118 fflush(stdout);
1c5b15ac
ML
119 if (coredump) {
120 curfunc = whatblock(pc);
121 } else {
122 curfunc = program;
123 }
00102538
ML
124 bpinit();
125 f = fopen(initfile, "r");
126 if (f != nil) {
127 fclose(f);
128 setinput(initfile);
129 } else {
130 home = getenv("HOME");
131 if (home != nil) {
132 sprintf(buf, "%s/%s", home, initfile);
133 f = fopen(buf, "r");
134 if (f != nil) {
135 fclose(f);
136 setinput(strdup(buf));
137 }
138 }
139 }
140 initdone = true;
141}
142
143/*
144 * Re-initialize the world, first de-allocating all storage.
145 * This is necessary when the symbol information must be re-read
146 * from the object file when it has changed.
147 *
148 * Before "forgetting" things, we save the current tracing/breakpoint
149 * information to a temp file. Then after re-creating the world,
150 * we read the temp file as commands. This isn't always the right thing;
151 * if a procedure that was being traced is deleted, an error message
152 * will be generated.
153 *
154 * If the argument vector is not nil, then this is re-initialize is being
155 * done in preparation for running the program. Since we want to process
156 * the commands in the temp file before running the program, we add the
157 * run command at the end of the temp file. In this case, reinit longjmps
158 * back to parsing rather than returning.
159 */
160
161public reinit(argv, infile, outfile)
162String *argv;
163String infile;
164String outfile;
165{
166 register Integer i;
167 String tmpfile;
168 extern String mktemp();
169
170 tmpfile = mktemp("/tmp/dbxXXXX");
171 setout(tmpfile);
172 status();
173 print_alias(nil);
174 if (argv != nil) {
175 printf("run");
176 for (i = 1; argv[i] != nil; i++) {
177 printf(" %s", argv[i]);
178 }
179 if (infile != nil) {
180 printf(" < %s", infile);
181 }
182 if (outfile != nil) {
183 printf(" > %s", outfile);
184 }
185 putchar('\n');
186 }
187 unsetout();
188 bpfree();
189 objfree();
190 process_init();
191 enterkeywords();
192 scanner_init();
193 readobj(objname);
194 bpinit();
195 fflush(stdout);
196 setinput(tmpfile);
197 unlink(tmpfile);
198 if (argv != nil) {
199 longjmp(env, 1);
200 /* NOTREACHED */
201 }
202}
203
204/*
205 * After a non-fatal error we jump back to command parsing.
206 */
207
208public erecover()
209{
210 if (initdone) {
211 gobble();
212 longjmp(env, 1);
213 }
214}
215
216/*
217 * This routine is called when an interrupt occurs.
218 */
219
220private catchintr()
221{
222 putchar('\n');
223 longjmp(env, 1);
224}
225
226/*
227 * Scan the argument list.
228 */
229
230private scanargs(argc, argv)
231int argc;
232String argv[];
233{
234 register int i, j;
235 register Boolean foundfile;
236 register File f;
237 char *tmp;
238
239 runfirst = false;
240 interactive = false;
241 lexdebug = false;
242 tracebpts = false;
243 traceexec = false;
244 tracesyms = false;
245 foundfile = false;
246 corefile = nil;
247 coredump = true;
248 sourcepath = list_alloc();
249 list_append(list_item("."), nil, sourcepath);
250 i = 1;
11d84b8e 251 while (i < argc and (not foundfile or (corefile == nil and not runfirst))) {
00102538
ML
252 if (argv[i][0] == '-') {
253 if (streq(argv[i], "-I")) {
254 ++i;
255 if (i >= argc) {
256 fatal("missing directory for -I");
257 }
258 list_append(list_item(argv[i]), nil, sourcepath);
259 } else {
260 for (j = 1; argv[i][j] != '\0'; j++) {
261 setoption(argv[i][j]);
262 }
263 }
264 } else if (not foundfile) {
265 objname = argv[i];
266 foundfile = true;
267 } else if (coredump and corefile == nil) {
268 corefile = fopen(argv[i], "r");
269 if (corefile == nil) {
270 coredump = false;
271 }
272 }
273 ++i;
274 }
275 if (i < argc and not runfirst) {
276 fatal("extraneous argument %s", argv[i]);
277 }
278 firstarg = i;
279 if (not foundfile and isatty(0)) {
280 printf("enter object file name (default is `%s'): ", objname);
281 fflush(stdout);
282 gets(namebuf);
283 if (namebuf[0] != '\0') {
284 objname = namebuf;
285 }
286 }
287 f = fopen(objname, "r");
288 if (f == nil) {
289 fatal("can't read %s", objname);
290 } else {
291 fclose(f);
292 }
293 if (rindex(objname, '/') != nil) {
294 tmp = strdup(objname);
295 *(rindex(tmp, '/')) = '\0';
296 list_append(list_item(tmp), nil, sourcepath);
297 }
298 if (coredump and corefile == nil) {
299 corefile = fopen("core", "r");
300 if (corefile == nil) {
301 coredump = false;
302 }
303 }
304}
305
306/*
307 * Take appropriate action for recognized command argument.
308 */
309
310private setoption(c)
311char c;
312{
313 switch (c) {
314 case 'r': /* run program before accepting commands */
315 runfirst = true;
316 coredump = false;
317 break;
318
319 case 'i':
320 interactive = true;
321 break;
322
323 case 'b':
324 tracebpts = true;
325 break;
326
327 case 'e':
328 traceexec = true;
329 break;
330
331 case 's':
332 tracesyms = true;
333 break;
334
335 case 'l':
336# ifdef LEXDEBUG
337 lexdebug = true;
338# else
339 fatal("\"-l\" only applicable when compiled with LEXDEBUG");
340# endif
341 break;
342
343 default:
344 fatal("unknown option '%c'", c);
345 }
346}
347
39144fe1
ML
348/*
349 * Save/restore the state of a tty.
350 */
351
352public savetty(f, t)
353File f;
354Ttyinfo *t;
355{
356 gtty(fileno(f), t);
357}
358
359public restoretty(f, t)
360File f;
361Ttyinfo *t;
362{
363 stty(fileno(f), t);
364}
365
00102538
ML
366/*
367 * Exit gracefully.
368 */
369
370public quit(r)
371Integer r;
372{
373 exit(r);
374}