/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)printsym.c 1.14 (Berkeley) %G%";
static char rcsid
[] = "$Header: printsym.c,v 1.5 84/12/26 10:41:28 linton Exp $";
* 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", "@dynarray",
"@subarray", "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 ", classname(s
));
* Note the exit of the given block
printf("leaving %s ", classname(s
));
* Note the call of s from t.
printf(" from %s ", classname(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) ");
* 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
= psize(param
) div
sizeof(Word
);
printparamv(param
, frame
);
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 out a parameter value.
* Since this is intended to be printed on a single line with other information
* aggregate values are not printed.
public printparamv (p
, frame
)
if (compatible(t
, t_char
)) {
printf("%s = (...)", symname(p
));
printf("%s = (...)", symname(p
));
* Print the name and value of a variable.
if (isambiguous(s
) and ismodule(container(s
))) {
printf("%s = ", symname(s
));
if (isvarparam(s
) and not isopenarray(s
)) {
rpush(address(s
, frame
), sizeof(Address
));
addr
= address(s
, frame
);
printf("*** expression too large ***");
* 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
));
if (s
->language
== nil
or s
->language
== primlang
) {
lang
= findlanguage(".s");
(*language_op(lang
, 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("size\t%d\n", size(s
));
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
or 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
<= '~') {
* Print out a value for a range type (integer, char, or boolean).
public printRangeVal (val
, t
)
if (t
== t_boolean
->type
or istypename(t
->type
, "boolean")) {
} else if (t
== t_char
->type
or istypename(t
->type
, "char")) {
if (varIsSet("$hexchars")) {
} else if (varIsSet("$hexints")) {
} else if (t
->symvalue
.rangev
.lower
>= 0) {
* Print out an enumerated value by finding the corresponding
* name in the enumeration list.
while (e
!= nil
and e
->symvalue
.constval
->value
.lcon
!= i
) {
printf("%s", symname(e
));
* Print out a null-terminated string (pointer to char)
* starting at the given address.
public printString (addr
, quotes
)
register boolean endofstring
;
if (varIsSet("$hexstrings")) {
while (not endofstring
) {
} while (i
< sizeof(Word
) and not endofstring
);