PF_VarString return a plain char * and make it easier to add "at load" init

functions
This commit is contained in:
Bill Currie 2003-11-20 07:46:56 +00:00
parent 14c65d48c7
commit 5f5662a063
8 changed files with 129 additions and 73 deletions

View file

@ -70,10 +70,10 @@ void PR_ExecuteProgram (progs_t *pr, func_t fnum);
void PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts,
int zone);
void PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone);
void PR_LoadStrings (progs_t *pr);
void PR_LoadDebug (progs_t *pr);
int PR_LoadStrings (progs_t *pr);
int PR_LoadDebug (progs_t *pr);
edict_t *PR_InitEdicts (progs_t *pr, int num_edicts);
void PR_Check_Opcodes (progs_t *pr);
int PR_Check_Opcodes (progs_t *pr);
void PR_Profile_f (void);
@ -206,11 +206,15 @@ builtin_t *PR_FindBuiltin (progs_t *pr, const char *name);
int PR_RelocateBuiltins (progs_t *pr);
int PR_ResolveGlobals (progs_t *pr);
typedef int pr_load_func_t (progs_t *);
void PR_AddLoadFunc (progs_t *pr, pr_load_func_t *func);
int PR_RunLoadFuncs (progs_t *pr);
//
// PR Obj stuff
//
void PR_Obj_Progs_Init (progs_t *pr);
void PR_InitRuntime (progs_t *pr);
int PR_InitRuntime (progs_t *pr);
//
// PR Strings stuff
@ -268,7 +272,7 @@ extern const char *pr_gametype;
// PR Cmds stuff
//
const char *PF_VarString (progs_t *pr, int first);
char *PF_VarString (progs_t *pr, int first);
void PR_Cmds_Init (progs_t *pr);
//============================================================================
@ -300,6 +304,10 @@ struct progs_s {
struct hashtab_s *global_hash;
struct hashtab_s *field_hash;
int num_load_funcs;
int max_load_funcs;
pr_load_func_t **load_funcs;
// garbage collected strings
strref_t *static_strings;
strref_t **dynamic_strings;

View file

@ -61,7 +61,7 @@ const char *pr_gametype = "";
// FIXME: Hunk_TempAlloc, Sys_Printf, Cvar_*, PR_SetString, PR_RunError, ED_PrintEdicts, PF_traceon, PF_traceoff, ED_PrintNum, PR_FindBuiltin isn't threadsafe/reentrant
const char *
char *
PF_VarString (progs_t *pr, int first)
{
char *out;

View file

@ -185,7 +185,7 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
return f;
}
void
int
PR_LoadDebug (progs_t *pr)
{
char *sym_path;
@ -202,7 +202,7 @@ PR_LoadDebug (progs_t *pr)
pr->local_defs = 0;
if (!pr_debug->int_val)
return;
return 1;
def = PR_FindGlobal (pr, ".debug_file");
if (def)
@ -210,7 +210,7 @@ PR_LoadDebug (progs_t *pr)
Hash_FlushTable (file_hash);
if (!str)
return;
return 1;
pr->debugfile = PR_GetString (pr, str->string_var);
sym_file = QFS_SkipPath (pr->debugfile);
path_end = QFS_SkipPath (pr->progs_name);
@ -221,7 +221,7 @@ PR_LoadDebug (progs_t *pr)
pr->debug = pr->load_file (pr, sym_path);
if (!pr->debug) {
Sys_Printf ("can't load %s for debug info\n", sym_path);
return;
return 1;
}
pr->debug->version = LittleLong (pr->debug->version);
if (pr->debug->version != PROG_DEBUG_VERSION) {
@ -232,7 +232,7 @@ PR_LoadDebug (progs_t *pr)
pr->debug->version & 0xfff);
Hunk_FreeToLowMark (start);
pr->debug = 0;
return;
return 1;
}
pr->debug->crc = LittleShort (pr->debug->crc);
if (pr->debug->crc != pr->crc) {
@ -244,7 +244,7 @@ PR_LoadDebug (progs_t *pr)
pr->crc);
Hunk_FreeToLowMark (start);
pr->debug = 0;
return;
return 1;
}
pr->debug->you_tell_me_and_we_will_both_know = LittleShort
(pr->debug->you_tell_me_and_we_will_both_know);
@ -287,6 +287,7 @@ PR_LoadDebug (progs_t *pr)
pr->local_defs[i].ofs = LittleShort (pr->local_defs[i].ofs);
pr->local_defs[i].s_name = LittleLong (pr->local_defs[i].s_name);
}
return 1;
}
pr_auxfunction_t *

View file

@ -265,6 +265,42 @@ PR_LoadProgsFile (progs_t * pr, QFile *file, int size, int edicts, int zone)
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
}
void
PR_AddLoadFunc (progs_t *pr, int (*func)(progs_t *))
{
if (pr->num_load_funcs == pr->max_load_funcs) {
int n;
pr->max_load_funcs += 8;
n = pr->max_load_funcs;
pr->load_funcs = realloc (pr->load_funcs,
n * sizeof (pr_load_func_t *));
SYS_CHECKMEM (pr->load_funcs);
}
pr->load_funcs[pr->num_load_funcs++] = func;
}
static int (*load_funcs[])(progs_t *) = {
PR_ResolveGlobals,
PR_Check_Opcodes,
PR_LoadStrings,
PR_LoadDebug,
};
int
PR_RunLoadFuncs (progs_t *pr)
{
int i;
for (i = 0; i < sizeof (load_funcs) / sizeof (load_funcs[0]); i++)
if (!load_funcs[i](pr))
return 0;
for (i = 0; i < pr->num_load_funcs; i++)
if (!pr->load_funcs[i](pr))
return 0;
return PR_InitRuntime (pr);
}
/*
PR_LoadProgs
*/
@ -282,20 +318,8 @@ PR_LoadProgs (progs_t *pr, const char *progsname, int edicts, int zone)
if (!pr->progs)
return;
if (!PR_RelocateBuiltins (pr))
if (!PR_RunLoadFuncs (pr))
PR_Error (pr, "unable to load %s", progsname);
if (!PR_ResolveGlobals (pr))
PR_Error (pr, "unable to load %s", progsname);
// initialise the strings managment code
PR_LoadStrings (pr);
PR_LoadDebug (pr);
PR_Check_Opcodes (pr);
PR_InitRuntime (pr);
}
void

View file

@ -965,7 +965,7 @@ PR_Obj_Progs_Init (progs_t *pr)
}
}
void
int
PR_InitRuntime (progs_t *pr)
{
int fnum;
@ -1019,4 +1019,5 @@ PR_InitRuntime (progs_t *pr)
finish_category (pr, *category);
}
free (category_list);
return 1;
}

View file

@ -1057,43 +1057,71 @@ error:
(long)(st - pr->pr_statements), op->opname);
}
void
int
PR_Check_Opcodes (progs_t *pr)
{
opcode_t *op;
dstatement_t *st;
int state_ok = 0;
unsigned i;
if (!pr_boundscheck->int_val)
return;
for (st = pr->pr_statements;
(unsigned long) (st - pr->pr_statements) < pr->progs->numstatements;
st++) {
op = PR_Opcode (st->op);
if (!op) {
PR_Error (pr,
"PR_Check_Opcodes: unknown opcode %d at statement %ld",
st->op, (long)(st - pr->pr_statements));
if (pr->globals.time && pr->globals.self && pr->fields.nextthink != -1
&& pr->fields.think != -1 && pr->fields.frame != -1)
state_ok = 1;
if (!pr_boundscheck->int_val) {
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements;
st++, i++) {
op = PR_Opcode (st->op);
if (!op) {
PR_Error (pr, "PR_Check_Opcodes: unknown opcode %d at "
"statement %ld", st->op,
(long)(st - pr->pr_statements));
}
if (st->op == OP_STATE && !state_ok) {
PR_Error (pr, "PR_Check_Opcodes: %s used with missing fields "
"or globals", op->opname);
}
}
switch (st->op) {
case OP_IF:
case OP_IFNOT:
check_global (pr, st, op, op->type_a, st->a);
check_branch (pr, st, op, st->b);
break;
case OP_GOTO:
check_branch (pr, st, op, st->a);
break;
case OP_DONE:
case OP_RETURN:
check_global (pr, st, op, ev_integer, st->a);
check_global (pr, st, op, ev_void, st->b);
check_global (pr, st, op, ev_void, st->c);
break;
default:
check_global (pr, st, op, op->type_a, st->a);
check_global (pr, st, op, op->type_b, st->b);
check_global (pr, st, op, op->type_c, st->c);
break;
} else {
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements;
st++, i++) {
op = PR_Opcode (st->op);
if (!op) {
PR_Error (pr, "PR_Check_Opcodes: unknown opcode %d at "
"statement %ld", st->op,
(long)(st - pr->pr_statements));
}
switch (st->op) {
case OP_IF:
case OP_IFNOT:
check_global (pr, st, op, op->type_a, st->a);
check_branch (pr, st, op, st->b);
break;
case OP_GOTO:
check_branch (pr, st, op, st->a);
break;
case OP_DONE:
case OP_RETURN:
check_global (pr, st, op, ev_integer, st->a);
check_global (pr, st, op, ev_void, st->b);
check_global (pr, st, op, ev_void, st->c);
break;
case OP_STATE:
if (!state_ok) {
PR_Error (pr, "PR_Check_Opcodes: %s used with missing "
"fields or globals", op->opname);
}
check_global (pr, st, op, op->type_a, st->a);
check_global (pr, st, op, op->type_b, st->b);
break;
default:
check_global (pr, st, op, op->type_a, st->a);
check_global (pr, st, op, op->type_b, st->b);
check_global (pr, st, op, op->type_c, st->c);
break;
}
}
}
return 1;
}

View file

@ -190,21 +190,14 @@ PR_ResolveGlobals (progs_t *pr)
goto error;
pr->pr_param_size = G_INT (pr, def->ofs);
}
if (!(def = PR_FindGlobal (pr, sym = "time")))
goto error;
pr->globals.time = &G_FLOAT (pr, def->ofs);
if (!(def = PR_FindGlobal (pr, ".self")))
if (!(def = PR_FindGlobal (pr, "self"))) {
sym = "self";
goto error;
}
pr->globals.self = &G_INT (pr, def->ofs);
if ((pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink")) == -1)
goto error;
if ((pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame")) == -1)
goto error;
if ((pr->fields.think = ED_GetFieldIndex (pr, sym = "think")) == -1)
goto error;
if ((def = PR_FindGlobal (pr, "time")))
pr->globals.time = &G_FLOAT (pr, def->ofs);
if ((def = PR_FindGlobal (pr, ".self"))
|| (def = PR_FindGlobal (pr, "self")))
pr->globals.self = &G_INT (pr, def->ofs);
pr->fields.nextthink = ED_GetFieldIndex (pr, sym = "nextthink");
pr->fields.frame = ED_GetFieldIndex (pr, sym = "frame");
pr->fields.think = ED_GetFieldIndex (pr, sym = "think");
return 1;
error:
Sys_Printf ("%s: undefined symbol: %s\n", pr->progs_name, sym);

View file

@ -115,7 +115,7 @@ strref_free (void *_sr, void *_pr)
}
}
void
int
PR_LoadStrings (progs_t *pr)
{
char *end = pr->pr_strings + pr->pr_stringsize;
@ -148,6 +148,7 @@ PR_LoadStrings (progs_t *pr)
count++;
}
pr->num_strings = count;
return 1;
}
void