/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)printsym.c 1.13 (Berkeley) %G%";
* Printing of symbolic information.
* Maximum number of arguments to a function.
* This is used as a check for the possibility that the stack has been
* overwritten and therefore a saved argument pointer might indicate
* to an absurdly large number of arguments.
* Return a pointer to the string for the name of the class that
* the given symbol belongs to.
private String clname
[] = {
"bad use", "constant", "type", "variable", "array", "fileptr",
"record", "field", "procedure", "function", "funcvar",
"ref", "pointer", "file", "set", "range", "label", "withptr",
"scalar", "string", "program", "improper", "variant",
"procparam", "funcparam", "module", "tag", "common", "extref", "typeref"
public String
classname(s
)
return clname
[ord(s
->class)];
* Note the entry of the given block, unless it's the main program.
printf("\nentering %s %s\n", classname(s
), symname(s
));
* Note the exit of the given block
printf("leaving %s %s\n\n", classname(s
), symname(s
));
* Note the call of s from t.
printf("calling %s", symname(s
));
printf(" from %s %s\n", classname(t
), symname(t
));
* Note the return from s. If s is a function, print the value
* it is returning. This is somewhat painful, since the function
* has actually just returned.
if (s
->class == FUNC
&& (!istypename(s
->type
,"void"))) {
isindirect
= (Boolean
) (t
->class == RECORD
or t
->class == VARNT
);
pushretval(len
, isindirect
);
printf("(value too large) ");
printf("from %s\n", symname(s
));
* Print the values of the parameters of the given procedure or function.
* The frame distinguishes recursive instances of a procedure.
* If the procedure or function is internal, the argument count is
* not valid so we ignore it.
public printparams(f
, frame
)
if (param
!= nil
or n
> 0) {
s
= size(param
) div
sizeof(Word
);
printf("0x%x", argn(n
- m
, frame
));
* Test if a symbol should be printed. We don't print files,
* for example, simply because there's no good way to do it.
* The symbol must be within the given function.
public Boolean
should_print(s
)
* Print the name and value of a variable.
if (isambiguous(s
) and ismodule(container(s
))) {
printf("%s = ", symname(s
));
if (t->class == ARRAY and not istypename(t->type, "char")) {
rpush(address(s
, frame
), sizeof(Address
));
addr
= address(s
, frame
);
printf("*** expression too large ***");
* Matches brace commented out above.
* Print out the name of a symbol.
} else if (s
== program
) {
} else if (isredirected() or isambiguous(s
)) {
fprintf(f
, "%s", symname(s
));
* Print the fully specified variable that is described by the given identifer.
printouter(f
, container(s
));
fprintf(f
, "%s", symname(s
));
* Print the fully qualified name of each symbol that has the same name
public printwhereis(f
, s
)
if (outer
!= nil
and outer
!= program
) {
fprintf(f
, "%s.", symname(s
));
(*language_op(s
->language
, L_PRINTDECL
))(s
);
* Straight dump of symbol information.
printf("name\t%s\n", symname(s
));
printf("lang\t%s\n", language_name(s
->language
));
printf("level\t%d\n", s
->level
);
printf("class\t%s\n", classname(s
));
printf("type\t0x%x", s
->type
);
if (s
->type
!= nil
and s
->type
->name
!= nil
) {
printf(" (%s)", symname(s
->type
));
printf("\nchain\t0x%x", s
->chain
);
if (s
->chain
!= nil
and s
->chain
->name
!= nil
) {
printf(" (%s)", symname(s
->chain
));
printf("\nblock\t0x%x", s
->block
);
if (s
->block
->name
!= nil
) {
printname(stdout
, s
->block
);
printf("address\t0x%x\n", s
->symvalue
.offset
);
printf("offset\t%d\n", s
->symvalue
.offset
);
printf("size\t%d\n", size(s
));
printf("size\t%d\n", s
->symvalue
.offset
);
printf("offset\t%d\n", s
->symvalue
.field
.offset
);
printf("size\t%d\n", s
->symvalue
.field
.length
);
printf("address\t0x%x\n", s
->symvalue
.funcv
.beginaddr
);
printf("inline procedure\n");
printf("does not have source information\n");
printf("has source information\n");
prangetype(s
->symvalue
.rangev
.lowertype
);
printf("lower\t%d\n", s
->symvalue
.rangev
.lower
);
prangetype(s
->symvalue
.rangev
.uppertype
);
printf("upper\t%d\n", s
->symvalue
.rangev
.upper
);
* Print out the value on top of the stack according to the given type.
if (t
->class == TYPEREF
) {
printf("%s", symname(s
));
if (t
->language
== nil
) {
error("unknown language");
} else if (t
->language
== primlang
) {
(*language_op(findlanguage(".c"), L_PRINTVAL
))(t
);
(*language_op(t
->language
, L_PRINTVAL
))(t
);
* Print out the value of a record, field by field.
error("record has no fields");
printf("%s = ", symname(f
));
off
= f
->symvalue
.field
.offset
;
len
= f
->symvalue
.field
.length
;
sp
+= ((off
+ len
+ BITSPERBYTE
- 1) div BITSPERBYTE
);
* Print out the contents of an array.
* Haven't quite figured out what the best format is.
* This is rather inefficient.
* The "2*elsize" is there since "printval" drops the stack by elsize.
if (eltype
->class == RECORD
or eltype
->class == ARRAY
or
eltype
->class == VARNT
) {
for (sp
+= elsize
; sp
<= savesp
; sp
+= 2*elsize
) {
if (sp
- elsize
!= newsp
) {
* Print out the value of a real number in Pascal notation.
* This is, unfortunately, different than what one gets
} else if (buf
[0] == '-' and buf
[1] == '.') {
if (index(buf
, '.') == nil
) {
* Print out a character using ^? notation for unprintables.
} else if (c
> 0 and c
< ' ') {
} else if (c
>= ' ' && c
<= '~') {