Added the string::findsub builtin. Added a reset function to the cbuf

interpreter struct so that custom cbuf data can be reset after an error.
This fixes a bug where GIB would think it was still waiting for a return
value after an error occurred in an embedded command.
This commit is contained in:
Brian Koropoff 2002-11-16 20:56:04 +00:00
parent ac8169ba54
commit d4b1c74866
8 changed files with 38 additions and 3 deletions

View file

@ -72,6 +72,7 @@ typedef struct cbuf_interpreter_s {
void (*execute_line) (struct cbuf_s *cbuf); void (*execute_line) (struct cbuf_s *cbuf);
void (*construct) (struct cbuf_s *cbuf); void (*construct) (struct cbuf_s *cbuf);
void (*destruct) (struct cbuf_s *cbuf); void (*destruct) (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;

View file

@ -50,7 +50,6 @@ typedef struct gib_buffer_data_s {
qboolean cat; // Concatenate to previous token? qboolean cat; // Concatenate to previous token?
int noprocess; // Process tokens? int noprocess; // Process tokens?
char delim; // delimiter of token char delim; // delimiter of token
} ret; } ret;
struct hashtab_s *locals; // Local variables struct hashtab_s *locals; // Local variables
@ -64,4 +63,4 @@ 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);

View file

@ -47,6 +47,8 @@ typedef struct gib_builtin_s {
#define GIB_Args(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->args[(x)] : "") #define GIB_Args(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->args[(x)] : "")
#define GIB_Argd(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->argv[(x)] : NULL) #define GIB_Argd(x) ((x) < cbuf_active->args->argc ? cbuf_active->args->argv[(x)] : NULL)
#define GIB_USAGE(x) (Cbuf_Error ("syntax", "%s: invalid syntax\nusage: %s %s", GIB_Argv(0), GIB_Argv(0), (x)))
void GIB_Arg_Strip_Delim (unsigned int arg); void GIB_Arg_Strip_Delim (unsigned int arg);
void GIB_Return (const char *str); void GIB_Return (const char *str);
void GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type); void GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type);

View file

@ -67,3 +67,9 @@ GIB_Buffer_Destruct (struct cbuf_s *cbuf)
Hash_DelTable (GIB_DATA(cbuf)->locals); Hash_DelTable (GIB_DATA(cbuf)->locals);
free (cbuf->data); free (cbuf->data);
} }
void
GIB_Buffer_Reset (struct cbuf_s *cbuf)
{
GIB_DATA (cbuf)->ret.waiting = GIB_DATA (cbuf)->ret.available = false;
}

View file

@ -446,7 +446,7 @@ GIB_Function_Export_f (void)
if (GIB_Argc() < 2) if (GIB_Argc() < 2)
Cbuf_Error ("syntax", Cbuf_Error ("syntax",
"function::export: invalid syntax\n" "function::export: invalid syntax\n"
"usage: funciton::export function1 function2 function3 [...]"); "usage: function::export function1 function2 function3 [...]");
for (i = 1; i < GIB_Argc(); i++) { for (i = 1; i < GIB_Argc(); i++) {
if (!(f = GIB_Function_Find (GIB_Argv (i)))) if (!(f = GIB_Function_Find (GIB_Argv (i))))
Cbuf_Error ("function", "function::export: function '%s' not found", GIB_Argv (i)); Cbuf_Error ("function", "function::export: function '%s' not found", GIB_Argv (i));
@ -479,6 +479,28 @@ GIB_String_Equal_f (void)
GIB_Return (va("%i", !strcmp(GIB_Argv(1), GIB_Argv(2)))); GIB_Return (va("%i", !strcmp(GIB_Argv(1), GIB_Argv(2))));
} }
void
GIB_String_Findsub_f (void)
{
char *haystack, *res;
unsigned int pos;
if (GIB_Argc() < 3 || GIB_Argc() > 4) {
GIB_USAGE ("string substr [start_pos]");
return;
}
haystack = GIB_Argv(1);
pos = atoi(GIB_Argv(3));
if (pos < 0)
Cbuf_Error ("string","%s: start position must be >= 0.", GIB_Argv(0));
else if (pos >= strlen (haystack))
GIB_Return ("-1");
else if ((res = strstr(haystack+pos, GIB_Argv(2))))
GIB_Return (va("%i", res - haystack));
else
GIB_Return ("-1");
}
void void
GIB_Thread_Create_f (void) GIB_Thread_Create_f (void)
{ {
@ -800,6 +822,7 @@ GIB_Builtin_Init (qboolean sandbox)
GIB_Builtin_Add ("break", GIB_Break_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("break", GIB_Break_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("string::length", GIB_String_Length_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("string::length", GIB_String_Length_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("string::equal", GIB_String_Equal_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("string::equal", GIB_String_Equal_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("string::findsub", GIB_String_Findsub_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("file::read", GIB_File_Read_f, GIB_BUILTIN_NORMAL); GIB_Builtin_Add ("file::read", GIB_File_Read_f, GIB_BUILTIN_NORMAL);

View file

@ -59,6 +59,7 @@ cbuf_interpreter_t gib_interp = {
GIB_Parse_Execute_Line, GIB_Parse_Execute_Line,
GIB_Buffer_Construct, GIB_Buffer_Construct,
GIB_Buffer_Destruct, GIB_Buffer_Destruct,
GIB_Buffer_Reset
}; };
/* /*

View file

@ -196,6 +196,8 @@ Cbuf_Execute_Stack (cbuf_t *cbuf)
Cbuf_DeleteStack (cbuf->down); Cbuf_DeleteStack (cbuf->down);
cbuf->down = 0; cbuf->down = 0;
} }
if (cbuf->interpreter->reset)
cbuf->interpreter->reset (cbuf);
} }
void void

View file

@ -178,4 +178,5 @@ cbuf_interpreter_t id_interp = {
COM_execute_line, COM_execute_line,
NULL, NULL,
NULL, NULL,
NULL
}; };