Logo Search packages:      
Sourcecode: lcrash version File versions  Download package

sial_print.c

/*
 * Copyright 2001 Silicon Graphics, Inc. All rights reserved.
 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "sial.h"
/*
      This set of function are used to print value_ts.
*/

/* utility that returns a string of '*' for a reference */
static
char *sial_getref(int lev)
{
static char *ptrs="*******";

      return ptrs+strlen(ptrs)-lev;
}

static char *
sial_getidx(type_t *t, char*buf, int len)
{
int pos=0;

      buf[0]='\0';
      if(t->idxlst) {

            int i;

            for(i=0; t->idxlst[i] && pos < len; i++) {

                  pos += snprintf(buf+pos, len-pos, "[%d]", t->idxlst[i]);
            }
      }
      return buf;
}

#define INDENT          4     /* print indent at beginning of new line */
#define SPACER          16    /* space for type string */
#define NAMESPACE 16    /* space used for member/var names */
#define NBUNDLE         4     /* when printing arrays print this much before \n */

static void
sial_indent(int level, int indent)
{
      if(!indent) return;
      sial_msg("%*s", level*INDENT, "");
}

static void sial_ptype2(type_t*t, value_t*v, int level, int indent, char *name, int ref, int justv);

/*
      Print a struct/union type or value
*/
static void
sial_print_ctype(type_t *t, value_t *v, int level, int indent, char *name, int ref, int justv)
{
stinfo_t *st=sial_getstbyindex(t->idx, t->type);
stmember_t *m;
char buf[100];

      if(!st) sial_error("Oops sial_print_ctype!");

      if(!st->all) {

            sial_fillst(st);
            if(!st->all) sial_error("Reference to a incomplete type");
      }

      sial_indent(level, indent);

      if(!justv) {
            snprintf(buf, sizeof(buf)-1, "%s %s", sial_ctypename(t->type), st->name?st->name:"");
            sial_msg("%-*s ", SPACER, buf);

            /* is this is a pointer, bail out */
      }
      if(ref) return;

      if(v && !justv) sial_msg(" = ");

      sial_msg("{\n");

      for(m=st->stm; m; m=m->next) {

            value_t *vm=0;

            sial_indent(level+1, 1);
            if(v) {
                  vm=sial_newval();
                  sial_duptype(&vm->type, &m->type);
                  sial_exememlocal(v, m, vm);
                  sial_ptype2(&vm->type, vm, level+1, 0, m->m.name, 0, 0);

            } else sial_ptype2(&m->type, vm, level+1, 0, m->m.name, 0, 0);
            sial_msg(";\n");
            if(vm) sial_freeval(vm);
      }

      sial_indent(level, 1);
      sial_msg("}");
      if(name) sial_msg(" %s", name);
      
}

static void
sial_prbval(value_t *v)
{
      if(sial_issigned(v->type.typattr)) sial_msg("%8lld", sial_getval(v));
      else sial_msg("%8llu", sial_getval(v));
}

static int 
sial_prtstr(value_t *v, int justv)
{
value_t *vs;
char *s, *p;

      if(sial_defbsize()==8) v->v.ull=v->mem;
      else v->v.ul=v->mem;
      vs=sial_getstr(v);
      s=sial_getptr(vs, char);
      for(p=s; *p; p++) if(!isprint(*p)) return 0;
      if(p==s) { sial_freeval(vs); return 0; }
      if(!justv) sial_msg("= ");
      sial_msg("\"%s\"", s);
      sial_freeval(vs);
      return 1;
}

static void
sial_prtarray(type_t*t, ull mem, int level, int idx)
{
int i;
int j, size=1;

      for(j=idx+1; t->idxlst[j]; j++) size *= t->idxlst[j];
      size *= t->type==V_REF ? sial_defbsize() : t->size;

      /* start printing */
      sial_msg("{");
      sial_msg("\n");
      sial_indent(level+1, 1);

      for(i=0; i<t->idxlst[idx]; i++, mem += size) {

            if(t->idxlst[idx+1]) {

                  sial_msg("[%d] = ", i);
                  sial_prtarray(t, mem, level+1, idx+1);

            } else {

                  /* time to deref and print final type */
                  value_t *v=sial_newval(), *vr=sial_newval();
                  int *pi=t->idxlst;

                  t->idxlst=0;

                  sial_duptype(&vr->type, t);
                  sial_pushref(&vr->type, 1);
                  if(sial_defbsize()==8) vr->v.ull=mem;
                  else vr->v.ul=(ul)mem;
                  sial_do_deref(1, v, vr);
                  if(is_ctype(v->type.type) || !(i%NBUNDLE)) sial_msg("[%2d] ", i);
                  sial_ptype2(&v->type, v, level+1, 0, 0, 0, 1);
                  sial_msg(", ");
                  /* anything else then struct/unions, print in buddles */
                  if(!is_ctype(v->type.type) && !((i+1)%NBUNDLE)) {

                        sial_msg("\n"); 
                        sial_indent(level+1, 1);
                  }
                  sial_freeval(v);
                  sial_freeval(vr);
                  t->idxlst=pi;
            }
      }
      sial_msg("\n");
      sial_indent(level, 1);
      sial_msg("}");
}

