mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 12:10:48 +00:00
More cleanups and bug fixes. Added stem-and-leaf variables back in and
added the global::delete builtin.
This commit is contained in:
parent
d626575091
commit
af520a373a
9 changed files with 218 additions and 162 deletions
|
@ -38,7 +38,6 @@ typedef struct gib_thread_s {
|
|||
unsigned long int id;
|
||||
struct cbuf_s *cbuf;
|
||||
struct gib_thread_s *prev, *next;
|
||||
qboolean trash;
|
||||
} gib_thread_t;
|
||||
|
||||
typedef struct gib_event_s {
|
||||
|
|
|
@ -36,7 +36,10 @@ extern hashtab_t *gib_globals;
|
|||
|
||||
typedef struct gib_var_s {
|
||||
const char *key;
|
||||
struct dstring_s **array;
|
||||
struct gib_varray_s {
|
||||
struct dstring_s *value;
|
||||
struct hashtab_s *leaves;
|
||||
} *array;
|
||||
unsigned int size;
|
||||
} gib_var_t;
|
||||
|
||||
|
@ -47,6 +50,7 @@ typedef struct gib_domain_s {
|
|||
|
||||
gib_var_t *GIB_Var_Get (hashtab_t *first, hashtab_t *second, const char *key);
|
||||
gib_var_t *GIB_Var_Get_Complex (hashtab_t **first, hashtab_t **second, char *key, unsigned int *ind, qboolean create);
|
||||
gib_var_t *GIB_Var_Get_Very_Complex (hashtab_t ** first, hashtab_t ** second, dstring_t *key, unsigned int start, unsigned int *ind, qboolean create);
|
||||
void GIB_Var_Assign (gib_var_t *var, unsigned int index, dstring_t **values, unsigned int numv);
|
||||
hashtab_t *GIB_Domain_Get (const char *name);
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ GIB_Buffer_Reset (struct cbuf_s *cbuf)
|
|||
free (g->script);
|
||||
}
|
||||
g->script = 0;
|
||||
g->program = 0;
|
||||
g->stack.p = 0;
|
||||
g->waitret = g->done = false;
|
||||
|
||||
|
|
|
@ -197,19 +197,20 @@ static void
|
|||
GIB_Local_f (void)
|
||||
{
|
||||
gib_var_t *var;
|
||||
unsigned int index;
|
||||
hashtab_t *zero = 0;
|
||||
unsigned int index, i;
|
||||
static hashtab_t *zero = 0;
|
||||
|
||||
if (GIB_Argc () < 2)
|
||||
GIB_USAGE ("var [= value1 value2 ...]");
|
||||
else {
|
||||
var =
|
||||
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals, &zero,
|
||||
GIB_USAGE ("var [= value1 value2 ...] || var [var2 var3 ...]");
|
||||
else if (!strcmp (GIB_Argv(2), "=")) {
|
||||
var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals, &zero,
|
||||
GIB_Argv (1), &index, true);
|
||||
if (GIB_Argc () >= 3)
|
||||
GIB_Var_Assign (var, index, cbuf_active->args->argv + 3,
|
||||
GIB_Argc () - 3);
|
||||
}
|
||||
} else for (i = 1; i < GIB_Argc(); i++)
|
||||
var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals, &zero,
|
||||
GIB_Argv (1), &index, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -217,18 +218,45 @@ static void
|
|||
GIB_Global_f (void)
|
||||
{
|
||||
gib_var_t *var;
|
||||
unsigned int index;
|
||||
hashtab_t *zero = 0;
|
||||
unsigned int index, i;
|
||||
static hashtab_t *zero = 0;
|
||||
|
||||
if (GIB_Argc () < 2)
|
||||
GIB_USAGE ("var [= value1 value2 ...]");
|
||||
else {
|
||||
var =
|
||||
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->globals, &zero,
|
||||
GIB_USAGE ("var [= value1 value2 ...] || var [var2 var3 ...]");
|
||||
else if (!strcmp (GIB_Argv(2), "=")) {
|
||||
var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->globals, &zero,
|
||||
GIB_Argv (1), &index, true);
|
||||
if (GIB_Argc () >= 3)
|
||||
GIB_Var_Assign (var, index, cbuf_active->args->argv + 3,
|
||||
GIB_Argc () - 3);
|
||||
} else for (i = 1; i < GIB_Argc(); i++)
|
||||
var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->globals, &zero,
|
||||
GIB_Argv (1), &index, true);
|
||||
}
|
||||
|
||||
static void
|
||||
GIB_Global_Delete_f (void)
|
||||
{
|
||||
gib_var_t *var;
|
||||
unsigned int index, i;
|
||||
hashtab_t *source;
|
||||
static hashtab_t *zero = 0;
|
||||
char *c;
|
||||
|
||||
if (GIB_Argc () < 2)
|
||||
GIB_USAGE ("var [var2 var2 ...]");
|
||||
else for (i = 1; i < GIB_Argc(); i++) {
|
||||
if ((c = strrchr (GIB_Argv(i), '.'))) {
|
||||
*(c++) = 0;
|
||||
if (!(var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->globals, &zero,
|
||||
GIB_Argv (i), &index, false)))
|
||||
continue;
|
||||
source = var->array[index].leaves;
|
||||
} else {
|
||||
c = GIB_Argv(i);
|
||||
source = GIB_DATA(cbuf_active)->globals;
|
||||
}
|
||||
Hash_Free (source, Hash_Del (source, c));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,13 +626,12 @@ GIB_Thread_Kill_f (void)
|
|||
id);
|
||||
return;
|
||||
}
|
||||
thread->trash = true;
|
||||
// Set error condition on the top of the stack so the thread will exit
|
||||
// if currently running
|
||||
// We can't simply nuke the thread, as it would cause the stack walker
|
||||
// to segfault if a thread kills itself.
|
||||
for (cur = thread->cbuf;
|
||||
cur->down && cur->down->state != CBUF_STATE_JUNK; cur = cur->down);
|
||||
cur->state = CBUF_STATE_ERROR;
|
||||
GIB_DATA (cur)->done = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -884,6 +911,7 @@ GIB_Builtin_Init (qboolean sandbox)
|
|||
GIB_Builtin_Add ("function::export", GIB_Function_Export_f);
|
||||
GIB_Builtin_Add ("local", GIB_Local_f);
|
||||
GIB_Builtin_Add ("global", GIB_Global_f);
|
||||
GIB_Builtin_Add ("global::delete", GIB_Global_Delete_f);
|
||||
GIB_Builtin_Add ("domain", GIB_Domain_f);
|
||||
GIB_Builtin_Add ("domain::clear", GIB_Domain_Clear_f);
|
||||
GIB_Builtin_Add ("return", GIB_Return_f);
|
||||
|
|
|
@ -80,7 +80,7 @@ GIB_Execute_Split_Array (cbuf_t * cbuf)
|
|||
{
|
||||
gib_var_t *var;
|
||||
unsigned int i;
|
||||
int start = 0, end = 0;
|
||||
int start = 0, end = (int) ((unsigned int) ~0 >> 1);
|
||||
char *c, *str = cbuf->args->argv[cbuf->args->argc - 1]->str + 1;
|
||||
void *m = cbuf->args->argm[cbuf->args->argc - 1];
|
||||
|
||||
|
@ -93,16 +93,12 @@ GIB_Execute_Split_Array (cbuf_t * cbuf)
|
|||
if ((c = strchr (str + i + 1, ':'))) {
|
||||
if (c[1] != ']')
|
||||
end = atoi (c + 1);
|
||||
else
|
||||
end = (int) ((unsigned int) ~0 >> 1);
|
||||
} else
|
||||
end = start + 1;
|
||||
break;
|
||||
}
|
||||
cbuf->args->argc--;
|
||||
if (!
|
||||
(var =
|
||||
GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals,
|
||||
if (!(var = GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals,
|
||||
&GIB_DATA (cbuf)->globals, str, &i, false)))
|
||||
return;
|
||||
if (end < 0)
|
||||
|
@ -116,8 +112,8 @@ GIB_Execute_Split_Array (cbuf_t * cbuf)
|
|||
} else if (start >= var->size || start >= end)
|
||||
return;
|
||||
for (i = start; i < end; i++) {
|
||||
if (var->array[i])
|
||||
Cbuf_ArgsAdd (cbuf->args, var->array[i]->str);
|
||||
if (var->array[i].value)
|
||||
Cbuf_ArgsAdd (cbuf->args, var->array[i].value->str);
|
||||
else
|
||||
Cbuf_ArgsAdd (cbuf->args, "");
|
||||
cbuf->args->argm[cbuf->args->argc - 1] = m;
|
||||
|
@ -174,8 +170,8 @@ GIB_Execute_For_Next (cbuf_t * cbuf)
|
|||
GIB_Var_Get_Complex (&GIB_DATA (cbuf)->locals,
|
||||
&GIB_DATA (cbuf)->globals, array->dstrs[0]->str,
|
||||
&index, true);
|
||||
dstring_clearstr (var->array[index]);
|
||||
dstring_appendstr (var->array[index], array->dstrs[array->size]->str);
|
||||
dstring_clearstr (var->array[index].value);
|
||||
dstring_appendstr (var->array[index].value, array->dstrs[array->size]->str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -195,10 +191,9 @@ GIB_Execute (cbuf_t * cbuf)
|
|||
if (GIB_Execute_Prepare_Line (cbuf, g->ip))
|
||||
return;
|
||||
if (g->ip->flags & TREE_COND) {
|
||||
cond =
|
||||
g->ip->flags & TREE_NOT ? atoi (cbuf->args->argv[1]->
|
||||
str) : !atoi (cbuf->args->
|
||||
argv[1]->str);
|
||||
cond = g->ip->flags & TREE_NOT ?
|
||||
atoi (cbuf->args->argv[1]->str) :
|
||||
!atoi (cbuf->args->argv[1]->str);
|
||||
if (cond)
|
||||
g->ip = g->ip->jump;
|
||||
} else if (g->ip->flags & TREE_FORNEXT) {
|
||||
|
|
|
@ -162,11 +162,11 @@ GIB_Function_Prepare_Args (cbuf_t * cbuf, dstring_t ** args, unsigned int argc)
|
|||
memset (var->array + 1, 0, (argc - 1) * sizeof (dstring_t *));
|
||||
var->size = argc;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (var->array[i])
|
||||
dstring_clearstr (var->array[i]);
|
||||
if (var->array[i].value)
|
||||
dstring_clearstr (var->array[i].value);
|
||||
else
|
||||
var->array[i] = dstring_newstr ();
|
||||
dstring_appendstr (var->array[i], args[i]->str);
|
||||
var->array[i].value = dstring_newstr ();
|
||||
dstring_appendstr (var->array[i].value, args[i]->str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,72 +51,6 @@ const char rcsid[] = "$Id$";
|
|||
|
||||
#include "exp.h"
|
||||
|
||||
static int
|
||||
GIB_Process_Variable (dstring_t * token, unsigned int *i)
|
||||
{
|
||||
hashtab_t *one = GIB_DATA (cbuf_active)->locals, *two =
|
||||
GIB_DATA (cbuf_active)->globals;
|
||||
unsigned int n = *i, j, k, start = *i, index = 0, len, len2;
|
||||
gib_var_t *var = 0;
|
||||
cvar_t *cvar;
|
||||
char c;
|
||||
const char *str;
|
||||
|
||||
(*i)++;
|
||||
if (token->str[*i] == '{') {
|
||||
if ((c = GIB_Parse_Match_Brace (token->str, i))) {
|
||||
GIB_Error ("Parse", "Could not find match for %c.", c);
|
||||
return -1;
|
||||
}
|
||||
n += 2;
|
||||
len = 1;
|
||||
} else {
|
||||
for (; isalnum ((byte) token->str[*i]) || token->str[*i] == '_';
|
||||
(*i)++);
|
||||
if (token->str[*i] == '[') {
|
||||
if ((c = GIB_Parse_Match_Index (token->str, i))) {
|
||||
GIB_Error ("Parse", "Could not find match for %c.", c);
|
||||
return -1;
|
||||
} else
|
||||
(*i)++;
|
||||
}
|
||||
n++;
|
||||
len = 0;
|
||||
}
|
||||
c = token->str[*i];
|
||||
token->str[*i] = 0;
|
||||
|
||||
for (k = n; token->str[n]; n++)
|
||||
if (token->str[n] == '$' || token->str[n] == '#')
|
||||
if (GIB_Process_Variable (token, &n))
|
||||
return -1;
|
||||
index = 0;
|
||||
if (n && token->str[n - 1] == ']')
|
||||
for (j = n - 1; j; j--)
|
||||
if (token->str[j] == '[') {
|
||||
index = atoi (token->str + j + 1);
|
||||
token->str[j] = 0;
|
||||
}
|
||||
if ((var = GIB_Var_Get (one, two, token->str + k)) && index < var->size
|
||||
&& var->array[index]) {
|
||||
if (token->str[start] == '#')
|
||||
str = va ("%u", var->size - index);
|
||||
else
|
||||
str = var->array[index]->str;
|
||||
} else if (token->str[start] == '#')
|
||||
str = "0";
|
||||
else if ((cvar = Cvar_FindVar (token->str + k)))
|
||||
str = cvar->string;
|
||||
else
|
||||
str = "";
|
||||
token->str[n] = c;
|
||||
len += n - start;
|
||||
len2 = strlen (str);
|
||||
dstring_replace (token, start, len, str, len2);
|
||||
*i = start + len2 - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GIB_Process_Math (struct dstring_s *token, unsigned int i)
|
||||
{
|
||||
|
@ -169,22 +103,28 @@ GIB_Process_Embedded (gib_tree_t * node, cbuf_args_t * args)
|
|||
GIB_Buffer_Pop_Sstack (cbuf_active);
|
||||
} else if (cur->flags & TREE_P_EMBED) {
|
||||
n = args->argv[args->argc - 1]->size - 1;
|
||||
if (cur->delim == '$')
|
||||
dstring_appendstr (args->argv[args->argc - 1], "${");
|
||||
else
|
||||
dstring_appendstr (args->argv[args->argc - 1], "#{");
|
||||
dstring_appendstr (args->argv[args->argc - 1], cur->str);
|
||||
dstring_appendstr (args->argv[args->argc - 1], "}");
|
||||
if (GIB_Process_Variable (args->argv[args->argc - 1], &n))
|
||||
return -1;
|
||||
} else
|
||||
if ((var =
|
||||
GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals,
|
||||
var = GIB_Var_Get_Very_Complex (&GIB_DATA (cbuf_active)->locals,
|
||||
&GIB_DATA (cbuf_active)->globals,
|
||||
args->argv[args->argc - 1], n, &index, false);
|
||||
cvar = Cvar_FindVar (args->argv[args->argc - 1]->str);
|
||||
args->argv[args->argc - 1]->size = n+1;
|
||||
args->argv[args->argc - 1]->str[n] = 0;
|
||||
if (var) {
|
||||
if (cur->delim == '#')
|
||||
dasprintf (args->argv[args->argc - 1], "%u", var->size);
|
||||
else
|
||||
dstring_appendstr (args->argv[args->argc - 1], var->array[index].value->str);
|
||||
} else if (cur->delim == '#')
|
||||
dstring_appendstr (args->argv[args->argc - 1], "0");
|
||||
else if (cvar)
|
||||
dstring_appendstr (args->argv[args->argc - 1], cvar->string);
|
||||
} else if ((var = GIB_Var_Get_Complex (&GIB_DATA (cbuf_active)->locals,
|
||||
&GIB_DATA (cbuf_active)->globals,
|
||||
(char *) cur->str, &index, false))) {
|
||||
if (cur->delim == '$')
|
||||
dstring_appendstr (args->argv[args->argc - 1],
|
||||
var->array[index]->str);
|
||||
var->array[index].value->str);
|
||||
else
|
||||
dasprintf (args->argv[args->argc - 1], "%u", var->size - index);
|
||||
} else if (cur->delim == '#')
|
||||
|
|
|
@ -117,11 +117,12 @@ GIB_Thread_Execute (void)
|
|||
|
||||
for (cur = gib_threads; cur; cur = tmp) {
|
||||
tmp = cur->next;
|
||||
if (cur->trash) {
|
||||
if (GIB_DATA(cur->cbuf)->program)
|
||||
Cbuf_Execute_Stack (cur->cbuf);
|
||||
else {
|
||||
GIB_Thread_Remove (cur);
|
||||
GIB_Thread_Delete (cur);
|
||||
} else
|
||||
Cbuf_Execute_Stack (cur->cbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@ const char rcsid[] = "$Id$";
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/gib_vars.h"
|
||||
#include "QF/gib_buffer.h"
|
||||
#include "QF/gib_parse.h"
|
||||
|
@ -69,9 +71,13 @@ GIB_Var_Free (void *ele, void *ptr)
|
|||
unsigned int i;
|
||||
gib_var_t *l = (gib_var_t *) ele;
|
||||
|
||||
for (i = 0; i < l->size; i++)
|
||||
if (l->array[i])
|
||||
dstring_delete (l->array[i]);
|
||||
for (i = 0; i < l->size; i++) {
|
||||
if (l->array[i].value)
|
||||
dstring_delete (l->array[i].value);
|
||||
if (l->array[i].leaves)
|
||||
Hash_DelTable (l->array[i].leaves);
|
||||
}
|
||||
free (l->array);
|
||||
free ((void *) l->key);
|
||||
free (l);
|
||||
}
|
||||
|
@ -89,48 +95,127 @@ GIB_Var_Get (hashtab_t * first, hashtab_t * second, const char *key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Modifies key but restores it before returning */
|
||||
/* Destroys key! */
|
||||
gib_var_t *
|
||||
GIB_Var_Get_Complex (hashtab_t ** first, hashtab_t ** second, char *key,
|
||||
unsigned int *ind, qboolean create)
|
||||
{
|
||||
unsigned int i, index;
|
||||
qboolean fix = false;
|
||||
static hashtab_t *zero = 0;
|
||||
unsigned int i, n, index, len, start;
|
||||
gib_var_t *var;
|
||||
|
||||
i = strlen (key);
|
||||
index = 0;
|
||||
if (i && key[i - 1] == ']')
|
||||
for (i--; i; i--)
|
||||
if (key[i] == '[') {
|
||||
index = atoi (key + i + 1);
|
||||
key[i] = 0;
|
||||
fix = true;
|
||||
break;
|
||||
len = strlen(key);
|
||||
for (start = i = 0; i <= len; i++) {
|
||||
if (key[i] == '.' || key[i] == 0) {
|
||||
index = 0;
|
||||
key[i] = 0;
|
||||
if (i && key[i - 1] == ']')
|
||||
for (n = i - 1; n; n--)
|
||||
if (key[n] == '[') {
|
||||
index = atoi (key + n + 1);
|
||||
key[n] = 0;
|
||||
break;
|
||||
}
|
||||
if (!(var = GIB_Var_Get (*first, *second, key+start))) {
|
||||
if (create) {
|
||||
var = GIB_Var_New (key+start);
|
||||
if (!*first)
|
||||
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||
Hash_Add (*first, var);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
if (!(var = GIB_Var_Get (*first, *second, key))) {
|
||||
if (create) {
|
||||
var = GIB_Var_New (key);
|
||||
if (!*first)
|
||||
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||
Hash_Add (*first, var);
|
||||
} else
|
||||
return 0;
|
||||
if (index >= var->size) {
|
||||
if (create) {
|
||||
var->array =
|
||||
realloc (var->array, (index + 1) * sizeof (struct gib_varray_s *));
|
||||
memset (var->array + var->size, 0,
|
||||
(index + 1 - var->size) * sizeof (struct gib_varray_s *));
|
||||
var->size = index + 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
second = &zero;
|
||||
first = &var->array[index].leaves;
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
if (fix)
|
||||
key[i] = '[';
|
||||
if (index >= var->size) {
|
||||
if (create) {
|
||||
var->array =
|
||||
realloc (var->array, (index + 1) * sizeof (dstring_t *));
|
||||
memset (var->array + var->size, 0,
|
||||
(index + 1 - var->size) * sizeof (dstring_t *));
|
||||
var->size = index + 1;
|
||||
} else
|
||||
return 0;
|
||||
if (!var->array[index].value)
|
||||
var->array[index].value = dstring_newstr ();
|
||||
*ind = index;
|
||||
return var;
|
||||
}
|
||||
|
||||
gib_var_t *
|
||||
GIB_Var_Get_Very_Complex (hashtab_t ** first, hashtab_t ** second, dstring_t *key, unsigned int start,
|
||||
unsigned int *ind, qboolean create)
|
||||
{
|
||||
static hashtab_t *zero = 0;
|
||||
hashtab_t *one = *first, *two = *second;
|
||||
unsigned int i, index, index2, n;
|
||||
gib_var_t *var;
|
||||
cvar_t *cvar;
|
||||
char c, *str;
|
||||
qboolean done = false;
|
||||
|
||||
for (i = start; !done; i++) {
|
||||
if (key->str[i] == '.' || key->str[i] == 0) {
|
||||
index = 0;
|
||||
if (!key->str[i])
|
||||
done = true;
|
||||
key->str[i] = 0;
|
||||
if (i && key->str[i - 1] == ']')
|
||||
for (n = i-1; n; n--)
|
||||
if (key->str[n] == '[') {
|
||||
index = atoi (key->str + n + 1);
|
||||
key->str[n] = 0;
|
||||
break;
|
||||
}
|
||||
if (!(var = GIB_Var_Get (*first, *second, key->str+start))) {
|
||||
if (create) {
|
||||
var = GIB_Var_New (key->str+start);
|
||||
if (!*first)
|
||||
*first = Hash_NewTable (256, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||
Hash_Add (*first, var);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
if (index >= var->size) {
|
||||
if (create) {
|
||||
var->array =
|
||||
realloc (var->array, (index + 1) * sizeof (struct gib_varray_s));
|
||||
memset (var->array + var->size, 0,
|
||||
(index + 1 - var->size) * sizeof (struct gib_varray_s));
|
||||
var->size = index + 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
second = &zero;
|
||||
first = &var->array[index].leaves;
|
||||
start = i+1;
|
||||
} else if (key->str[i] == '$' || key->str[i] == '#') {
|
||||
n = i;
|
||||
if (GIB_Parse_Match_Var (key->str, &i))
|
||||
return 0;
|
||||
c = key->str[i];
|
||||
key->str[i+(c != '}')] = 0;
|
||||
if ((var = GIB_Var_Get_Very_Complex (&one, &two, key, n+1+(c == '}'), &index2, create))) {
|
||||
if (key->str[n] == '#')
|
||||
str = va("%u", var->size);
|
||||
else
|
||||
str = var->array[index2].value->str;
|
||||
dstring_replace (key, n, i-n, str, strlen (str));
|
||||
} else if (key->str[n] == '#')
|
||||
dstring_replace (key, n, i-n, "0", 1);
|
||||
else if ((cvar = Cvar_FindVar (key->str+n+1+(c == '}'))))
|
||||
dstring_replace (key, n, i-n, cvar->string, strlen (cvar->string));
|
||||
else
|
||||
dstring_snip (key, n, n-i);
|
||||
}
|
||||
|
||||
}
|
||||
if (!var->array[index])
|
||||
var->array[index] = dstring_newstr ();
|
||||
if (!var->array[index].value)
|
||||
var->array[index].value = dstring_newstr ();
|
||||
*ind = index;
|
||||
return var;
|
||||
}
|
||||
|
@ -144,23 +229,26 @@ GIB_Var_Assign (gib_var_t * var, unsigned int index, dstring_t ** values,
|
|||
// Now, expand the array to the correct size
|
||||
len = numv + index;
|
||||
if (len >= var->size) {
|
||||
var->array = realloc (var->array, len * sizeof (dstring_t *));
|
||||
var->array = realloc (var->array, len * sizeof (struct gib_varray_s));
|
||||
memset (var->array + var->size, 0,
|
||||
(len - var->size) * sizeof (dstring_t *));
|
||||
(len - var->size) * sizeof (struct gib_varray_s));
|
||||
var->size = len;
|
||||
} else if (len < var->size) {
|
||||
for (i = len; i < var->size; i++)
|
||||
if (var->array[i])
|
||||
dstring_delete (var->array[i]);
|
||||
var->array = realloc (var->array, len * sizeof (dstring_t *));
|
||||
for (i = len; i < var->size; i++) {
|
||||
if (var->array[i].value)
|
||||
dstring_delete (var->array[i].value);
|
||||
if (var->array[i].leaves)
|
||||
Hash_DelTable (var->array[i].leaves);
|
||||
}
|
||||
var->array = realloc (var->array, len * sizeof (struct gib_varray_s));
|
||||
}
|
||||
var->size = len;
|
||||
for (i = 0; i < numv; i++) {
|
||||
if (var->array[i + index])
|
||||
dstring_clearstr (var->array[i + index]);
|
||||
if (var->array[i + index].value)
|
||||
dstring_clearstr (var->array[i + index].value);
|
||||
else
|
||||
var->array[i + index] = dstring_newstr ();
|
||||
dstring_appendstr (var->array[i + index], values[i]->str);
|
||||
var->array[i + index].value = dstring_newstr ();
|
||||
dstring_appendstr (var->array[i + index].value, values[i]->str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue