/* This software is Copyright 1989, 1990, 1992, 1993 by various individuals. Please see the accompanying file COPYRIGHT for details. */ #include "db.h" #include "inst.h" #include "config.h" #include "externs.h" #include "interface.h" #include "strings.h" const char *base_inst[] = { PRIMS_CONVERSIONS_TL, PRIMS_INTERACTION_TL, PRIMS_LOGIC_TL, PRIMS_OPERANDS_TL, PRIMS_OBJECTS_TL, PRIMS_CREATE_TL, PRIMS_PROPERTY_TL, PRIMS_STACK_TL, PRIMS_STRINGS_TL, PRIMS_TESTS_TL, PRIMS_TIME_TL, PRIMS_DESCRIPTOR_TL, PRIMS_ARRAY_TL, PRIMS_FILE_TL, PRIMS_FOR_TL, /* these must agree with ../include/inst.h */ /* the space suffix should be used for non-user-accessible ones */ "IF", "CALL", "READ", "PROMPT", "EXIT", "JMP ", "PROGRAM ", "EXECUTE", "SLEEP", "WAKEUP", "VAR", "LOOP", "NOP", "FORK", "EXEC", "ENDEXEC ", "YIELD", "TIMED-PROMPT", "T-P-READ ", "T-P-ABORT ", "LIBCALL ", }; /* converts an instruction into a printable string, stores the string in an internal buffer and returns a pointer to it */ char *insttotext(struct inst *theinst) { static char buffer[256]; switch (theinst->type) { case PROG_PRIMITIVE: if ( (theinst->data.number >= BASE_MIN) && (theinst->data.number <= BASE_MAX) ) { strcpy(buffer,base_inst[theinst->data.number-BASE_MIN]); } else { sprintf(buffer,"?P%d?",theinst->data.number-BASE_MIN); } break; case PROG_STRING: if (!theinst->data.string) { strcpy(buffer, "\"\""); } else { sprintf(buffer,"\"%1.29s%c",theinst->data.string,(strlen(theinst->data.string)<=30)?'"':'_'); } break; case PROG_INTEGER: sprintf(buffer,"%d",theinst->data.number); break; case PROG_ADD: { dbref d; union specific *s; buffer[0] = '\0'; d = theinst->data.call->prog; if ( (d < db_top) && (Typeof(d) == TYPE_PROGRAM) ) { s = &DBFETCH(d)->sp; if ( s->program.codevec && (theinst->data.call >= s->program.codevec) && (theinst->data.call < s->program.codevec+s->program.codesiz) ) { struct stab *st; st = findstab(d,theinst->data.call-s->program.codevec); if (st) { if (st->off == theinst->data.call-s->program.codevec) { sprintf(buffer,"'%s",st->name); } else { sprintf(buffer,"'%s+%d",st->name,(int)(theinst->data.call-s->program.codevec)-st->off); } } } } if (! buffer[0]) { sprintf(buffer,"<#%d addr>",(int)d); } } break; case PROG_OBJECT: sprintf(buffer,"#%d",theinst->data.objref); break; case PROG_VAR: sprintf(buffer,"V%d",theinst->data.number); break; case PROG_PTR: { dbref d; union specific *s; buffer[0] = '\0'; d = theinst->data.ptr->prog; if ( (d < db_top) && (Typeof(d) == TYPE_PROGRAM) ) { s = &DBFETCH(d)->sp; if ( s->program.codevec && (theinst->data.ptr->ptr >= s->program.codevec) && (theinst->data.ptr->ptr < s->program.codevec+s->program.codesiz) ) { struct stab *st; st = findstab(d,theinst->data.ptr->ptr-s->program.codevec); if (st) { if (st->off == theinst->data.ptr->ptr-s->program.codevec) { sprintf(buffer,"<#%d '%s>",(int)theinst->data.ptr->prog,st->name); } else { sprintf(buffer,"<#%d '%s+%d>",(int)theinst->data.ptr->prog,st->name,(int)(theinst->data.ptr->ptr-s->program.codevec)-st->off); } } } } if (! buffer[0]) { sprintf(buffer,"<#%d ptr>",(int)d); } } break; case PROG_RE: sprintf(buffer,""); break; case PROG_PLT: if (theinst->data.plt->props) { sprintf(buffer,"",theinst->data.plt->dbr,theinst->data.plt->props->name,(strlen(theinst->data.plt->props->name)<=30)?'"':'_'); } else { sprintf(buffer,"",theinst->data.plt->dbr); } break; case PROG_FLOAT: sprintf(buffer,"%#g",*theinst->data.flt); break; case PROG_ARRAY: { int n; char c; int i; bcopy("data.arr->ndims); n += strlen(&buffer[n]); c = ':'; for (i=0;(idata.arr->ndims)&&(n<32);i++) { buffer[n++] = c; sprintf(&buffer[n],"%d",theinst->data.arr->dims[i]); n += strlen(&buffer[n]); c = 'x'; } if (i < theinst->data.arr->ndims) { buffer[n++] = 'x'; buffer[n++] = '.'; buffer[n++] = '.'; buffer[n++] = '.'; } sprintf(&buffer[n],"[%d]>",theinst->data.arr->refcnt); n += strlen(&buffer[n]); } break; case PROG_QUAD: sprintf(buffer,"",mufquad_to_str(*theinst->data.quad)); break; case PROG_OFILE: sprintf(buffer,"",fileno(theinst->data.ofile->f),(int)theinst->data.ofile->who,theinst->data.ofile->path); break; default: sprintf(buffer,"?T%d?",theinst->type); break; } return(&buffer[0]); } /* produce one line summary of current state. Note that sp is the next space on the stack -- 0..sp-1 is the current contents. */ char *debug_inst(struct inst *pc, struct inst *stack, int sp) { static char buffer[512]; int count; char *bp; dbref d; bp = &buffer[0]; strcpy(bp,"Debug> Stack( "); bp += strlen(bp); if (sp > 5) { strcpy(bp,"..., "); bp += 5; } count = (sp > 5) ? sp - 5 : 0; while (count < sp) { strcpy(bp,insttotext(stack+count)); bp += strlen(bp); if (++count < sp) { strcat(bp,", "); bp += 2; } } strcpy(bp," ) "); bp += 3; d = pc->prog; if ((d < db_top) && (Typeof(d) == TYPE_PROGRAM)) { union specific *s; s = &DBFETCH(d)->sp; if ( s->program.codevec && (pc >= s->program.codevec) && (pc < s->program.codevec+s->program.codesiz) ) { struct stab *st; st = findstab(d,pc-s->program.codevec); if (st) { sprintf(bp,"%s+%d",st->name,(int)(pc-s->program.codevec)-st->off); } else { sprintf(bp,"#%d?ns",(int)d); } } else { sprintf(bp,"#%d?nc",(int)d); } } else { sprintf(bp,"#%d?np",(int)d); } bp += strlen(bp); *bp++ = ':'; *bp++ = ' '; strcpy(bp,insttotext(pc)); return(&buffer[0]); }