mirror of
https://git.code.sf.net/p/quake/nuq
synced 2024-11-22 04:01:11 +00:00
GIB has completed its de-evolution into a cheap ripoff of bash, thus determining the meaning of its own acronym: GIB Isn't Bash
This commit is contained in:
parent
490409a57b
commit
58ef964ae2
9 changed files with 328 additions and 86 deletions
|
@ -1,8 +1,11 @@
|
|||
#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
|
||||
#define GIB_E_PARSE 1
|
||||
#define GIB_E_NUMARGS 2
|
||||
#define GIB_E_ARG 3
|
||||
#define GIB_E_CALLS 4
|
||||
#define GIB_E_NOSUB 5
|
||||
#define GIB_E_NOVAR 6
|
||||
#define GIB_E_BUFFER 7
|
||||
#define GIB_E_TYPE 8
|
||||
#define GIB_E_ULIMIT 9
|
||||
|
|
|
@ -5,3 +5,10 @@ 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);
|
||||
|
|
|
@ -6,11 +6,15 @@ 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_argv[GIB_MAXCALLS][80];
|
||||
|
||||
extern int gib_argofs;
|
||||
|
||||
extern char *GIB_SUBARGV[GIB_MAXSUBARGS];
|
||||
extern int GIB_SUBARGC;
|
||||
|
||||
extern char errorline[1024];
|
||||
|
||||
char *GIB_Argv(int i);
|
||||
int GIB_Argc(void);
|
||||
void GIB_Strip_Arg (char *arg);
|
||||
|
|
|
@ -5,3 +5,4 @@ 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);
|
||||
int GIB_ExpandEscapes (char *source);
|
||||
|
|
|
@ -51,7 +51,7 @@ void GIB_Gib_f (void)
|
|||
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);
|
||||
Con_Printf("Error in execution of %s!\nError code: %i\n\nLine at fault: %s\n", Cmd_Argv(1), ret, errorline);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include "cvar.h"
|
||||
#include "console.h"
|
||||
#include "qargs.h"
|
||||
|
@ -50,11 +51,17 @@ void GIB_Init_Instructions (void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
int GIB_Echo_f (void)
|
||||
{
|
||||
Con_Printf("%s\n",GIB_Argv(1));
|
||||
Con_Printf(GIB_Argv(1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -76,7 +83,10 @@ int GIB_Call_f (void)
|
|||
GIB_SUBARGV[i] = GIB_Argv(i + 1);
|
||||
ret = GIB_Run_Sub (mod, sub);
|
||||
if (gib_subret)
|
||||
{
|
||||
GIB_Var_Set("retval", gib_subret);
|
||||
free (gib_subret);
|
||||
}
|
||||
gib_subret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
@ -104,3 +114,165 @@ int GIB_Return_f (void)
|
|||
strcpy(gib_subret, GIB_Argv(1));
|
||||
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;
|
||||
gib_var_t *var;
|
||||
int i, n, m;
|
||||
|
||||
if (GIB_Argc() != 2)
|
||||
return GIB_E_NUMARGS;
|
||||
|
||||
if (!(var = GIB_Var_FindLocal(GIB_Argv(1))))
|
||||
return GIB_E_NOVAR;
|
||||
for (i = 0; isspace(var->value[i]); i++);
|
||||
for (n = 1; n < atoi(GIB_Argv(2)); n++)
|
||||
{
|
||||
if ((m = GIB_Get_Arg (var->value + i)) < 1)
|
||||
return GIB_E_ULIMIT;
|
||||
i += m;
|
||||
for (; isspace(var->value[i]); i++);
|
||||
}
|
||||
if ((m = GIB_Get_Arg (var->value + i)) < 1)
|
||||
return GIB_E_ULIMIT;
|
||||
element = malloc(m + 1);
|
||||
strncpy(element, var->value + i, m);
|
||||
element[m] = 0;
|
||||
GIB_Var_Set ("retval", element);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GIB_Con_f (void)
|
||||
{
|
||||
if (GIB_Argc() != 1)
|
||||
return GIB_E_NUMARGS;
|
||||
|
||||
Cmd_ExecuteString (GIB_Argv(1), src_command);
|
||||
|
||||
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;
|
||||
|
||||
char varname[256];
|
||||
gib_var_t *var;
|
||||
|
||||
for (i = 0, n = 0; i <= strlen(source); i++)
|
||||
{
|
||||
if (source[i] == '$')
|
||||
{
|
||||
m = 0;
|
||||
while(isalnum(source[++i]))
|
||||
varname[m++] = source[i];
|
||||
|
||||
varname[m++] = 0;
|
||||
if (!(var = GIB_Var_FindLocal (varname)))
|
||||
return GIB_E_NOVAR;
|
||||
if (n + strlen(var->value) >= buffersize)
|
||||
return GIB_E_BUFFER;
|
||||
memcpy(buffer + n, var->value, strlen(var->value));
|
||||
|
||||
n += strlen(var->value);
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n >= buffersize + 1)
|
||||
return GIB_E_BUFFER;
|
||||
buffer[n++] = source[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GIB_ExpandBackticks (char *source, char *buffer, int buffersize)
|
||||
{
|
||||
int i, n, m, ret;
|
||||
|
||||
char tick[256];
|
||||
gib_var_t *var;
|
||||
|
||||
for (i = 0, n = 0; i <= strlen(source); i++)
|
||||
{
|
||||
if (source[i] == '`')
|
||||
{
|
||||
m = 0;
|
||||
while(source[++i] != '`')
|
||||
tick[m++] = source[i];
|
||||
|
||||
tick[m++] = 0;
|
||||
gib_argofs++;
|
||||
ret = GIB_Execute_Inst (tick);
|
||||
gib_argofs--;
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
if (!(var = GIB_Var_FindLocal ("retval")))
|
||||
return GIB_E_NOVAR;
|
||||
if (n + strlen(var->value) >= buffersize)
|
||||
return GIB_E_BUFFER;
|
||||
memcpy(buffer + n, var->value, strlen(var->value));
|
||||
|
||||
n += strlen(var->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n >= buffersize + 1)
|
||||
return GIB_E_BUFFER;
|
||||
buffer[n++] = source[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -29,14 +29,18 @@ int GIB_SUBARGC;
|
|||
int gib_argc[GIB_MAXCALLS];
|
||||
char *gib_argv[GIB_MAXCALLS][80];
|
||||
|
||||
int gib_argofs = 0;
|
||||
|
||||
char errorline[1024];
|
||||
|
||||
char *GIB_Argv(int i)
|
||||
{
|
||||
return gib_argv[gib_subsp][i];
|
||||
return gib_argv[gib_subsp + gib_argofs][i];
|
||||
}
|
||||
|
||||
int GIB_Argc(void)
|
||||
{
|
||||
return gib_argc[gib_subsp];
|
||||
return gib_argc[gib_subsp + gib_argofs];
|
||||
}
|
||||
|
||||
void GIB_Strip_Arg (char *arg)
|
||||
|
@ -65,8 +69,12 @@ int GIB_Execute_Block (char *block, int retflag)
|
|||
if (retflag && ret == GIB_E_RETURN)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
strcpy(errorline, code);
|
||||
free (code);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
free (code);
|
||||
i += len + 1;
|
||||
}
|
||||
|
@ -76,9 +84,12 @@ int GIB_Execute_Block (char *block, int retflag)
|
|||
int GIB_Execute_Inst (char *inst)
|
||||
{
|
||||
char *buffer;
|
||||
char *buffer2;
|
||||
char *buffer3;
|
||||
int i, n, len, ret;
|
||||
gib_inst_t *ginst;
|
||||
|
||||
|
||||
buffer = malloc(strlen(inst) + 1);
|
||||
i = 0;
|
||||
|
||||
|
@ -93,38 +104,48 @@ int GIB_Execute_Inst (char *inst)
|
|||
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;
|
||||
|
||||
|
||||
buffer2 = malloc(2048);
|
||||
buffer3 = malloc(2048);
|
||||
GIB_ExpandVars (buffer, buffer2, 2048);
|
||||
GIB_ExpandBackticks (buffer2, buffer3, 2048);
|
||||
|
||||
gib_argc[gib_subsp + gib_argofs] = 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;
|
||||
for (n = 0;;n++)
|
||||
{
|
||||
for (;isspace(buffer[i]); i++);
|
||||
if (buffer[i] == 0)
|
||||
for (;isspace(buffer3[i]); i++);
|
||||
if (buffer3[i] == 0)
|
||||
break;
|
||||
if ((len = GIB_Get_Arg(buffer + i)) < 0) // Parse error
|
||||
return len;
|
||||
if ((len = GIB_Get_Arg(buffer3 + i)) < 0) // Parse error
|
||||
return GIB_E_PARSE;
|
||||
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;
|
||||
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]);
|
||||
i += len;
|
||||
}
|
||||
}
|
||||
gib_argc[gib_subsp] = n;
|
||||
gib_argc[gib_subsp + gib_argofs] = n;
|
||||
|
||||
free(buffer);
|
||||
free(buffer2);
|
||||
free(buffer3);
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
GIB_Strip_Arg (gib_argv[gib_subsp][i]);
|
||||
if (!(ginst = GIB_Find_Instruction(gib_argv[gib_subsp][0])))
|
||||
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 ();
|
||||
|
||||
for (i = 0; i <= n; i++)
|
||||
free(gib_argv[gib_subsp][i]);
|
||||
free(gib_argv[gib_subsp + gib_argofs][i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "gib_modules.h"
|
||||
#include "gib_parse.h"
|
||||
#include "gib_vars.h"
|
||||
|
||||
#include "gib_error.h"
|
||||
|
||||
int GIB_Get_Inst(char *start)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ int GIB_Get_Inst(char *start)
|
|||
}
|
||||
if (start[i] == '{')
|
||||
{
|
||||
if ((len = GIB_End_DQuote(start + i)) < 0)
|
||||
if ((len = GIB_End_Bracket(start + i)) < 0)
|
||||
return len;
|
||||
else
|
||||
i += len;
|
||||
|
@ -73,7 +73,7 @@ int GIB_Get_Arg (char *start)
|
|||
}
|
||||
if (start[i] == '{')
|
||||
{
|
||||
if ((len = GIB_End_DQuote(start + i)) < 0)
|
||||
if ((len = GIB_End_Bracket(start + i)) < 0)
|
||||
return len;
|
||||
else
|
||||
i += len;
|
||||
|
@ -86,6 +86,8 @@ int GIB_End_Quote (char *start)
|
|||
int i;
|
||||
int len = 0;
|
||||
for (i = 1; start[i] != '\''; i++)
|
||||
{
|
||||
if (start[i - 1] != '\\')
|
||||
{
|
||||
if (start[i] == '\"')
|
||||
{
|
||||
|
@ -105,12 +107,15 @@ int GIB_End_Quote (char *start)
|
|||
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 - 1] != '\\')
|
||||
{
|
||||
if (start[i] == '\'')
|
||||
{
|
||||
|
@ -128,7 +133,8 @@ int GIB_End_DQuote (char *start)
|
|||
i += ret;
|
||||
}
|
||||
if (start[i] == 0)
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -137,6 +143,8 @@ int GIB_End_Bracket (char *start)
|
|||
{
|
||||
int i, ret;
|
||||
for (i = 1; start[i] != '}'; i++)
|
||||
{
|
||||
if (start[i - 1] != '\\')
|
||||
{
|
||||
if (start[i] == '\'')
|
||||
{
|
||||
|
@ -163,7 +171,8 @@ int GIB_End_Bracket (char *start)
|
|||
}
|
||||
|
||||
if (start[i] == 0)
|
||||
return -3;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -197,3 +206,29 @@ gib_module_t *GIB_Get_ModSub_Mod (char *modsub)
|
|||
return mod;
|
||||
}
|
||||
|
||||
int GIB_ExpandEscapes (char *source)
|
||||
{
|
||||
int i, m;
|
||||
for (i = 0, m = 0; i <= strlen(source); i++)
|
||||
{
|
||||
if (source[i] == '\\')
|
||||
{
|
||||
switch(source[++i])
|
||||
{
|
||||
case 0:
|
||||
return GIB_E_PARSE;
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
source[m] = '\n';
|
||||
break;
|
||||
default:
|
||||
source[m] = source[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
source[m] = source[i];
|
||||
m++;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -47,7 +47,6 @@ 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
|
||||
|
|
Loading…
Reference in a new issue