ack/util/grind/print.c

299 lines
6.5 KiB
C
Raw Normal View History

1990-08-31 18:22:53 +00:00
/* $Header$ */
#include <alloc.h>
#include <assert.h>
#include <stdio.h>
#include "type.h"
#include "message.h"
#include "langdep.h"
#include "scope.h"
#include "symbol.h"
#include "position.h"
#include "idf.h"
1990-09-25 17:40:47 +00:00
#include "expr.h"
1990-08-31 18:22:53 +00:00
extern FILE *db_out;
extern long float_size, pointer_size, int_size;
static
print_literal(tp, v)
p_type tp;
1990-09-25 17:40:47 +00:00
long v;
1990-08-31 18:22:53 +00:00
{
register struct literal *lit = tp->ty_literals;
register int i;
for (i = tp->ty_nenums; i; i--, lit++) {
if (lit->lit_val == v) {
fprintf(db_out, lit->lit_name);
break;
}
}
if (! i) {
fprintf(db_out, "unknown enumeration value %d", v);
}
}
static
print_unsigned(tp, v)
p_type tp;
long v;
{
if (tp == uchar_type) {
1990-09-19 14:31:12 +00:00
(*currlang->printchar)((int) v);
1990-08-31 18:22:53 +00:00
}
else fprintf(db_out, currlang->uns_fmt, v);
}
static
print_integer(tp, v)
p_type tp;
long v;
{
if (tp == char_type) {
1990-09-19 14:31:12 +00:00
(*currlang->printchar)((int) v);
1990-08-31 18:22:53 +00:00
}
else fprintf(db_out, currlang->decint_fmt, v);
}
print_params(tp, AB, static_link)
p_type tp;
t_addr AB;
{
char *param_bytes;
register char *p;
register int i;
register struct param *par;
long size;
if (! tp) return;
assert(tp->ty_class == T_PROCEDURE);
if ((i = tp->ty_nparams) == 0) return;
/* get parameter bytes */
par = tp->ty_params;
size = tp->ty_nbparams;
if (static_link) size += pointer_size;
1990-09-25 17:40:47 +00:00
param_bytes = p = malloc((unsigned)size);
if (! p) {
error("could not allocate enough memory");
return;
}
1990-08-31 18:22:53 +00:00
if (static_link) p += pointer_size;
if (! get_bytes(size, AB, param_bytes)) {
error("no debuggee");
free(param_bytes);
return;
}
while (i--) {
if (par->par_kind == 'v' || par->par_kind == 'i') {
/* call by reference parameter, or
call by value parameter, but address is passed;
try and get value.
*/
char *q;
1990-09-25 17:40:47 +00:00
t_addr addr = get_int(p, pointer_size, T_UNSIGNED);
1990-08-31 18:22:53 +00:00
if ((size = par->par_type->ty_size) == 0) {
size = compute_size(par->par_type, param_bytes);
}
1990-09-25 17:40:47 +00:00
q = malloc((unsigned) size);
if (! q) {
error("could not allocate enough memory");
free(param_bytes);
return;
}
if (! get_bytes(size, addr, q)) {
fprintf(db_out, currlang->addr_fmt, (long) addr);
1990-08-31 18:22:53 +00:00
}
else {
1990-09-07 14:56:24 +00:00
print_val(par->par_type, size, q, 1, 0);
1990-08-31 18:22:53 +00:00
}
free(q);
}
1990-09-07 14:56:24 +00:00
else print_val(par->par_type, par->par_type->ty_size, p, 1, 0);
1990-08-31 18:22:53 +00:00
if (i) fputs(", ", db_out);
p += param_size(par->par_type, par->par_kind);
par++;
}
free(param_bytes);
}
1990-09-07 14:56:24 +00:00
print_val(tp, tp_sz, addr, compressed, indent)
1990-08-31 18:22:53 +00:00
p_type tp; /* type of value to be printed */
1990-09-07 14:56:24 +00:00
long tp_sz; /* size of object to be printed */
1990-08-31 18:22:53 +00:00
char *addr; /* address to get value from */
int compressed; /* for parameter lists */
int indent; /* indentation */
{
register int i;
long elsize;
if (indent == 0) indent = 4;
switch(tp->ty_class) {
case T_SUBRANGE:
1990-09-20 17:51:14 +00:00
print_val(tp->ty_base, tp_sz, addr, compressed, indent);
1990-08-31 18:22:53 +00:00
break;
case T_ARRAY:
if (tp->ty_elements == char_type ||
tp->ty_elements == uchar_type) {
1990-09-07 14:56:24 +00:00
print_val(string_type, tp_sz, addr, compressed, indent);
1990-08-31 18:22:53 +00:00
break;
}
if (compressed) {
fprintf(db_out, currlang->open_array_display);
}
else {
fprintf(db_out, "\n%*c%s%*c",
indent,
' ',
currlang->open_array_display,
4-strlen(currlang->open_array_display), ' ');
}
indent += 4;
elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
1990-09-07 14:56:24 +00:00
for (i = tp_sz/elsize; i; i--) {
print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent);
1990-08-31 18:22:53 +00:00
addr += elsize;
if (compressed && i > 1) {
fprintf(db_out, ", ...");
break;
}
if (i > 1) {
fputc(',', db_out);
}
fprintf(db_out, "\n%*c", i > 1 ? indent : indent - 4, ' ');
}
fprintf(db_out, currlang->close_array_display);
indent -= 4;
break;
case T_STRUCT: {
register struct fields *fld = tp->ty_fields;
if (compressed) {
fprintf(db_out, currlang->open_struct_display);
}
else {
fprintf(db_out, "\n%*c%s%*c",
indent,
' ',
currlang->open_struct_display,
4-strlen(currlang->open_struct_display), ' ');
}
indent += 4;
for (i = tp->ty_nfields; i; i--, fld++) {
1990-09-07 14:56:24 +00:00
long sz = fld->fld_type->ty_size;
1990-08-31 18:22:53 +00:00
if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
1990-09-25 17:40:47 +00:00
if (fld->fld_bitsize < (sz << 3)) {
1990-08-31 18:22:53 +00:00
/* apparently a bit field */
/* ??? */
1990-09-12 16:13:59 +00:00
fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
1990-08-31 18:22:53 +00:00
}
1990-09-07 14:56:24 +00:00
else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent);
1990-08-31 18:22:53 +00:00
if (compressed && i > 1) {
fprintf(db_out, ", ...");
break;
}
if (i > 1) {
fputc(',', db_out);
}
fprintf(db_out, "\n%*c", i > 1 ? indent : indent - 4, ' ');
}
indent -= 4;
fprintf(db_out, currlang->close_struct_display);
break;
}
case T_UNION:
fprintf(db_out, "<union>");
break;
case T_ENUM:
1990-09-25 17:40:47 +00:00
print_literal(tp, get_int(addr, tp_sz, T_ENUM));
1990-08-31 18:22:53 +00:00
break;
case T_PROCEDURE: {
1990-09-25 17:40:47 +00:00
register p_scope sc = get_scope_from_addr((t_addr) get_int(addr, pointer_size, T_UNSIGNED));
1990-08-31 18:22:53 +00:00
if (sc && sc->sc_definedby) {
fprintf(db_out, sc->sc_definedby->sy_idf->id_text);
break;
}
}
/* Fall through */
case T_POINTER:
1990-09-25 17:40:47 +00:00
fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED));
1990-08-31 18:22:53 +00:00
break;
case T_FILE:
fprintf(db_out, "<file>");
break;
case T_SET: {
long val = tp->ty_setlow;
p_type base = tp->ty_setbase;
long nelements = tp->ty_size << 3;
int count = 0;
int rsft = 3 + (int_size == 2 ? 1 : 2);
1990-09-25 17:40:47 +00:00
long mask = int_size == 2 ? 017: 037;
1990-08-31 18:22:53 +00:00
if (base->ty_class == T_SUBRANGE) base = base->ty_base;
if (compressed) {
fprintf(db_out, currlang->open_set_display);
}
else {
fprintf(db_out, "\n%*c%s%*c",
indent,
' ',
currlang->open_set_display,
4-strlen(currlang->open_set_display), ' ');
}
indent += 4;
for (i = 0; i < nelements; i++) {
1990-09-25 17:40:47 +00:00
if (get_int(addr + (i >> rsft), int_size, T_UNSIGNED) & (1 << (i & mask))) {
1990-08-31 18:22:53 +00:00
count++;
if (count > 1) {
if (compressed) {
fprintf(db_out, ", ...");
break;
}
fprintf(db_out, ",\n%*c", indent , ' ');
}
switch(base->ty_class) {
case T_INTEGER:
print_integer(base, val+i);
break;
case T_UNSIGNED:
print_unsigned(base, val+i);
break;
case T_ENUM:
1990-09-25 17:40:47 +00:00
print_literal(base, val+i);
1990-08-31 18:22:53 +00:00
break;
default:
assert(0);
}
}
}
if (! compressed) {
fprintf(db_out, "\n%*c", indent-4 , ' ');
}
indent -= 4;
fprintf(db_out, currlang->close_set_display);
}
break;
1990-09-25 17:40:47 +00:00
case T_REAL:
fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size));
1990-08-31 18:22:53 +00:00
break;
case T_UNSIGNED:
1990-09-25 17:40:47 +00:00
print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED));
1990-08-31 18:22:53 +00:00
break;
case T_INTEGER:
1990-09-25 17:40:47 +00:00
print_integer(tp, get_int(addr, tp_sz, T_INTEGER));
1990-08-31 18:22:53 +00:00
break;
case T_STRING:
1990-09-14 14:37:26 +00:00
(*currlang->printstring)(addr, (int) tp_sz);
1990-08-31 18:22:53 +00:00
break;
default:
assert(0);
break;
}
}