mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-27 06:34:11 +00:00
debugging improvements. opcodes now sport an optional format specifier for
printing their args (default is "%Ga, %Gb, %gc") and PR_ValueString will try to print what a pointer points to
This commit is contained in:
parent
ab94498503
commit
0806fc33dd
5 changed files with 890 additions and 234 deletions
|
@ -296,6 +296,7 @@ typedef struct opcode_s {
|
||||||
qboolean right_associative;
|
qboolean right_associative;
|
||||||
etype_t type_a, type_b, type_c;
|
etype_t type_a, type_b, type_c;
|
||||||
unsigned int min_version;
|
unsigned int min_version;
|
||||||
|
const char *fmt;
|
||||||
} opcode_t;
|
} opcode_t;
|
||||||
|
|
||||||
extern opcode_t pr_opcodes[];
|
extern opcode_t pr_opcodes[];
|
||||||
|
|
|
@ -196,8 +196,8 @@ void ED_PrintNum (progs_t *pr, int ent);
|
||||||
void ED_Count (progs_t *pr);
|
void ED_Count (progs_t *pr);
|
||||||
void PR_Profile (progs_t *pr);
|
void PR_Profile (progs_t *pr);
|
||||||
|
|
||||||
struct dstring_s *PR_GlobalString (progs_t *pr, int ofs, etype_t type);
|
const char *PR_GlobalString (progs_t *pr, int ofs, etype_t type);
|
||||||
struct dstring_s *PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type);
|
const char *PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type);
|
||||||
|
|
||||||
pr_type_t *GetEdictFieldValue(progs_t *pr, edict_t *ed, const char *field);
|
pr_type_t *GetEdictFieldValue(progs_t *pr, edict_t *ed, const char *field);
|
||||||
|
|
||||||
|
|
|
@ -431,76 +431,105 @@ void
|
||||||
PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
||||||
{
|
{
|
||||||
int addr = s - pr->pr_statements;
|
int addr = s - pr->pr_statements;
|
||||||
int ofs;
|
const char *fmt;
|
||||||
opcode_t *op;
|
opcode_t *op;
|
||||||
|
static dstring_t *line;
|
||||||
|
|
||||||
|
if (!line)
|
||||||
|
line = dstring_new ();
|
||||||
|
|
||||||
|
dstring_clearstr (line);
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug) {
|
if (pr_debug->int_val && pr->debug) {
|
||||||
const char *source_line = PR_Get_Source_Line (pr, addr);
|
const char *source_line = PR_Get_Source_Line (pr, addr);
|
||||||
|
|
||||||
if (source_line)
|
if (source_line)
|
||||||
Sys_Printf ("%s\n", source_line);
|
dasprintf (line, "%s\n", source_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
op = PR_Opcode (s->op);
|
op = PR_Opcode (s->op);
|
||||||
if (!op) {
|
if (!op) {
|
||||||
Sys_Printf ("Unknown instruction %d\n", s->op);
|
Sys_Printf ("%sUnknown instruction %d\n", line->str, s->op);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_Printf ("%04x ", addr);
|
if (!(fmt = op->fmt))
|
||||||
|
fmt = "%Ga %Gb %gc";
|
||||||
|
|
||||||
|
dasprintf (line, "%04x ", addr);
|
||||||
if (pr_debug->int_val > 1)
|
if (pr_debug->int_val > 1)
|
||||||
Sys_Printf ("%02x %04x(%s) %04x(%s) %04x(%s)\t",
|
dasprintf (line, "%02x %04x(%8s) %04x(%8s) %04x(%8s)\t",
|
||||||
s->op,
|
s->op,
|
||||||
s->a, pr_type_name[op->type_a],
|
s->a, pr_type_name[op->type_a],
|
||||||
s->b, pr_type_name[op->type_b],
|
s->b, pr_type_name[op->type_b],
|
||||||
s->c, pr_type_name[op->type_c]);
|
s->c, pr_type_name[op->type_c]);
|
||||||
|
|
||||||
Sys_Printf ("%s ", op->opname);
|
dasprintf (line, "%s ", op->opname);
|
||||||
|
|
||||||
switch (s->op) {
|
while (*fmt) {
|
||||||
case OP_IF:
|
if (*fmt == '%') {
|
||||||
case OP_IFNOT:
|
if (fmt[1] == '%') {
|
||||||
case OP_IFBE:
|
dstring_appendsubstr (line, fmt + 1, 1);
|
||||||
case OP_IFB:
|
fmt += 2;
|
||||||
case OP_IFAE:
|
} else {
|
||||||
case OP_IFA:
|
char mode = fmt[1];
|
||||||
ofs = (short) s->b;
|
char opchar = fmt[2];
|
||||||
|
long opval;
|
||||||
|
etype_t optype;
|
||||||
|
|
||||||
Sys_Printf ("%s branch %i (%04x)",
|
switch (opchar) {
|
||||||
PR_GlobalString (pr, s->a, ev_integer)->str, ofs, addr + ofs);
|
case 'a':
|
||||||
break;
|
opval = s->a;
|
||||||
|
optype = op->type_a;
|
||||||
case OP_GOTO:
|
break;
|
||||||
ofs = (short) s->a;
|
case 'b':
|
||||||
Sys_Printf ("branch %i (%04x)", ofs, addr + ofs);
|
opval = s->b;
|
||||||
break;
|
optype = op->type_b;
|
||||||
|
break;
|
||||||
case OP_RETURN:
|
case 'c':
|
||||||
case OP_DONE:
|
opval = s->c;
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->a, ev_void)->str);
|
optype = op->type_c;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
default:
|
goto err;
|
||||||
if (op->type_a != ev_void)
|
}
|
||||||
Sys_Printf ("%s", PR_GlobalString (pr, s->a, op->type_a)->str);
|
switch (mode) {
|
||||||
|
case 'V':
|
||||||
if (op->type_b != ev_void) {
|
dstring_appendstr (line,
|
||||||
if (op->type_c != ev_void)
|
PR_GlobalString (pr, opval,
|
||||||
Sys_Printf (", %s", PR_GlobalString (pr, s->b, op->type_b)->str);
|
ev_void));
|
||||||
else
|
break;
|
||||||
Sys_Printf (", %s",
|
case 'G':
|
||||||
PR_GlobalStringNoContents (pr, s->b, op->type_b)->str);
|
dstring_appendstr (line,
|
||||||
}
|
PR_GlobalString (pr, opval,
|
||||||
|
optype));
|
||||||
if (op->type_c != ev_void) {
|
break;
|
||||||
if (op->type_b == ev_pointer && op->type_c == ev_integer)
|
case 'g':
|
||||||
Sys_Printf (", %s", PR_GlobalString (pr, s->c, op->type_c)->str);
|
dstring_appendstr (line,
|
||||||
else
|
PR_GlobalStringNoContents (pr,
|
||||||
Sys_Printf (", %s",
|
opval,
|
||||||
PR_GlobalStringNoContents (pr, s->c, op->type_c)->str);
|
optype));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
dasprintf (line, "%d", (short) opval);
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
dasprintf (line, "%d", addr + (short) opval);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
fmt += 3;
|
||||||
|
continue;
|
||||||
|
err:
|
||||||
|
dstring_appendstr (line, fmt);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dstring_appendsubstr (line, fmt++, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Sys_Printf ("\n");
|
Sys_Printf ("%s\n", line->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -194,6 +194,7 @@ PR_ValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
||||||
{
|
{
|
||||||
static char line[256];
|
static char line[256];
|
||||||
ddef_t *def;
|
ddef_t *def;
|
||||||
|
int ofs;
|
||||||
dfunction_t *f;
|
dfunction_t *f;
|
||||||
|
|
||||||
type &= ~DEF_SAVEGLOBAL;
|
type &= ~DEF_SAVEGLOBAL;
|
||||||
|
@ -238,7 +239,17 @@ PR_ValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
||||||
val->vector_var[2]);
|
val->vector_var[2]);
|
||||||
break;
|
break;
|
||||||
case ev_pointer:
|
case ev_pointer:
|
||||||
snprintf (line, sizeof (line), "[$%x]", val->integer_var);
|
def = 0;
|
||||||
|
ofs = val->integer_var;
|
||||||
|
if (pr_debug->int_val && pr->debug)
|
||||||
|
def = PR_Get_Local_Def (pr, ofs);
|
||||||
|
if (!def)
|
||||||
|
def = ED_GlobalAtOfs (pr, ofs);
|
||||||
|
if (def)
|
||||||
|
snprintf (line, sizeof (line), "&%s",
|
||||||
|
PR_GetString (pr, def->s_name));
|
||||||
|
else
|
||||||
|
snprintf (line, sizeof (line), "[$%x]", ofs);
|
||||||
break;
|
break;
|
||||||
case ev_quaternion:
|
case ev_quaternion:
|
||||||
snprintf (line, sizeof (line), "'%g %g %g %g'",
|
snprintf (line, sizeof (line), "'%g %g %g %g'",
|
||||||
|
@ -268,7 +279,7 @@ PR_ValueString (progs_t *pr, etype_t type, pr_type_t *val)
|
||||||
|
|
||||||
Returns a string with a description and the contents of a global
|
Returns a string with a description and the contents of a global
|
||||||
*/
|
*/
|
||||||
dstring_t *
|
const char *
|
||||||
PR_GlobalString (progs_t *pr, int ofs, etype_t type)
|
PR_GlobalString (progs_t *pr, int ofs, etype_t type)
|
||||||
{
|
{
|
||||||
ddef_t *def = NULL;
|
ddef_t *def = NULL;
|
||||||
|
@ -280,7 +291,7 @@ PR_GlobalString (progs_t *pr, int ofs, etype_t type)
|
||||||
|
|
||||||
if (type == ev_short) {
|
if (type == ev_short) {
|
||||||
dsprintf (line, "%04x", (short) ofs);
|
dsprintf (line, "%04x", (short) ofs);
|
||||||
return line;
|
return line->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug)
|
if (pr_debug->int_val && pr->debug)
|
||||||
|
@ -320,10 +331,10 @@ PR_GlobalString (progs_t *pr, int ofs, etype_t type)
|
||||||
dsprintf (line, "%s%s(%s)", name, oi, s);
|
dsprintf (line, "%s%s(%s)", name, oi, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return line;
|
return line->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
dstring_t *
|
const char *
|
||||||
PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type)
|
PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type)
|
||||||
{
|
{
|
||||||
static dstring_t *line = NULL;
|
static dstring_t *line = NULL;
|
||||||
|
@ -334,7 +345,7 @@ PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type)
|
||||||
|
|
||||||
if (type == ev_short) {
|
if (type == ev_short) {
|
||||||
dsprintf (line, "%x", (short) ofs);
|
dsprintf (line, "%x", (short) ofs);
|
||||||
return line;
|
return line->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pr_debug->int_val && pr->debug)
|
if (pr_debug->int_val && pr->debug)
|
||||||
|
@ -346,7 +357,7 @@ PR_GlobalStringNoContents (progs_t *pr, int ofs, etype_t type)
|
||||||
else
|
else
|
||||||
dsprintf (line, "%s", PR_GetString (pr, def->s_name));
|
dsprintf (line, "%s", PR_GetString (pr, def->s_name));
|
||||||
|
|
||||||
return line;
|
return line->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue