#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" char *gib_subargv[256]; int gib_subargc; char *GIB_Argv(int i) { return gib_instack[gib_insp - 1].argv[i]; } int GIB_Argc(void) { return gib_instack[gib_insp - 1].argc; } void GIB_Strip_Arg (char *arg) { if (arg[0] == '{' || arg[0] == '\'' || arg[0] == '\"') { arg[strlen(arg) - 1] = 0; memmove(arg, arg + 1, strlen(arg)); } } int GIB_Execute_Block (char *block, int retflag) { int len, i, ret; char *code; i = 0; while ((len = GIB_Get_Inst(block + i)) > 0) { code = malloc(len + 1); strncpy(code, block + i, len); code[len] = 0; if ((ret = GIB_Interpret_Inst(code))) { free (code); return ret; } if ((ret = GIB_Execute_Inst())) { free (code); if (ret == GIB_E_RETURN && retflag) return 0; return ret; } i += len + 1; free (code); } if (len == -1) return GIB_E_PARSE; return 0; } 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, gib_argc; char *gib_argv[256]; gib_inst_t *ginst; buffer = malloc(strlen(inst) + 1); i = 0; while (isspace(inst[i])) i++; for (n = 0; i <= strlen(inst); i++) { if (inst[i] == '\n' || inst[i] == '\t') buffer[n] = ' '; else buffer[n] = inst[i]; n++; } buffer2 = malloc(2048); buffer3 = malloc(2048); 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[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) return GIB_E_PARSE; else { 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 = n; free(buffer); free(buffer2); free(buffer3); for (i = 1; i <= n; i++) 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[i]); return 0; } int GIB_Run_Sub (gib_module_t *mod, gib_sub_t *sub) { int ret, i; char buf[256]; GIB_SubStack_Push (mod, sub, 0); for (i = 0; i <= gib_subargc; i++) { snprintf(buf, sizeof(buf), "arg%i", i); GIB_Var_Set (buf, gib_subargv[i]); } snprintf(buf, sizeof(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 (); }