/*
      Print a type.
      Typical output of the 'whatis' command.
*/
static
void sial_ptype2(type_t*t, value_t*v, int level, int indent, char *name, int ref, int justv)
{
int type=t->type;

      sial_indent(level, indent);
      switch(type) {

            case V_STRUCT: case V_UNION:

                  /* make sure we have all the member info */
                  sial_print_ctype(t, v, level, 0, name, ref, justv);
            break;


            case V_TYPEDEF:
                  /* no typedef should get here */
                  sial_warning("Typedef in print!");
            break;

            case V_ENUM:
                  /* no enum should get here */
                  sial_warning("ENUM in print!");
            break;

            case V_REF:
            {
            int refi=t->ref, ref=refi;

                  /* decrement ref if this was declared as a array */
                  if(t->idxlst) ref--;

                  /* print the referenced type */
                  sial_popref(t, t->ref);
                  sial_ptype2(t, 0, level, 0, 0, 1, justv);
                  sial_pushref(t, refi);

                  if(!justv) {

                        char buf[100], buf2[100];
                        int pos=0, len=sizeof(buf);

                        buf[0]='\0';
                        if(t->fct) buf[pos++]='(';
                        if(pos < len)
                              pos += snprintf(buf+pos, len-pos, "%s%s", sial_getref(ref), name?name:"");
                        if(pos < len)
                              pos += snprintf(buf+pos, len-pos, "%s", sial_getidx(t, buf2, sizeof(buf2)));
                        if(pos < len && t->fct)
                              pos += snprintf(buf+pos, len-pos, "%s", ")()");

                        sial_msg("%*s ", NAMESPACE, buf);
                  }

                  /* arrays are ref with boundaries... */
                  if(t->idxlst && v) {

                        if(t->idxlst[1] || t->rtype!=V_BASE || t->size!=1 || !sial_prtstr(v, justv)) 
                        {
                              if(!justv) sial_msg("= ");
                              sial_popref(t, 1);
                              sial_prtarray(t, v->mem, level, 0);
                              sial_pushref(t, 1);
                        }

                  } else if(v) {

                        if(!justv) sial_msg("= ");
                        if(!sial_getval(v)) sial_msg("(nil)");
                        else {
                              if(sial_defbsize()==8) sial_msg("0x%016llx", sial_getval(v));
                              else sial_msg("0x%08x", sial_getval(v));
                        }
                        if(t->ref==1 && t->rtype==V_BASE && t->size==1) {

                              (void)sial_prtstr(v, justv);
                        }
                  }
            }
            break;

            case V_BASE:
            {
                  if(sial_isenum(t->typattr)) {

                        stinfo_t *st=sial_getstbyindex(t->rtype, V_ENUM);
                        if(!justv) {
                              char buf[200];
                              snprintf(buf, sizeof(buf), "enum %s", st->name?st->name:"");
                              sial_msg("%-*s ", SPACER, buf);
                              sial_msg("%*s ", NAMESPACE, (name&&v)?name:"");
                        }
                        if(v) {

                              enum_t *e=st->enums;

                              sial_msg("= ");
                              sial_prbval(v);
                              while(e) {

                                    if(e->value==sial_getval(v)) {
                                          sial_msg(" [%s]", e->name);
                                          break;
                                    }
                                    e=e->next;
                              }
                              if(!e) sial_msg(" [???]");

                        }else{

                              enum_t *e=st->enums;
                              int count=0;

                              sial_msg(" {");
                              while(e) {

                                    if(!(count%4)) {
                                          sial_msg("\n");
                                          sial_indent(level+1, 1);
                                    }
                                    count ++;
                                    sial_msg("%s = %d, ", e->name, e->value);
                                    e=e->next;

                              }
                              sial_msg("\n");
                              sial_indent(level, 1);
                              sial_msg("%-*s ", SPACER, "}");
                              if(ref) return;
                              sial_msg("%*s ", NAMESPACE, name?name:"");
                        }

                  } else {

                        if(!justv) {
                              sial_msg("%-*s " , SPACER , sial_getbtypename(t->typattr));
                              if(ref) return;
                              sial_msg("%s%*s ", sial_getref(t->ref), NAMESPACE, name?name:"");
                        }
                        if(v) { 

                              if(!justv) sial_msg("= ");
                              sial_prbval(v);
                        }
                  }
            }
            break;
            case V_STRING:
                  if(!justv) {
                        sial_msg("%-*s " , SPACER , "string");
                        sial_msg("%*s ", NAMESPACE, name?name:"");
                  }
                  if(v) {

                        if(!justv) sial_msg("= ");
                        sial_msg("\"%s\"", v->v.data);
                  }
            break;
      }
      if(indent) sial_msg("\n");
}

static value_t*
sial_ptype(value_t*v)
{
      sial_ptype2(&v->type, 0, 0, 1, 0, 0, 0);
      sial_msg("\n");
      return 0;
}

node_t*
sial_newptype(var_t*v)
{
node_t*n=sial_newnode();

      n->data=v->next->v;
      v->next->v=0; /* save value against freeing */
      sial_freevar(v->next);
      sial_freevar(v);
      n->exe=(xfct_t)sial_ptype;
      n->free=(ffct_t)sial_freeval;
      n->name=0;
      sial_setpos(&n->pos);
      return n;
}

static value_t *
sial_pval(node_t*n)
{
value_t *v=NODE_EXE(n);
char *name=NODE_NAME(n);

      sial_ptype2(&v->type, v, 0, 1, name, 0, 0);
      sial_free(name);
      sial_freeval(v);
      return 0;
}

node_t*
sial_newpval(node_t*vn, int fmt)
{
node_t*n=sial_newnode();

      n->data=vn;
      n->exe=(xfct_t)sial_pval;
      n->free=(ffct_t)sial_freenode;
      n->name=0;
      sial_setpos(&n->pos);
      return n;
}

Generated by  Doxygen 1.6.0   Back to index