mirror of
https://git.code.sf.net/p/quake/nuq
synced 2024-11-28 23:01:53 +00:00
Adds GIB, an experimental scripting language for QF, and a few compile fixes.
This commit is contained in:
parent
86a0a6aa3e
commit
a4a7abb902
17 changed files with 875 additions and 1 deletions
38
include/gib.h
Normal file
38
include/gib.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
typedef int (*gib_func_t) (void);
|
||||||
|
|
||||||
|
typedef struct gib_var_s
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
struct gib_var_s *next;
|
||||||
|
} gib_var_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct gib_sub_s
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *code;
|
||||||
|
gib_var_t *vars;
|
||||||
|
struct gib_sub_s *next;
|
||||||
|
} gib_sub_t;
|
||||||
|
|
||||||
|
typedef struct gib_module_s
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
gib_sub_t *subs;
|
||||||
|
gib_var_t *vars;
|
||||||
|
struct gib_module_s *next;
|
||||||
|
} gib_module_t;
|
||||||
|
|
||||||
|
typedef struct gib_inst_s
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
gib_func_t func;
|
||||||
|
struct gib_inst_s *next;
|
||||||
|
} gib_inst_t;
|
||||||
|
|
||||||
|
void GIB_Init (void);
|
||||||
|
void GIB_Gib_f (void);
|
||||||
|
void GIB_Load_f (void);
|
||||||
|
void GIB_Stats_f (void);
|
||||||
|
|
8
include/gib_error.h
Normal file
8
include/gib_error.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#define GIB_E_EXIT -2
|
||||||
|
#define GIB_E_RETURN -1
|
||||||
|
#define GIB_E_PARSE 6
|
||||||
|
#define GIB_E_NUMARGS 1
|
||||||
|
#define GIB_E_ARG 2
|
||||||
|
#define GIB_E_CALLS 3
|
||||||
|
#define GIB_E_NOSUB 4
|
||||||
|
#define GIB_E_NOVAR 5
|
7
include/gib_instructions.h
Normal file
7
include/gib_instructions.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
void GIB_AddInstruction (char *name, gib_func_t func);
|
||||||
|
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);
|
19
include/gib_interpret.h
Normal file
19
include/gib_interpret.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#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];
|
||||||
|
char *gib_argv[GIB_MAXCALLS][80];
|
||||||
|
|
||||||
|
extern char *GIB_SUBARGV[GIB_MAXSUBARGS];
|
||||||
|
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_Run_Sub (gib_module_t *mod, gib_sub_t *sub);
|
7
include/gib_modules.h
Normal file
7
include/gib_modules.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
void GIB_Module_Load (char *name, FILE *f);
|
||||||
|
gib_module_t *GIB_Create_Module (char *name);
|
||||||
|
gib_sub_t *GIB_Create_Sub (gib_module_t *mod, char *name);
|
||||||
|
void GIB_Read_Sub (gib_sub_t *sub, FILE *f);
|
||||||
|
gib_module_t *GIB_Find_Module (char *name);
|
||||||
|
gib_sub_t *GIB_Find_Sub (gib_module_t *mod, char *name);
|
||||||
|
void GIB_Stats_f (void);
|
7
include/gib_parse.h
Normal file
7
include/gib_parse.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
int GIB_Get_Inst (char *start);
|
||||||
|
int GIB_Get_Arg (char *start);
|
||||||
|
int GIB_End_Quote (char *start);
|
||||||
|
int GIB_End_DQuote (char *start);
|
||||||
|
int GIB_End_Bracket (char *start);
|
||||||
|
gib_sub_t *GIB_Get_ModSub_Sub (char *modsub);
|
||||||
|
gib_module_t *GIB_Get_ModSub_Mod (char *modsub);
|
6
include/gib_vars.h
Normal file
6
include/gib_vars.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
extern gib_var_t *gib_locals[GIB_MAXCALLS];
|
||||||
|
|
||||||
|
gib_var_t *GIB_Var_FindLocal (char *key);
|
||||||
|
gib_var_t *GIB_Var_FindGlobal (char *key);
|
||||||
|
void GIB_Var_Set (char *key, char *value);
|
||||||
|
void GIB_Var_FreeAll (gib_var_t *var);
|
|
@ -114,7 +114,8 @@ 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 \
|
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 \
|
cl_tent.c console.c keys.c menu.c sbar.c r_view.c \
|
||||||
nonintel.c
|
nonintel.c gib.c gib_instructions.c gib_vars.c \
|
||||||
|
gib_interpret.c gib_modules.c gib_parse.c
|
||||||
|
|
||||||
server_SOURCES= host.c host_cmd.c \
|
server_SOURCES= host.c host_cmd.c \
|
||||||
pr_cmds.c pr_edict.c pr_exec.c \
|
pr_cmds.c pr_edict.c pr_exec.c \
|
||||||
|
|
81
source/gib.c
Normal file
81
source/gib.c
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//static char *gib_args;
|
||||||
|
|
||||||
|
// Standard cvars
|
||||||
|
|
||||||
|
void GIB_Init (void)
|
||||||
|
{
|
||||||
|
Cmd_AddCommand("gibload", GIB_Load_f);
|
||||||
|
Cmd_AddCommand("gibstats", GIB_Stats_f);
|
||||||
|
Cmd_AddCommand("gib", GIB_Gib_f);
|
||||||
|
GIB_Init_Instructions ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GIB_Gib_f (void)
|
||||||
|
{
|
||||||
|
gib_sub_t *sub;
|
||||||
|
gib_module_t *mod;
|
||||||
|
int i, ret;
|
||||||
|
if (!(mod = GIB_Get_ModSub_Mod(Cmd_Argv(1))))
|
||||||
|
{
|
||||||
|
Con_Printf("Module not found!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(sub = GIB_Get_ModSub_Sub(Cmd_Argv(1))))
|
||||||
|
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);
|
||||||
|
ret = GIB_Run_Sub(mod, sub);
|
||||||
|
if (ret != 0)
|
||||||
|
Con_Printf("Error in execution of %s!\nError code: %i\n", Cmd_Argv(1), ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GIB_Load_f (void)
|
||||||
|
{
|
||||||
|
char filename[256];
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
sprintf(filename, "%s/%s.gib", com_gamedir, Cmd_Argv(1));
|
||||||
|
f = fopen(filename, "r");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
GIB_Module_Load(Cmd_Argv(1), f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con_Printf("gibload: File not found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
106
source/gib_instructions.c
Normal file
106
source/gib_instructions.c
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
static gib_inst_t *gibinstructions;
|
||||||
|
|
||||||
|
char *gib_subret;
|
||||||
|
|
||||||
|
void GIB_AddInstruction (char *name, gib_func_t func)
|
||||||
|
{
|
||||||
|
gib_inst_t *new;
|
||||||
|
new = malloc(sizeof(gib_inst_t));
|
||||||
|
new->name = malloc(strlen(name) + 1);
|
||||||
|
new->func = func;
|
||||||
|
strcpy(new->name, name);
|
||||||
|
new->next = gibinstructions;
|
||||||
|
gibinstructions = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_inst_t *GIB_Find_Instruction (char *name)
|
||||||
|
{
|
||||||
|
gib_inst_t *inst;
|
||||||
|
if (!(gibinstructions))
|
||||||
|
return 0;
|
||||||
|
for (inst = gibinstructions; strcmp(inst->name, name); inst = inst->next)
|
||||||
|
if (!(inst->next))
|
||||||
|
return 0;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_Echo_f (void)
|
||||||
|
{
|
||||||
|
Con_Printf("%s\n",GIB_Argv(1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_Call_f (void)
|
||||||
|
{
|
||||||
|
gib_module_t *mod;
|
||||||
|
gib_sub_t *sub;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
mod = GIB_Get_ModSub_Mod (GIB_Argv(1));
|
||||||
|
if (!mod)
|
||||||
|
return GIB_E_NOSUB;
|
||||||
|
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);
|
||||||
|
ret = GIB_Run_Sub (mod, sub);
|
||||||
|
if (gib_subret)
|
||||||
|
GIB_Var_Set("retval", gib_subret);
|
||||||
|
gib_subret = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_VarPrint_f (void)
|
||||||
|
{
|
||||||
|
gib_var_t *var;
|
||||||
|
int i;
|
||||||
|
for (i = 1; i <= GIB_Argc(); i++)
|
||||||
|
{
|
||||||
|
var = GIB_Var_FindLocal(GIB_Argv(i));
|
||||||
|
if (!var)
|
||||||
|
return GIB_E_NOVAR;
|
||||||
|
Con_Printf("%s", var->value);
|
||||||
|
}
|
||||||
|
Con_Printf ("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_Return_f (void)
|
||||||
|
{
|
||||||
|
if (GIB_Argc() != 1)
|
||||||
|
return GIB_E_NUMARGS;
|
||||||
|
gib_subret = malloc(strlen(GIB_Argv(1)) + 1);
|
||||||
|
strcpy(gib_subret, GIB_Argv(1));
|
||||||
|
return GIB_E_RETURN; // Signal to block executor to return immediately
|
||||||
|
}
|
152
source/gib_interpret.c
Normal file
152
source/gib_interpret.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
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];
|
||||||
|
|
||||||
|
char *GIB_Argv(int i)
|
||||||
|
{
|
||||||
|
return gib_argv[gib_subsp][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_Argc(void)
|
||||||
|
{
|
||||||
|
return gib_argc[gib_subsp];
|
||||||
|
}
|
||||||
|
|
||||||
|
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_Execute_Inst(code)))
|
||||||
|
{
|
||||||
|
if (retflag && ret == GIB_E_RETURN)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
free (code);
|
||||||
|
i += len + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_Execute_Inst (char *inst)
|
||||||
|
{
|
||||||
|
char *buffer;
|
||||||
|
int i, n, len, ret;
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
gib_argc[gib_subsp] = 0;
|
||||||
|
for (i = 0; buffer[i] != ' '; i++);
|
||||||
|
gib_argv[gib_subsp][0] = malloc(i + 1);
|
||||||
|
strncpy(gib_argv[gib_subsp][0], buffer, i);
|
||||||
|
gib_argv[gib_subsp][0][i] = 0;
|
||||||
|
for (n = 0;;n++)
|
||||||
|
{
|
||||||
|
for (;isspace(buffer[i]); i++);
|
||||||
|
if (buffer[i] == 0)
|
||||||
|
break;
|
||||||
|
if ((len = GIB_Get_Arg(buffer + i)) < 0) // Parse error
|
||||||
|
return len;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gib_argv[gib_subsp][n + 1] = malloc(len + 1);
|
||||||
|
strncpy(gib_argv[gib_subsp][n + 1], buffer + i, len);
|
||||||
|
gib_argv[gib_subsp][n + 1][len] = 0;
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gib_argc[gib_subsp] = n;
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
for (i = 1; i <= n; i++)
|
||||||
|
GIB_Strip_Arg (gib_argv[gib_subsp][i]);
|
||||||
|
if (!(ginst = GIB_Find_Instruction(gib_argv[gib_subsp][0])))
|
||||||
|
return 1;
|
||||||
|
ret = ginst->func ();
|
||||||
|
|
||||||
|
for (i = 0; i <= n; i++)
|
||||||
|
free(gib_argv[gib_subsp][i]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
sprintf(buf, "arg%i", 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--;
|
||||||
|
return ret;
|
||||||
|
}
|
157
source/gib_modules.c
Normal file
157
source/gib_modules.c
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
static gib_module_t *gibmodules;
|
||||||
|
|
||||||
|
void GIB_Module_Load (char *name, FILE *f)
|
||||||
|
{
|
||||||
|
char line[1024];
|
||||||
|
gib_module_t *newmod;
|
||||||
|
gib_sub_t *newsub;
|
||||||
|
int nameofs;
|
||||||
|
int namelen;
|
||||||
|
|
||||||
|
newmod = GIB_Create_Module(name);
|
||||||
|
|
||||||
|
while (fgets(line, 1024, f))
|
||||||
|
{
|
||||||
|
if (strncmp("sub", line, 3) == 0)
|
||||||
|
{
|
||||||
|
nameofs = 3;
|
||||||
|
while(isspace(line[nameofs]))
|
||||||
|
nameofs++;
|
||||||
|
namelen = 0;
|
||||||
|
while(!(isspace(line[nameofs+namelen])))
|
||||||
|
{
|
||||||
|
namelen++;
|
||||||
|
}
|
||||||
|
line[nameofs + namelen] = 0;
|
||||||
|
newsub = GIB_Create_Sub(newmod, line + nameofs);
|
||||||
|
GIB_Read_Sub(newsub, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_module_t *GIB_Create_Module(char *name)
|
||||||
|
{
|
||||||
|
gib_module_t *new;
|
||||||
|
|
||||||
|
new = malloc(sizeof(gib_module_t));
|
||||||
|
new->name = malloc(strlen(name) + 1);
|
||||||
|
strcpy(new->name, name);
|
||||||
|
new->subs = 0;
|
||||||
|
new->vars = 0;
|
||||||
|
new->next = gibmodules;
|
||||||
|
gibmodules = new;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_sub_t *GIB_Create_Sub(gib_module_t *mod, char *name)
|
||||||
|
{
|
||||||
|
gib_sub_t *new;
|
||||||
|
|
||||||
|
new = malloc(sizeof(gib_sub_t));
|
||||||
|
new->name = malloc(strlen(name) + 1);
|
||||||
|
strcpy(new->name, name);
|
||||||
|
new->code = 0;
|
||||||
|
new->vars = 0;
|
||||||
|
new->next = mod->subs;
|
||||||
|
mod->subs = new;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GIB_Read_Sub(gib_sub_t *sub, FILE *f)
|
||||||
|
{
|
||||||
|
char line[1024];
|
||||||
|
fpos_t begin;
|
||||||
|
int sublen = 0;
|
||||||
|
int insub = 0;
|
||||||
|
|
||||||
|
while (fgets(line, 1024, f))
|
||||||
|
{
|
||||||
|
if (strncmp("}}", line, 2) == 0 && insub == 1)
|
||||||
|
{
|
||||||
|
insub = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (insub == 1)
|
||||||
|
{
|
||||||
|
sublen += strlen(line);
|
||||||
|
}
|
||||||
|
if (strncmp("{{", line, 2) == 0)
|
||||||
|
{
|
||||||
|
fgetpos(f, &begin);
|
||||||
|
insub = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub->code = malloc(sublen + 1);
|
||||||
|
fsetpos(f, &begin);
|
||||||
|
fread(sub->code, 1, sublen, f);
|
||||||
|
sub->code[sublen] = 0;
|
||||||
|
Con_Printf("Loaded sub %s\n", sub->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_module_t *GIB_Find_Module(char *name)
|
||||||
|
{
|
||||||
|
gib_module_t *mod;
|
||||||
|
if (!(gibmodules))
|
||||||
|
return 0;
|
||||||
|
for (mod = gibmodules; strcmp(mod->name, name); mod = mod->next)
|
||||||
|
if (mod->next == 0)
|
||||||
|
return 0;
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_sub_t *GIB_Find_Sub(gib_module_t *mod, char *name)
|
||||||
|
{
|
||||||
|
gib_sub_t *sub;
|
||||||
|
if (!(mod->subs))
|
||||||
|
return 0;
|
||||||
|
for (sub = mod->subs; strcmp(sub->name, name); sub = sub->next)
|
||||||
|
if (sub->next == 0)
|
||||||
|
return 0;
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GIB_Stats_f (void)
|
||||||
|
{
|
||||||
|
int modc, subc;
|
||||||
|
|
||||||
|
gib_module_t *mod;
|
||||||
|
gib_sub_t *sub;
|
||||||
|
|
||||||
|
modc = 0;
|
||||||
|
Con_Printf("---=== GIB statistics ===---\n");
|
||||||
|
for(mod = gibmodules; mod; mod = mod->next)
|
||||||
|
{
|
||||||
|
Con_Printf("\nSubroutines for module %s:\n", mod->name);
|
||||||
|
Con_Printf("-------------------------------------\n");
|
||||||
|
subc = 0;
|
||||||
|
for(sub = mod->subs; sub; sub = sub->next)
|
||||||
|
{
|
||||||
|
Con_Printf("%s::%s\n", mod->name, sub->name);
|
||||||
|
subc++;
|
||||||
|
}
|
||||||
|
Con_Printf("-------------------------------------\nSubroutines: %i\n", subc);
|
||||||
|
modc++;
|
||||||
|
}
|
||||||
|
Con_Printf("Modules installed: %i\n", modc);
|
||||||
|
Con_Printf("---=== GIB statistics ===---\n");
|
||||||
|
}
|
199
source/gib_parse.c
Normal file
199
source/gib_parse.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
|
||||||
|
int GIB_Get_Inst(char *start)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = 0;
|
||||||
|
for (i = 0; start[i] != ';'; i++)
|
||||||
|
{
|
||||||
|
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_DQuote(start + i)) < 0)
|
||||||
|
return len;
|
||||||
|
else
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
if (start[i] == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int GIB_Get_Arg (char *start)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
for (i = 0; start[i] != ' ' && start[i] != 0; i++)
|
||||||
|
{
|
||||||
|
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_DQuote(start + i)) < 0)
|
||||||
|
return len;
|
||||||
|
else
|
||||||
|
i += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int GIB_End_Quote (char *start)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int len = 0;
|
||||||
|
for (i = 1; start[i] != '\''; i++)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (start[i] == 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
int GIB_End_DQuote (char *start)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
for (i = 1; start[i] != '\"'; i++)
|
||||||
|
{
|
||||||
|
if (start[i] == '\'')
|
||||||
|
{
|
||||||
|
if ((ret = GIB_End_Quote(start + i)) < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
i += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start[i] == '{')
|
||||||
|
{
|
||||||
|
if ((ret = GIB_End_Bracket(start +i)) < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
i += ret;
|
||||||
|
}
|
||||||
|
if (start[i] == 0)
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GIB_End_Bracket (char *start)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
for (i = 1; start[i] != '}'; i++)
|
||||||
|
{
|
||||||
|
if (start[i] == '\'')
|
||||||
|
{
|
||||||
|
if ((ret = GIB_End_Quote(start + i)) < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
i += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start[i] == '\"')
|
||||||
|
{
|
||||||
|
if ((ret = GIB_End_DQuote(start + i)) < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
i += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start[i] == '{')
|
||||||
|
{
|
||||||
|
if ((ret = GIB_End_Bracket(start + i)) < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
i += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start[i] == 0)
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
gib_sub_t *GIB_Get_ModSub_Sub (char *modsub)
|
||||||
|
{
|
||||||
|
gib_module_t *mod;
|
||||||
|
gib_sub_t *sub;
|
||||||
|
char *divider;
|
||||||
|
|
||||||
|
if (!(divider = strstr(modsub, "::")))
|
||||||
|
return 0;
|
||||||
|
*divider = 0;
|
||||||
|
mod = GIB_Find_Module (modsub);
|
||||||
|
*divider = ':';
|
||||||
|
if (!mod)
|
||||||
|
return 0;
|
||||||
|
sub = GIB_Find_Sub (mod, divider + 2);
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
gib_module_t *GIB_Get_ModSub_Mod (char *modsub)
|
||||||
|
{
|
||||||
|
gib_module_t *mod;
|
||||||
|
char *divider;
|
||||||
|
|
||||||
|
if (!(divider = strstr(modsub, "::")))
|
||||||
|
return 0;
|
||||||
|
*divider = 0;
|
||||||
|
mod = GIB_Find_Module (modsub);
|
||||||
|
*divider = ':';
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
76
source/gib_vars.c
Normal file
76
source/gib_vars.c
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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"
|
||||||
|
|
||||||
|
gib_var_t *gib_locals[GIB_MAXCALLS];
|
||||||
|
|
||||||
|
gib_var_t *GIB_Var_FindLocal (char *key)
|
||||||
|
{
|
||||||
|
gib_var_t *var;
|
||||||
|
if (!(gib_locals[gib_subsp]))
|
||||||
|
return 0;
|
||||||
|
for (var = gib_locals[gib_subsp]; strcmp(key, var->key); var = var->next)
|
||||||
|
if (!(var->next))
|
||||||
|
return 0;
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
gib_var_t *GIB_Var_FindGlobal (char *key)
|
||||||
|
{
|
||||||
|
gib_var_t *var;
|
||||||
|
if (!(gib_currentmod[gib_subsp]->vars))
|
||||||
|
return 0;
|
||||||
|
for (var = gib_currentmod[gib_subsp]->vars; strcmp(key, var->key); var = var->next)
|
||||||
|
if (!(var->next))
|
||||||
|
return 0;
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GIB_Var_Set (char *key, char *value)
|
||||||
|
{
|
||||||
|
gib_var_t *var;
|
||||||
|
if ((var = GIB_Var_FindLocal(key)))
|
||||||
|
{
|
||||||
|
Con_Printf("Value already found.\n");
|
||||||
|
free(var->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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->value = malloc(strlen(value) + 1);
|
||||||
|
strcpy(var->value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GIB_Var_FreeAll (gib_var_t *var)
|
||||||
|
{
|
||||||
|
gib_var_t *temp;
|
||||||
|
|
||||||
|
for (;var; var = temp)
|
||||||
|
{
|
||||||
|
temp = var->next;
|
||||||
|
free(var->key);
|
||||||
|
free(var->value);
|
||||||
|
free(var);
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
#include "gib.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -889,6 +890,8 @@ void Host_Init (quakeparms_t *parms)
|
||||||
Cbuf_Init ();
|
Cbuf_Init ();
|
||||||
Cmd_Init ();
|
Cmd_Init ();
|
||||||
|
|
||||||
|
GIB_Init ();
|
||||||
|
|
||||||
// execute +set as early as possible
|
// execute +set as early as possible
|
||||||
Cmd_StuffCmds_f ();
|
Cmd_StuffCmds_f ();
|
||||||
Cbuf_Execute_Sets ();
|
Cbuf_Execute_Sets ();
|
||||||
|
|
|
@ -387,6 +387,9 @@ void PR_ExecuteProgram (func_t fnum)
|
||||||
int exitdepth;
|
int exitdepth;
|
||||||
eval_t *ptr;
|
eval_t *ptr;
|
||||||
|
|
||||||
|
a = b = c = 0;
|
||||||
|
st = 0;
|
||||||
|
|
||||||
if (!fnum || fnum >= progs->numfunctions)
|
if (!fnum || fnum >= progs->numfunctions)
|
||||||
{
|
{
|
||||||
if (pr_global_struct->self)
|
if (pr_global_struct->self)
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <linux/soundcard.h>
|
#include <linux/soundcard.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "qtypes.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "sound.h"
|
||||||
|
#include "qargs.h"
|
||||||
|
|
||||||
int audio_fd;
|
int audio_fd;
|
||||||
int snd_inited;
|
int snd_inited;
|
||||||
|
|
Loading…
Reference in a new issue