added an argument to the continue command to allow a signal to be
[unix-history] / usr / src / old / dbx / printsym.c
CommitLineData
6eb0951d
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
550fe947 3static char sccsid[] = "@(#)printsym.c 1.2 %G%";
6eb0951d
ML
4
5/*
6 * Printing of symbolic information.
7 */
8
9#include "defs.h"
10#include "symbols.h"
11#include "languages.h"
12#include "printsym.h"
13#include "tree.h"
14#include "eval.h"
15#include "mappings.h"
16#include "process.h"
17#include "runtime.h"
18#include "machine.h"
19#include "names.h"
20#include "main.h"
21
22#ifndef public
23#endif
24
25/*
26 * Return a pointer to the string for the name of the class that
27 * the given symbol belongs to.
28 */
29
30private String clname[] = {
31 "bad use", "constant", "type", "variable", "array", "fileptr",
32 "record", "field", "procedure", "function", "funcvar",
33 "ref", "pointer", "file", "set", "range", "label", "withptr",
34 "scalar", "string", "program", "improper", "variant",
35 "procparam", "funcparam", "module", "typeref", "tag"
36};
37
38public String classname(s)
39Symbol s;
40{
41 return clname[ord(s->class)];
42}
43
44/*
45 * Note the entry of the given block, unless it's the main program.
46 */
47
48public printentry(s)
49Symbol s;
50{
51 if (s != program) {
52 printf("\nentering %s %s\n", classname(s), symname(s));
53 }
54}
55
56/*
57 * Note the exit of the given block
58 */
59
60public printexit(s)
61Symbol s;
62{
63 if (s != program) {
64 printf("leaving %s %s\n\n", classname(s), symname(s));
65 }
66}
67
68/*
69 * Note the call of s from t.
70 */
71
72public printcall(s, t)
73Symbol s, t;
74{
75 printf("calling %s", symname(s));
76 printparams(s, nil);
77 printf(" from %s %s\n", classname(t), symname(t));
78}
79
80/*
81 * Note the return from s. If s is a function, print the value
82 * it is returning. This is somewhat painful, since the function
83 * has actually just returned.
84 */
85
86public printrtn(s)
87Symbol s;
88{
89 register Symbol t;
90 register int len;
91 Boolean isindirect;
92
93 printf("returning ");
94 if (s->class == FUNC) {
95 len = size(s->type);
96 if (canpush(len)) {
97 t = rtype(s->type);
98 isindirect = (Boolean) (t->class == RECORD or t->class == VARNT);
99 pushretval(len, isindirect);
100 printval(s->type);
101 putchar(' ');
102 } else {
103 printf("(value too large) ");
104 }
105 }
106 printf("from %s\n", symname(s));
107}
108
109/*
110 * Print the values of the parameters of the given procedure or function.
111 * The frame distinguishes recursive instances of a procedure.
112 */
113
114public printparams(f, frame)
115Symbol f;
116Frame frame;
117{
118 Symbol param;
119 int n, m, s;
120
121 n = nargspassed(frame);
122 param = f->chain;
123 if (param != nil or n > 0) {
124 printf("(");
125 m = n;
126 if (param != nil) {
127 for (;;) {
128 s = size(param) div sizeof(Word);
129 if (s == 0) {
130 s = 1;
131 }
132 m -= s;
133 printv(param, frame);
134 param = param->chain;
135 if (param == nil) break;
136 printf(", ");
137 }
138 }
139 if (m > 0) {
140 if (f->chain != nil) {
141 printf(", ");
142 }
143 for (;;) {
144 --m;
145 printf("0x%x", argn(n - m, frame));
146 if (m <= 0) break;
147 printf(", ");
148 }
149 }
150 printf(")");
151 }
152}
153
154/*
155 * Test if a symbol should be printed. We don't print files,
156 * for example, simply because there's no good way to do it.
157 * The symbol must be within the given function.
158 */
159
160public Boolean should_print(s)
161Symbol s;
162{
163 Boolean b;
164 register Symbol t;
165
166 switch (s->class) {
167 case VAR:
168 case FVAR:
169 t = rtype(s->type);
170 b = (Boolean) (
171 not isparam(s) and
172 t != nil and t->class != FILET and t->class != SET
173 );
174 break;
175
176 default:
177 b = false;
178 break;
179 }
180 return b;
181}
182
183/*
184 * Print the name and value of a variable.
185 */
186
187public printv(s, frame)
188Symbol s;
189Frame frame;
190{
191 Address addr;
192 int len;
193
194 if (isambiguous(s) and ismodule(container(s))) {
195 printname(stdout, s);
196 printf(" = ");
197 } else {
198 printf("%s = ", symname(s));
199 }
200 if (isvarparam(s)) {
201 rpush(address(s, frame), sizeof(Address));
202 addr = pop(Address);
203 len = size(s->type);
204 } else {
205 addr = address(s, frame);
206 len = size(s);
207 }
208 if (canpush(len)) {
209 rpush(addr, len);
210 printval(s->type);
211 } else {
212 printf("*** expression too large ***");
213 }
214}
215
216/*
217 * Print out the name of a symbol.
218 */
219
220public printname(f, s)
221File f;
222Symbol s;
223{
224 if (s == nil) {
225 fprintf(f, "(noname)");
226 } else if (isredirected() or isambiguous(s)) {
227 printwhich(f, s);
228 } else {
229 fprintf(f, "%s", symname(s));
230 }
231}
232
233/*
234 * Print the fully specified variable that is described by the given identifer.
235 */
236
237public printwhich(f, s)
238File f;
239Symbol s;
240{
241 printouter(f, container(s));
242 fprintf(f, "%s", symname(s));
243}
244
245/*
246 * Print the fully qualified name of each symbol that has the same name
247 * as the given symbol.
248 */
249
250public printwhereis(f, s)
251File f;
252Symbol s;
253{
254 register Name n;
255 register Symbol t;
256
257 checkref(s);
258 n = s->name;
259 t = lookup(n);
260 printwhich(f, t);
261 t = t->next_sym;
262 while (t != nil) {
263 if (t->name == n) {
264 putc(' ', f);
265 printwhich(f, t);
266 }
267 t = t->next_sym;
268 }
269 putc('\n', f);
270}
271
272private printouter(f, s)
273File f;
274Symbol s;
275{
276 Symbol outer;
277
278 if (s != nil) {
279 outer = container(s);
280 if (outer != nil and outer != program) {
281 printouter(f, outer);
282 }
283 fprintf(f, "%s.", symname(s));
284 }
285}
286
287public printdecl(s)
288Symbol s;
289{
290 checkref(s);
291 (*language_op(s->language, L_PRINTDECL))(s);
292}
293
294/*
295 * Straight dump of symbol information.
296 */
297
298public psym(s)
299Symbol s;
300{
301 printf("name\t%s\n", symname(s));
302 printf("lang\t%s\n", language_name(s->language));
303 printf("level\t%d\n", s->level);
304 printf("class\t%s\n", classname(s));
305 printf("type\t0x%x", s->type);
306 if (s->type != nil and s->type->name != nil) {
307 printf(" (%s)", symname(s->type));
308 }
309 printf("\nchain\t0x%x", s->chain);
310 if (s->chain != nil and s->chain->name != nil) {
311 printf(" (%s)", symname(s->chain));
312 }
313 printf("\nblock\t0x%x", s->block);
314 if (s->block->name != nil) {
315 printf(" (");
316 printname(stdout, s->block);
317 putchar(')');
318 }
319 putchar('\n');
320 switch (s->class) {
321 case VAR:
322 case REF:
323 if (s->level >= 3) {
324 printf("address\t0x%x\n", s->symvalue.offset);
325 } else {
326 printf("offset\t%d\n", s->symvalue.offset);
327 }
328 break;
329
330 case RECORD:
331 case VARNT:
332 printf("size\t%d\n", s->symvalue.offset);
333 break;
334
335 case FIELD:
336 printf("offset\t%d\n", s->symvalue.field.offset);
337 printf("size\t%d\n", s->symvalue.field.length);
338 break;
339
340 case PROC:
341 case FUNC:
342 printf("address\t0x%x\n", s->symvalue.funcv.beginaddr);
343 break;
344
345 case RANGE:
346 printf("lower\t%d\n", s->symvalue.rangev.lower);
347 printf("upper\t%d\n", s->symvalue.rangev.upper);
348 break;
349
350 default:
351 /* do nothing */
352 break;
353 }
354}
355
356/*
357 * Print out the value on top of the stack according to the given type.
358 */
359
360public printval(t)
361Symbol t;
362{
363 Symbol s;
364
365 checkref(t);
366 switch (t->class) {
367 case PROC:
368 case FUNC:
369 s = pop(Symbol);
370 printf("%s", symname(s));
371 break;
372
373 default:
374 if (t->language == nil) {
375 error("unknown language");
376 } else {
377 (*language_op(t->language, L_PRINTVAL))(t);
378 }
379 break;
380 }
381}
382
383/*
384 * Print out the value of a record, field by field.
385 */
386
387public printrecord(s)
388Symbol s;
389{
390 if (s->chain == nil) {
391 error("record has no fields");
392 }
393 printf("(");
394 sp -= size(s);
395 printfield(s->chain);
396 printf(")");
397}
398
399/*
400 * Print out a field, first printing out other fields.
401 * This is done because the fields are chained together backwards.
402 */
403
404private printfield(s)
405Symbol s;
406{
407 Stack *savesp;
408
409 if (s->chain != nil) {
410 printfield(s->chain);
411 printf(", ");
412 }
413 printf("%s = ", symname(s));
414 savesp = sp;
415 sp += ((s->symvalue.field.offset div BITSPERBYTE) + size(s->type));
416 printval(s);
417 sp = savesp;
418}
419
420/*
421 * Print out the contents of an array.
422 * Haven't quite figured out what the best format is.
423 *
424 * This is rather inefficient.
425 *
426 * The "2*elsize" is there since "printval" drops the stack by elsize.
427 */
428
429public printarray(a)
430Symbol a;
431{
432 Stack *savesp, *newsp;
433 Symbol eltype;
434 long elsize;
435 String sep;
436
437 savesp = sp;
438 sp -= size(a);
439 newsp = sp;
440 eltype = rtype(a->type);
441 elsize = size(eltype);
442 printf("(");
443 if (eltype->class == RECORD or eltype->class == ARRAY or
444 eltype->class == VARNT) {
445 sep = "\n";
446 putchar('\n');
447 } else {
448 sep = ", ";
449 }
450 for (sp += elsize; sp <= savesp; sp += 2*elsize) {
451 if (sp - elsize != newsp) {
452 fputs(sep, stdout);
453 }
454 printval(eltype);
455 }
456 sp = newsp;
457 if (streq(sep, "\n")) {
458 putchar('\n');
459 }
460 printf(")");
461}
462
463/*
464 * Print out the value of a real number in Pascal notation.
465 * This is, unfortunately, different than what one gets
466 * from "%g" in printf.
467 */
468
469public prtreal(r)
470double r;
471{
472 extern char *index();
473 char buf[256];
474
475 sprintf(buf, "%g", r);
476 if (buf[0] == '.') {
477 printf("0%s", buf);
478 } else if (buf[0] == '-' and buf[1] == '.') {
479 printf("-0%s", &buf[1]);
480 } else {
481 printf("%s", buf);
482 }
483 if (index(buf, '.') == nil) {
484 printf(".0");
485 }
486}
487
488/*
489 * Print out a character using ^? notation for unprintables.
490 */
491
492public printchar(c)
493char c;
494{
495 if (c == 0) {
496 putchar('\\');
497 putchar('0');
498 } else if (c == '\n') {
499 putchar('\\');
500 putchar('n');
501 } else if (c > 0 and c < ' ') {
502 putchar('^');
503 putchar(c - 1 + 'A');
504 } else {
505 putchar(c);
506 }
507}