mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
A few GIB bugfixes, cleanups, and enhancements. Still more to come.
This commit is contained in:
parent
06cd013fc6
commit
1f5cabcba9
10 changed files with 112 additions and 103 deletions
|
@ -55,11 +55,10 @@ typedef struct cbuf_s {
|
||||||
CBUF_STATE_NORMAL = 0, // Normal condition
|
CBUF_STATE_NORMAL = 0, // Normal condition
|
||||||
CBUF_STATE_WAIT, // Buffer is stalled until next frame
|
CBUF_STATE_WAIT, // Buffer is stalled until next frame
|
||||||
CBUF_STATE_ERROR, // An unrecoverable error occured
|
CBUF_STATE_ERROR, // An unrecoverable error occured
|
||||||
CBUF_STATE_STACK, // A buffer has been added to the stack
|
CBUF_STATE_STACK // A buffer has been added to the stack
|
||||||
CBUF_STATE_DONE, // This buffer has completed execution
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
qboolean strict; // Should we tolerate unknown commands
|
qboolean strict; // Should we tolerate unknown commands?
|
||||||
double resumetime; // Time when stack can be executed again
|
double resumetime; // Time when stack can be executed again
|
||||||
|
|
||||||
void *data; // Pointer to interpreter data
|
void *data; // Pointer to interpreter data
|
||||||
|
@ -72,7 +71,6 @@ typedef struct cbuf_interpreter_s {
|
||||||
void (*insert) (struct cbuf_s *cbuf, const char *str);
|
void (*insert) (struct cbuf_s *cbuf, const char *str);
|
||||||
void (*execute) (struct cbuf_s *cbuf);
|
void (*execute) (struct cbuf_s *cbuf);
|
||||||
void (*execute_sets) (struct cbuf_s *cbuf);
|
void (*execute_sets) (struct cbuf_s *cbuf);
|
||||||
void (*reset) (struct cbuf_s *cbuf);
|
|
||||||
} cbuf_interpreter_t;
|
} cbuf_interpreter_t;
|
||||||
|
|
||||||
extern cbuf_t *cbuf_active;
|
extern cbuf_t *cbuf_active;
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
typedef struct gib_buffer_data_s {
|
typedef struct gib_buffer_data_s {
|
||||||
struct gib_tree_s *program, *ip;
|
struct gib_tree_s *program, *ip;
|
||||||
struct dstring_s *arg_composite;
|
struct dstring_s *arg_composite;
|
||||||
qboolean done, waitret, haveret;
|
qboolean done, waitret;
|
||||||
struct gib_sstack_s {
|
struct gib_sstack_s {
|
||||||
struct gib_dsarray_s {
|
struct gib_dsarray_s {
|
||||||
struct dstring_s **dstrs;
|
struct dstring_s **dstrs;
|
||||||
|
@ -53,7 +53,6 @@ typedef struct gib_buffer_data_s {
|
||||||
|
|
||||||
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);
|
||||||
void GIB_Buffer_Reset (struct cbuf_s *cbuf);
|
|
||||||
void GIB_Buffer_Add (cbuf_t *cbuf, const char *str);
|
void GIB_Buffer_Add (cbuf_t *cbuf, const char *str);
|
||||||
void GIB_Buffer_Insert (cbuf_t *cbuf, const char *str);
|
void GIB_Buffer_Insert (cbuf_t *cbuf, const char *str);
|
||||||
void GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf);
|
void GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf);
|
||||||
|
|
|
@ -47,6 +47,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 (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_Complex (hashtab_t **first, hashtab_t **second, char *key, 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);
|
hashtab_t *GIB_Domain_Get (const char *name);
|
||||||
|
|
||||||
void GIB_Var_Init (void);
|
void GIB_Var_Init (void);
|
||||||
|
|
|
@ -111,16 +111,6 @@ GIB_Buffer_Insert (cbuf_t *cbuf, const char *str)
|
||||||
Cbuf_Error ("parse", "Parse error in program!");
|
Cbuf_Error ("parse", "Parse error in program!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
GIB_Buffer_Reset (cbuf_t *cbuf)
|
|
||||||
{
|
|
||||||
GIB_DATA(cbuf)->done = GIB_DATA(cbuf)->waitret = GIB_DATA(cbuf)->haveret = false;
|
|
||||||
if (GIB_DATA(cbuf)->program)
|
|
||||||
GIB_Tree_Free_Recursive (GIB_DATA(cbuf)->program, false);
|
|
||||||
GIB_DATA(cbuf)->ip = 0;
|
|
||||||
GIB_DATA(cbuf)->program = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf)
|
GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf)
|
||||||
{
|
{
|
||||||
|
@ -160,5 +150,4 @@ cbuf_interpreter_t gib_interp = {
|
||||||
GIB_Buffer_Insert,
|
GIB_Buffer_Insert,
|
||||||
GIB_Execute,
|
GIB_Execute,
|
||||||
GIB_Execute,
|
GIB_Execute,
|
||||||
GIB_Buffer_Reset
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -124,7 +124,6 @@ GIB_Return (const char *str)
|
||||||
{
|
{
|
||||||
dstring_t *dstr;
|
dstring_t *dstr;
|
||||||
if (GIB_DATA(cbuf_active)->waitret) {
|
if (GIB_DATA(cbuf_active)->waitret) {
|
||||||
GIB_DATA(cbuf_active)->haveret = true;
|
|
||||||
dstr = GIB_Buffer_Dsarray_Get (cbuf_active);
|
dstr = GIB_Buffer_Dsarray_Get (cbuf_active);
|
||||||
dstring_clearstr (dstr);
|
dstring_clearstr (dstr);
|
||||||
if (!str)
|
if (!str)
|
||||||
|
@ -179,32 +178,38 @@ GIB_Function_Get_f (void)
|
||||||
static void
|
static void
|
||||||
GIB_Local_f (void)
|
GIB_Local_f (void)
|
||||||
{
|
{
|
||||||
unsigned int i, index;
|
gib_var_t *var;
|
||||||
|
unsigned int index;
|
||||||
hashtab_t *zero = 0;
|
hashtab_t *zero = 0;
|
||||||
|
|
||||||
if (GIB_Argc () < 2)
|
if (GIB_Argc () < 2)
|
||||||
GIB_USAGE ("var1 [var2 var3 ...]");
|
GIB_USAGE ("var [= value1 value2 ...]");
|
||||||
else
|
else {
|
||||||
for (i = 1; i < GIB_Argc(); i++)
|
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->locals, &zero, GIB_Argv(1), &index, true);
|
||||||
GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->locals, &zero, GIB_Argv(i), &index, true);
|
if (GIB_Argc() >= 3)
|
||||||
|
GIB_Var_Assign (var, index, cbuf_active->args->argv+3, GIB_Argc() - 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Global_f (void)
|
GIB_Global_f (void)
|
||||||
{
|
{
|
||||||
unsigned int i, index;
|
gib_var_t *var;
|
||||||
|
unsigned int index;
|
||||||
hashtab_t *zero = 0;
|
hashtab_t *zero = 0;
|
||||||
|
|
||||||
if (GIB_Argc () < 2)
|
if (GIB_Argc () < 2)
|
||||||
GIB_USAGE ("var1 [var2 var3 ...]");
|
GIB_USAGE ("var [= value1 value2 ...]");
|
||||||
else
|
else {
|
||||||
for (i = 1; i < GIB_Argc(); i++)
|
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->globals, &zero, GIB_Argv(1), &index, true);
|
||||||
GIB_Var_Get_Complex (&GIB_DATA(cbuf_active)->globals, &zero, GIB_Argv(i), &index, true);
|
if (GIB_Argc() >= 3)
|
||||||
|
GIB_Var_Assign (var, index, cbuf_active->args->argv+3, GIB_Argc() - 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Global_Domain_f (void)
|
GIB_Domain_f (void)
|
||||||
{
|
{
|
||||||
if (GIB_Argc() != 2)
|
if (GIB_Argc() != 2)
|
||||||
GIB_USAGE ("domain");
|
GIB_USAGE ("domain");
|
||||||
|
@ -218,15 +223,8 @@ GIB_Return_f (void)
|
||||||
cbuf_t *sp = cbuf_active->up;
|
cbuf_t *sp = cbuf_active->up;
|
||||||
|
|
||||||
GIB_DATA(cbuf_active)->done = true;
|
GIB_DATA(cbuf_active)->done = true;
|
||||||
if (!GIB_Argm(0)->next) // No return values
|
|
||||||
return;
|
if (GIB_Argc() > 1 && sp && sp->interpreter == &gib_interp && GIB_DATA(sp)->waitret) {
|
||||||
else if (GIB_Argc() == 1) // Empty return array
|
|
||||||
GIB_DATA(sp)->waitret = false;
|
|
||||||
else if (!sp || // Nothing above us on the stack
|
|
||||||
sp->interpreter != &gib_interp || // Not a GIB buffer
|
|
||||||
!GIB_DATA(sp)->waitret) // Doesn't want a return value
|
|
||||||
Sys_DPrintf("GIB warning: unwanted return value(s) discarded.\n"); // Not a serious error
|
|
||||||
else {
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
dstring_t *dstr;
|
dstring_t *dstr;
|
||||||
for (i = 1; i < GIB_Argc(); i++) {
|
for (i = 1; i < GIB_Argc(); i++) {
|
||||||
|
@ -234,7 +232,6 @@ GIB_Return_f (void)
|
||||||
dstring_clearstr (dstr);
|
dstring_clearstr (dstr);
|
||||||
dstring_appendstr (dstr, GIB_Argv(i));
|
dstring_appendstr (dstr, GIB_Argv(i));
|
||||||
}
|
}
|
||||||
GIB_DATA(sp)->waitret = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,12 +392,36 @@ GIB_String_Equal_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_String_Findsub_f (void)
|
GIB_String_Sub_f (void)
|
||||||
|
{
|
||||||
|
dstring_t *ret;
|
||||||
|
int start, end, len;
|
||||||
|
if (GIB_Argc() != 4)
|
||||||
|
GIB_USAGE ("string start end");
|
||||||
|
else {
|
||||||
|
len = strlen (GIB_Argv(1));
|
||||||
|
start = atoi (GIB_Argv(2));
|
||||||
|
end = atoi (GIB_Argv(3));
|
||||||
|
while (start < 0)
|
||||||
|
start += len-1;
|
||||||
|
while (end < 0)
|
||||||
|
end += len;
|
||||||
|
if (start >= len)
|
||||||
|
return;
|
||||||
|
if (end > len || !end)
|
||||||
|
end = len;
|
||||||
|
if ((ret = GIB_Return (0)))
|
||||||
|
dstring_appendsubstr (ret, GIB_Argv(1)+start, end-start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GIB_String_Find_f (void)
|
||||||
{
|
{
|
||||||
dstring_t *ret;
|
dstring_t *ret;
|
||||||
char *haystack, *res;
|
char *haystack, *res;
|
||||||
if (GIB_Argc() != 3) {
|
if (GIB_Argc() != 3) {
|
||||||
GIB_USAGE ("string substr");
|
GIB_USAGE ("haystack needle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
haystack = GIB_Argv(1);
|
haystack = GIB_Argv(1);
|
||||||
|
@ -752,6 +773,16 @@ GIB_Print_f (void)
|
||||||
Sys_Printf ("%s", GIB_Argv(1));
|
Sys_Printf ("%s", GIB_Argv(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GIB_Random_f (void)
|
||||||
|
{
|
||||||
|
dstring_t *ret;
|
||||||
|
if (GIB_Argc() != 1)
|
||||||
|
GIB_USAGE ("");
|
||||||
|
else if ((ret = GIB_Return (0)))
|
||||||
|
dsprintf (ret, "%.10g", (double) random()/(double) RAND_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Builtin_Init (qboolean sandbox)
|
GIB_Builtin_Init (qboolean sandbox)
|
||||||
{
|
{
|
||||||
|
@ -766,15 +797,15 @@ GIB_Builtin_Init (qboolean sandbox)
|
||||||
GIB_Builtin_Add ("function::export", GIB_Function_Export_f);
|
GIB_Builtin_Add ("function::export", GIB_Function_Export_f);
|
||||||
GIB_Builtin_Add ("local", GIB_Local_f);
|
GIB_Builtin_Add ("local", GIB_Local_f);
|
||||||
GIB_Builtin_Add ("global", GIB_Global_f);
|
GIB_Builtin_Add ("global", GIB_Global_f);
|
||||||
GIB_Builtin_Add ("global::domain", GIB_Global_Domain_f);
|
GIB_Builtin_Add ("domain", GIB_Domain_f);
|
||||||
GIB_Builtin_Add ("return", GIB_Return_f);
|
GIB_Builtin_Add ("return", GIB_Return_f);
|
||||||
// GIB_Builtin_Add ("dieifnot", GIB_Dieifnot_f);
|
|
||||||
GIB_Builtin_Add ("for", GIB_For_f);
|
GIB_Builtin_Add ("for", GIB_For_f);
|
||||||
GIB_Builtin_Add ("break", GIB_Break_f);
|
GIB_Builtin_Add ("break", GIB_Break_f);
|
||||||
GIB_Builtin_Add ("continue", GIB_Continue_f);
|
GIB_Builtin_Add ("continue", GIB_Continue_f);
|
||||||
GIB_Builtin_Add ("string::length", GIB_String_Length_f);
|
GIB_Builtin_Add ("string::length", GIB_String_Length_f);
|
||||||
GIB_Builtin_Add ("string::equal", GIB_String_Equal_f);
|
GIB_Builtin_Add ("string::equal", GIB_String_Equal_f);
|
||||||
GIB_Builtin_Add ("string::findsub", GIB_String_Findsub_f);
|
GIB_Builtin_Add ("string::sub", GIB_String_Sub_f);
|
||||||
|
GIB_Builtin_Add ("string::find", GIB_String_Find_f);
|
||||||
GIB_Builtin_Add ("regex::match", GIB_Regex_Match_f);
|
GIB_Builtin_Add ("regex::match", GIB_Regex_Match_f);
|
||||||
GIB_Builtin_Add ("regex::replace", GIB_Regex_Replace_f);
|
GIB_Builtin_Add ("regex::replace", GIB_Regex_Replace_f);
|
||||||
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f);
|
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f);
|
||||||
|
@ -788,4 +819,5 @@ GIB_Builtin_Init (qboolean sandbox)
|
||||||
GIB_Builtin_Add ("file::delete", GIB_File_Delete_f);
|
GIB_Builtin_Add ("file::delete", GIB_File_Delete_f);
|
||||||
GIB_Builtin_Add ("range", GIB_Range_f);
|
GIB_Builtin_Add ("range", GIB_Range_f);
|
||||||
GIB_Builtin_Add ("print", GIB_Print_f);
|
GIB_Builtin_Add ("print", GIB_Print_f);
|
||||||
|
GIB_Builtin_Add ("random", GIB_Random_f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,38 +145,6 @@ GIB_Execute_Prepare_Line (cbuf_t *cbuf, gib_tree_t *line)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
GIB_Execute_Assign (cbuf_t *cbuf)
|
|
||||||
{
|
|
||||||
cbuf_args_t *args = cbuf->args;
|
|
||||||
gib_var_t *var;
|
|
||||||
unsigned int index, i, len, el;
|
|
||||||
|
|
||||||
// First, grab our variable
|
|
||||||
var = GIB_Var_Get_Complex (&GIB_DATA(cbuf)->locals, &GIB_DATA(cbuf)->globals, args->argv[0]->str, &index, true);
|
|
||||||
// Now, expand the array to the correct size
|
|
||||||
len = args->argc-2 + index;
|
|
||||||
if (len >= var->size) {
|
|
||||||
var->array = realloc (var->array, len * sizeof (dstring_t *));
|
|
||||||
memset (var->array+var->size, 0, (len-var->size) * sizeof (dstring_t *));
|
|
||||||
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 *));
|
|
||||||
}
|
|
||||||
var->size = len;
|
|
||||||
for (i = 2; i < args->argc; i++) {
|
|
||||||
el = i-2+index;
|
|
||||||
if (var->array[el])
|
|
||||||
dstring_clearstr (var->array[el]);
|
|
||||||
else
|
|
||||||
var->array[el] = dstring_newstr ();
|
|
||||||
dstring_appendstr (var->array[el], args->argv[i]->str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
GIB_Execute_For_Next (cbuf_t *cbuf)
|
GIB_Execute_For_Next (cbuf_t *cbuf)
|
||||||
{
|
{
|
||||||
|
@ -201,13 +169,8 @@ GIB_Execute (cbuf_t *cbuf)
|
||||||
gib_builtin_t *b;
|
gib_builtin_t *b;
|
||||||
gib_function_t *f;
|
gib_function_t *f;
|
||||||
|
|
||||||
if (g->waitret) {
|
if (!g->program)
|
||||||
Cbuf_Error ("return", "Embedded function '%s' did not return a value.", cbuf->args->argv[0]->str);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (!g->program) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!g->ip)
|
if (!g->ip)
|
||||||
g->ip = g->program;
|
g->ip = g->program;
|
||||||
while (!g->done) {
|
while (!g->done) {
|
||||||
|
@ -225,29 +188,23 @@ GIB_Execute (cbuf_t *cbuf)
|
||||||
continue;
|
continue;
|
||||||
} else if (cbuf->args->argc) {
|
} else if (cbuf->args->argc) {
|
||||||
if (g->ip->flags & TREE_EMBED) {
|
if (g->ip->flags & TREE_EMBED) {
|
||||||
|
// Get ready for return values
|
||||||
g->waitret = true;
|
g->waitret = true;
|
||||||
GIB_Buffer_Push_Sstack (cbuf); // Make room for return values
|
GIB_Buffer_Push_Sstack (cbuf);
|
||||||
|
} else
|
||||||
|
g->waitret = false;
|
||||||
|
if (cbuf->args->argc >= 2 && !strcmp (cbuf->args->argv[1]->str, "=") && ((gib_tree_t *)cbuf->args->argm[1])->delim == ' ') {
|
||||||
|
unsigned int index;
|
||||||
|
GIB_Var_Assign (GIB_Var_Get_Complex (&g->locals, &g->globals, cbuf->args->argv[0]->str, &index, true), index, cbuf->args->argv+2, cbuf->args->argc-2);
|
||||||
}
|
}
|
||||||
if (!strcmp (cbuf->args->argv[1]->str, "=") && ((gib_tree_t *)cbuf->args->argm[1])->delim == ' ')
|
|
||||||
GIB_Execute_Assign (cbuf);
|
|
||||||
else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
|
else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
|
||||||
b->func ();
|
b->func ();
|
||||||
// If there already was an error, don't override it
|
|
||||||
if (g->ip->flags & TREE_EMBED && !cbuf->state) {
|
|
||||||
if (!g->haveret) {
|
|
||||||
Cbuf_Error ("return", "Embedded builtin '%s' did not return a value.", cbuf->args->argv[0]->str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g->haveret = g->waitret = 0;
|
|
||||||
}
|
|
||||||
} else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
|
} else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
|
||||||
cbuf_t *new = Cbuf_New (&gib_interp);
|
cbuf_t *new = Cbuf_New (&gib_interp);
|
||||||
cbuf->down = new;
|
cbuf->down = new;
|
||||||
new->up = cbuf;
|
new->up = cbuf;
|
||||||
cbuf->state = CBUF_STATE_STACK;
|
cbuf->state = CBUF_STATE_STACK;
|
||||||
GIB_Function_Execute (new, f, cbuf->args);
|
GIB_Function_Execute (new, f, cbuf->args);
|
||||||
if (g->ip->flags & TREE_EMBED)
|
|
||||||
g->waitret = true;
|
|
||||||
} else {
|
} else {
|
||||||
GIB_Execute_Generate_Composite (cbuf);
|
GIB_Execute_Generate_Composite (cbuf);
|
||||||
Cmd_Command (cbuf->args);
|
Cmd_Command (cbuf->args);
|
||||||
|
|
|
@ -246,7 +246,7 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
// Handle comments
|
// Handle comments
|
||||||
} else if (program[*i] == '/' && program[*i+1] == '/') {
|
} else if (program[*i] == '/' && program[*i+1] == '/') {
|
||||||
for((*i) += 2; program[*i] && program[*i] != '\n'; (*i)++);
|
for((*i) += 2; program[*i] && program[*i] != '\n'; (*i)++);
|
||||||
return nodes;
|
goto DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
cur->flags |= TREE_P_EMBED;
|
cur->flags |= TREE_P_EMBED;
|
||||||
// Add any embedded commands to top of chain
|
// Add any embedded commands to top of chain
|
||||||
if (new) {
|
if (new) {
|
||||||
for (tmp = new; tmp->next; tmp = tmp->next); // Get to end of embedded list
|
for (tmp = new; tmp->next; tmp = tmp->next);
|
||||||
tmp->next = embs;
|
tmp->next = embs;
|
||||||
embs = new;
|
embs = new;
|
||||||
}
|
}
|
||||||
|
@ -306,6 +306,7 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
(*i)++;
|
(*i)++;
|
||||||
node = &cur->next;
|
node = &cur->next;
|
||||||
}
|
}
|
||||||
|
DONE:
|
||||||
*embedded = embs;
|
*embedded = embs;
|
||||||
return nodes;
|
return nodes;
|
||||||
ERROR:
|
ERROR:
|
||||||
|
@ -375,7 +376,11 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
// If we have a while loop, handle that
|
// If we have a while loop, handle that
|
||||||
if (!strcmp (line->children->str, "while")) {
|
if (!strcmp (line->children->str, "while")) {
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (!line->children->next || !line->children->next->next || !line->children->next->next->children || line->flags & TREE_EMBED) {
|
if (!line->children->next ||
|
||||||
|
!line->children->next->next ||
|
||||||
|
line->children->next->next->delim != '{' ||
|
||||||
|
!line->children->next->next->children ||
|
||||||
|
line->flags & TREE_EMBED) {
|
||||||
gib_parse_error = true;
|
gib_parse_error = true;
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +411,7 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
// Find last token in line (contains program block)
|
// Find last token in line (contains program block)
|
||||||
for (tmp = line->children->next->next->next->next; tmp->next; tmp = tmp->next);
|
for (tmp = line->children->next->next->next->next; tmp->next; tmp = tmp->next);
|
||||||
// More sanity
|
// More sanity
|
||||||
if (!tmp->children) {
|
if (tmp->delim != '{' || !tmp->children) {
|
||||||
gib_parse_error = true;
|
gib_parse_error = true;
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,33 @@ GIB_Var_Get_Complex (hashtab_t **first, hashtab_t **second, char *key, unsigned
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Var_Assign (gib_var_t *var, unsigned int index, dstring_t **values, unsigned int numv)
|
||||||
|
{
|
||||||
|
unsigned int i, len;
|
||||||
|
|
||||||
|
// Now, expand the array to the correct size
|
||||||
|
len = numv + index;
|
||||||
|
if (len >= var->size) {
|
||||||
|
var->array = realloc (var->array, len * sizeof (dstring_t *));
|
||||||
|
memset (var->array+var->size, 0, (len-var->size) * sizeof (dstring_t *));
|
||||||
|
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 *));
|
||||||
|
}
|
||||||
|
var->size = len;
|
||||||
|
for (i = 0; i < numv; i++) {
|
||||||
|
if (var->array[i+index])
|
||||||
|
dstring_clearstr (var->array[i+index]);
|
||||||
|
else
|
||||||
|
var->array[i+index] = dstring_newstr ();
|
||||||
|
dstring_appendstr (var->array[i+index], values[i]->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
GIB_Domain_Get_Key (void *ele, void *ptr)
|
GIB_Domain_Get_Key (void *ele, void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -150,6 +177,7 @@ GIB_Domain_Get (const char *name)
|
||||||
d = calloc (1, sizeof (gib_domain_t));
|
d = calloc (1, sizeof (gib_domain_t));
|
||||||
d->name = strdup(name);
|
d->name = strdup(name);
|
||||||
d->vars = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
d->vars = Hash_NewTable (1024, GIB_Var_Get_Key, GIB_Var_Free, 0);
|
||||||
|
Hash_Add (gib_domains, d);
|
||||||
}
|
}
|
||||||
return d->vars;
|
return d->vars;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,8 +191,9 @@ ERROR:
|
||||||
Cbuf_DeleteStack (cbuf->down);
|
Cbuf_DeleteStack (cbuf->down);
|
||||||
cbuf->down = 0;
|
cbuf->down = 0;
|
||||||
}
|
}
|
||||||
if (cbuf->interpreter->reset)
|
// Tear it down and build it back up
|
||||||
cbuf->interpreter->reset (cbuf);
|
cbuf->interpreter->destruct (cbuf);
|
||||||
|
cbuf->interpreter->construct (cbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -236,5 +236,4 @@ cbuf_interpreter_t id_interp = {
|
||||||
COM_insert,
|
COM_insert,
|
||||||
COM_execute,
|
COM_execute,
|
||||||
COM_execute_sets,
|
COM_execute_sets,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue