diff --git a/include/gib_error.h b/include/gib_error.h index 1adbd92..8a31d71 100644 --- a/include/gib_error.h +++ b/include/gib_error.h @@ -9,3 +9,4 @@ #define GIB_E_BUFFER 7 #define GIB_E_TYPE 8 #define GIB_E_ULIMIT 9 +#define GIB_E_ILLINST 10 diff --git a/include/gib_instructions.h b/include/gib_instructions.h index 1b7e358..605ee59 100644 --- a/include/gib_instructions.h +++ b/include/gib_instructions.h @@ -3,12 +3,8 @@ gib_inst_t *GIB_Find_Instruction (char *name); void GIB_Init_Instructions (void); int GIB_Echo_f (void); int GIB_Call_f (void); -int GIB_VarPrint_f (void); int GIB_Return_f (void); -int GIB_VarSub_f (void); int GIB_Con_f (void); -int GIB_Eval_f (void); int GIB_ListFetch_f (void); -int GIB_BackTick_f (void); int GIB_ExpandVars (char *source, char *buffer, int bufferlen); int GIB_ExpandBackticks (char *source, char *buffer, int bufferlen); diff --git a/include/gib_interpret.h b/include/gib_interpret.h index d9292c5..dae7a1c 100644 --- a/include/gib_interpret.h +++ b/include/gib_interpret.h @@ -1,23 +1,15 @@ #define GIB_MAXCALLS 2048 #define GIB_MAXSUBARGS 256 -extern gib_module_t *gib_currentmod[GIB_MAXCALLS]; -extern gib_sub_t *gib_currentsub[GIB_MAXCALLS]; -extern int gib_subsp; - -extern int gib_argc[GIB_MAXCALLS]; -extern char *gib_argv[GIB_MAXCALLS][80]; - -extern int gib_argofs; - -extern char *GIB_SUBARGV[GIB_MAXSUBARGS]; -extern int GIB_SUBARGC; - -extern char errorline[1024]; +extern char *gib_subargv[256]; +extern int gib_subargc; char *GIB_Argv(int i); int GIB_Argc(void); void GIB_Strip_Arg (char *arg); int GIB_Execute_Block (char *block, int retflag); -int GIB_Execute_Inst (char *inst); +int GIB_Execute_Inst (void); +int GIB_Execute_Sub (void); +int GIB_Interpret_Inst (char *inst); +int GIB_Run_Inst (char *inst); int GIB_Run_Sub (gib_module_t *mod, gib_sub_t *sub); diff --git a/include/gib_stack.h b/include/gib_stack.h new file mode 100644 index 0000000..85cdbaf --- /dev/null +++ b/include/gib_stack.h @@ -0,0 +1,29 @@ +#define GIB_LOCALS gib_substack[gib_subsp - 1].local +#define GIB_CURRENTMOD gib_substack[gib_subsp - 1].mod +#define GIB_CURRENTSUB gib_substack[gib_subsp - 1].sub + +typedef struct gib_instack_s +{ + gib_inst_t *instruction; + char **argv; + int argc; +} gib_instack_t; + +typedef struct gib_substack_s +{ + gib_module_t *mod; + gib_sub_t *sub; + gib_var_t *local; +} gib_substack_t; + +extern gib_instack_t *gib_instack; +extern gib_substack_t *gib_substack; + +extern int gib_insp; +extern int gib_subsp; + +void GIB_InStack_Push (gib_inst_t *instruction, int argc, char **argv); +void GIB_InStack_Pop (); +void GIB_SubStack_Push (gib_module_t *mod, gib_sub_t *sub, gib_var_t *local); +void GIB_SubStack_Pop (); + diff --git a/include/gib_vars.h b/include/gib_vars.h index 321249b..cd1d8dc 100644 --- a/include/gib_vars.h +++ b/include/gib_vars.h @@ -1,4 +1,3 @@ -extern gib_var_t *gib_locals[GIB_MAXCALLS]; gib_var_t *GIB_Var_FindLocal (char *key); gib_var_t *GIB_Var_FindGlobal (char *key); diff --git a/source/Makefile.am b/source/Makefile.am index 9e184e9..705ba8e 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -115,7 +115,7 @@ client_LIBS= -L. -lqfsys -lqfsnd -lqfcd -lqfnet $(SOUND_LIBS) $(NET_LIBS) client_SOURCES= cl_cam.c cl_demo.c cl_input.c cl_main.c cl_parse.c \ cl_tent.c console.c keys.c menu.c sbar.c r_view.c \ nonintel.c gib.c gib_instructions.c gib_vars.c \ - gib_interpret.c gib_modules.c gib_parse.c + gib_interpret.c gib_modules.c gib_parse.c gib_stack.c server_SOURCES= host.c host_cmd.c \ pr_cmds.c pr_edict.c pr_exec.c \ diff --git a/source/gib.c b/source/gib.c index 5344812..e8a3de5 100644 --- a/source/gib.c +++ b/source/gib.c @@ -18,9 +18,6 @@ #include "gib_vars.h" - -//static char *gib_args; - // Standard cvars void GIB_Init (void) @@ -45,13 +42,13 @@ void GIB_Gib_f (void) Con_Printf("Subroutine not found!\n"); else { - GIB_SUBARGC = Cmd_Argc() - 1; - GIB_SUBARGV[0] = sub->name; - for (i = 1; i <= GIB_SUBARGC; i++) - GIB_SUBARGV[i] = Cmd_Argv(i + 1); + gib_subargc = Cmd_Argc() - 1; + gib_subargv[0] = sub->name; + for (i = 1; i <= gib_subargc; i++) + gib_subargv[i] = Cmd_Argv(i + 1); ret = GIB_Run_Sub(mod, sub); if (ret != 0) - Con_Printf("Error in execution of %s!\nError code: %i\n\nLine at fault: %s\n", Cmd_Argv(1), ret, errorline); + Con_Printf("Error in execution of %s!\nError code: %i\n", Cmd_Argv(1), ret); } } diff --git a/source/gib_instructions.c b/source/gib_instructions.c index 9226853..47560e1 100644 --- a/source/gib_instructions.c +++ b/source/gib_instructions.c @@ -18,6 +18,7 @@ #include "gib_parse.h" #include "gib_vars.h" #include "gib_error.h" +#include "gib_stack.h" static gib_inst_t *gibinstructions; @@ -49,13 +50,9 @@ void GIB_Init_Instructions (void) { GIB_AddInstruction("echo", GIB_Echo_f); GIB_AddInstruction("call", GIB_Call_f); - GIB_AddInstruction("varprint", GIB_VarPrint_f); GIB_AddInstruction("return", GIB_Return_f); - GIB_AddInstruction("varsub", GIB_VarSub_f); GIB_AddInstruction("con", GIB_Con_f); GIB_AddInstruction("listfetch", GIB_ListFetch_f); - GIB_AddInstruction("eval", GIB_Eval_f); - GIB_AddInstruction("backtick", GIB_BackTick_f); } @@ -77,10 +74,10 @@ int GIB_Call_f (void) sub = GIB_Get_ModSub_Sub (GIB_Argv(1)); if (!sub) return GIB_E_NOSUB; - GIB_SUBARGC = GIB_Argc() - 1; - GIB_SUBARGV[0] = sub->name; - for (i = 1; i <= GIB_SUBARGC; i++) - GIB_SUBARGV[i] = GIB_Argv(i + 1); + gib_subargc = GIB_Argc() - 1; + gib_subargv[0] = sub->name; + for (i = 1; i <= gib_subargc; i++) + gib_subargv[i] = GIB_Argv(i + 1); ret = GIB_Run_Sub (mod, sub); if (gib_subret) { @@ -115,20 +112,6 @@ int GIB_Return_f (void) return GIB_E_RETURN; // Signal to block executor to return immediately } -int GIB_VarSub_f (void) -{ - char buffer[1024]; - int ret; - - if (GIB_Argc() != 1) - return GIB_E_NUMARGS; - - if ((ret = GIB_ExpandVars(GIB_Argv(1), buffer, 1024))) - return ret; - GIB_Var_Set ("retval", buffer); - return 0; -} - int GIB_ListFetch_f (void) { char *element; @@ -167,40 +150,6 @@ int GIB_Con_f (void) return 0; } -int GIB_Eval_f (void) -{ - gib_var_t *var; - char *buffer; - int ret; - - if (GIB_Argc() != 1) - return GIB_E_NUMARGS; - if (!(var = GIB_Var_FindLocal (GIB_Argv(1)))) - return GIB_E_NOVAR; - buffer = malloc(strlen(var->value) + 1); - strcpy(buffer, var->value); - gib_argofs++; /* HACK HACK HACK - This is required or - GIB_Execute_Instruction will smash gib_argv */ - ret = GIB_Execute_Block (buffer, 0); - gib_argofs--; - free (buffer); - return ret; -} - -int GIB_BackTick_f (void) -{ - char buffer[1024]; - int ret; - - if (GIB_Argc() != 1) - return GIB_E_NUMARGS; - if ((ret = GIB_ExpandBackticks (GIB_Argv(1), buffer, 1024))) - return ret; - GIB_Var_Set ("retval", buffer); - return 0; -} - - int GIB_ExpandVars (char *source, char *buffer, int buffersize) { int i, n, m; @@ -252,9 +201,7 @@ int GIB_ExpandBackticks (char *source, char *buffer, int buffersize) tick[m++] = source[i]; tick[m++] = 0; - gib_argofs++; - ret = GIB_Execute_Inst (tick); - gib_argofs--; + ret = GIB_Run_Inst (tick); if (ret) { return ret; diff --git a/source/gib_interpret.c b/source/gib_interpret.c index b7a7dda..6f21d6d 100644 --- a/source/gib_interpret.c +++ b/source/gib_interpret.c @@ -18,29 +18,19 @@ #include "gib_parse.h" #include "gib_vars.h" #include "gib_error.h" +#include "gib_stack.h" -gib_module_t *gib_currentmod[GIB_MAXCALLS]; -gib_sub_t *gib_currentsub[GIB_MAXCALLS]; -int gib_subsp = 0; - -char *GIB_SUBARGV[GIB_MAXSUBARGS]; -int GIB_SUBARGC; - -int gib_argc[GIB_MAXCALLS]; -char *gib_argv[GIB_MAXCALLS][80]; - -int gib_argofs = 0; - -char errorline[1024]; +char *gib_subargv[256]; +int gib_subargc; char *GIB_Argv(int i) { - return gib_argv[gib_subsp + gib_argofs][i]; + return gib_instack[gib_insp - 1].argv[i]; } int GIB_Argc(void) { - return gib_argc[gib_subsp + gib_argofs]; + return gib_instack[gib_insp - 1].argc; } void GIB_Strip_Arg (char *arg) @@ -64,29 +54,41 @@ int GIB_Execute_Block (char *block, int retflag) code = malloc(len + 1); strncpy(code, block + i, len); code[len] = 0; - if ((ret = GIB_Execute_Inst(code))) + if ((ret = GIB_Interpret_Inst(code))) { - if (retflag && ret == GIB_E_RETURN) - return 0; - else - { - strcpy(errorline, code); - free (code); - return ret; - } + free (code); + return ret; + } + if ((ret = GIB_Execute_Inst())) + { + free (code); + if (ret == GIB_E_RETURN && retflag) + return 0; + return ret; } - free (code); i += len + 1; + free (code); } + if (len == -1) + return GIB_E_PARSE; return 0; } -int GIB_Execute_Inst (char *inst) +int GIB_Execute_Inst (void) +{ + int ret; + ret = gib_instack[gib_insp - 1].instruction->func (); + GIB_InStack_Pop(); + return ret; +} + +int GIB_Interpret_Inst (char *inst) { char *buffer; char *buffer2; char *buffer3; - int i, n, len, ret; + int i, n, len, ret, gib_argc; + char *gib_argv[256]; gib_inst_t *ginst; @@ -108,66 +110,89 @@ int GIB_Execute_Inst (char *inst) buffer2 = malloc(2048); buffer3 = malloc(2048); - GIB_ExpandVars (buffer, buffer2, 2048); - GIB_ExpandBackticks (buffer2, buffer3, 2048); - - gib_argc[gib_subsp + gib_argofs] = 0; + ret = GIB_ExpandVars (buffer, buffer2, 2048); + if (ret) + return ret; + ret = GIB_ExpandBackticks (buffer2, buffer3, 2048); + if (ret) + return ret; + gib_argc = 0; for (i = 0; buffer3[i] != ' '; i++); - gib_argv[gib_subsp + gib_argofs][0] = malloc(i + 1); - strncpy(gib_argv[gib_subsp + gib_argofs][0], buffer3, i); - gib_argv[gib_subsp + gib_argofs][0][i] = 0; + gib_argv[0] = malloc(i + 1); + strncpy(gib_argv[0], buffer3, i); + gib_argv[0][i] = 0; for (n = 0;;n++) { for (;isspace(buffer3[i]); i++); if (buffer3[i] == 0) break; - if ((len = GIB_Get_Arg(buffer3 + i)) < 0) // Parse error + if ((len = GIB_Get_Arg(buffer3 + i)) < 0) return GIB_E_PARSE; else { - gib_argv[gib_subsp + gib_argofs][n + 1] = malloc(len + 1); - strncpy(gib_argv[gib_subsp + gib_argofs][n + 1], buffer3 + i, len); - gib_argv[gib_subsp + gib_argofs][n + 1][len] = 0; - GIB_ExpandEscapes (gib_argv[gib_subsp + gib_argofs][n + 1]); + gib_argv[n + 1] = malloc(len + 1); + strncpy(gib_argv[n + 1], buffer3 + i, len); + gib_argv[n + 1][len] = 0; + GIB_ExpandEscapes (gib_argv[n + 1]); i += len; } } - gib_argc[gib_subsp + gib_argofs] = n; + gib_argc = n; free(buffer); free(buffer2); free(buffer3); for (i = 1; i <= n; i++) - GIB_Strip_Arg (gib_argv[gib_subsp + gib_argofs][i]); - if (!(ginst = GIB_Find_Instruction(gib_argv[gib_subsp + gib_argofs][0]))) - return 1; - ret = ginst->func (); + GIB_Strip_Arg (gib_argv[i]); + if (!(ginst = GIB_Find_Instruction(gib_argv[0]))) + return GIB_E_ILLINST; + GIB_InStack_Push(ginst, gib_argc, gib_argv); for (i = 0; i <= n; i++) - free(gib_argv[gib_subsp + gib_argofs][i]); - return ret; + free(gib_argv[i]); + return 0; } int GIB_Run_Sub (gib_module_t *mod, gib_sub_t *sub) { int ret, i; char buf[256]; - if (++gib_subsp >= GIB_MAXCALLS) - return 3; - gib_currentmod[gib_subsp] = mod; - gib_currentsub[gib_subsp] = sub; - gib_locals[gib_subsp] = 0; - for (i = 0; i <= GIB_SUBARGC; i++) + GIB_SubStack_Push (mod, sub, 0); + + for (i = 0; i <= gib_subargc; i++) { sprintf(buf, "arg%i", i); - GIB_Var_Set (buf, GIB_SUBARGV[i]); + GIB_Var_Set (buf, gib_subargv[i]); } - ret = GIB_Execute_Block(sub->code, 1); - if (gib_locals[gib_subsp]) - GIB_Var_FreeAll(gib_locals[gib_subsp]); - gib_subsp--; + sprintf(buf, "%i", gib_subargc); + GIB_Var_Set ("argc", buf); + + ret = GIB_Execute_Sub (); + + if (GIB_LOCALS) + GIB_Var_FreeAll(GIB_LOCALS); + + GIB_SubStack_Pop (); return ret; } + +int GIB_Execute_Sub (void) +{ + return GIB_Execute_Block (GIB_CURRENTSUB->code, 1); +} + +int GIB_Run_Inst (char *inst) +{ + int ret; + + ret = GIB_Interpret_Inst (inst); + if (ret) + { + GIB_InStack_Pop (); + return ret; + } + return GIB_Execute_Inst (); +} \ No newline at end of file diff --git a/source/gib_parse.c b/source/gib_parse.c index 94c4d13..15d214b 100644 --- a/source/gib_parse.c +++ b/source/gib_parse.c @@ -53,32 +53,29 @@ int GIB_Get_Inst(char *start) int GIB_Get_Arg (char *start) { int i; - int len = 0; + int ret = -2; - for (i = 0; start[i] != ' ' && start[i] != 0; i++) + Con_Printf("Parsing at %s\n", start); + + if (*start == '\'') { - if (start[i] == '\'') - { - if ((len = GIB_End_Quote(start + i)) < 0) - return len; - else - i += len; - } - if (start[i] == '\"') - { - if ((len = GIB_End_DQuote(start + i)) < 0) - return len; - else - i += len; - } - if (start[i] == '{') - { - if ((len = GIB_End_Bracket(start + i)) < 0) - return len; - else - i += len; - } - } + ret = GIB_End_Quote(start); + } + if (*start == '\"') + { + ret = GIB_End_DQuote(start); + } + if (*start == '{') + { + ret = GIB_End_Bracket(start); + } + + if (ret == -1) + return -1; + if (ret >= 0) + return ret; + + for (i = 1; (start[i] != ' ' && start[i] != 0 && start[i] != '\'' && start[i] != '\"' && start[i] != '{') || start[i - 1] == '\\'; i++); return i; } int GIB_End_Quote (char *start) diff --git a/source/gib_stack.c b/source/gib_stack.c new file mode 100644 index 0000000..efe0631 --- /dev/null +++ b/source/gib_stack.c @@ -0,0 +1,73 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include "cvar.h" +#include "console.h" +#include "qargs.h" +#include "cmd.h" +#include "zone.h" +#include "quakefs.h" +#include "gib.h" +#include "gib_instructions.h" +#include "gib_interpret.h" +#include "gib_modules.h" +#include "gib_parse.h" +#include "gib_vars.h" +#include "gib_error.h" +#include "gib_stack.h" + +gib_instack_t *gib_instack = 0; +gib_substack_t *gib_substack = 0; + +int gib_insp = 0; +int gib_subsp = 0; + +void GIB_InStack_Push (gib_inst_t *instruction, int argc, char **argv) +{ + int i; + + gib_instack = realloc(gib_instack, sizeof(gib_instack_t) * (gib_insp + 1)); + gib_instack[gib_insp].argv = malloc(argc + 1); + + for (i = 0; i <= argc; i++) + { + gib_instack[gib_insp].argv[i] = malloc(strlen(argv[i]) + 1); + strcpy(gib_instack[gib_insp].argv[i], argv[i]); + } + + gib_instack[gib_insp].argc = argc; + gib_instack[gib_insp].instruction = instruction; + gib_insp++; +} + +void GIB_InStack_Pop (void) +{ + int i; + + gib_insp--; + + for (i = 0; i <= gib_instack[gib_insp].argc; i++) + free(gib_instack[gib_insp].argv[i]); + + free(gib_instack[gib_insp].argv); + + gib_instack = realloc(gib_instack, sizeof(gib_instack_t) * gib_insp); +} + +void GIB_SubStack_Push (gib_module_t *mod, gib_sub_t *sub, gib_var_t *local) +{ + gib_substack = realloc(gib_substack, sizeof(gib_substack_t) * (gib_subsp + 1)); + gib_substack[gib_subsp].mod = mod; + gib_substack[gib_subsp].sub = sub; + gib_substack[gib_subsp].local = local; + gib_subsp++; +} + +void GIB_SubStack_Pop (void) +{ + gib_instack = realloc(gib_instack, sizeof(gib_instack_t) * (--gib_subsp)); +} \ No newline at end of file diff --git a/source/gib_vars.c b/source/gib_vars.c index 12d6a67..8ed435e 100644 --- a/source/gib_vars.c +++ b/source/gib_vars.c @@ -17,15 +17,14 @@ #include "gib_modules.h" #include "gib_parse.h" #include "gib_vars.h" - -gib_var_t *gib_locals[GIB_MAXCALLS]; +#include "gib_stack.h" gib_var_t *GIB_Var_FindLocal (char *key) { gib_var_t *var; - if (!(gib_locals[gib_subsp])) + if (!(GIB_LOCALS)) return 0; - for (var = gib_locals[gib_subsp]; strcmp(key, var->key); var = var->next) + for (var = GIB_LOCALS; strcmp(key, var->key); var = var->next) if (!(var->next)) return 0; return var; @@ -33,9 +32,9 @@ gib_var_t *GIB_Var_FindLocal (char *key) gib_var_t *GIB_Var_FindGlobal (char *key) { gib_var_t *var; - if (!(gib_currentmod[gib_subsp]->vars)) + if (!(GIB_CURRENTMOD->vars)) return 0; - for (var = gib_currentmod[gib_subsp]->vars; strcmp(key, var->key); var = var->next) + for (var = GIB_CURRENTMOD->vars; strcmp(key, var->key); var = var->next) if (!(var->next)) return 0; return var; @@ -54,8 +53,8 @@ void GIB_Var_Set (char *key, char *value) var = malloc(sizeof(gib_var_t)); var->key = malloc(strlen(key) + 1); strcpy(var->key, key); - var->next = gib_locals[gib_subsp]; - gib_locals[gib_subsp] = var; + var->next = GIB_LOCALS; + GIB_LOCALS = var; } var->value = malloc(strlen(value) + 1); strcpy(var->value, value);