mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
If and while now work, and embedded commands use backticks instead of <> now
to prevent conflicts with math expressions. All clients and servers are set to create buffers with the normal parser. However, scripts ending in .gib are now executed in a GIB buffer, and the export command can be used to make specific GIB functions available to normal command buffers (i.e. the console).
This commit is contained in:
parent
e56404d242
commit
5c60be3a49
12 changed files with 224 additions and 63 deletions
|
@ -37,17 +37,20 @@ typedef struct gib_local_s {
|
|||
typedef struct gib_buffer_data_s {
|
||||
struct dstring_s *arg_composite;
|
||||
struct dstring_s *current_token;
|
||||
struct dstring_s *loop_program;
|
||||
|
||||
// Data for handling return values
|
||||
struct {
|
||||
qboolean waiting, available; // Return value states
|
||||
struct dstring_s *retval; // Returned value
|
||||
|
||||
// Data saved by tokenizer/processor
|
||||
unsigned int line_pos; // Position within line
|
||||
unsigned int token_pos; // Position within token
|
||||
qboolean cat; // Concatenate to previous token?
|
||||
int noprocess; // Process tokens?
|
||||
char delim; // delimiter of token
|
||||
struct dstring_s *retval; // Returned value
|
||||
|
||||
} ret;
|
||||
|
||||
struct hashtab_s *locals; // Local variables
|
||||
|
|
|
@ -31,13 +31,13 @@
|
|||
typedef struct gib_builtin_s {
|
||||
struct dstring_s *name;
|
||||
void (*func) (void);
|
||||
enum {
|
||||
GIB_BUILTIN_NORMAL, // Normal argument processing
|
||||
GIB_BUILTIN_NOPROCESS, // Don't process arguments
|
||||
GIB_BUILTIN_FIRSTONLY, // Process only the first argument
|
||||
enum gib_builtin_type_e {
|
||||
GIB_BUILTIN_NORMAL = 0, // Normal argument processing
|
||||
GIB_BUILTIN_NOPROCESS = 1, // Don't process arguments
|
||||
GIB_BUILTIN_FIRSTONLY = 2, // Process only the first argument
|
||||
} type;
|
||||
} gib_builtin_t;
|
||||
|
||||
void GIB_Builtin_Add (const char *name, void (*func) (void));
|
||||
void GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type);
|
||||
gib_builtin_t *GIB_Builtin_Find (const char *name);
|
||||
void GIB_Builtin_Init (void);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
typedef struct gib_function_s {
|
||||
struct dstring_s *name, *program;
|
||||
qboolean exported;
|
||||
} gib_function_t;
|
||||
|
||||
void GIB_Function_Define (const char *name, const char *program);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
*/
|
||||
|
||||
char GIB_Parse_Match_Angle (const char *str, unsigned int *i);
|
||||
char GIB_Parse_Match_Backtick (const char *str, unsigned int *i);
|
||||
|
||||
void GIB_Parse_Extract_Line (struct cbuf_s *cbuf);
|
||||
void GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf);
|
||||
|
|
|
@ -53,6 +53,7 @@ static const char rcsid[] =
|
|||
#include "QF/vfs.h"
|
||||
#include "QF/zone.h"
|
||||
#include "QF/gib_builtin.h"
|
||||
#include "QF/gib_parse.h"
|
||||
|
||||
typedef struct cmdalias_s {
|
||||
struct cmdalias_s *next;
|
||||
|
@ -489,9 +490,19 @@ Cmd_Exec_f (void)
|
|||
if (!Cvar_Command ()
|
||||
&& (cmd_warncmd->int_val || (developer && developer->int_val)))
|
||||
Sys_Printf ("execing %s\n", Cmd_Argv (1));
|
||||
|
||||
if (!strcmp (Cmd_Argv (1) + strlen (Cmd_Argv(1)) - 4, ".gib")) {
|
||||
// GIB script, put it in a new buffer on the stack
|
||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||
if (cbuf_active->down)
|
||||
Cbuf_DeleteStack (cbuf_active->down);
|
||||
cbuf_active->down = sub;
|
||||
sub->up = cbuf_active;
|
||||
cbuf_active->state = CBUF_STATE_STACK;
|
||||
Cbuf_AddText (sub, f);
|
||||
} else
|
||||
Cbuf_InsertText (cbuf_active, f);
|
||||
Hunk_FreeToLowMark (mark);
|
||||
Cbuf_Execute (cbuf_active);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -99,6 +99,8 @@ void GIB_Buffer_Destruct (struct cbuf_s *cbuf)
|
|||
{
|
||||
dstring_delete (GIB_DATA (cbuf)->arg_composite);
|
||||
dstring_delete (GIB_DATA (cbuf)->current_token);
|
||||
if (GIB_DATA (cbuf)->loop_program)
|
||||
dstring_delete (GIB_DATA(cbuf)->loop_program);
|
||||
dstring_delete (GIB_DATA (cbuf)->ret.retval);
|
||||
if (GIB_DATA(cbuf)->locals && GIB_DATA(cbuf)->type == GIB_BUFFER_NORMAL)
|
||||
Hash_DelTable (GIB_DATA(cbuf)->locals);
|
||||
|
|
|
@ -29,12 +29,15 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "QF/va.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/gib_parse.h"
|
||||
#include "QF/gib_builtin.h"
|
||||
#include "QF/gib_buffer.h"
|
||||
#include "QF/gib_function.h"
|
||||
|
@ -57,7 +60,7 @@ GIB_Builtin_Free (void *ele, void *ptr)
|
|||
}
|
||||
|
||||
void
|
||||
GIB_Builtin_Add (const char *name, void (*func) (void))
|
||||
GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type)
|
||||
{
|
||||
gib_builtin_t *new;
|
||||
|
||||
|
@ -67,6 +70,7 @@ GIB_Builtin_Add (const char *name, void (*func) (void))
|
|||
new = calloc (1, sizeof (gib_builtin_t));
|
||||
new->func = func;
|
||||
new->name = dstring_newstr();
|
||||
new->type = type;
|
||||
dstring_appendstr (new->name, name);
|
||||
Hash_Add (gib_builtins, new);
|
||||
}
|
||||
|
@ -94,12 +98,31 @@ GIB_Argv (unsigned int arg)
|
|||
return "";
|
||||
}
|
||||
|
||||
const char *
|
||||
GIB_Args (unsigned int arg)
|
||||
{
|
||||
if (arg < cbuf_active->args->argc)
|
||||
return cbuf_active->args->args[arg];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Arg_Strip_Delim (unsigned int arg)
|
||||
{
|
||||
char *p = cbuf_active->args->argv[arg]->str;
|
||||
if (*p == '{' || *p == '\"') {
|
||||
dstring_snip (cbuf_active->args->argv[arg], 0, 1);
|
||||
p[strlen(p)-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Function_f (void)
|
||||
{
|
||||
if (GIB_Argc () != 3)
|
||||
Cbuf_Error ("numargs",
|
||||
"function: invalid number of arguments\n"
|
||||
Cbuf_Error ("syntax",
|
||||
"function: invalid syntax\n"
|
||||
"usage: function function_name {program}");
|
||||
else
|
||||
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2));
|
||||
|
@ -109,8 +132,8 @@ void
|
|||
GIB_Lset_f (void)
|
||||
{
|
||||
if (GIB_Argc () != 3)
|
||||
Cbuf_Error ("numargs",
|
||||
"lset: invalid number of arguments\n"
|
||||
Cbuf_Error ("syntax",
|
||||
"lset: invalid syntax\n"
|
||||
"usage: lset variable value");
|
||||
else
|
||||
GIB_Local_Set (cbuf_active, GIB_Argv(1), GIB_Argv(2));
|
||||
|
@ -119,28 +142,136 @@ GIB_Lset_f (void)
|
|||
void
|
||||
GIB_Return_f (void)
|
||||
{
|
||||
cbuf_t *sp;
|
||||
|
||||
if (GIB_Argc () > 2)
|
||||
Cbuf_Error ("numargs",
|
||||
"return: invalid number of arguments\n"
|
||||
Cbuf_Error ("syntax",
|
||||
"return: invalid syntax\n"
|
||||
"usage: return <value>");
|
||||
else {
|
||||
dstring_clearstr (cbuf_active->buf);
|
||||
sp = cbuf_active;
|
||||
while (sp->interpreter == &gib_interp && GIB_DATA(sp)->type == GIB_BUFFER_LOOP) { // Get out of loops
|
||||
GIB_DATA(sp)->type = GIB_BUFFER_PROXY;
|
||||
dstring_clearstr (sp->buf);
|
||||
dstring_clearstr (sp->line);
|
||||
sp = sp->up;
|
||||
}
|
||||
dstring_clearstr (sp->buf);
|
||||
dstring_clearstr (sp->line);
|
||||
if (GIB_Argc () == 1)
|
||||
return;
|
||||
if (!cbuf_active->up || !cbuf_active->up->up)
|
||||
Cbuf_Error ("return","return attempted at top of stack");
|
||||
if (GIB_DATA(cbuf_active->up->up)->ret.waiting) {
|
||||
dstring_clearstr (GIB_DATA(cbuf_active->up->up)->ret.retval);
|
||||
dstring_appendstr (GIB_DATA(cbuf_active->up->up)->ret.retval, GIB_Argv(1));
|
||||
GIB_DATA(cbuf_active->up->up)->ret.available = true;
|
||||
if (!sp->up || !sp->up->up)
|
||||
Cbuf_Error ("stack","return attempted at top of stack");
|
||||
else if (sp->up->up->interpreter != &gib_interp)
|
||||
Cbuf_Error ("stack","return to non-GIB command buffer attempted");
|
||||
else if (GIB_DATA(sp->up->up)->ret.waiting) {
|
||||
dstring_clearstr (GIB_DATA(sp->up->up)->ret.retval);
|
||||
dstring_appendstr (GIB_DATA(sp->up->up)->ret.retval, GIB_Argv(1));
|
||||
GIB_DATA(sp->up->up)->ret.available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_If_f (void)
|
||||
{
|
||||
int condition;
|
||||
if ((!strcmp (GIB_Argv (3), "else") && GIB_Argc() >= 5) || // if condition {program} else ...
|
||||
(GIB_Argc() == 3)) { // if condition {program}
|
||||
condition = atoi(GIB_Argv(1));
|
||||
if (!strcmp (GIB_Argv(0), "ifnot"))
|
||||
condition = !condition;
|
||||
if (condition) {
|
||||
GIB_Arg_Strip_Delim (2);
|
||||
Cbuf_InsertText (cbuf_active, GIB_Argv(2));
|
||||
} else if (GIB_Argc() == 5) {
|
||||
GIB_Arg_Strip_Delim (4);
|
||||
Cbuf_InsertText (cbuf_active, GIB_Argv(4));
|
||||
} else if (GIB_Argc() > 5)
|
||||
Cbuf_InsertText (cbuf_active, GIB_Args (4));
|
||||
} else
|
||||
Cbuf_Error ("syntax",
|
||||
"if: invalid syntax\n"
|
||||
"usage: if condition {program} [else ...]"
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
GIB_While_f (void)
|
||||
{
|
||||
if (GIB_Argc() != 3) {
|
||||
Cbuf_Error ("syntax",
|
||||
"while: invalid syntax\n"
|
||||
"usage: while condition {program}"
|
||||
);
|
||||
} else {
|
||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
||||
GIB_DATA(sub)->type = GIB_BUFFER_LOOP;
|
||||
GIB_DATA(sub)->locals = GIB_DATA(cbuf_active)->locals;
|
||||
GIB_DATA(sub)->loop_program = dstring_newstr ();
|
||||
if (cbuf_active->down)
|
||||
Cbuf_DeleteStack (cbuf_active->down);
|
||||
cbuf_active->down = sub;
|
||||
sub->up = cbuf_active;
|
||||
GIB_Arg_Strip_Delim (2);
|
||||
dstring_appendstr (GIB_DATA(sub)->loop_program, va("ifnot %s break\n%s", GIB_Argv (1), GIB_Argv (2)));
|
||||
Cbuf_AddText (sub, GIB_DATA(sub)->loop_program->str);
|
||||
cbuf_active->state = CBUF_STATE_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Break_f (void)
|
||||
{
|
||||
if (GIB_DATA(cbuf_active)->type != GIB_BUFFER_LOOP)
|
||||
Cbuf_Error ("syntax",
|
||||
"break attempted outside of a loop"
|
||||
);
|
||||
else {
|
||||
GIB_DATA(cbuf_active)->type = GIB_BUFFER_PROXY; // If we set it to normal locals will get freed
|
||||
dstring_clearstr (cbuf_active->buf);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Runexported_f (void)
|
||||
{
|
||||
gib_function_t *f;
|
||||
|
||||
if (!(f = GIB_Function_Find (Cmd_Argv (0))))
|
||||
Sys_Printf ("Error: No function found for exported command \"%s\".\n"
|
||||
"This is most likely a bug, please report it to"
|
||||
"The QuakeForge developers.", Cmd_Argv(0));
|
||||
else
|
||||
GIB_Function_Execute (f);
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Export_f (void)
|
||||
{
|
||||
gib_function_t *f;
|
||||
|
||||
if (GIB_Argc() != 2)
|
||||
Cbuf_Error ("syntax",
|
||||
"export: invalid syntax\n"
|
||||
"usage: export function");
|
||||
else if (!(f = GIB_Function_Find (GIB_Argv (1))))
|
||||
Cbuf_Error ("existance", "export: function '%s' not found", GIB_Argv (1));
|
||||
else if (!f->exported) {
|
||||
Cmd_AddCommand (f->name->str, GIB_Runexported_f, "Exported GIB function.");
|
||||
f->exported = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Builtin_Init (void)
|
||||
{
|
||||
GIB_Builtin_Add ("function", GIB_Function_f);
|
||||
GIB_Builtin_Add ("lset", GIB_Lset_f);
|
||||
GIB_Builtin_Add ("return", GIB_Return_f);
|
||||
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("export", GIB_Export_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("lset", GIB_Lset_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("return", GIB_Return_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("if", GIB_If_f, GIB_BUILTIN_FIRSTONLY);
|
||||
GIB_Builtin_Add ("ifnot", GIB_If_f, GIB_BUILTIN_FIRSTONLY);
|
||||
GIB_Builtin_Add ("while", GIB_While_f, GIB_BUILTIN_NOPROCESS);
|
||||
GIB_Builtin_Add ("break", GIB_Break_f, GIB_BUILTIN_NORMAL);
|
||||
}
|
||||
|
|
|
@ -96,29 +96,25 @@ GIB_Parse_Match_Paren (const char *str, unsigned int *i)
|
|||
return c;
|
||||
} else if (str[*i] == ')')
|
||||
return 0;
|
||||
else if (str[*i] == '\n') // Newlines in math == bad
|
||||
return '(';
|
||||
}
|
||||
return '(';
|
||||
}
|
||||
|
||||
char
|
||||
GIB_Parse_Match_Angle (const char *str, unsigned int *i)
|
||||
GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
||||
{
|
||||
char c;
|
||||
for ((*i)++; str[*i]; (*i)++) {
|
||||
if (str[*i] == '>')
|
||||
if (str[*i] == '`')
|
||||
return 0;
|
||||
else if (str[*i] == '<') {
|
||||
if ((c = GIB_Parse_Match_Angle (str, i))) // Embedded inside embedded
|
||||
return c;
|
||||
} else if (str[*i] == '(') { // Skip over math expressions to avoid < and >
|
||||
if ((c = GIB_Parse_Match_Paren (str, i)))
|
||||
return c;
|
||||
} else if (str[*i] == '\"') { // Skip over strings
|
||||
else if (str[*i] == '\"') { // Skip over strings
|
||||
if ((c = GIB_Parse_Match_Dquote (str, i)))
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return '<';
|
||||
return '`';
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -145,11 +141,6 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
|||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return;
|
||||
}
|
||||
} else if (dstr->str[i] == '<') {
|
||||
if ((c = GIB_Parse_Match_Angle (dstr->str, &i))) {
|
||||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return;
|
||||
}
|
||||
} else if (dstr->str[i] == '\n' || dstr->str[i] == ';')
|
||||
break;
|
||||
else if (dstr->str[i] == '/' && dstr->str[i+1] == '/') {
|
||||
|
@ -171,12 +162,15 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
|||
dstring_snip (dstr, 0, i + (dstr->str[i] == '\n' || dstr->str[i] == ';'));
|
||||
}
|
||||
|
||||
if (GIB_DATA(cbuf)->type == GIB_BUFFER_LOOP && !dstr->str[0])
|
||||
Cbuf_AddText (cbuf, GIB_DATA(cbuf)->loop_program->str);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
inline static char
|
||||
GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr)
|
||||
GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean include_delim)
|
||||
{
|
||||
int n;
|
||||
char c;
|
||||
|
@ -187,7 +181,7 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr)
|
|||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return 0; // Parse error
|
||||
} else {
|
||||
dstring_insert (dstr, 0, str+n+1, *i-n-1);
|
||||
dstring_insert (dstr, 0, str+n+!include_delim, *i-n+1-!include_delim-!include_delim);
|
||||
return '\"';
|
||||
}
|
||||
} else if (str[*i] == '{') {
|
||||
|
@ -195,7 +189,7 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr)
|
|||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return 0; // Parse error
|
||||
} else {
|
||||
dstring_insert (dstr, 0, str+n+1, *i-n-1);
|
||||
dstring_insert (dstr, 0, str+n+!include_delim, *i-n+1-!include_delim-!include_delim);
|
||||
return '{';
|
||||
}
|
||||
} else if (str[*i] == '(') {
|
||||
|
@ -203,13 +197,13 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr)
|
|||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return 0; // Parse error
|
||||
} else {
|
||||
dstring_insert (dstr, 0, str+n+1, *i-n-1);
|
||||
dstring_insert (dstr, 0, str+n+!include_delim, *i-n+1-!include_delim-!include_delim);
|
||||
return '\(';
|
||||
}
|
||||
} else {
|
||||
while (str[*i] && !isspace(str[*i]) && str[*i] != ',') { // find end of token
|
||||
if (str[*i] == '<') {
|
||||
if ((c = GIB_Parse_Match_Angle (str, i))) {
|
||||
if (str[*i] == '`') {
|
||||
if ((c = GIB_Parse_Match_Backtick (str, i))) {
|
||||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return 0; // Parse error
|
||||
}
|
||||
|
@ -262,6 +256,7 @@ GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf)
|
|||
const char *str = cbuf->line->str;
|
||||
cbuf_args_t *args = cbuf->args;
|
||||
qboolean cat = false;
|
||||
int noprocess;
|
||||
char delim;
|
||||
int i;
|
||||
|
||||
|
@ -276,9 +271,11 @@ GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf)
|
|||
return; // Still not done, or error
|
||||
GIB_Parse_Add_Token (cbuf->args, GIB_DATA(cbuf)->ret.cat, arg);
|
||||
i = GIB_DATA(cbuf)->ret.line_pos; // Start tokenizing where we left off
|
||||
noprocess = GIB_DATA(cbuf)->ret.noprocess ? 1 : 0; // Past second token, no sense in having it be 2
|
||||
} else {
|
||||
args->argc = 0; // Start from scratch
|
||||
i = 0;
|
||||
noprocess = 0;
|
||||
}
|
||||
|
||||
while (str[i]) {
|
||||
|
@ -292,41 +289,55 @@ GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf)
|
|||
continue;
|
||||
}
|
||||
dstring_clearstr (arg);
|
||||
delim = GIB_Parse_Get_Token (str, &i, arg);
|
||||
delim = GIB_Parse_Get_Token (str, &i, arg, noprocess == 1);
|
||||
if (!delim)
|
||||
break;
|
||||
Sys_DPrintf("Got token: %s\n", arg->str);
|
||||
if (delim != ' ') // Move into whitespace if we haven't already
|
||||
i++;
|
||||
|
||||
if (noprocess != 1)
|
||||
if (GIB_Process_Token (arg, delim))
|
||||
goto FILTER_ERROR; // Error or GIB subroutine needs to be called
|
||||
|
||||
if (noprocess > 1)
|
||||
noprocess--;
|
||||
|
||||
GIB_Parse_Add_Token (cbuf->args, cat, arg);
|
||||
if (cat)
|
||||
cat = false;
|
||||
|
||||
if (delim != ' ') // Move into whitespace if we haven't already
|
||||
i++;
|
||||
|
||||
if (cbuf->args->argc == 1) {
|
||||
gib_builtin_t *b;
|
||||
if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str)))
|
||||
noprocess = b->type;
|
||||
}
|
||||
}
|
||||
GIB_Parse_Generate_Composite (cbuf);
|
||||
dstring_clearstr (cbuf->line);
|
||||
return;
|
||||
FILTER_ERROR:
|
||||
GIB_DATA(cbuf)->ret.line_pos = i; // save our information in case
|
||||
GIB_DATA(cbuf)->ret.cat = cat; // error is not fatal
|
||||
GIB_DATA(cbuf)->ret.delim = delim;
|
||||
GIB_DATA(cbuf)->ret.noprocess = noprocess;
|
||||
return;
|
||||
}
|
||||
|
||||
void GIB_Parse_Execute_Line (cbuf_t *cbuf)
|
||||
{
|
||||
cbuf_args_t *args = cbuf->args;
|
||||
gib_builtin_t *b;
|
||||
gib_function_t *f;
|
||||
|
||||
if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str)))
|
||||
if ((b = GIB_Builtin_Find (args->argv[0]->str)))
|
||||
b->func ();
|
||||
else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
|
||||
else if ((f = GIB_Function_Find (args->argv[0]->str)))
|
||||
GIB_Function_Execute (f);
|
||||
} else
|
||||
else if (args->argc == 3 && !strcmp (args->argv[1]->str, "="))
|
||||
GIB_Local_Set (cbuf, args->argv[0]->str, args->argv[2]->str);
|
||||
else
|
||||
Cmd_Command (cbuf->args);
|
||||
dstring_clearstr (cbuf->line);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,9 @@ GIB_Process_Variables_All (struct dstring_s *token)
|
|||
for (i = 0; token->str[i]; i++) {
|
||||
if (token->str[i] == '$') {
|
||||
for (n = 1; token->str[i+n] == '$'; n++); // get past $s
|
||||
for (; isalnum(token->str[i+n]); n++); // find end of var
|
||||
for (; isalnum(token->str[i+n]) ||
|
||||
token->str[i+n] == '.' ||
|
||||
token->str[i+n] == '_'; n++); // find end of var
|
||||
dstring_insert (var, 0, token->str+i, n); // extract it
|
||||
GIB_Process_Variable (var);
|
||||
dstring_replace (token, i, n, var->str, strlen(var->str));
|
||||
|
@ -114,9 +116,9 @@ GIB_Process_Embedded (struct dstring_s *token)
|
|||
i = 0;
|
||||
|
||||
for (; token->str[i]; i++) {
|
||||
if (token->str[i] == '<') {
|
||||
if (token->str[i] == '`') {
|
||||
n = i;
|
||||
if ((c = GIB_Parse_Match_Angle (token->str, &i))) {
|
||||
if ((c = GIB_Parse_Match_Backtick (token->str, &i))) {
|
||||
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -607,7 +607,7 @@ _Host_Frame (float time)
|
|||
|
||||
// process console commands
|
||||
cmd_source = src_command;
|
||||
Cbuf_Execute (host_cbuf);
|
||||
Cbuf_Execute_Stack (host_cbuf);
|
||||
|
||||
NET_Poll ();
|
||||
|
||||
|
|
|
@ -1535,7 +1535,7 @@ Host_Frame (float time)
|
|||
IN_Commands ();
|
||||
|
||||
// process console commands
|
||||
Cbuf_Execute (cl_cbuf);
|
||||
Cbuf_Execute_Stack (cl_cbuf);
|
||||
|
||||
// fetch results from server
|
||||
CL_ReadPackets ();
|
||||
|
|
|
@ -2408,7 +2408,7 @@ SV_Init (void)
|
|||
// COM_AddParm ("-game");
|
||||
// COM_AddParm ("qw");
|
||||
|
||||
sv_cbuf = Cbuf_New (&gib_interp);
|
||||
sv_cbuf = Cbuf_New (&id_interp);
|
||||
sv_args = Cbuf_ArgsNew ();
|
||||
|
||||
Sys_RegisterShutdown (SV_Shutdown);
|
||||
|
|
Loading…
Reference in a new issue