mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-25 02:52:06 +00:00
new internal printf engine for progs, mostly thanks to Deek.
also a few cleanup bits
This commit is contained in:
parent
538d669887
commit
dfe7f263c7
8 changed files with 495 additions and 361 deletions
|
@ -127,6 +127,7 @@ qboolean PR_EdictValid (progs_t *pr, int e);
|
||||||
#define G_EDICT(p,o) ((edict_t *)(PR_edicts (p) + G_INT (p, o)))
|
#define G_EDICT(p,o) ((edict_t *)(PR_edicts (p) + G_INT (p, o)))
|
||||||
#define G_EDICTNUM(p,o) NUM_FOR_EDICT(p, G_EDICT (p, o))
|
#define G_EDICTNUM(p,o) NUM_FOR_EDICT(p, G_EDICT (p, o))
|
||||||
#define G_GSTRING(p,o) PR_GetString (p, G_STRING (p, o))
|
#define G_GSTRING(p,o) PR_GetString (p, G_STRING (p, o))
|
||||||
|
#define G_DSTRING(p,o) PR_GetDString (p, G_STRING (p, o))
|
||||||
#define G_GPOINTER(p,o) PR_GetPointer (p, o)
|
#define G_GPOINTER(p,o) PR_GetPointer (p, o)
|
||||||
#define G_STRUCT(p,t,o) (*(t *)G_GPOINTER (p, o))
|
#define G_STRUCT(p,t,o) (*(t *)G_GPOINTER (p, o))
|
||||||
|
|
||||||
|
@ -143,6 +144,7 @@ qboolean PR_EdictValid (progs_t *pr, int e);
|
||||||
#define P_EDICT(p,n) ((edict_t *)(PR_edicts (p) + P_INT (p, n)))
|
#define P_EDICT(p,n) ((edict_t *)(PR_edicts (p) + P_INT (p, n)))
|
||||||
#define P_EDICTNUM(p,n) NUM_FOR_EDICT (p, P_EDICT (p, n))
|
#define P_EDICTNUM(p,n) NUM_FOR_EDICT (p, P_EDICT (p, n))
|
||||||
#define P_GSTRING(p,n) PR_GetString (p, P_STRING (p, n))
|
#define P_GSTRING(p,n) PR_GetString (p, P_STRING (p, n))
|
||||||
|
#define P_DSTRING(p,n) PR_GetDString (p, P_STRING (p, n))
|
||||||
#define P_GPOINTER(p,n) PR_GetPointer (p, P_POINTER (p, n))
|
#define P_GPOINTER(p,n) PR_GetPointer (p, P_POINTER (p, n))
|
||||||
#define P_STRUCT(p,t,n) (*(t *)P_GPOINTER (p, n))
|
#define P_STRUCT(p,t,n) (*(t *)P_GPOINTER (p, n))
|
||||||
|
|
||||||
|
@ -172,12 +174,13 @@ qboolean PR_EdictValid (progs_t *pr, int e);
|
||||||
#define E_POINTER(p,o) E_var (p, o, pointer)
|
#define E_POINTER(p,o) E_var (p, o, pointer)
|
||||||
|
|
||||||
#define E_GSTRING(p,e,o) (PR_GetString (p, E_STRING (e, o)))
|
#define E_GSTRING(p,e,o) (PR_GetString (p, E_STRING (e, o)))
|
||||||
|
#define E_DSTRING(p,e,o) (PR_GetDString (p, E_STRING (e, o)))
|
||||||
|
|
||||||
typedef void (*builtin_proc) (progs_t *pr);
|
typedef void (*builtin_proc) (progs_t *pr);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
builtin_proc proc;
|
builtin_proc proc;
|
||||||
int first_statement;
|
int binum;
|
||||||
} builtin_t;
|
} builtin_t;
|
||||||
|
|
||||||
ddef_t *PR_FindGlobal (progs_t *pr, const char *name);
|
ddef_t *PR_FindGlobal (progs_t *pr, const char *name);
|
||||||
|
@ -224,9 +227,12 @@ const char *PR_GetString(progs_t *pr, int num);
|
||||||
struct dstring_s *PR_GetDString(progs_t *pr, int num);
|
struct dstring_s *PR_GetDString(progs_t *pr, int num);
|
||||||
int PR_SetString(progs_t *pr, const char *s);
|
int PR_SetString(progs_t *pr, const char *s);
|
||||||
int PR_SetTempString(progs_t *pr, const char *s);
|
int PR_SetTempString(progs_t *pr, const char *s);
|
||||||
|
void PR_MakeTempString(progs_t *pr, int str);
|
||||||
int PR_NewString (progs_t *pr);
|
int PR_NewString (progs_t *pr);
|
||||||
void PR_FreeString (progs_t *pr, int str);
|
void PR_FreeString (progs_t *pr, int str);
|
||||||
void PR_FreeTempStrings (progs_t *pr);
|
void PR_FreeTempStrings (progs_t *pr);
|
||||||
|
void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name,
|
||||||
|
const char *format, int count, pr_type_t **args);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PR Resources stuff
|
// PR Resources stuff
|
||||||
|
|
|
@ -43,13 +43,11 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "QF/clip_hull.h"
|
|
||||||
#include "QF/cmd.h"
|
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
|
#include "QF/dstring.h"
|
||||||
#include "QF/mathlib.h"
|
#include "QF/mathlib.h"
|
||||||
#include "QF/progs.h"
|
#include "QF/progs.h"
|
||||||
#include "QF/sys.h"
|
#include "QF/sys.h"
|
||||||
#include "QF/va.h"
|
|
||||||
#include "QF/zone.h"
|
#include "QF/zone.h"
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
@ -58,9 +56,6 @@ const char *pr_gametype = "";
|
||||||
|
|
||||||
/* BUILT-IN FUNCTIONS */
|
/* BUILT-IN FUNCTIONS */
|
||||||
|
|
||||||
// FIXME: Hunk_TempAlloc, Sys_Printf, Cvar_*, PR_SetString, PR_RunError, ED_PrintEdicts, PF_traceon, PF_traceoff, ED_PrintNum, PR_FindBuiltin isn't threadsafe/reentrant
|
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
PF_VarString (progs_t *pr, int first)
|
PF_VarString (progs_t *pr, int first)
|
||||||
{
|
{
|
||||||
|
@ -77,9 +72,7 @@ PF_VarString (progs_t *pr, int first)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_normalize
|
vector (vector v) normalize
|
||||||
|
|
||||||
vector normalize(vector)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_normalize (progs_t *pr)
|
PF_normalize (progs_t *pr)
|
||||||
|
@ -107,9 +100,7 @@ PF_normalize (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_vlen
|
float (vector v) vlen
|
||||||
|
|
||||||
scalar vlen(vector)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_vlen (progs_t *pr)
|
PF_vlen (progs_t *pr)
|
||||||
|
@ -127,9 +118,7 @@ PF_vlen (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_vectoyaw
|
float (vector v) vectoyaw
|
||||||
|
|
||||||
float vectoyaw(vector)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_vectoyaw (progs_t *pr)
|
PF_vectoyaw (progs_t *pr)
|
||||||
|
@ -151,9 +140,7 @@ PF_vectoyaw (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_vectoangles
|
vector (vector v) vectoangles
|
||||||
|
|
||||||
vector vectoangles(vector)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_vectoangles (progs_t *pr)
|
PF_vectoangles (progs_t *pr)
|
||||||
|
@ -186,11 +173,9 @@ PF_vectoangles (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_Random
|
float () random
|
||||||
|
|
||||||
Returns a number from 0<= num < 1
|
Returns a number from 0<= num < 1
|
||||||
|
|
||||||
random()
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_random (progs_t *pr)
|
PF_random (progs_t *pr)
|
||||||
|
@ -203,23 +188,17 @@ PF_random (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_break
|
void () break
|
||||||
|
|
||||||
break()
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_break (progs_t *pr)
|
PF_break (progs_t *pr)
|
||||||
{
|
{
|
||||||
Sys_Printf ("break statement\n");
|
Sys_Printf ("break statement\n");
|
||||||
//*(int *) -4 = 0; // dump to debugger
|
|
||||||
PR_DumpState (pr);
|
PR_DumpState (pr);
|
||||||
// PR_RunError (pr, "break statement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_cvar
|
float (string s) cvar
|
||||||
|
|
||||||
float cvar (string)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_cvar (progs_t *pr)
|
PF_cvar (progs_t *pr)
|
||||||
|
@ -232,9 +211,7 @@ PF_cvar (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_cvar_set
|
void (string var, string val) cvar_set
|
||||||
|
|
||||||
float cvar (string)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_cvar_set (progs_t *pr)
|
PF_cvar_set (progs_t *pr)
|
||||||
|
@ -255,6 +232,9 @@ PF_cvar_set (progs_t *pr)
|
||||||
Cvar_Set (var, val);
|
Cvar_Set (var, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
float (float f) fabs
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_fabs (progs_t *pr)
|
PF_fabs (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
@ -264,12 +244,14 @@ PF_fabs (progs_t *pr)
|
||||||
R_FLOAT (pr) = fabs (v);
|
R_FLOAT (pr) = fabs (v);
|
||||||
}
|
}
|
||||||
|
|
||||||
// entity (entity start, .string field, string match) find = #5;
|
/*
|
||||||
|
entity (entity start, .(...) fld, ... match) find
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_Find (progs_t *pr)
|
PF_Find (progs_t *pr)
|
||||||
{
|
{
|
||||||
const char *s = 0, *t; // ev_string
|
const char *s = 0, *t; // ev_string
|
||||||
int i; // ev_vector
|
int i; // ev_vector
|
||||||
int e, f;
|
int e, f;
|
||||||
etype_t type;
|
etype_t type;
|
||||||
ddef_t *field_def;
|
ddef_t *field_def;
|
||||||
|
@ -326,36 +308,54 @@ PF_Find (progs_t *pr)
|
||||||
RETURN_EDICT (pr, *pr->edicts);
|
RETURN_EDICT (pr, *pr->edicts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void () coredump
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_coredump (progs_t *pr)
|
PF_coredump (progs_t *pr)
|
||||||
{
|
{
|
||||||
ED_PrintEdicts (pr, "");
|
ED_PrintEdicts (pr, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void () traceon
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_traceon (progs_t *pr)
|
PF_traceon (progs_t *pr)
|
||||||
{
|
{
|
||||||
pr->pr_trace = true;
|
pr->pr_trace = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void () traceoff
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_traceoff (progs_t *pr)
|
PF_traceoff (progs_t *pr)
|
||||||
{
|
{
|
||||||
pr->pr_trace = false;
|
pr->pr_trace = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void (entity e) eprint
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_eprint (progs_t *pr)
|
PF_eprint (progs_t *pr)
|
||||||
{
|
{
|
||||||
ED_PrintNum (pr, P_EDICTNUM (pr, 0));
|
ED_PrintNum (pr, P_EDICTNUM (pr, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void (string s) dprint
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_dprint (progs_t *pr)
|
PF_dprint (progs_t *pr)
|
||||||
{
|
{
|
||||||
Sys_Printf ("%s", PF_VarString (pr, 0));
|
Sys_Printf ("%s", PF_VarString (pr, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
float (float v) rint
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_rint (progs_t *pr)
|
PF_rint (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
@ -368,12 +368,18 @@ PF_rint (progs_t *pr)
|
||||||
R_FLOAT (pr) = (int) (f - 0.5);
|
R_FLOAT (pr) = (int) (f - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
float (float v) floor
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_floor (progs_t *pr)
|
PF_floor (progs_t *pr)
|
||||||
{
|
{
|
||||||
R_FLOAT (pr) = floor (P_FLOAT (pr, 0));
|
R_FLOAT (pr) = floor (P_FLOAT (pr, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
float (float v) ceil
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_ceil (progs_t *pr)
|
PF_ceil (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
@ -381,9 +387,7 @@ PF_ceil (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_nextent
|
entity (entity e) nextent
|
||||||
|
|
||||||
entity nextent(entity)
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_nextent (progs_t *pr)
|
PF_nextent (progs_t *pr)
|
||||||
|
@ -414,8 +418,6 @@ PF_nextent (progs_t *pr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_ftoi
|
|
||||||
|
|
||||||
integer (float f) ftoi
|
integer (float f) ftoi
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -425,8 +427,6 @@ PF_ftoi (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_ftos
|
|
||||||
|
|
||||||
string (float f) ftos
|
string (float f) ftos
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -451,8 +451,6 @@ PF_ftos (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_itof
|
|
||||||
|
|
||||||
float (integer i) itof
|
float (integer i) itof
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -462,8 +460,6 @@ PF_itof (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_itos
|
|
||||||
|
|
||||||
string (integer i) itos
|
string (integer i) itos
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -477,8 +473,6 @@ PF_itos (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_stof
|
|
||||||
|
|
||||||
float (string s) stof
|
float (string s) stof
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -488,8 +482,6 @@ PF_stof (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_stoi
|
|
||||||
|
|
||||||
integer (string s) stoi
|
integer (string s) stoi
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -499,8 +491,6 @@ PF_stoi (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_stov
|
|
||||||
|
|
||||||
vector (string s) stov
|
vector (string s) stov
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -514,8 +504,6 @@ PF_stov (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_vtos
|
|
||||||
|
|
||||||
string (vector v) vtos
|
string (vector v) vtos
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
|
@ -532,9 +520,7 @@ PF_vtos (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_strlen
|
float (string s) strlen
|
||||||
|
|
||||||
float(string s) strlen
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_strlen (progs_t *pr)
|
PF_strlen (progs_t *pr)
|
||||||
|
@ -546,9 +532,7 @@ PF_strlen (progs_t *pr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PF_charcount
|
float (string char, string s) charcount
|
||||||
|
|
||||||
float(string char, string s) charcount
|
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
PF_charcount (progs_t *pr)
|
PF_charcount (progs_t *pr)
|
||||||
|
@ -580,282 +564,78 @@ PF_charcount (progs_t *pr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_ARG 7
|
#define MAX_ARG 7
|
||||||
|
/*
|
||||||
|
string (...) sprintf
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PF_sprintf (progs_t *pr)
|
PF_sprintf (progs_t *pr)
|
||||||
{
|
{
|
||||||
const char *format;
|
const char *fmt = P_GSTRING (pr, 0);
|
||||||
const char *c; // current
|
int count = pr->pr_argc - 1;
|
||||||
char *out = 0;
|
pr_type_t **args = pr->pr_params + 1;
|
||||||
char new_format[INT_WIDTH * 2 + 9]; // "%0-+ #." and conversion
|
dstring_t *dstr;
|
||||||
int fmt_alternate, fmt_leadzero, fmt_leftjust, fmt_minwidth;
|
int str;
|
||||||
int fmt_precision, fmt_signed, fmt_space, fmt_type, looping;
|
|
||||||
int ret;
|
|
||||||
size_t new_format_i;
|
|
||||||
int curarg = 1, out_max = 32, out_size = 0;
|
|
||||||
|
|
||||||
format = P_GSTRING (pr, 0);
|
str = PR_NewString (pr);
|
||||||
c = format;
|
dstr = PR_GetDString (pr, str);
|
||||||
|
PR_Sprintf (pr, dstr, "bi_printf", fmt, count, args);
|
||||||
out = malloc (out_max);
|
PR_MakeTempString (pr, str);
|
||||||
if (!out)
|
R_STRING (pr) = str;
|
||||||
goto mallocerror;
|
|
||||||
|
|
||||||
while (*c) {
|
|
||||||
if (*c == '%' && c[1] != '%' && c[1] != 's') {
|
|
||||||
c++;
|
|
||||||
if (curarg > MAX_ARG)
|
|
||||||
goto maxargs;
|
|
||||||
|
|
||||||
// flags
|
|
||||||
looping = 1;
|
|
||||||
fmt_leadzero = 0;
|
|
||||||
fmt_leftjust = 0;
|
|
||||||
fmt_signed = 0;
|
|
||||||
fmt_space = 0;
|
|
||||||
fmt_alternate = 0;
|
|
||||||
while (looping) {
|
|
||||||
switch (*c) {
|
|
||||||
case '0': fmt_leadzero = 1; break;
|
|
||||||
case '-': fmt_leftjust = 1; break;
|
|
||||||
case '+': fmt_signed = 1; break;
|
|
||||||
case ' ': fmt_space = 1; break;
|
|
||||||
case '#': fmt_alternate = 1; break;
|
|
||||||
case '\0': goto endofstring;
|
|
||||||
default: looping = 0; continue;
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// minimum field width
|
|
||||||
fmt_minwidth = 0;
|
|
||||||
if (*c >= '1' && *c <= '9')
|
|
||||||
while (*c >= '0' && *c <= '9') {
|
|
||||||
fmt_minwidth *= 10;
|
|
||||||
fmt_minwidth += *c - '0';
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
else if (*c == '*') {
|
|
||||||
fmt_minwidth = P_INT (pr, 0 + curarg);
|
|
||||||
curarg++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// precision
|
|
||||||
fmt_precision = -1;
|
|
||||||
if (*c == '.') {
|
|
||||||
c++;
|
|
||||||
if (*c >= '0' && *c <= '9') {
|
|
||||||
fmt_precision = 0;
|
|
||||||
while (*c >= '0' && *c <= '9') {
|
|
||||||
fmt_precision *= 10;
|
|
||||||
fmt_precision += *c - '0';
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
} else if (*c == '*') {
|
|
||||||
fmt_precision = P_INT (pr, 0 + curarg);
|
|
||||||
curarg++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!*c)
|
|
||||||
goto endofstring;
|
|
||||||
// length? Nope, not in QC
|
|
||||||
fmt_type = *c++;
|
|
||||||
|
|
||||||
// some preperation
|
|
||||||
if (fmt_precision < 0)
|
|
||||||
switch (fmt_type) {
|
|
||||||
case 'i': fmt_precision = 0; break;
|
|
||||||
case 'f': fmt_precision = 6; break;
|
|
||||||
case 'v': fmt_precision = 1; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// built the format string
|
|
||||||
new_format_i = 0;
|
|
||||||
new_format[new_format_i++] = '%';
|
|
||||||
if (fmt_leadzero) new_format[new_format_i++] = '0';
|
|
||||||
if (fmt_leftjust) new_format[new_format_i++] = '-';
|
|
||||||
if (fmt_signed) new_format[new_format_i++] = '+';
|
|
||||||
if (fmt_space) new_format[new_format_i++] = ' ';
|
|
||||||
if (fmt_alternate) new_format[new_format_i++] = '#';
|
|
||||||
if (fmt_minwidth)
|
|
||||||
if ((new_format_i += snprintf (new_format + new_format_i,
|
|
||||||
sizeof (new_format) -
|
|
||||||
new_format_i,
|
|
||||||
"%d", fmt_minwidth))
|
|
||||||
>= sizeof (new_format))
|
|
||||||
PR_Error (pr, "PF_sprintf: new_format overflowed?!");
|
|
||||||
if (fmt_type != 'i') {
|
|
||||||
new_format[new_format_i++] = '.';
|
|
||||||
if ((new_format_i += snprintf (new_format + new_format_i,
|
|
||||||
sizeof (new_format)
|
|
||||||
- new_format_i,
|
|
||||||
"%d", fmt_precision))
|
|
||||||
>= sizeof (new_format))
|
|
||||||
PR_Error (pr, "PF_sprintf: new_format overflowed?!");
|
|
||||||
}
|
|
||||||
switch (fmt_type) {
|
|
||||||
case 'i': new_format[new_format_i++] = 'd'; break;
|
|
||||||
case 'f':
|
|
||||||
case 'v': new_format[new_format_i++] = 'f'; break;
|
|
||||||
default: PR_Error (pr, "PF_sprintf: unknown type '%c'!", *c);
|
|
||||||
}
|
|
||||||
new_format[new_format_i++] = '\0';
|
|
||||||
|
|
||||||
switch (fmt_type) {
|
|
||||||
case 'i':
|
|
||||||
while ((ret = snprintf (&out[out_size], out_max - out_size,
|
|
||||||
new_format,
|
|
||||||
P_INT (pr, 0 + curarg)))
|
|
||||||
>= out_max - out_size) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out_size += ret;
|
|
||||||
curarg++;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
while ((ret = snprintf (&out[out_size], out_max - out_size,
|
|
||||||
new_format,
|
|
||||||
P_FLOAT (pr, 0 + curarg)))
|
|
||||||
>= out_max - out_size) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out_size += ret;
|
|
||||||
curarg++;
|
|
||||||
break;
|
|
||||||
case 'v': {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i <= 2; i++) {
|
|
||||||
if (curarg > MAX_ARG)
|
|
||||||
goto maxargs;
|
|
||||||
while ((ret = snprintf (&out[out_size],
|
|
||||||
out_max - out_size, new_format,
|
|
||||||
P_VECTOR (pr, 0 + curarg)[i]))
|
|
||||||
>= out_max - out_size) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out_size += ret;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
curarg++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (*c == '%' && *(c + 1) == 's') {
|
|
||||||
const char *s;
|
|
||||||
if (curarg > MAX_ARG)
|
|
||||||
goto maxargs;
|
|
||||||
s = P_GSTRING (pr, 0 + curarg);
|
|
||||||
while ((ret = snprintf (&out[out_size], out_max - out_size, "%s",
|
|
||||||
s))
|
|
||||||
>= out_max - out_size) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out_size += ret;
|
|
||||||
curarg++;
|
|
||||||
c += 2;
|
|
||||||
} else {
|
|
||||||
if (*c == '%')
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if (out_size == out_max) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out[out_size] = *c;
|
|
||||||
out_size++;
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (out_size == out_max) {
|
|
||||||
char *o;
|
|
||||||
out_max *= 2;
|
|
||||||
o = realloc (out, out_max);
|
|
||||||
if (!o)
|
|
||||||
goto mallocerror;
|
|
||||||
out = o;
|
|
||||||
}
|
|
||||||
out[out_size] = '\0';
|
|
||||||
RETURN_STRING (pr, out);
|
|
||||||
free (out);
|
|
||||||
return;
|
|
||||||
|
|
||||||
mallocerror:
|
|
||||||
// if (errno == ENOMEM)
|
|
||||||
// hopefully we can free up some mem so it can be used during shutdown
|
|
||||||
// free (out);
|
|
||||||
PR_Error (pr, "PF_sprintf: memory allocation error!\n");
|
|
||||||
|
|
||||||
endofstring:
|
|
||||||
PR_Error (pr, "PF_sprintf: unexpected end of string!\n");
|
|
||||||
|
|
||||||
maxargs:
|
|
||||||
PR_Error (pr, "PF_sprintf: argument limit exceeded\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
string () gametype
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
PR_gametype (progs_t *pr)
|
PR_gametype (progs_t *pr)
|
||||||
{
|
{
|
||||||
RETURN_STRING (pr, pr_gametype);
|
RETURN_STRING (pr, pr_gametype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static builtin_t builtins[] = {
|
||||||
|
{"break", PF_break, 6},
|
||||||
|
{"random", PF_random, 7},
|
||||||
|
{"normalize", PF_normalize, 9},
|
||||||
|
{"vlen", PF_vlen, 12},
|
||||||
|
{"vectoyaw", PF_vectoyaw, 13},
|
||||||
|
{"find", PF_Find, 18},
|
||||||
|
{"dprint", PF_dprint, 25},
|
||||||
|
{"ftos", PF_ftos, 26},
|
||||||
|
{"vtos", PF_vtos, 27},
|
||||||
|
{"coredump", PF_coredump, 28},
|
||||||
|
{"traceon", PF_traceon, 29},
|
||||||
|
{"traceoff", PF_traceoff, 30},
|
||||||
|
{"eprint", PF_eprint, 31},
|
||||||
|
{"rint", PF_rint, 36},
|
||||||
|
{"floor", PF_floor, 37},
|
||||||
|
{"ceil", PF_ceil, 38},
|
||||||
|
{"fabs", PF_fabs, 43},
|
||||||
|
{"cvar", PF_cvar, 45},
|
||||||
|
{"nextent", PF_nextent, 47},
|
||||||
|
{"vectoangles", PF_vectoangles, 51},
|
||||||
|
{"cvar_set", PF_cvar_set, 72},
|
||||||
|
{"stof", PF_stof, 81},
|
||||||
|
|
||||||
|
|
||||||
|
{"strlen", PF_strlen, 100},
|
||||||
|
{"charcount", PF_charcount, 101},
|
||||||
|
{"sprintf", PF_sprintf, 109},
|
||||||
|
{"ftoi", PF_ftoi, 110},
|
||||||
|
{"itof", PF_itof, 111},
|
||||||
|
{"itos", PF_itos, 112},
|
||||||
|
{"stoi", PF_stoi, 113},
|
||||||
|
{"stov", PF_stov, 114},
|
||||||
|
{"gametype", PR_gametype, 115},
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
PR_Cmds_Init (progs_t *pr)
|
PR_Cmds_Init (progs_t *pr)
|
||||||
{
|
{
|
||||||
PR_AddBuiltin (pr, "break", PF_break, 6); // void () break
|
int i;
|
||||||
PR_AddBuiltin (pr, "random", PF_random, 7); // float () random
|
builtin_t *bi;
|
||||||
PR_AddBuiltin (pr, "normalize", PF_normalize, 9); // vector (vector v) normalize
|
|
||||||
PR_AddBuiltin (pr, "vlen", PF_vlen, 12); // float (vector v) vlen
|
for (i = 0; i < sizeof (builtins) / sizeof (builtins[0]); i++) {
|
||||||
PR_AddBuiltin (pr, "vectoyaw", PF_vectoyaw, 13); // float (vector v) vectoyaw
|
bi = builtins + i;
|
||||||
PR_AddBuiltin (pr, "find", PF_Find, 18); // entity (entity start, .(...) fld, ... match) find
|
PR_AddBuiltin (pr, bi->name, bi->proc, bi->binum);
|
||||||
PR_AddBuiltin (pr, "dprint", PF_dprint, 25); // void (string s) dprint
|
}
|
||||||
PR_AddBuiltin (pr, "ftos", PF_ftos, 26); // string (float f) ftos
|
|
||||||
PR_AddBuiltin (pr, "vtos", PF_vtos, 27); // string (vector v) vtos
|
|
||||||
PR_AddBuiltin (pr, "coredump", PF_coredump, 28); // void () coredump
|
|
||||||
PR_AddBuiltin (pr, "traceon", PF_traceon, 29); // void () traceon
|
|
||||||
PR_AddBuiltin (pr, "traceoff", PF_traceoff, 30); // void () traceoff
|
|
||||||
PR_AddBuiltin (pr, "eprint", PF_eprint, 31); // void (entity e) eprint
|
|
||||||
PR_AddBuiltin (pr, "rint", PF_rint, 36); // float (float v) rint
|
|
||||||
PR_AddBuiltin (pr, "floor", PF_floor, 37); // float (float v) floor
|
|
||||||
PR_AddBuiltin (pr, "ceil", PF_ceil, 38); // float (float v) ceil
|
|
||||||
PR_AddBuiltin (pr, "fabs", PF_fabs, 43); // float (float f) fabs
|
|
||||||
PR_AddBuiltin (pr, "cvar", PF_cvar, 45); // float (string s) cvar
|
|
||||||
PR_AddBuiltin (pr, "nextent", PF_nextent, 47); // entity (entity e) nextent
|
|
||||||
PR_AddBuiltin (pr, "vectoangles", PF_vectoangles, 51); // vector (vector v) vectoangles
|
|
||||||
PR_AddBuiltin (pr, "cvar_set", PF_cvar_set, 72); // void (string var, string val) cvar_set
|
|
||||||
PR_AddBuiltin (pr, "stof", PF_stof, 81); // float (string s) stof
|
|
||||||
|
|
||||||
|
|
||||||
PR_AddBuiltin (pr, "strlen", PF_strlen, 100); // float (string s) strlen
|
|
||||||
PR_AddBuiltin (pr, "charcount", PF_charcount, 101); // float (string goal, string s) charcount
|
|
||||||
PR_AddBuiltin (pr, "sprintf", PF_sprintf, 109); // string (...) sprintf
|
|
||||||
PR_AddBuiltin (pr, "ftoi", PF_ftoi, 110); // integer (float f) ftoi
|
|
||||||
PR_AddBuiltin (pr, "itof", PF_itof, 111); // float (integer i) itof
|
|
||||||
PR_AddBuiltin (pr, "itos", PF_itos, 112); // string (integer i) itos
|
|
||||||
PR_AddBuiltin (pr, "stoi", PF_stoi, 113); // integer (string s) stoi
|
|
||||||
PR_AddBuiltin (pr, "stov", PF_stov, 114); // vector (string s) stov
|
|
||||||
PR_AddBuiltin (pr, "gametype", PR_gametype, 115); // string () gametype
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,7 +98,7 @@ PR_AddBuiltin (progs_t *pr, const char *name, builtin_proc builtin, int num)
|
||||||
pr->builtins[i] = malloc (sizeof (builtin_t));
|
pr->builtins[i] = malloc (sizeof (builtin_t));
|
||||||
pr->builtins[i]->proc = builtin;
|
pr->builtins[i]->proc = builtin;
|
||||||
pr->builtins[i]->name = name;
|
pr->builtins[i]->name = name;
|
||||||
pr->builtins[i]->first_statement = i;
|
pr->builtins[i]->binum = i;
|
||||||
Hash_Add (pr->builtin_hash, pr->builtins[i]);
|
Hash_Add (pr->builtin_hash, pr->builtins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ PR_RelocateBuiltins (progs_t *pr)
|
||||||
pr->progs_name, bi_name);
|
pr->progs_name, bi_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
func->first_statement = -bi->first_statement;
|
func->first_statement = -bi->binum;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
# include <strings.h>
|
# include <strings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ strref_free (void *_sr, void *_pr)
|
||||||
int
|
int
|
||||||
PR_LoadStrings (progs_t *pr)
|
PR_LoadStrings (progs_t *pr)
|
||||||
{
|
{
|
||||||
char *end = pr->pr_strings + pr->pr_stringsize;
|
char *end = pr->pr_strings + pr->progs->numstrings;
|
||||||
char *str = pr->pr_strings;
|
char *str = pr->pr_strings;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
@ -289,6 +290,25 @@ PR_SetTempString (progs_t *pr, const char *s)
|
||||||
return string_index (pr, sr);
|
return string_index (pr, sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PR_MakeTempString (progs_t *pr, int str)
|
||||||
|
{
|
||||||
|
strref_t *sr = get_strref (pr, str);
|
||||||
|
|
||||||
|
if (!sr)
|
||||||
|
PR_RunError (pr, "invalid string %d", str);
|
||||||
|
if (sr->dstring) {
|
||||||
|
if (sr->dstring->str)
|
||||||
|
sr->string = sr->dstring->str;
|
||||||
|
PR_Zone_Free (pr, sr->dstring);
|
||||||
|
}
|
||||||
|
if (!sr->string)
|
||||||
|
sr->string = pr_strdup (pr, "");
|
||||||
|
sr->count = 0;
|
||||||
|
sr->next = pr->pr_xtstr;
|
||||||
|
pr->pr_xtstr = sr;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PR_NewString (progs_t *pr)
|
PR_NewString (progs_t *pr)
|
||||||
{
|
{
|
||||||
|
@ -325,3 +345,353 @@ 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) \
|
||||||
|
switch ((doWidth << 1) | doPrecision) { \
|
||||||
|
case 3: \
|
||||||
|
dasprintf (result, tmp->str, current->minFieldWidth, \
|
||||||
|
current->precision, current->data.t##_var); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
dasprintf (result, tmp->str, current->minFieldWidth, \
|
||||||
|
current->precision, current->data.t##_var); \
|
||||||
|
break; \
|
||||||
|
case 1: \
|
||||||
|
dasprintf (result, tmp->str, current->precision, \
|
||||||
|
current->data.t##_var); \
|
||||||
|
break; \
|
||||||
|
case 0: \
|
||||||
|
dasprintf (result, tmp->str, current->data.t##_var); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function takes as input a linked list of fmt_item_t representing
|
||||||
|
EVERYTHING to be printed. This includes text that is not affected by
|
||||||
|
formatting. A string without any formatting would wind up with only one
|
||||||
|
list item.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
I_DoPrint (dstring_t *result, fmt_item_t *formatting)
|
||||||
|
{
|
||||||
|
fmt_item_t *current = formatting;
|
||||||
|
dstring_t *tmp = dstring_new ();
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
qboolean doPrecision, doWidth;
|
||||||
|
|
||||||
|
doPrecision = -1 != current->precision;
|
||||||
|
doWidth = 0 != current->minFieldWidth;
|
||||||
|
|
||||||
|
dsprintf (tmp, "%%%s%s%s%s%s%s%s",
|
||||||
|
(current->flags & FMT_ALTFORM) ? "#" : "", // hash
|
||||||
|
(current->flags & FMT_ZEROPAD) ? "0" : "", // zero padding
|
||||||
|
(current->flags & FMT_LJUSTIFY) ? "-" : "", // left justify
|
||||||
|
(current->flags & FMT_ADDBLANK) ? " " : "", // add space for +ve
|
||||||
|
(current->flags & FMT_ADDSIGN) ? "+" : "", // add sign always
|
||||||
|
doWidth ? "*" : "",
|
||||||
|
doPrecision ? ".*" : "");
|
||||||
|
|
||||||
|
switch (current->type) {
|
||||||
|
case 's':
|
||||||
|
dstring_appendstr (tmp, "s");
|
||||||
|
PRINT (string);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
dstring_appendstr (tmp, "ld");
|
||||||
|
PRINT (integer);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
if (current->flags & FMT_HEX)
|
||||||
|
dstring_appendstr (tmp, "lx");
|
||||||
|
else
|
||||||
|
dstring_appendstr (tmp, "lu");
|
||||||
|
PRINT (uinteger);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
dstring_appendstr (tmp, "f");
|
||||||
|
PRINT (float);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
dstring_appendstr (tmp, "g");
|
||||||
|
PRINT (float);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
dstring_delete (tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static fmt_item_t *free_fmt_items;
|
||||||
|
|
||||||
|
static fmt_item_t *
|
||||||
|
new_fmt_item (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
fmt_item_t *fi;
|
||||||
|
|
||||||
|
if (!free_fmt_items) {
|
||||||
|
free_fmt_items = malloc (16 * sizeof (fmt_item_t));
|
||||||
|
for (i = 0; i < 15; i++)
|
||||||
|
free_fmt_items[i].next = free_fmt_items + i + 1;
|
||||||
|
free_fmt_items[i].next = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fi = free_fmt_items;
|
||||||
|
free_fmt_items = fi->next;
|
||||||
|
memset (fi, 0, sizeof (*fi));
|
||||||
|
fi->precision = -1;
|
||||||
|
return fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_fmt_item (fmt_item_t *fi)
|
||||||
|
{
|
||||||
|
fi->next = free_fmt_items;
|
||||||
|
free_fmt_items = fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef P_var
|
||||||
|
#define P_var(p,n,t) (args[n]->t##_var)
|
||||||
|
void
|
||||||
|
PR_Sprintf (progs_t *pr, dstring_t *result, const char *name,
|
||||||
|
const char *format, int count, pr_type_t **args)
|
||||||
|
{
|
||||||
|
const char *c, *l;
|
||||||
|
const char *msg = "";
|
||||||
|
fmt_item_t *fmt_items = 0;
|
||||||
|
fmt_item_t **fi = &fmt_items;
|
||||||
|
int fmt_count = 0;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
name = "PF_InternalSprintf";
|
||||||
|
|
||||||
|
*fi = new_fmt_item ();
|
||||||
|
c = l = format;
|
||||||
|
while (*c) { // count "%"s, checking our input along the way
|
||||||
|
if (*c++ == '%') {
|
||||||
|
if (c != l + 1) {
|
||||||
|
// have some unformatted text to print
|
||||||
|
(*fi)->precision = c - l - 1;
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = l;
|
||||||
|
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
}
|
||||||
|
if (*c == '%') {
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = "%";
|
||||||
|
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
switch (*c) {
|
||||||
|
// format options
|
||||||
|
case '\0':
|
||||||
|
msg = "Unexpected end of format string";
|
||||||
|
goto error;
|
||||||
|
case '0':
|
||||||
|
(*fi)->flags |= FMT_ZEROPAD;
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
case '#':
|
||||||
|
(*fi)->flags |= FMT_ALTFORM;
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
case ' ':
|
||||||
|
(*fi)->flags |= FMT_ADDBLANK;
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
case '-':
|
||||||
|
(*fi)->flags |= FMT_LJUSTIFY;
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
case '+':
|
||||||
|
(*fi)->flags |= FMT_ADDSIGN;
|
||||||
|
c++;
|
||||||
|
continue;
|
||||||
|
case '.':
|
||||||
|
(*fi)->precision = 0;
|
||||||
|
c++;
|
||||||
|
while (isdigit (*c)) {
|
||||||
|
(*fi)->precision *= 10;
|
||||||
|
(*fi)->precision += *c++ - '0';
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case '1': case '2': case '3': case '4': case '5':
|
||||||
|
case '6': case '7': case '8': case '9':
|
||||||
|
while (isdigit (*c)) {
|
||||||
|
(*fi)->minFieldWidth *= 10;
|
||||||
|
(*fi)->minFieldWidth += *c++ - '0';
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
// format types
|
||||||
|
case '@':
|
||||||
|
// object
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
// entity
|
||||||
|
(*fi)->type = 'i';
|
||||||
|
(*fi)->data.integer_var =
|
||||||
|
P_EDICTNUM (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
// integer
|
||||||
|
(*fi)->type = *c;
|
||||||
|
(*fi)->data.integer_var = P_INT (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
// float
|
||||||
|
case 'g':
|
||||||
|
// float, no trailing zeroes, trim "." if nothing
|
||||||
|
// after
|
||||||
|
(*fi)->type = *c;
|
||||||
|
(*fi)->data.float_var = P_FLOAT (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
// pointer
|
||||||
|
(*fi)->flags |= FMT_ALTFORM;
|
||||||
|
(*fi)->type = 'x';
|
||||||
|
(*fi)->data.uinteger_var = P_UINT (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
// string
|
||||||
|
(*fi)->type = *c;
|
||||||
|
(*fi)->data.string_var = P_GSTRING (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
// vector
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int flags = (*fi)->flags;
|
||||||
|
int precision = (*fi)->precision;
|
||||||
|
unsigned minWidth = (*fi)->minFieldWidth;
|
||||||
|
|
||||||
|
(*fi)->flags = 0;
|
||||||
|
(*fi)->precision = -1;
|
||||||
|
(*fi)->minFieldWidth = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = "'";
|
||||||
|
} else {
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = " ";
|
||||||
|
}
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
|
||||||
|
(*fi)->flags = flags;
|
||||||
|
(*fi)->precision = precision;
|
||||||
|
(*fi)->minFieldWidth = minWidth;
|
||||||
|
(*fi)->type = 'g';
|
||||||
|
(*fi)->data.float_var =
|
||||||
|
P_VECTOR (pr, fmt_count)[i];
|
||||||
|
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = "'";
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
// integer, hex notation
|
||||||
|
(*fi)->type = *c;
|
||||||
|
(*fi)->data.uinteger_var = P_UINT (pr, fmt_count);
|
||||||
|
|
||||||
|
fmt_count++;
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
l = ++c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c != l) {
|
||||||
|
// have some unformatted text to print
|
||||||
|
(*fi)->precision = c - l;
|
||||||
|
(*fi)->type = 's';
|
||||||
|
(*fi)->data.string_var = l;
|
||||||
|
|
||||||
|
(*fi)->next = new_fmt_item ();
|
||||||
|
fi = &(*fi)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 && fmt_count != count) {
|
||||||
|
printf ("%d %d", fmt_count, count);
|
||||||
|
if (fmt_count > count)
|
||||||
|
msg = "Not enough arguments for format string.";
|
||||||
|
else
|
||||||
|
msg = "Too many arguments for format string.";
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
I_DoPrint (result, fmt_items);
|
||||||
|
while (fmt_items) {
|
||||||
|
fmt_item_t *t = fmt_items->next;
|
||||||
|
free_fmt_item (fmt_items);
|
||||||
|
fmt_items = t;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
PR_RunError (pr, "%s: %s", name, msg);
|
||||||
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ _dvsprintf (dstring_t *dstr, int offs, const char *fmt, va_list args)
|
||||||
dstring_clearstr (dstr); // Make it a string
|
dstring_clearstr (dstr); // Make it a string
|
||||||
// Some vsnprintf implementations return -1 on truncation
|
// Some vsnprintf implementations return -1 on truncation
|
||||||
while ((size = vsnprintf (dstr->str + offs, dstr->truesize - offs, fmt, args)) == -1) {
|
while ((size = vsnprintf (dstr->str + offs, dstr->truesize - offs, fmt, args)) == -1) {
|
||||||
dstr->size = dstr->truesize + 1024;
|
dstr->size = (dstr->truesize & 1023) + 1024;
|
||||||
dstring_adjust (dstr);
|
dstring_adjust (dstr);
|
||||||
#ifdef VA_LIST_IS_ARRAY
|
#ifdef VA_LIST_IS_ARRAY
|
||||||
VA_COPY (args, tmp_args);
|
VA_COPY (args, tmp_args);
|
||||||
|
|
|
@ -134,7 +134,8 @@ SV_CreateBaseline (void)
|
||||||
} else {
|
} else {
|
||||||
((entity_state_t*)svent->data)->colormap = 0;
|
((entity_state_t*)svent->data)->colormap = 0;
|
||||||
((entity_state_t*)svent->data)->modelindex =
|
((entity_state_t*)svent->data)->modelindex =
|
||||||
SV_ModelIndex (PR_GetString (&sv_pr_state, SVstring (svent, model)));
|
SV_ModelIndex (PR_GetString (&sv_pr_state,
|
||||||
|
SVstring (svent, model)));
|
||||||
}
|
}
|
||||||
// LordHavoc: setup baseline to include new effects
|
// LordHavoc: setup baseline to include new effects
|
||||||
((entity_state_t*)svent->data)->alpha = 255;
|
((entity_state_t*)svent->data)->alpha = 255;
|
||||||
|
|
|
@ -41,6 +41,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <QF/dstring.h>
|
||||||
#include <QF/progs.h>
|
#include <QF/progs.h>
|
||||||
#include <QF/zone.h>
|
#include <QF/zone.h>
|
||||||
|
|
||||||
|
@ -138,39 +139,14 @@ static void
|
||||||
bi_printf (progs_t *pr)
|
bi_printf (progs_t *pr)
|
||||||
{
|
{
|
||||||
const char *fmt = P_GSTRING (pr, 0);
|
const char *fmt = P_GSTRING (pr, 0);
|
||||||
char c;
|
int count = pr->pr_argc - 1;
|
||||||
int count = 0;
|
pr_type_t **args = pr->pr_params + 1;
|
||||||
float *v;
|
dstring_t *dstr = dstring_new ();
|
||||||
|
|
||||||
while ((c = *fmt++)) {
|
PR_Sprintf (pr, dstr, "bi_printf", fmt, count, args);
|
||||||
if (c == '%' && count < 7) {
|
if (dstr->str)
|
||||||
switch (c = *fmt++) {
|
fputs (dstr->str, stdout);
|
||||||
case 'i':
|
dstring_delete (dstr);
|
||||||
fprintf (stdout, "%i",
|
|
||||||
P_INT (pr, 1 + count++ * pr->pr_param_size));
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
fprintf (stdout, "%f",
|
|
||||||
P_FLOAT (pr, 1 + count++ * pr->pr_param_size));
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
fputs (P_GSTRING (pr, 1 + count++ * pr->pr_param_size),
|
|
||||||
stdout);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
v = P_VECTOR (pr, 1 + count++ * pr->pr_param_size);
|
|
||||||
fprintf (stdout, "'%f %f %f'", v[0], v[1], v[2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fputc ('%', stdout);
|
|
||||||
fputc (c, stdout);
|
|
||||||
count = 7;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fputc (c, stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -6,6 +6,7 @@ void () test_str =
|
||||||
c = "strings ";
|
c = "strings ";
|
||||||
d = "\n";
|
d = "\n";
|
||||||
print (a + b + c + d);
|
print (a + b + c + d);
|
||||||
|
printf ("%i \"%.5s\" %3.4f %v\n", 14, "hi there", 3.1415926, '4 1 3');
|
||||||
};
|
};
|
||||||
|
|
||||||
integer (integer argc, string []argv) main =
|
integer (integer argc, string []argv) main =
|
||||||
|
|
Loading…
Reference in a new issue