mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
add PR_PushFrame and PR_PopFrame so temp strings are easy to use for
parameters to progs functions. double the progs stack sizes (call depth of 32? eek) allow one extra call on the progs stack :) misc minor cleanups
This commit is contained in:
parent
211908e741
commit
dfc83c1f5f
10 changed files with 177 additions and 134 deletions
|
@ -64,6 +64,8 @@ void PR_Init (void);
|
||||||
void PR_Init_Cvars (void);
|
void PR_Init_Cvars (void);
|
||||||
|
|
||||||
void PR_PrintStatement (progs_t *pr, dstatement_t *s);
|
void PR_PrintStatement (progs_t *pr, dstatement_t *s);
|
||||||
|
void PR_PushFrame (progs_t *pr);
|
||||||
|
void PR_PopFrame (progs_t *pr);
|
||||||
void PR_EnterFunction (progs_t *pr, dfunction_t *f);
|
void PR_EnterFunction (progs_t *pr, dfunction_t *f);
|
||||||
void PR_ExecuteProgram (progs_t *pr, func_t fnum);
|
void PR_ExecuteProgram (progs_t *pr, func_t fnum);
|
||||||
void PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int edicts,
|
void PR_LoadProgsFile (progs_t *pr, QFile *file, int size, int edicts,
|
||||||
|
@ -286,13 +288,15 @@ void PR_Cmds_Init (progs_t *pr);
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#define MAX_STACK_DEPTH 32
|
#define MAX_STACK_DEPTH 64
|
||||||
#define LOCALSTACK_SIZE 2048
|
#define LOCALSTACK_SIZE 4096
|
||||||
|
|
||||||
|
typedef struct strref_s strref_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int s;
|
int s;
|
||||||
dfunction_t *f;
|
dfunction_t *f;
|
||||||
struct strref_s *tstr;
|
strref_t *tstr;
|
||||||
} prstack_t;
|
} prstack_t;
|
||||||
|
|
||||||
struct progs_s {
|
struct progs_s {
|
||||||
|
@ -312,15 +316,13 @@ struct progs_s {
|
||||||
int max_load_funcs;
|
int max_load_funcs;
|
||||||
pr_load_func_t **load_funcs;
|
pr_load_func_t **load_funcs;
|
||||||
|
|
||||||
// garbage collected strings
|
|
||||||
struct dstring_mem_s *ds_mem;
|
struct dstring_mem_s *ds_mem;
|
||||||
struct strref_s *static_strings;
|
strref_t *static_strings;
|
||||||
struct strref_s **dynamic_strings;
|
strref_t **dynamic_strings;
|
||||||
struct strref_s *free_string_refs;
|
|
||||||
unsigned dyn_str_size;
|
unsigned dyn_str_size;
|
||||||
struct hashtab_s *strref_hash;
|
struct hashtab_s *strref_hash;
|
||||||
int num_strings;
|
int num_strings;
|
||||||
struct strref_s *pr_xtstr;
|
strref_t *pr_xtstr;
|
||||||
|
|
||||||
dfunction_t *pr_functions;
|
dfunction_t *pr_functions;
|
||||||
char *pr_strings;
|
char *pr_strings;
|
||||||
|
|
|
@ -586,14 +586,13 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
||||||
return;
|
return;
|
||||||
} else if (menu->items && menu->items[menu->cur_item]->func
|
} else if (menu->items && menu->items[menu->cur_item]->func
|
||||||
&& menu->items[menu->cur_item]->allkeys) {
|
&& menu->items[menu->cur_item]->allkeys) {
|
||||||
|
PR_PushFrame (&menu_pr_state);
|
||||||
item = menu->items[menu->cur_item];
|
item = menu->items[menu->cur_item];
|
||||||
if (item->text)
|
P_STRING (&menu_pr_state, 0) = PR_SetTempString (&menu_pr_state,
|
||||||
P_INT (&menu_pr_state, 0) =
|
item->text);
|
||||||
PR_SetString (&menu_pr_state, item->text);
|
|
||||||
else
|
|
||||||
P_INT (&menu_pr_state, 0) = 0;
|
|
||||||
P_INT (&menu_pr_state, 1) = key;
|
P_INT (&menu_pr_state, 1) = key;
|
||||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||||
|
PR_PopFrame (&menu_pr_state);
|
||||||
if (R_INT (&menu_pr_state))
|
if (R_INT (&menu_pr_state))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -615,13 +614,12 @@ Menu_KeyEvent (knum_t key, short unicode, qboolean down)
|
||||||
{
|
{
|
||||||
item = menu->items[menu->cur_item];
|
item = menu->items[menu->cur_item];
|
||||||
if (item->func) {
|
if (item->func) {
|
||||||
if (item->text)
|
PR_PushFrame (&menu_pr_state);
|
||||||
P_INT (&menu_pr_state, 0) =
|
P_STRING (&menu_pr_state, 0) =
|
||||||
PR_SetString (&menu_pr_state, item->text);
|
PR_SetTempString (&menu_pr_state, item->text);
|
||||||
else
|
|
||||||
P_INT (&menu_pr_state, 0) = 0;
|
|
||||||
P_INT (&menu_pr_state, 1) = key;
|
P_INT (&menu_pr_state, 1) = key;
|
||||||
PR_ExecuteProgram (&menu_pr_state, item->func);
|
PR_ExecuteProgram (&menu_pr_state, item->func);
|
||||||
|
PR_PopFrame (&menu_pr_state);
|
||||||
} else {
|
} else {
|
||||||
menu = item;
|
menu = item;
|
||||||
if (menu->enter_hook) {
|
if (menu->enter_hook) {
|
||||||
|
|
|
@ -85,14 +85,16 @@ bi_gib_builtin_f (void)
|
||||||
if (!builtin)
|
if (!builtin)
|
||||||
Sys_Error ("bi_gib_builtin_f: unexpected call %s", GIB_Argv (0));
|
Sys_Error ("bi_gib_builtin_f: unexpected call %s", GIB_Argv (0));
|
||||||
|
|
||||||
|
PR_PushFrame (builtin->pr);
|
||||||
pr_list = PR_Zone_Malloc (builtin->pr, GIB_Argc() * sizeof (pr_type_t));
|
pr_list = PR_Zone_Malloc (builtin->pr, GIB_Argc() * sizeof (pr_type_t));
|
||||||
|
|
||||||
for (i = 0; i < GIB_Argc(); i++)
|
for (i = 0; i < GIB_Argc(); i++)
|
||||||
pr_list[i].integer_var = PR_SetString (builtin->pr, GIB_Argv(i));
|
pr_list[i].integer_var = PR_SetTempString (builtin->pr, GIB_Argv(i));
|
||||||
|
|
||||||
P_INT (builtin->pr, 0) = GIB_Argc();
|
P_INT (builtin->pr, 0) = GIB_Argc();
|
||||||
P_INT (builtin->pr, 1) = POINTER_TO_PROG (builtin->pr, pr_list);
|
P_INT (builtin->pr, 1) = POINTER_TO_PROG (builtin->pr, pr_list);
|
||||||
PR_ExecuteProgram (builtin->pr, builtin->func);
|
PR_ExecuteProgram (builtin->pr, builtin->func);
|
||||||
|
PR_PopFrame (builtin->pr);
|
||||||
PR_Zone_Free (builtin->pr, pr_list);
|
PR_Zone_Free (builtin->pr, pr_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -535,51 +535,57 @@ PR_PrintStatement (progs_t * pr, dstatement_t *s)
|
||||||
Sys_Printf ("%s\n", line->str);
|
Sys_Printf ("%s\n", line->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_frame (progs_t *pr, prstack_t *frame)
|
||||||
|
{
|
||||||
|
dfunction_t *f = frame->f;
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
Sys_Printf ("<NO FUNCTION>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pr_debug->int_val && pr->debug) {
|
||||||
|
pr_lineno_t *lineno = PR_Find_Lineno (pr, frame->s);
|
||||||
|
pr_auxfunction_t *func = PR_Get_Lineno_Func (pr, lineno);
|
||||||
|
unsigned int line = PR_Get_Lineno_Line (pr, lineno);
|
||||||
|
int addr = PR_Get_Lineno_Addr (pr, lineno);
|
||||||
|
|
||||||
|
line += func->source_line;
|
||||||
|
if (addr == frame->s) {
|
||||||
|
Sys_Printf ("%12s:%d : %s: %x\n",
|
||||||
|
PR_GetString (pr, f->s_file),
|
||||||
|
line,
|
||||||
|
PR_GetString (pr, f->s_name),
|
||||||
|
frame->s);
|
||||||
|
} else {
|
||||||
|
Sys_Printf ("%12s:%d+%d : %s: %x\n",
|
||||||
|
PR_GetString (pr, f->s_file),
|
||||||
|
line, frame->s - addr,
|
||||||
|
PR_GetString (pr, f->s_name),
|
||||||
|
frame->s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Sys_Printf ("%12s : %s: %x\n", PR_GetString (pr, f->s_file),
|
||||||
|
PR_GetString (pr, f->s_name), frame->s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PR_StackTrace (progs_t * pr)
|
PR_StackTrace (progs_t *pr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
dfunction_t *f;
|
prstack_t top;
|
||||||
|
|
||||||
if (pr->pr_depth == 0) {
|
if (pr->pr_depth == 0) {
|
||||||
Sys_Printf ("<NO STACK>\n");
|
Sys_Printf ("<NO STACK>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
|
top.s = pr->pr_xstatement;
|
||||||
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
top.f = pr->pr_xfunction;
|
||||||
for (i = pr->pr_depth; i >= 0; i--) {
|
dump_frame (pr, &top);
|
||||||
f = pr->pr_stack[i].f;
|
for (i = pr->pr_depth - 1; i >= 0; i--)
|
||||||
|
dump_frame (pr, pr->pr_stack + i);
|
||||||
if (!f) {
|
|
||||||
Sys_Printf ("<NO FUNCTION>\n");
|
|
||||||
} else {
|
|
||||||
if (pr_debug->int_val && pr->debug) {
|
|
||||||
pr_lineno_t *lineno = PR_Find_Lineno (pr, pr->pr_stack[i].s);
|
|
||||||
pr_auxfunction_t *func = PR_Get_Lineno_Func (pr, lineno);
|
|
||||||
unsigned int line = PR_Get_Lineno_Line (pr, lineno);
|
|
||||||
int addr = PR_Get_Lineno_Addr (pr, lineno);
|
|
||||||
|
|
||||||
line += func->source_line;
|
|
||||||
if (addr == pr->pr_stack[i].s) {
|
|
||||||
Sys_Printf ("%12s:%d : %s: %x\n",
|
|
||||||
PR_GetString (pr, f->s_file),
|
|
||||||
line,
|
|
||||||
PR_GetString (pr, f->s_name),
|
|
||||||
pr->pr_stack[i].s);
|
|
||||||
} else {
|
|
||||||
Sys_Printf ("%12s:%d+%d : %s: %x\n",
|
|
||||||
PR_GetString (pr, f->s_file),
|
|
||||||
line, pr->pr_stack[i].s - addr,
|
|
||||||
PR_GetString (pr, f->s_name),
|
|
||||||
pr->pr_stack[i].s);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Sys_Printf ("%12s : %s: %x\n", PR_GetString (pr, f->s_file),
|
|
||||||
PR_GetString (pr, f->s_name), pr->pr_stack[i].s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -75,23 +75,59 @@ PR_RunError (progs_t * pr, const char *error, ...)
|
||||||
PR_Error (pr, "Program error: %s", string->str);
|
PR_Error (pr, "Program error: %s", string->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
PR_PushFrame (progs_t *pr)
|
||||||
|
{
|
||||||
|
prstack_t *frame;
|
||||||
|
|
||||||
|
if (pr->pr_depth == MAX_STACK_DEPTH)
|
||||||
|
PR_RunError (pr, "stack overflow");
|
||||||
|
|
||||||
|
frame = pr->pr_stack + pr->pr_depth++;
|
||||||
|
|
||||||
|
frame->s = pr->pr_xstatement;
|
||||||
|
frame->f = pr->pr_xfunction;
|
||||||
|
frame->tstr = pr->pr_xtstr;
|
||||||
|
|
||||||
|
pr->pr_xtstr = 0;
|
||||||
|
pr->pr_xfunction = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
PR_PopFrame (progs_t *pr)
|
||||||
|
{
|
||||||
|
prstack_t *frame;
|
||||||
|
|
||||||
|
if (pr->pr_depth <= 0)
|
||||||
|
PR_Error (pr, "prog stack underflow");
|
||||||
|
|
||||||
|
if (pr->pr_xtstr)
|
||||||
|
PR_FreeTempStrings (pr);
|
||||||
|
|
||||||
|
// up stack
|
||||||
|
frame = pr->pr_stack + --pr->pr_depth;
|
||||||
|
|
||||||
|
pr->pr_xfunction = frame->f;
|
||||||
|
pr->pr_xstatement = frame->s;
|
||||||
|
pr->pr_xtstr = frame->tstr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PR_EnterFunction
|
PR_EnterFunction
|
||||||
|
|
||||||
Returns the new program statement counter
|
Returns the new program statement counter
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
PR_EnterFunction (progs_t *pr, dfunction_t *f)
|
||||||
{
|
{
|
||||||
int i, j, c, o;
|
int i, j, c, o;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
PR_PushFrame (pr);
|
||||||
|
|
||||||
//Sys_Printf("%s:\n", PR_GetString(pr,f->s_name));
|
//Sys_Printf("%s:\n", PR_GetString(pr,f->s_name));
|
||||||
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
|
pr->pr_xfunction = f;
|
||||||
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
|
pr->pr_xstatement = f->first_statement - 1; // offset the st++
|
||||||
pr->pr_depth++;
|
|
||||||
if (pr->pr_depth >= MAX_STACK_DEPTH - 1)
|
|
||||||
PR_RunError (pr, "stack overflow");
|
|
||||||
|
|
||||||
// save off any locals that the new function steps on
|
// save off any locals that the new function steps on
|
||||||
c = f->locals;
|
c = f->locals;
|
||||||
|
@ -134,39 +170,24 @@ PR_EnterFunction (progs_t * pr, dfunction_t *f)
|
||||||
(MAX_PARMS - i) * pr->pr_param_size * sizeof (pr_type_t));
|
(MAX_PARMS - i) * pr->pr_param_size * sizeof (pr_type_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pr->pr_xfunction = f;
|
|
||||||
pr->pr_xstatement = f->first_statement - 1; // offset the st++
|
|
||||||
pr->pr_xtstr = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PR_LeaveFunction (progs_t * pr)
|
PR_LeaveFunction (progs_t *pr)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
dfunction_t *f = pr->pr_xfunction;
|
||||||
|
|
||||||
if (pr->pr_depth <= 0)
|
PR_PopFrame (pr);
|
||||||
PR_Error (pr, "prog stack underflow");
|
|
||||||
|
|
||||||
// restore locals from the stack
|
// restore locals from the stack
|
||||||
c = pr->pr_xfunction->locals;
|
c = f->locals;
|
||||||
pr->localstack_used -= c;
|
pr->localstack_used -= c;
|
||||||
if (pr->localstack_used < 0)
|
if (pr->localstack_used < 0)
|
||||||
PR_RunError (pr, "PR_LeaveFunction: locals stack underflow");
|
PR_RunError (pr, "PR_LeaveFunction: locals stack underflow");
|
||||||
|
|
||||||
memcpy (&pr->pr_globals[pr->pr_xfunction->parm_start],
|
memcpy (&pr->pr_globals[f->parm_start],
|
||||||
&pr->localstack[pr->localstack_used],
|
&pr->localstack[pr->localstack_used], sizeof (pr_type_t) * c);
|
||||||
sizeof (pr_type_t) * c);
|
|
||||||
|
|
||||||
if (pr->pr_xtstr)
|
|
||||||
PR_FreeTempStrings (pr);
|
|
||||||
|
|
||||||
// up stack
|
|
||||||
pr->pr_depth--;
|
|
||||||
pr->pr_xfunction = pr->pr_stack[pr->pr_depth].f;
|
|
||||||
pr->pr_xstatement = pr->pr_stack[pr->pr_depth].s;
|
|
||||||
pr->pr_xtstr = pr->pr_stack[pr->pr_depth].tstr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPA (*op_a)
|
#define OPA (*op_a)
|
||||||
|
|
|
@ -403,7 +403,7 @@ pr_obj_msg_sendv (progs_t *pr)
|
||||||
PR_GetString (pr, op->sel_id));
|
PR_GetString (pr, op->sel_id));
|
||||||
if (args.count > 6)
|
if (args.count > 6)
|
||||||
args.count = 6;
|
args.count = 6;
|
||||||
memcpy (P_GPOINTER (pr, 2), G_GPOINTER (pr, args.list),
|
memcpy (pr->pr_params[2], G_GPOINTER (pr, args.list),
|
||||||
args.count * 4 * pr->pr_param_size);
|
args.count * 4 * pr->pr_param_size);
|
||||||
call_function (pr, method->method_imp);
|
call_function (pr, method->method_imp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,12 +46,37 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
|
|
||||||
typedef struct strref_s {
|
struct strref_s {
|
||||||
struct strref_s *next;
|
strref_t *next;
|
||||||
char *string;
|
char *string;
|
||||||
dstring_t *dstring;
|
dstring_t *dstring;
|
||||||
int count;
|
int count;
|
||||||
} strref_t;
|
};
|
||||||
|
|
||||||
|
// format adjustments
|
||||||
|
#define FMT_ALTFORM (1<<0)
|
||||||
|
#define FMT_LJUSTIFY (1<<1)
|
||||||
|
#define FMT_ZEROPAD (1<<2)
|
||||||
|
#define FMT_ADDSIGN (1<<3)
|
||||||
|
#define FMT_ADDBLANK (1<<4)
|
||||||
|
#define FMT_HEX (1<<5)
|
||||||
|
|
||||||
|
typedef struct fmt_item_s {
|
||||||
|
byte type;
|
||||||
|
unsigned flags;
|
||||||
|
int minFieldWidth;
|
||||||
|
int precision;
|
||||||
|
union {
|
||||||
|
const char *string_var;
|
||||||
|
int integer_var;
|
||||||
|
unsigned uinteger_var;
|
||||||
|
float float_var;
|
||||||
|
} data;
|
||||||
|
struct fmt_item_s *next;
|
||||||
|
} fmt_item_t;
|
||||||
|
|
||||||
|
static strref_t *free_string_refs;
|
||||||
|
static fmt_item_t *free_fmt_items;
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
pr_strings_alloc (void *_pr, size_t size)
|
pr_strings_alloc (void *_pr, size_t size)
|
||||||
|
@ -78,7 +103,7 @@ static strref_t *
|
||||||
new_string_ref (progs_t *pr)
|
new_string_ref (progs_t *pr)
|
||||||
{
|
{
|
||||||
strref_t *sr;
|
strref_t *sr;
|
||||||
if (!pr->free_string_refs) {
|
if (!free_string_refs) {
|
||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
pr->dyn_str_size++;
|
pr->dyn_str_size++;
|
||||||
|
@ -86,15 +111,15 @@ new_string_ref (progs_t *pr)
|
||||||
pr->dynamic_strings = realloc (pr->dynamic_strings, size);
|
pr->dynamic_strings = realloc (pr->dynamic_strings, size);
|
||||||
if (!pr->dynamic_strings)
|
if (!pr->dynamic_strings)
|
||||||
PR_Error (pr, "out of memory");
|
PR_Error (pr, "out of memory");
|
||||||
if (!(pr->free_string_refs = calloc (1024, sizeof (strref_t))))
|
if (!(free_string_refs = calloc (1024, sizeof (strref_t))))
|
||||||
PR_Error (pr, "out of memory");
|
PR_Error (pr, "out of memory");
|
||||||
pr->dynamic_strings[pr->dyn_str_size - 1] = pr->free_string_refs;
|
pr->dynamic_strings[pr->dyn_str_size - 1] = free_string_refs;
|
||||||
for (i = 0, sr = pr->free_string_refs; i < 1023; i++, sr++)
|
for (i = 0, sr = free_string_refs; i < 1023; i++, sr++)
|
||||||
sr->next = sr + 1;
|
sr->next = sr + 1;
|
||||||
sr->next = 0;
|
sr->next = 0;
|
||||||
}
|
}
|
||||||
sr = pr->free_string_refs;
|
sr = free_string_refs;
|
||||||
pr->free_string_refs = sr->next;
|
free_string_refs = sr->next;
|
||||||
sr->next = 0;
|
sr->next = 0;
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
@ -104,8 +129,8 @@ free_string_ref (progs_t *pr, strref_t *sr)
|
||||||
{
|
{
|
||||||
sr->string = 0;
|
sr->string = 0;
|
||||||
sr->dstring = 0;
|
sr->dstring = 0;
|
||||||
sr->next = pr->free_string_refs;
|
sr->next = free_string_refs;
|
||||||
pr->free_string_refs = sr;
|
free_string_refs = sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -173,7 +198,7 @@ PR_LoadStrings (progs_t *pr)
|
||||||
pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
|
pr->strref_hash = Hash_NewTable (1021, strref_get_key, strref_free,
|
||||||
pr);
|
pr);
|
||||||
pr->dynamic_strings = 0;
|
pr->dynamic_strings = 0;
|
||||||
pr->free_string_refs = 0;
|
free_string_refs = 0;
|
||||||
pr->dyn_str_size = 0;
|
pr->dyn_str_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,6 +307,9 @@ PR_SetTempString (progs_t *pr, const char *s)
|
||||||
{
|
{
|
||||||
strref_t *sr;
|
strref_t *sr;
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return PR_SetString (pr, "");
|
||||||
|
|
||||||
sr = new_string_ref (pr);
|
sr = new_string_ref (pr);
|
||||||
sr->string = pr_strdup(pr, s);
|
sr->string = pr_strdup(pr, s);
|
||||||
sr->count = 0;
|
sr->count = 0;
|
||||||
|
@ -346,28 +374,6 @@ PR_FreeTempStrings (progs_t *pr)
|
||||||
pr->pr_xtstr = 0;
|
pr->pr_xtstr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// format adjustments
|
|
||||||
#define FMT_ALTFORM (1<<0)
|
|
||||||
#define FMT_LJUSTIFY (1<<1)
|
|
||||||
#define FMT_ZEROPAD (1<<2)
|
|
||||||
#define FMT_ADDSIGN (1<<3)
|
|
||||||
#define FMT_ADDBLANK (1<<4)
|
|
||||||
#define FMT_HEX (1<<5)
|
|
||||||
|
|
||||||
typedef struct fmt_item_s {
|
|
||||||
byte type;
|
|
||||||
unsigned flags;
|
|
||||||
int minFieldWidth;
|
|
||||||
int precision;
|
|
||||||
union {
|
|
||||||
const char *string_var;
|
|
||||||
int integer_var;
|
|
||||||
unsigned uinteger_var;
|
|
||||||
float float_var;
|
|
||||||
} data;
|
|
||||||
struct fmt_item_s *next;
|
|
||||||
} fmt_item_t;
|
|
||||||
|
|
||||||
#define PRINT(t) \
|
#define PRINT(t) \
|
||||||
switch ((doWidth << 1) | doPrecision) { \
|
switch ((doWidth << 1) | doPrecision) { \
|
||||||
case 3: \
|
case 3: \
|
||||||
|
@ -446,8 +452,6 @@ I_DoPrint (dstring_t *result, fmt_item_t *formatting)
|
||||||
dstring_delete (tmp);
|
dstring_delete (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fmt_item_t *free_fmt_items;
|
|
||||||
|
|
||||||
static fmt_item_t *
|
static fmt_item_t *
|
||||||
new_fmt_item (void)
|
new_fmt_item (void)
|
||||||
{
|
{
|
||||||
|
@ -492,7 +496,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
||||||
|
|
||||||
*fi = new_fmt_item ();
|
*fi = new_fmt_item ();
|
||||||
c = l = format;
|
c = l = format;
|
||||||
while (*c) { // count "%"s, checking our input along the way
|
while (*c) {
|
||||||
if (*c++ == '%') {
|
if (*c++ == '%') {
|
||||||
if (c != l + 1) {
|
if (c != l + 1) {
|
||||||
// have some unformatted text to print
|
// have some unformatted text to print
|
||||||
|
@ -676,7 +680,7 @@ PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
||||||
fi = &(*fi)->next;
|
fi = &(*fi)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 && fmt_count != count) {
|
if (fmt_count != count) {
|
||||||
printf ("%d %d", fmt_count, count);
|
printf ("%d %d", fmt_count, count);
|
||||||
if (fmt_count > count)
|
if (fmt_count > count)
|
||||||
msg = "Not enough arguments for format string.";
|
msg = "Not enough arguments for format string.";
|
||||||
|
|
|
@ -859,10 +859,12 @@ SV_SetLocalinfo (const char *key, const char *value)
|
||||||
if (sv_funcs.LocalinfoChanged) {
|
if (sv_funcs.LocalinfoChanged) {
|
||||||
*sv_globals.time = sv.time;
|
*sv_globals.time = sv.time;
|
||||||
*sv_globals.self = 0;
|
*sv_globals.self = 0;
|
||||||
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, key);
|
PR_PushFrame (&sv_pr_state);
|
||||||
P_STRING (&sv_pr_state, 1) = PR_SetString (&sv_pr_state, oldvalue);
|
P_STRING (&sv_pr_state, 0) = PR_SetTempString (&sv_pr_state, key);
|
||||||
P_STRING (&sv_pr_state, 2) = PR_SetString (&sv_pr_state, value);
|
P_STRING (&sv_pr_state, 1) = PR_SetTempString (&sv_pr_state, oldvalue);
|
||||||
|
P_STRING (&sv_pr_state, 2) = PR_SetTempString (&sv_pr_state, value);
|
||||||
PR_ExecuteProgram (&sv_pr_state, sv_funcs.LocalinfoChanged);
|
PR_ExecuteProgram (&sv_pr_state, sv_funcs.LocalinfoChanged);
|
||||||
|
PR_PopFrame (&sv_pr_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldvalue)
|
if (oldvalue)
|
||||||
|
|
|
@ -810,12 +810,14 @@ SV_Say (qboolean team)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sv_funcs.ChatMessage) {
|
if (sv_funcs.ChatMessage) {
|
||||||
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, p);
|
PR_PushFrame (&sv_pr_state);
|
||||||
|
P_STRING (&sv_pr_state, 0) = PR_SetTempString (&sv_pr_state, p);
|
||||||
G_FLOAT (&sv_pr_state, 1) = (float) team;
|
G_FLOAT (&sv_pr_state, 1) = (float) team;
|
||||||
|
|
||||||
*sv_globals.time = sv.time;
|
*sv_globals.time = sv.time;
|
||||||
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
||||||
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ChatMessage);
|
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ChatMessage);
|
||||||
|
PR_PopFrame (&sv_pr_state);
|
||||||
if (R_FLOAT (&sv_pr_state))
|
if (R_FLOAT (&sv_pr_state))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1121,12 +1123,14 @@ SV_SetUserinfo (client_t *client, const char *key, const char *value)
|
||||||
key, oldvalue, value);
|
key, oldvalue, value);
|
||||||
|
|
||||||
if (sv_funcs.UserInfoChanged) {
|
if (sv_funcs.UserInfoChanged) {
|
||||||
|
PR_PushFrame (&sv_pr_state);
|
||||||
*sv_globals.time = sv.time;
|
*sv_globals.time = sv.time;
|
||||||
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, client->edict);
|
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, client->edict);
|
||||||
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, key);
|
P_STRING (&sv_pr_state, 0) = PR_SetTempString (&sv_pr_state, key);
|
||||||
P_STRING (&sv_pr_state, 1) = PR_SetString (&sv_pr_state, oldvalue);
|
P_STRING (&sv_pr_state, 1) = PR_SetTempString (&sv_pr_state, oldvalue);
|
||||||
P_STRING (&sv_pr_state, 2) = PR_SetString (&sv_pr_state, value);
|
P_STRING (&sv_pr_state, 2) = PR_SetTempString (&sv_pr_state, value);
|
||||||
PR_ExecuteProgram (&sv_pr_state, sv_funcs.UserInfoChanged);
|
PR_ExecuteProgram (&sv_pr_state, sv_funcs.UserInfoChanged);
|
||||||
|
PR_PopFrame (&sv_pr_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldvalue)
|
if (oldvalue)
|
||||||
|
@ -1169,10 +1173,12 @@ SV_SetInfo_f (void *unused)
|
||||||
value = Cmd_Argv (2);
|
value = Cmd_Argv (2);
|
||||||
|
|
||||||
if (sv_funcs.UserInfoCallback) {
|
if (sv_funcs.UserInfoCallback) {
|
||||||
|
PR_PushFrame (&sv_pr_state);
|
||||||
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
|
||||||
P_STRING (&sv_pr_state, 0) = PR_SetString (&sv_pr_state, key);
|
P_STRING (&sv_pr_state, 0) = PR_SetTempString (&sv_pr_state, key);
|
||||||
P_STRING (&sv_pr_state, 1) = PR_SetString (&sv_pr_state, value);
|
P_STRING (&sv_pr_state, 1) = PR_SetTempString (&sv_pr_state, value);
|
||||||
PR_ExecuteProgram (&sv_pr_state, sv_funcs.UserInfoCallback);
|
PR_ExecuteProgram (&sv_pr_state, sv_funcs.UserInfoCallback);
|
||||||
|
PR_PopFrame (&sv_pr_state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,17 +161,19 @@ main (int argc, char **argv)
|
||||||
if (!load_progs (name))
|
if (!load_progs (name))
|
||||||
Sys_Error ("couldn't load %s", "qwaq.dat");
|
Sys_Error ("couldn't load %s", "qwaq.dat");
|
||||||
|
|
||||||
|
PR_PushFrame (&pr);
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
pr_argc = argc - 1;
|
pr_argc = argc - 1;
|
||||||
pr_argv = PR_Zone_Malloc (&pr, (pr_argc + 1) * 4);
|
pr_argv = PR_Zone_Malloc (&pr, (pr_argc + 1) * 4);
|
||||||
pr_argv[0] = PR_SetString (&pr, name);
|
pr_argv[0] = PR_SetTempString (&pr, name);
|
||||||
for (i = 1; i < pr_argc; i++)
|
for (i = 1; i < pr_argc; i++)
|
||||||
pr_argv[i] = PR_SetString (&pr, argv[1 + i]);
|
pr_argv[i] = PR_SetTempString (&pr, argv[1 + i]);
|
||||||
pr_argv[i] = 0;
|
pr_argv[i] = 0;
|
||||||
|
|
||||||
main_func = PR_GetFunctionIndex (&pr, "main");
|
main_func = PR_GetFunctionIndex (&pr, "main");
|
||||||
P_INT (&pr, 0) = pr_argc;
|
P_POINTER (&pr, 0) = pr_argc;
|
||||||
P_INT (&pr, 1) = POINTER_TO_PROG (&pr, pr_argv);
|
P_POINTER (&pr, 1) = POINTER_TO_PROG (&pr, pr_argv);
|
||||||
PR_ExecuteProgram (&pr, main_func);
|
PR_ExecuteProgram (&pr, main_func);
|
||||||
|
PR_PopFrame (&pr);
|
||||||
return R_INT (&pr);
|
return R_INT (&pr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue