mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
Added tree variables (blah.1, blah.2, blah.1.foobar, etc), global variables,
made var substitution more robust, and began adding proper comments to the code.
This commit is contained in:
parent
30012cc753
commit
0390fe22ce
15 changed files with 466 additions and 109 deletions
|
@ -3,7 +3,7 @@ SUBDIRS = GL plugin
|
||||||
includedir = $(prefix)/include/QF
|
includedir = $(prefix)/include/QF
|
||||||
include_HEADERS = bspfile.h cbuf.h cdaudio.h checksum.h clip_hull.h cmd.h \
|
include_HEADERS = bspfile.h cbuf.h cdaudio.h checksum.h clip_hull.h cmd.h \
|
||||||
console.h crc.h csqc.h cvar.h dstring.h draw.h gcc_attr.h gib_buffer.h \
|
console.h crc.h csqc.h cvar.h dstring.h draw.h gcc_attr.h gib_buffer.h \
|
||||||
gib_builtin.h gib_function.h gib_parse.h gib_process.h hash.h hl.h \
|
gib_builtin.h gib_function.h gib_parse.h gib_process.h gib_vars.h hash.h hl.h \
|
||||||
idparse.h in_event.h info.h input.h joystick.h keys.h link.h locs.h \
|
idparse.h in_event.h info.h input.h joystick.h keys.h link.h locs.h \
|
||||||
mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pakfile.h pcx.h \
|
mathlib.h mdfour.h model.h modelgen.h msg.h pak.h pakfile.h pcx.h \
|
||||||
plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h qdefs.h qendian.h \
|
plugin.h pr_comp.h pr_debug.h pr_obj.h progs.h qargs.h qdefs.h qendian.h \
|
||||||
|
|
|
@ -25,15 +25,12 @@
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GIB_DATA(buffer) ((gib_buffer_data_t *)(buffer->data))
|
#define GIB_DATA(buffer) ((gib_buffer_data_t *)(buffer->data))
|
||||||
|
|
||||||
typedef struct gib_local_s {
|
|
||||||
struct dstring_s *key, *value;
|
|
||||||
} gib_local_t;
|
|
||||||
|
|
||||||
typedef struct gib_buffer_data_s {
|
typedef struct gib_buffer_data_s {
|
||||||
struct dstring_s *arg_composite;
|
struct dstring_s *arg_composite;
|
||||||
struct dstring_s *current_token;
|
struct dstring_s *current_token;
|
||||||
|
@ -62,7 +59,6 @@ typedef struct gib_buffer_data_s {
|
||||||
} type;
|
} type;
|
||||||
} gib_buffer_data_t;
|
} gib_buffer_data_t;
|
||||||
|
|
||||||
void GIB_Local_Set (cbuf_t *cbuf, const char *key, const char *value);
|
|
||||||
const char *GIB_Local_Get (cbuf_t *cbuf, const char *key);
|
|
||||||
void GIB_Buffer_Construct (struct cbuf_s *cbuf);
|
void GIB_Buffer_Construct (struct cbuf_s *cbuf);
|
||||||
void GIB_Buffer_Destruct (struct cbuf_s *cbuf);
|
void GIB_Buffer_Destruct (struct cbuf_s *cbuf);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct gib_builtin_s {
|
typedef struct gib_builtin_s {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct gib_function_s {
|
typedef struct gib_function_s {
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
char GIB_Parse_Match_Brace (const char *str, unsigned int *i);
|
||||||
char GIB_Parse_Match_Backtick (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_Extract_Line (struct cbuf_s *cbuf);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void GIB_Process_Variable (struct dstring_s *token);
|
void GIB_Process_Variable (struct dstring_s *token);
|
||||||
|
|
47
include/QF/gib_vars.h
Normal file
47
include/QF/gib_vars.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
#FILENAME#
|
||||||
|
|
||||||
|
#DESCRIPTION#
|
||||||
|
|
||||||
|
Copyright (C) 2002 #AUTHOR#
|
||||||
|
|
||||||
|
Author: #AUTHOR#
|
||||||
|
Date: #DATE#
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "QF/hash.h"
|
||||||
|
#include "QF/cbuf.h"
|
||||||
|
|
||||||
|
extern hashtab_t *gib_globals;
|
||||||
|
|
||||||
|
typedef struct gib_var_s {
|
||||||
|
struct dstring_s *key, *value;
|
||||||
|
struct hashtab_s *subvars;
|
||||||
|
} gib_var_t;
|
||||||
|
|
||||||
|
void GIB_Var_Set (cbuf_t *cbuf, const char *key, const char *value);
|
||||||
|
const char *GIB_Var_Get (cbuf_t *cbuf, const char *key);
|
||||||
|
const char *GIB_Var_Get_Key (void *ele, void *ptr);
|
||||||
|
void GIB_Var_Free (void *ele, void *ptr);
|
||||||
|
void GIB_Var_Set_R (hashtab_t *vars, char *name, const char *value);
|
||||||
|
gib_var_t *GIB_Var_Get_R (hashtab_t *vars, char *name);
|
|
@ -28,8 +28,9 @@ libQFutil_la_DEPENDENCIES= libasm.la
|
||||||
libQFutil_la_SOURCES= \
|
libQFutil_la_SOURCES= \
|
||||||
buildnum.c cbuf.c checksum.c cmd.c crc.c cvar.c dstring.c exp.c fendian.c \
|
buildnum.c cbuf.c checksum.c cmd.c crc.c cvar.c dstring.c exp.c fendian.c \
|
||||||
getopt.c getopt1.c gib_buffer.c gib_builtin.c gib_function.c gib_parse.c \
|
getopt.c getopt1.c gib_buffer.c gib_builtin.c gib_function.c gib_parse.c \
|
||||||
gib_process.c hash.c idparse.c info.c link.c mathlib.c mdfour.c msg.c ops.c \
|
gib_process.c gib_vars.c hash.c idparse.c info.c link.c mathlib.c mdfour.c \
|
||||||
pakfile.c pcx.c plugin.c qargs.c qendian.c qfplist.c quakefs.c quakeio.c \
|
msg.c ops.c pakfile.c pcx.c plugin.c qargs.c qendian.c qfplist.c quakefs.c \
|
||||||
sizebuf.c string.c sys.c tga.c va.c ver_check.c wad.c zone.c $(fnmatch)
|
quakeio.c sizebuf.c string.c sys.c tga.c va.c ver_check.c wad.c zone.c \
|
||||||
|
$(fnmatch)
|
||||||
|
|
||||||
EXTRA_DIST= $(asm_src) $(fnmatch_src)
|
EXTRA_DIST= $(asm_src) $(fnmatch_src)
|
||||||
|
|
|
@ -28,65 +28,21 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
#include "QF/gib_buffer.h"
|
#include "QF/gib_buffer.h"
|
||||||
|
|
||||||
gib_local_t *
|
|
||||||
GIB_Local_New (void)
|
|
||||||
{
|
|
||||||
gib_local_t *new = calloc (1, sizeof (gib_local_t));
|
|
||||||
new->key = dstring_newstr();
|
|
||||||
new->value = dstring_newstr();
|
|
||||||
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
GIB_Local_Get_Key (void *ele, void *ptr)
|
|
||||||
{
|
|
||||||
return ((gib_local_t *)ele)->key->str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GIB_Local_Free (void *ele, void *ptr)
|
|
||||||
{
|
|
||||||
gib_local_t *l = (gib_local_t *)ele;
|
|
||||||
dstring_delete (l->key);
|
|
||||||
dstring_delete (l->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
GIB_Local_Set (cbuf_t *cbuf, const char *key, const char *value)
|
|
||||||
{
|
|
||||||
gib_local_t *l;
|
|
||||||
if (!GIB_DATA(cbuf)->locals)
|
|
||||||
GIB_DATA(cbuf)->locals = Hash_NewTable (256, GIB_Local_Get_Key, GIB_Local_Free, 0);
|
|
||||||
if ((l = Hash_Find (GIB_DATA(cbuf)->locals, key)))
|
|
||||||
dstring_clearstr (l->value);
|
|
||||||
else {
|
|
||||||
l = GIB_Local_New ();
|
|
||||||
dstring_appendstr (l->key, key);
|
|
||||||
Hash_Add (GIB_DATA(cbuf)->locals, l);
|
|
||||||
}
|
|
||||||
dstring_appendstr (l->value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
GIB_Local_Get (cbuf_t *cbuf, const char *key)
|
|
||||||
{
|
|
||||||
gib_local_t *l;
|
|
||||||
|
|
||||||
if (!GIB_DATA(cbuf)->locals)
|
|
||||||
return 0;
|
|
||||||
if (!(l = Hash_Find (GIB_DATA(cbuf)->locals, key)))
|
|
||||||
return 0;
|
|
||||||
return l->value->str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GIB_Buffer_Construct (struct cbuf_s *cbuf)
|
void GIB_Buffer_Construct (struct cbuf_s *cbuf)
|
||||||
{
|
{
|
||||||
cbuf->data = calloc (1, sizeof (gib_buffer_data_t));
|
cbuf->data = calloc (1, sizeof (gib_buffer_data_t));
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -41,6 +48,7 @@
|
||||||
#include "QF/gib_builtin.h"
|
#include "QF/gib_builtin.h"
|
||||||
#include "QF/gib_buffer.h"
|
#include "QF/gib_buffer.h"
|
||||||
#include "QF/gib_function.h"
|
#include "QF/gib_function.h"
|
||||||
|
#include "QF/gib_vars.h"
|
||||||
|
|
||||||
hashtab_t *gib_builtins;
|
hashtab_t *gib_builtins;
|
||||||
|
|
||||||
|
@ -129,14 +137,30 @@ GIB_Function_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Lset_f (void)
|
GIB_Local_f (void)
|
||||||
{
|
{
|
||||||
if (GIB_Argc () != 3)
|
if (GIB_Argc () != 2)
|
||||||
Cbuf_Error ("syntax",
|
Cbuf_Error ("syntax",
|
||||||
"lset: invalid syntax\n"
|
"lset: invalid syntax\n"
|
||||||
"usage: lset variable value");
|
"usage: local variable");
|
||||||
else
|
else
|
||||||
GIB_Local_Set (cbuf_active, GIB_Argv(1), GIB_Argv(2));
|
GIB_Var_Set (cbuf_active, GIB_Argv(1), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Global_f (void)
|
||||||
|
{
|
||||||
|
if (GIB_Argc () != 2)
|
||||||
|
Cbuf_Error ("syntax",
|
||||||
|
"global: invalid syntax\n"
|
||||||
|
"usage: global variable");
|
||||||
|
else {
|
||||||
|
char *a = strdup (GIB_Argv(1));
|
||||||
|
if (!gib_globals)
|
||||||
|
gib_globals = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||||
|
GIB_Var_Set_R (gib_globals, a, "");
|
||||||
|
free(a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -268,7 +292,8 @@ GIB_Builtin_Init (void)
|
||||||
{
|
{
|
||||||
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
|
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
|
||||||
GIB_Builtin_Add ("export", GIB_Export_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 ("local", GIB_Local_f, GIB_BUILTIN_NORMAL);
|
||||||
|
GIB_Builtin_Add ("global", GIB_Global_f, GIB_BUILTIN_NORMAL);
|
||||||
GIB_Builtin_Add ("return", GIB_Return_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 ("if", GIB_If_f, GIB_BUILTIN_FIRSTONLY);
|
||||||
GIB_Builtin_Add ("ifnot", GIB_If_f, GIB_BUILTIN_FIRSTONLY);
|
GIB_Builtin_Add ("ifnot", GIB_If_f, GIB_BUILTIN_FIRSTONLY);
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
@ -36,10 +43,17 @@
|
||||||
#include "QF/gib_parse.h"
|
#include "QF/gib_parse.h"
|
||||||
#include "QF/gib_buffer.h"
|
#include "QF/gib_buffer.h"
|
||||||
#include "QF/gib_function.h"
|
#include "QF/gib_function.h"
|
||||||
|
#include "QF/gib_vars.h"
|
||||||
#include "QF/va.h"
|
#include "QF/va.h"
|
||||||
|
|
||||||
hashtab_t *gib_functions = 0;
|
hashtab_t *gib_functions = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Function_New
|
||||||
|
|
||||||
|
Builds a new function struct and returns
|
||||||
|
a pointer to it.
|
||||||
|
*/
|
||||||
gib_function_t *
|
gib_function_t *
|
||||||
GIB_Function_New (void)
|
GIB_Function_New (void)
|
||||||
{
|
{
|
||||||
|
@ -50,12 +64,14 @@ GIB_Function_New (void)
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Hashtable callbacks
|
||||||
|
*/
|
||||||
const char *
|
const char *
|
||||||
GIB_Function_Get_Key (void *ele, void *ptr)
|
GIB_Function_Get_Key (void *ele, void *ptr)
|
||||||
{
|
{
|
||||||
return ((gib_function_t *)ele)->name->str;
|
return ((gib_function_t *)ele)->name->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Function_Free (void *ele, void *ptr)
|
GIB_Function_Free (void *ele, void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -64,6 +80,13 @@ GIB_Function_Free (void *ele, void *ptr)
|
||||||
dstring_delete (func->program);
|
dstring_delete (func->program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Function_Define
|
||||||
|
|
||||||
|
Sets the program text of a GIB function,
|
||||||
|
allocating one and adding it to the functions
|
||||||
|
hash if needed.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
GIB_Function_Define (const char *name, const char *program)
|
GIB_Function_Define (const char *name, const char *program)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +105,13 @@ GIB_Function_Define (const char *name, const char *program)
|
||||||
dstring_appendstr (func->program, program);
|
dstring_appendstr (func->program, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Function_Find
|
||||||
|
|
||||||
|
Looks up a function in the function hash
|
||||||
|
and returns a pointer to it on success,
|
||||||
|
0 otherwise
|
||||||
|
*/
|
||||||
gib_function_t *
|
gib_function_t *
|
||||||
GIB_Function_Find (const char *name)
|
GIB_Function_Find (const char *name)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +120,15 @@ GIB_Function_Find (const char *name)
|
||||||
return (gib_function_t *) Hash_Find (gib_functions, name);
|
return (gib_function_t *) Hash_Find (gib_functions, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Function_Execute
|
||||||
|
|
||||||
|
Creates a new buffer on the current stack
|
||||||
|
and copies the program text of a function
|
||||||
|
into it. Also sets local variables on the
|
||||||
|
buffer for all arguments passed to the
|
||||||
|
function
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
GIB_Function_Execute (gib_function_t *func)
|
GIB_Function_Execute (gib_function_t *func)
|
||||||
{
|
{
|
||||||
|
@ -104,6 +143,6 @@ GIB_Function_Execute (gib_function_t *func)
|
||||||
cbuf_active->state = CBUF_STATE_STACK;
|
cbuf_active->state = CBUF_STATE_STACK;
|
||||||
|
|
||||||
for (i = 0; i < cbuf_active->args->argc; i++)
|
for (i = 0; i < cbuf_active->args->argc; i++)
|
||||||
GIB_Local_Set (sub, va("%i", i), cbuf_active->args->argv[i]->str);
|
GIB_Var_Set (sub, va("%i", i), cbuf_active->args->argv[i]->str);
|
||||||
GIB_Local_Set (sub, "argc", va("%i", cbuf_active->args->argc));
|
GIB_Var_Set (sub, "argc", va("%i", cbuf_active->args->argc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
/*
|
/*
|
||||||
#FILENAME#
|
gib_parse.c
|
||||||
|
|
||||||
#DESCRIPTION#
|
GIB parser functions
|
||||||
|
|
||||||
Copyright (C) 2002 #AUTHOR#
|
Copyright (C) 2002 Brian Koropoff
|
||||||
|
|
||||||
Author: #AUTHOR#
|
Author: Brian Koropoff
|
||||||
Date: #DATE#
|
Date: #DATE#
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -39,6 +46,7 @@
|
||||||
#include "QF/gib_process.h"
|
#include "QF/gib_process.h"
|
||||||
#include "QF/gib_builtin.h"
|
#include "QF/gib_builtin.h"
|
||||||
#include "QF/gib_function.h"
|
#include "QF/gib_function.h"
|
||||||
|
#include "QF/gib_vars.h"
|
||||||
|
|
||||||
// Interpreter structure and prototypes
|
// Interpreter structure and prototypes
|
||||||
|
|
||||||
|
@ -55,8 +63,14 @@ cbuf_interpreter_t gib_interp = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Co-recursive parsing functions */
|
/*
|
||||||
|
GIB_Parse_Match_Dquote
|
||||||
|
|
||||||
|
Progresses an index variable through a string
|
||||||
|
until a double quote is reached. Returns
|
||||||
|
0 on success, or the character it could not
|
||||||
|
match otherwise
|
||||||
|
*/
|
||||||
char
|
char
|
||||||
GIB_Parse_Match_Dquote (const char *str, unsigned int *i)
|
GIB_Parse_Match_Dquote (const char *str, unsigned int *i)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +83,16 @@ GIB_Parse_Match_Dquote (const char *str, unsigned int *i)
|
||||||
return '\"';
|
return '\"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Match_Brace
|
||||||
|
|
||||||
|
Progresses an index variable through a string
|
||||||
|
until a closing brace (}) is reached. Calls
|
||||||
|
other matching functions to skip areas of a
|
||||||
|
string it does not want to handle. Returns
|
||||||
|
0 on success, or the character it could not
|
||||||
|
match otherwise.
|
||||||
|
*/
|
||||||
char
|
char
|
||||||
GIB_Parse_Match_Brace (const char *str, unsigned int *i)
|
GIB_Parse_Match_Brace (const char *str, unsigned int *i)
|
||||||
{
|
{
|
||||||
|
@ -86,6 +110,16 @@ GIB_Parse_Match_Brace (const char *str, unsigned int *i)
|
||||||
return '{';
|
return '{';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Match_Paren
|
||||||
|
|
||||||
|
Progresses an index variable through a string
|
||||||
|
until a closing parenthesis is reached. Calls
|
||||||
|
other matching functions to skip areas of a
|
||||||
|
string it does not want to handle. Returns
|
||||||
|
0 on success, or the character it could not
|
||||||
|
match otherwise.
|
||||||
|
*/
|
||||||
char
|
char
|
||||||
GIB_Parse_Match_Paren (const char *str, unsigned int *i)
|
GIB_Parse_Match_Paren (const char *str, unsigned int *i)
|
||||||
{
|
{
|
||||||
|
@ -102,6 +136,16 @@ GIB_Parse_Match_Paren (const char *str, unsigned int *i)
|
||||||
return '(';
|
return '(';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Match_Backtick
|
||||||
|
|
||||||
|
Progresses an index variable through a string
|
||||||
|
until a backtick (`) is reached. Calls
|
||||||
|
other matching functions to skip areas of a
|
||||||
|
string it does not want to handle. Returns
|
||||||
|
0 on success, or the character it could not
|
||||||
|
match otherwise.
|
||||||
|
*/
|
||||||
char
|
char
|
||||||
GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
||||||
{
|
{
|
||||||
|
@ -109,7 +153,7 @@ GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
||||||
for ((*i)++; str[*i]; (*i)++) {
|
for ((*i)++; str[*i]; (*i)++) {
|
||||||
if (str[*i] == '`')
|
if (str[*i] == '`')
|
||||||
return 0;
|
return 0;
|
||||||
else if (str[*i] == '\"') { // Skip over strings
|
else if (str[*i] == '\"') { // Skip over strings as usual
|
||||||
if ((c = GIB_Parse_Match_Dquote (str, i)))
|
if ((c = GIB_Parse_Match_Dquote (str, i)))
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +161,13 @@ GIB_Parse_Match_Backtick (const char *str, unsigned int *i)
|
||||||
return '`';
|
return '`';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Extract_Line
|
||||||
|
|
||||||
|
Extracts the next command from a cbuf and
|
||||||
|
deposits it in cbuf->line, removing the
|
||||||
|
portion used from the buffer
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +180,6 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
||||||
|
|
||||||
dstring_clearstr (cbuf->line);
|
dstring_clearstr (cbuf->line);
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; dstr->str[i]; i++) {
|
for (i = 0; dstr->str[i]; i++) {
|
||||||
if (dstr->str[i] == '{') {
|
if (dstr->str[i] == '{') {
|
||||||
if ((c = GIB_Parse_Match_Brace (dstr->str, &i))) {
|
if ((c = GIB_Parse_Match_Brace (dstr->str, &i))) {
|
||||||
|
@ -149,19 +199,22 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
||||||
dstring_snip (dstr, i, n-dstr->str);
|
dstring_snip (dstr, i, n-dstr->str);
|
||||||
else {
|
else {
|
||||||
dstring_snip (dstr, i, strlen(dstr->str+i));
|
dstring_snip (dstr, i, strlen(dstr->str+i));
|
||||||
i--; // So we don't go past null
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dstr->str[0]) {
|
if (dstr->str[0]) { // If something is left in the buffer
|
||||||
if (i) {
|
if (i) { // If we used any of it
|
||||||
dstring_insert (cbuf->line, 0, dstr->str, i);
|
dstring_insert (cbuf->line, 0, dstr->str, i);
|
||||||
Sys_DPrintf ("extracted line: %s\n", cbuf->line->str);
|
Sys_DPrintf ("extracted line: %s\n", cbuf->line->str);
|
||||||
}
|
}
|
||||||
|
// Clip out what we used or any leftover newlines or ;s
|
||||||
dstring_snip (dstr, 0, i + (dstr->str[i] == '\n' || dstr->str[i] == ';'));
|
dstring_snip (dstr, 0, i + (dstr->str[i] == '\n' || dstr->str[i] == ';'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a looping buffer and it is now empty
|
||||||
|
// copy the loop program back in
|
||||||
if (GIB_DATA(cbuf)->type == GIB_BUFFER_LOOP && !dstr->str[0])
|
if (GIB_DATA(cbuf)->type == GIB_BUFFER_LOOP && !dstr->str[0])
|
||||||
Cbuf_AddText (cbuf, GIB_DATA(cbuf)->loop_program->str);
|
Cbuf_AddText (cbuf, GIB_DATA(cbuf)->loop_program->str);
|
||||||
|
|
||||||
|
@ -169,6 +222,16 @@ GIB_Parse_Extract_Line (struct cbuf_s *cbuf)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Get_Token
|
||||||
|
|
||||||
|
Progresses an index variable through a string
|
||||||
|
until the end of the next token is found.
|
||||||
|
Stores the token in dstr with or without
|
||||||
|
wrapping characters as specified by include_delim.
|
||||||
|
Returns 0 on error or the wrapping character of
|
||||||
|
the token otherwise
|
||||||
|
*/
|
||||||
inline static char
|
inline static char
|
||||||
GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean include_delim)
|
GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean include_delim)
|
||||||
{
|
{
|
||||||
|
@ -208,6 +271,12 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean
|
||||||
return 0; // Parse error
|
return 0; // Parse error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (str[*i] == '{') {
|
||||||
|
if ((c = GIB_Parse_Match_Brace (str, i))) {
|
||||||
|
Cbuf_Error ("parse", "Could not find matching %c", c);
|
||||||
|
return 0; // Parse error
|
||||||
|
}
|
||||||
|
}
|
||||||
(*i)++;
|
(*i)++;
|
||||||
}
|
}
|
||||||
dstring_insert (dstr, 0, str+n, *i-n);
|
dstring_insert (dstr, 0, str+n, *i-n);
|
||||||
|
@ -216,6 +285,14 @@ GIB_Parse_Get_Token (const char *str, unsigned int *i, dstring_t *dstr, qboolean
|
||||||
return 0; // We should never get here
|
return 0; // We should never get here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Generate_Composite
|
||||||
|
|
||||||
|
Concatenates all parsed arguments in cbuf
|
||||||
|
into a single string and creates an array
|
||||||
|
of pointers to the beginnings of tokens
|
||||||
|
within it.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
GIB_Parse_Generate_Composite (struct cbuf_s *cbuf)
|
GIB_Parse_Generate_Composite (struct cbuf_s *cbuf)
|
||||||
{
|
{
|
||||||
|
@ -240,6 +317,13 @@ GIB_Parse_Generate_Composite (struct cbuf_s *cbuf)
|
||||||
args->args[i] += (unsigned long int) GIB_DATA (cbuf)->arg_composite->str;
|
args->args[i] += (unsigned long int) GIB_DATA (cbuf)->arg_composite->str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Add_Token
|
||||||
|
|
||||||
|
Adds a new token to the argument list args
|
||||||
|
or concatenates it to the end of the last
|
||||||
|
according to cat.
|
||||||
|
*/
|
||||||
inline void
|
inline void
|
||||||
GIB_Parse_Add_Token (struct cbuf_args_s *args, qboolean cat, dstring_t *token)
|
GIB_Parse_Add_Token (struct cbuf_args_s *args, qboolean cat, dstring_t *token)
|
||||||
{
|
{
|
||||||
|
@ -249,6 +333,16 @@ GIB_Parse_Add_Token (struct cbuf_args_s *args, qboolean cat, dstring_t *token)
|
||||||
Cbuf_ArgsAdd (args, token->str);
|
Cbuf_ArgsAdd (args, token->str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Tokenize_Line
|
||||||
|
|
||||||
|
Tokenizes and processes an extracted command,
|
||||||
|
producing an argument list suitable for executing
|
||||||
|
the command. This function can be interrupted
|
||||||
|
to call a GIB subroutine, in which case it will
|
||||||
|
save important variables and start where it left
|
||||||
|
off when called again.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf)
|
GIB_Parse_Tokenize_Line (struct cbuf_s *cbuf)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +418,18 @@ FILTER_ERROR:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GIB_Parse_Execute_Line
|
||||||
|
|
||||||
|
After an argument list has been created,
|
||||||
|
this function executes the appropriate command,
|
||||||
|
searching in this order:
|
||||||
|
|
||||||
|
GIB builtins
|
||||||
|
GIB functions
|
||||||
|
Assignment to a local variable
|
||||||
|
Normal quake console commands
|
||||||
|
*/
|
||||||
void GIB_Parse_Execute_Line (cbuf_t *cbuf)
|
void GIB_Parse_Execute_Line (cbuf_t *cbuf)
|
||||||
{
|
{
|
||||||
cbuf_args_t *args = cbuf->args;
|
cbuf_args_t *args = cbuf->args;
|
||||||
|
@ -334,9 +440,12 @@ void GIB_Parse_Execute_Line (cbuf_t *cbuf)
|
||||||
b->func ();
|
b->func ();
|
||||||
else if ((f = GIB_Function_Find (args->argv[0]->str)))
|
else if ((f = GIB_Function_Find (args->argv[0]->str)))
|
||||||
GIB_Function_Execute (f);
|
GIB_Function_Execute (f);
|
||||||
else if (args->argc == 3 && !strcmp (args->argv[1]->str, "="))
|
else if (args->argc == 3 && !strcmp (args->argv[1]->str, "=")) {
|
||||||
GIB_Local_Set (cbuf, args->argv[0]->str, args->argv[2]->str);
|
if (!GIB_Var_Get (cbuf, args->argv[0]->str) && GIB_Var_Get_R (gib_globals, args->argv[0]->str))
|
||||||
else
|
GIB_Var_Set_R (gib_globals, args->argv[0]->str, args->argv[2]->str);
|
||||||
|
else
|
||||||
|
GIB_Var_Set (cbuf, args->argv[0]->str, args->argv[2]->str);
|
||||||
|
} else
|
||||||
Cmd_Command (cbuf->args);
|
Cmd_Command (cbuf->args);
|
||||||
dstring_clearstr (cbuf->line);
|
dstring_clearstr (cbuf->line);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
@ -36,49 +43,73 @@
|
||||||
#include "QF/cvar.h"
|
#include "QF/cvar.h"
|
||||||
#include "QF/gib_buffer.h"
|
#include "QF/gib_buffer.h"
|
||||||
#include "QF/gib_parse.h"
|
#include "QF/gib_parse.h"
|
||||||
|
#include "QF/gib_vars.h"
|
||||||
|
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
|
|
||||||
void
|
unsigned int
|
||||||
GIB_Process_Variable (struct dstring_s *dstr)
|
GIB_Process_Variable (struct dstring_s *dstr, unsigned int pos, qboolean tolerant)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
cvar_t *cvar;
|
cvar_t *cvar;
|
||||||
|
gib_var_t *gvar;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
char *p, c;
|
||||||
|
|
||||||
for (i = 0; dstr->str[i] == '$'; i++);
|
for (p = dstr->str+pos+1; tolerant ? *p : isalnum (*p) || *p == '_'; p++);
|
||||||
i--;
|
c = *p;
|
||||||
for (; i >= 0; i--) {
|
*p = 0;
|
||||||
if ((str = GIB_Local_Get (cbuf_active, dstr->str+i+1)))
|
if ((str = GIB_Var_Get (cbuf_active, dstr->str+pos+1)))
|
||||||
; // yay for us
|
; // yay for us
|
||||||
else if ((cvar = Cvar_FindVar (dstr->str+i+1)))
|
else if ((gvar = GIB_Var_Get_R (gib_globals, dstr->str+pos+1)))
|
||||||
str = cvar->string;
|
str = gvar->value->str;
|
||||||
else
|
else if ((cvar = Cvar_FindVar (dstr->str+pos+1)))
|
||||||
return;
|
str = cvar->string;
|
||||||
dstr->str[i] = 0;
|
else
|
||||||
dstring_appendstr (dstr, str);
|
str = 0;
|
||||||
}
|
*p = c;
|
||||||
|
if (str)
|
||||||
|
dstring_replace (dstr, pos, p - dstr->str - pos, str, strlen(str));
|
||||||
|
else
|
||||||
|
dstring_snip (dstr, pos, p - dstr->str - pos);
|
||||||
|
return str ? strlen (str) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
GIB_Process_Variables_All (struct dstring_s *token)
|
GIB_Process_Variables_All (struct dstring_s *token)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n, m;
|
||||||
dstring_t *var = dstring_newstr ();
|
dstring_t *var = dstring_newstr ();
|
||||||
|
char c = 0;
|
||||||
|
|
||||||
for (i = 0; token->str[i]; i++) {
|
for (i = 0; token->str[i]; i++) {
|
||||||
if (token->str[i] == '$') {
|
if (token->str[i] == '$') {
|
||||||
for (n = 1; token->str[i+n] == '$'; n++); // get past $s
|
if (token->str[i+1] == '{') {
|
||||||
for (; isalnum(token->str[i+n]) ||
|
n = i+1;
|
||||||
token->str[i+n] == '.' ||
|
if ((c = GIB_Parse_Match_Brace (token->str, &n))) {
|
||||||
token->str[i+n] == '_'; n++); // find end of var
|
Cbuf_Error ("parse", "Could not find match for %c", c);
|
||||||
dstring_insert (var, 0, token->str+i, n); // extract it
|
goto ERROR;
|
||||||
GIB_Process_Variable (var);
|
}
|
||||||
|
n -= i;
|
||||||
|
dstring_insert (var, 0, token->str+i+2, n-2);
|
||||||
|
dstring_insertstr (var, 0, "$");
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
for (n = 1; 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
|
||||||
|
}
|
||||||
|
for (m = 1; var->str[m]; m++) {
|
||||||
|
if (var->str[m] == '$')
|
||||||
|
m += GIB_Process_Variable (var, m, false) - 1;
|
||||||
|
}
|
||||||
|
GIB_Process_Variable (var, 0, true);
|
||||||
dstring_replace (token, i, n, var->str, strlen(var->str));
|
dstring_replace (token, i, n, var->str, strlen(var->str));
|
||||||
i += strlen (var->str) - 1;
|
i += strlen (var->str) - 1;
|
||||||
dstring_clearstr (var);
|
dstring_clearstr (var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ERROR:
|
||||||
|
dstring_delete (var);
|
||||||
|
return c ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -153,7 +184,8 @@ GIB_Process_Token (struct dstring_s *token, char delim)
|
||||||
if (delim != '{' && delim != '\"') {
|
if (delim != '{' && delim != '\"') {
|
||||||
if (GIB_Process_Embedded (token))
|
if (GIB_Process_Embedded (token))
|
||||||
return -1;
|
return -1;
|
||||||
GIB_Process_Variables_All (token);
|
if (GIB_Process_Variables_All (token))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (delim == '(')
|
if (delim == '(')
|
||||||
if (GIB_Process_Math (token))
|
if (GIB_Process_Math (token))
|
||||||
|
|
140
libs/util/gib_vars.c
Normal file
140
libs/util/gib_vars.c
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
#FILENAME#
|
||||||
|
|
||||||
|
#DESCRIPTION#
|
||||||
|
|
||||||
|
Copyright (C) 2002 #AUTHOR#
|
||||||
|
|
||||||
|
Author: #AUTHOR#
|
||||||
|
Date: #DATE#
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to:
|
||||||
|
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330
|
||||||
|
Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "QF/dstring.h"
|
||||||
|
#include "QF/hash.h"
|
||||||
|
#include "QF/gib_vars.h"
|
||||||
|
#include "QF/gib_buffer.h"
|
||||||
|
|
||||||
|
hashtab_t *gib_globals = 0;
|
||||||
|
|
||||||
|
gib_var_t *
|
||||||
|
GIB_Var_New (void)
|
||||||
|
{
|
||||||
|
gib_var_t *new = calloc (1, sizeof (gib_var_t));
|
||||||
|
new->key = dstring_newstr();
|
||||||
|
new->value = dstring_newstr();
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GIB_Var_Get_Key (void *ele, void *ptr)
|
||||||
|
{
|
||||||
|
return ((gib_var_t *)ele)->key->str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Var_Free (void *ele, void *ptr)
|
||||||
|
{
|
||||||
|
gib_var_t *l = (gib_var_t *)ele;
|
||||||
|
dstring_delete (l->key);
|
||||||
|
dstring_delete (l->value);
|
||||||
|
if (l->subvars)
|
||||||
|
Hash_DelTable (l->subvars);
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_var_t *
|
||||||
|
GIB_Var_Get_R (hashtab_t *vars, char *name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
gib_var_t *l;
|
||||||
|
|
||||||
|
if ((p = strchr (name, '.'))) {
|
||||||
|
*p = 0;
|
||||||
|
l = Hash_Find (vars, name);
|
||||||
|
*p = '.';
|
||||||
|
if (!l || !l->subvars)
|
||||||
|
return 0;
|
||||||
|
return GIB_Var_Get_R (l->subvars, p+1);
|
||||||
|
} else
|
||||||
|
return Hash_Find (vars, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Var_Set_R (hashtab_t *vars, char *name, const char *value)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
gib_var_t *l;
|
||||||
|
|
||||||
|
if ((p = strchr (name, '.'))) {
|
||||||
|
*p = 0;
|
||||||
|
if (!(l = Hash_Find (vars, name))) {
|
||||||
|
l = GIB_Var_New ();
|
||||||
|
dstring_appendstr (l->key, name);
|
||||||
|
Hash_Add (vars, l);
|
||||||
|
}
|
||||||
|
*p = '.';
|
||||||
|
if (!l->subvars)
|
||||||
|
l->subvars = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||||
|
GIB_Var_Set_R (l->subvars, p+1, value);
|
||||||
|
} else {
|
||||||
|
if ((l = Hash_Find (vars, name)))
|
||||||
|
dstring_clearstr (l->value);
|
||||||
|
else {
|
||||||
|
l = GIB_Var_New ();
|
||||||
|
dstring_appendstr (l->key, name);
|
||||||
|
Hash_Add (vars, l);
|
||||||
|
}
|
||||||
|
dstring_appendstr (l->value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Var_Set (cbuf_t *cbuf, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
char *k = strdup (key);
|
||||||
|
if (!GIB_DATA(cbuf)->locals)
|
||||||
|
GIB_DATA(cbuf)->locals = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||||
|
GIB_Var_Set_R (GIB_DATA(cbuf)->locals, k, value);
|
||||||
|
free(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GIB_Var_Get (cbuf_t *cbuf, const char *key)
|
||||||
|
{
|
||||||
|
gib_var_t *l;
|
||||||
|
char *k;
|
||||||
|
if (!GIB_DATA(cbuf)->locals)
|
||||||
|
return 0;
|
||||||
|
k = strdup(key);
|
||||||
|
l = GIB_Var_Get_R (GIB_DATA(cbuf)->locals, k);
|
||||||
|
free(k);
|
||||||
|
if (l)
|
||||||
|
return l->value->str;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -28,6 +28,13 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static const char rcsid[] =
|
||||||
|
"$Id$";
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
|
Loading…
Reference in a new issue