mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 23:52:22 +00:00
Various cleanups and bugfixes. Added proper line number reporting to
errors. A few new builtin functions, such as slice::find and thread::list.
This commit is contained in:
parent
2cb4c7836d
commit
3c522a83bc
24 changed files with 456 additions and 217 deletions
|
@ -55,7 +55,8 @@ typedef struct cbuf_s {
|
||||||
CBUF_STATE_NORMAL = 0, // Normal condition
|
CBUF_STATE_NORMAL = 0, // Normal condition
|
||||||
CBUF_STATE_WAIT, // Buffer is stalled until next frame
|
CBUF_STATE_WAIT, // Buffer is stalled until next frame
|
||||||
CBUF_STATE_ERROR, // An unrecoverable error occured
|
CBUF_STATE_ERROR, // An unrecoverable error occured
|
||||||
CBUF_STATE_STACK // A buffer has been added to the stack
|
CBUF_STATE_STACK, // A buffer has been added to the stack
|
||||||
|
CBUF_STATE_JUNK // Buffer can be freed or reused
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
qboolean strict; // Should we tolerate unknown commands?
|
qboolean strict; // Should we tolerate unknown commands?
|
||||||
|
@ -67,6 +68,7 @@ typedef struct cbuf_s {
|
||||||
typedef struct cbuf_interpreter_s {
|
typedef struct cbuf_interpreter_s {
|
||||||
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);
|
||||||
void (*add) (struct cbuf_s *cbuf, const char *str);
|
void (*add) (struct cbuf_s *cbuf, const char *str);
|
||||||
void (*insert) (struct cbuf_s *cbuf, const char *str);
|
void (*insert) (struct cbuf_s *cbuf, const char *str);
|
||||||
void (*execute) (struct cbuf_s *cbuf);
|
void (*execute) (struct cbuf_s *cbuf);
|
||||||
|
@ -83,12 +85,12 @@ cbuf_t * Cbuf_New (cbuf_interpreter_t *interp);
|
||||||
|
|
||||||
void Cbuf_Delete (cbuf_t *cbuf);
|
void Cbuf_Delete (cbuf_t *cbuf);
|
||||||
void Cbuf_DeleteStack (cbuf_t *stack);
|
void Cbuf_DeleteStack (cbuf_t *stack);
|
||||||
void Cbuf_PushStack (cbuf_t *new);
|
void Cbuf_Reset (cbuf_t *cbuf);
|
||||||
|
cbuf_t *Cbuf_PushStack (cbuf_interpreter_t *interp);
|
||||||
void Cbuf_AddText (cbuf_t *cbuf, const char *text);
|
void Cbuf_AddText (cbuf_t *cbuf, const char *text);
|
||||||
void Cbuf_InsertText (cbuf_t *cbuf, const char *text);
|
void Cbuf_InsertText (cbuf_t *cbuf, const char *text);
|
||||||
void Cbuf_Execute (cbuf_t *cbuf);
|
void Cbuf_Execute (cbuf_t *cbuf);
|
||||||
void Cbuf_Execute_Stack (cbuf_t *cbuf);
|
void Cbuf_Execute_Stack (cbuf_t *cbuf);
|
||||||
void Cbuf_Execute_Sets (cbuf_t *cbuf);
|
void Cbuf_Execute_Sets (cbuf_t *cbuf);
|
||||||
void Cbuf_Error (const char *class, const char *fmt, ...);
|
|
||||||
|
|
||||||
#endif//__QF_cbuf_h
|
#endif//__QF_cbuf_h
|
||||||
|
|
|
@ -57,7 +57,7 @@ int Cmd_Argc (void);
|
||||||
const char *Cmd_Argv (int arg);
|
const char *Cmd_Argv (int arg);
|
||||||
const char *Cmd_Args (int start);
|
const char *Cmd_Args (int start);
|
||||||
struct cbuf_args_s;
|
struct cbuf_args_s;
|
||||||
void Cmd_Command (struct cbuf_args_s *args);
|
int Cmd_Command (struct cbuf_args_s *args);
|
||||||
int Cmd_ExecuteString (const char *text, cmd_source_t src);
|
int Cmd_ExecuteString (const char *text, cmd_source_t src);
|
||||||
struct cbuf_s;
|
struct cbuf_s;
|
||||||
void Cmd_StuffCmds (struct cbuf_s *cbuf);
|
void Cmd_StuffCmds (struct cbuf_s *cbuf);
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __gib_buffer_h
|
||||||
|
#define __gib_buffer_h
|
||||||
|
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/gib_tree.h"
|
#include "QF/gib_tree.h"
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
|
@ -36,7 +39,13 @@
|
||||||
#define GIB_DATA(buffer) ((gib_buffer_data_t *)(buffer->data))
|
#define GIB_DATA(buffer) ((gib_buffer_data_t *)(buffer->data))
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct gib_script_s {
|
||||||
|
const char *text, *file;
|
||||||
|
unsigned int refs;
|
||||||
|
} gib_script_t;
|
||||||
|
|
||||||
typedef struct gib_buffer_data_s {
|
typedef struct gib_buffer_data_s {
|
||||||
|
struct gib_script_s *script;
|
||||||
struct gib_tree_s *program, *ip;
|
struct gib_tree_s *program, *ip;
|
||||||
struct dstring_s *arg_composite;
|
struct dstring_s *arg_composite;
|
||||||
qboolean done, waitret;
|
qboolean done, waitret;
|
||||||
|
@ -51,13 +60,18 @@ typedef struct gib_buffer_data_s {
|
||||||
struct hashtab_s *globals; // Current domain
|
struct hashtab_s *globals; // Current domain
|
||||||
} gib_buffer_data_t;
|
} gib_buffer_data_t;
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
void GIB_Buffer_Set_Program (cbuf_t *cbuf, gib_tree_t *program);
|
void GIB_Buffer_Set_Program (cbuf_t *cbuf, gib_tree_t *program);
|
||||||
void GIB_Buffer_Add (cbuf_t *cbuf, const char *str);
|
void GIB_Buffer_Add (cbuf_t *cbuf, const char *str);
|
||||||
void GIB_Buffer_Insert (cbuf_t *cbuf, const char *str);
|
void GIB_Buffer_Insert (cbuf_t *cbuf, const char *str);
|
||||||
void GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf);
|
void GIB_Buffer_Push_Sstack (struct cbuf_s *cbuf);
|
||||||
void GIB_Buffer_Pop_Sstack (struct cbuf_s *cbuf);
|
void GIB_Buffer_Pop_Sstack (struct cbuf_s *cbuf);
|
||||||
dstring_t *GIB_Buffer_Dsarray_Get (struct cbuf_s *cbuf);
|
dstring_t *GIB_Buffer_Dsarray_Get (struct cbuf_s *cbuf);
|
||||||
|
void GIB_Buffer_Error (cbuf_t *cbuf, const char *type, const char *fmt, va_list args);
|
||||||
|
|
||||||
extern struct cbuf_interpreter_s gib_interp;
|
extern struct cbuf_interpreter_s gib_interp;
|
||||||
|
|
||||||
|
#endif // __gib_buffer_h
|
||||||
|
|
|
@ -45,10 +45,13 @@ extern char gib_null_string[];
|
||||||
#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_Argm(x) ((x) < cbuf_active->args->argc ? (gib_tree_t *)cbuf_active->args->argm[(x)] : NULL)
|
#define GIB_Argm(x) ((x) < cbuf_active->args->argc ? (gib_tree_t *)cbuf_active->args->argm[(x)] : NULL)
|
||||||
|
|
||||||
#define GIB_USAGE(x) (Cbuf_Error ("syntax", "%s: invalid syntax\nusage: %s %s", GIB_Argv(0), GIB_Argv(0), (x)))
|
#define GIB_USAGE(x) (GIB_Error ("syntax", "%s: invalid syntax\nusage: %s %s", GIB_Argv(0), GIB_Argv(0), (x)))
|
||||||
|
|
||||||
|
#define GIB_CanReturn() (GIB_DATA(cbuf_active)->waitret)
|
||||||
|
|
||||||
void GIB_Arg_Strip_Delim (unsigned int arg);
|
void GIB_Arg_Strip_Delim (unsigned int arg);
|
||||||
dstring_t *GIB_Return (const char *str);
|
dstring_t *GIB_Return (const char *str);
|
||||||
|
void GIB_Error (const char *type, const char *fmt, ...);
|
||||||
void GIB_Builtin_Add (const char *name, void (*func) (void));
|
void GIB_Builtin_Add (const char *name, void (*func) (void));
|
||||||
gib_builtin_t *GIB_Builtin_Find (const char *name);
|
gib_builtin_t *GIB_Builtin_Find (const char *name);
|
||||||
void GIB_Builtin_Init (qboolean sandbox);
|
void GIB_Builtin_Init (qboolean sandbox);
|
||||||
|
|
|
@ -35,16 +35,18 @@
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
#include "QF/gib_tree.h"
|
#include "QF/gib_tree.h"
|
||||||
|
#include "QF/gib_buffer.h"
|
||||||
|
|
||||||
typedef struct gib_function_s {
|
typedef struct gib_function_s {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct gib_script_s *script;
|
||||||
struct dstring_s *text;
|
struct dstring_s *text;
|
||||||
struct gib_tree_s *program;
|
struct gib_tree_s *program;
|
||||||
struct hashtab_s *globals;
|
struct hashtab_s *globals;
|
||||||
qboolean exported;
|
qboolean exported;
|
||||||
} gib_function_t;
|
} gib_function_t;
|
||||||
|
|
||||||
void GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, hashtab_t *globals);
|
void GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, gib_script_t *script, hashtab_t *globals);
|
||||||
gib_function_t *GIB_Function_Find (const char *name);
|
gib_function_t *GIB_Function_Find (const char *name);
|
||||||
void GIB_Function_Prepare_Args (cbuf_t *cbuf, dstring_t **args, unsigned int argc);
|
void GIB_Function_Prepare_Args (cbuf_t *cbuf, dstring_t **args, unsigned int argc);
|
||||||
void GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, dstring_t **args, unsigned int argc);
|
void GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, dstring_t **args, unsigned int argc);
|
||||||
|
|
|
@ -39,7 +39,9 @@ char GIB_Parse_Match_Index (const char *str, unsigned int *i);
|
||||||
char GIB_Parse_Match_Paren (const char *str, unsigned int *i);
|
char GIB_Parse_Match_Paren (const char *str, unsigned int *i);
|
||||||
char GIB_Parse_Match_Var (const char *str, unsigned int *i);
|
char GIB_Parse_Match_Var (const char *str, unsigned int *i);
|
||||||
|
|
||||||
gib_tree_t *GIB_Parse_Lines (const char *program, unsigned int flags);
|
gib_tree_t *GIB_Parse_Lines (const char *program, unsigned int pofs, gib_tree_flags_t flags);
|
||||||
gib_tree_t *GIB_Parse_Embedded (const char *program, unsigned int flags, gib_tree_t **embedded);
|
gib_tree_t *GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t flags, gib_tree_t **embedded);
|
||||||
|
|
||||||
extern qboolean gib_parse_error;
|
extern qboolean gib_parse_error;
|
||||||
|
const char *GIB_Parse_ErrorMsg (void);
|
||||||
|
unsigned int GIB_Parse_ErrorPos (void);
|
||||||
|
|
|
@ -38,6 +38,7 @@ typedef struct gib_thread_s {
|
||||||
unsigned long int id;
|
unsigned long int id;
|
||||||
struct cbuf_s *cbuf;
|
struct cbuf_s *cbuf;
|
||||||
struct gib_thread_s *prev, *next;
|
struct gib_thread_s *prev, *next;
|
||||||
|
qboolean trash;
|
||||||
} gib_thread_t;
|
} gib_thread_t;
|
||||||
|
|
||||||
typedef struct gib_event_s {
|
typedef struct gib_event_s {
|
||||||
|
@ -55,4 +56,6 @@ int GIB_Event_Register (const char *name, gib_function_t *func);
|
||||||
void GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...);
|
void GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...);
|
||||||
void GIB_Event_Init (void);
|
void GIB_Event_Init (void);
|
||||||
|
|
||||||
|
extern gib_thread_t *gib_threads;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,23 +33,30 @@
|
||||||
#define __GIB_TREE_H
|
#define __GIB_TREE_H
|
||||||
|
|
||||||
#define TREE_NORMAL 0 // Normal node
|
#define TREE_NORMAL 0 // Normal node
|
||||||
|
// Flags for tokens
|
||||||
#define TREE_CONCAT 1 // Concatenate to previous
|
#define TREE_CONCAT 1 // Concatenate to previous
|
||||||
#define TREE_EMBED 2 // Embedded command (expect return value)
|
#define TREE_P_EMBED 2 // Embedded stuff needs to be processed
|
||||||
#define TREE_P_EMBED 4 // Embedded stuff needs to be processed
|
#define TREE_ASPLIT 4 // Token is the name of an array that should be split
|
||||||
#define TREE_ASPLIT 8 // Token is the name of an array that should be split
|
// Flags for lines
|
||||||
#define TREE_FUNC 16 // Node is the first in a function
|
#define TREE_COND 1 // Conditional jump (if or while command)
|
||||||
#define TREE_COND 32 // Conditional jump (if or while command)
|
#define TREE_NOT 2 // Invert condition
|
||||||
#define TREE_NOT 64
|
#define TREE_END 4 // Node ends a loop or conditional
|
||||||
#define TREE_END 128 // Node ends a loop or conditional
|
#define TREE_FORNEXT 8 // For loop is starting again
|
||||||
#define TREE_FORNEXT 256 // For loop is starting again
|
#define TREE_EMBED 16 // Embedded command (expect return value)
|
||||||
|
|
||||||
|
typedef char gib_tree_flags_t;
|
||||||
|
|
||||||
typedef struct gib_tree_s {
|
typedef struct gib_tree_s {
|
||||||
const char *str;
|
const char *str;
|
||||||
char delim;
|
char delim;
|
||||||
|
unsigned int start, end, refs;
|
||||||
|
gib_tree_flags_t flags;
|
||||||
struct gib_tree_s *children, *next, *jump;
|
struct gib_tree_s *children, *next, *jump;
|
||||||
unsigned int flags, start, end, refs;
|
|
||||||
} gib_tree_t;
|
} gib_tree_t;
|
||||||
|
|
||||||
gib_tree_t *GIB_Tree_New (unsigned int flags);
|
gib_tree_t *GIB_Tree_New (gib_tree_flags_t flags);
|
||||||
void GIB_Tree_Free_Recursive (gib_tree_t *tree);
|
void GIB_Tree_Free_Recursive (gib_tree_t *tree);
|
||||||
|
void GIB_Tree_Ref (gib_tree_t **tp);
|
||||||
|
void GIB_Tree_Unref (gib_tree_t **tp);
|
||||||
|
|
||||||
#endif /* __GIB_TREE_H */
|
#endif /* __GIB_TREE_H */
|
||||||
|
|
|
@ -345,11 +345,8 @@ static void
|
||||||
C_GIB_Print_Center_f (void)
|
C_GIB_Print_Center_f (void)
|
||||||
{
|
{
|
||||||
if (GIB_Argc () != 2) {
|
if (GIB_Argc () != 2) {
|
||||||
Cbuf_Error ("syntax",
|
GIB_USAGE ("text");
|
||||||
"print::center: invalid syntax\n"
|
} else
|
||||||
"usage: print::center text");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SCR_CenterPrint (GIB_Argv(1));
|
SCR_CenterPrint (GIB_Argv(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,9 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "QF/sys.h"
|
||||||
#include "QF/dstring.h"
|
#include "QF/dstring.h"
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/hash.h"
|
#include "QF/hash.h"
|
||||||
|
@ -65,9 +67,12 @@ GIB_Buffer_Destruct (struct cbuf_s *cbuf)
|
||||||
dstring_delete (g->arg_composite);
|
dstring_delete (g->arg_composite);
|
||||||
if (g->locals)
|
if (g->locals)
|
||||||
Hash_DelTable (g->locals);
|
Hash_DelTable (g->locals);
|
||||||
if (g->program) {
|
if (g->program)
|
||||||
g->program->refs--;
|
GIB_Tree_Unref (&g->program);
|
||||||
GIB_Tree_Free_Recursive (g->program);
|
if (g->script && !(--g->script->refs)) {
|
||||||
|
free ((void *)g->script->text);
|
||||||
|
free ((void *)g->script->file);
|
||||||
|
free (g->script);
|
||||||
}
|
}
|
||||||
for (i = 0; i < g->stack.size; i++) {
|
for (i = 0; i < g->stack.size; i++) {
|
||||||
for (j = 0; j < g->stack.values[i].realsize; j++)
|
for (j = 0; j < g->stack.values[i].realsize; j++)
|
||||||
|
@ -80,12 +85,43 @@ GIB_Buffer_Destruct (struct cbuf_s *cbuf)
|
||||||
free (cbuf->data);
|
free (cbuf->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Buffer_Reset (struct cbuf_s *cbuf)
|
||||||
|
{
|
||||||
|
gib_buffer_data_t *g = GIB_DATA(cbuf);
|
||||||
|
|
||||||
|
if (g->locals)
|
||||||
|
Hash_FlushTable (g->locals);
|
||||||
|
g->globals = gib_globals;
|
||||||
|
if (g->program)
|
||||||
|
GIB_Tree_Unref (&g->program);
|
||||||
|
if (g->script && !(--g->script->refs)) {
|
||||||
|
free ((void *) g->script->text);
|
||||||
|
free ((void *) g->script->file);
|
||||||
|
free (g->script);
|
||||||
|
}
|
||||||
|
g->script = 0;
|
||||||
|
g->stack.p = 0;
|
||||||
|
g->waitret = g->done = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Buffer_Set_Program (cbuf_t *cbuf, gib_tree_t *program)
|
GIB_Buffer_Set_Program (cbuf_t *cbuf, gib_tree_t *program)
|
||||||
{
|
{
|
||||||
GIB_DATA(cbuf)->program = program;
|
GIB_DATA(cbuf)->program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
GIB_Buffer_Get_Line_Num (const char *program, unsigned int pos)
|
||||||
|
{
|
||||||
|
unsigned int i, line;
|
||||||
|
for (i = 0, line = 1; i < pos; i++)
|
||||||
|
if (program[i] == '\n')
|
||||||
|
line++;
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GIB_Buffer_Add (cbuf_t *cbuf, const char *str)
|
GIB_Buffer_Add (cbuf_t *cbuf, const char *str)
|
||||||
{
|
{
|
||||||
|
@ -97,9 +133,14 @@ GIB_Buffer_Add (cbuf_t *cbuf, const char *str)
|
||||||
save = &cur->next;
|
save = &cur->next;
|
||||||
} else
|
} else
|
||||||
save = &g->program;
|
save = &g->program;
|
||||||
*save = GIB_Parse_Lines (str, TREE_NORMAL);
|
if (!(*save = GIB_Parse_Lines (str, 0, TREE_NORMAL)))
|
||||||
if (gib_parse_error)
|
Sys_Printf (
|
||||||
Cbuf_Error ("parse", "Parse error in program!");
|
"-----------------\n"
|
||||||
|
"|GIB Parse Error|\n"
|
||||||
|
"-----------------\n"
|
||||||
|
"Parse error while adding text to GIB buffer.\n"
|
||||||
|
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str, GIB_Parse_ErrorPos()), GIB_Parse_ErrorMsg()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -108,17 +149,21 @@ GIB_Buffer_Insert (cbuf_t *cbuf, const char *str)
|
||||||
gib_buffer_data_t *g = GIB_DATA (cbuf);
|
gib_buffer_data_t *g = GIB_DATA (cbuf);
|
||||||
gib_tree_t *lines, *cur;
|
gib_tree_t *lines, *cur;
|
||||||
|
|
||||||
if ((lines = GIB_Parse_Lines (str, TREE_NORMAL))) {
|
if ((lines = GIB_Parse_Lines (str, 0, TREE_NORMAL))) {
|
||||||
for (cur = lines; cur; cur = cur->next);
|
for (cur = lines; cur; cur = cur->next);
|
||||||
//if (g->ip) { // This buffer is already running!
|
//if (g->ip) { // This buffer is already running!
|
||||||
|
|
||||||
if (g->program)
|
GIB_Tree_Unref (&g->program);
|
||||||
g->program->refs--;
|
|
||||||
cur->next = g->program;
|
cur->next = g->program;
|
||||||
g->program = lines;
|
g->program = lines;
|
||||||
}
|
} else
|
||||||
if (gib_parse_error)
|
Sys_Printf (
|
||||||
Cbuf_Error ("parse", "Parse error in program!");
|
"-----------------\n"
|
||||||
|
"|GIB Parse Error|\n"
|
||||||
|
"-----------------\n"
|
||||||
|
"Parse error while inserting text into GIB buffer.\n"
|
||||||
|
"Line %u: %s\n", GIB_Buffer_Get_Line_Num (str, GIB_Parse_ErrorPos()), GIB_Parse_ErrorMsg()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -153,9 +198,71 @@ GIB_Buffer_Dsarray_Get (struct cbuf_s *cbuf)
|
||||||
return vals->dstrs[vals->size-1];
|
return vals->dstrs[vals->size-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
GIB_Buffer_Get_Line_Info (cbuf_t *cbuf, char **line)
|
||||||
|
{
|
||||||
|
const char *text;
|
||||||
|
unsigned int ofs, i, start, linenum;
|
||||||
|
|
||||||
|
// Do we have a copy of the original program this buffer comes from?
|
||||||
|
if (GIB_DATA(cbuf)->script) {
|
||||||
|
text = GIB_DATA(cbuf)->script->text;
|
||||||
|
for (ofs = GIB_DATA(cbuf)->ip->start, start = 0, i = 0, linenum = 1; i <= ofs; i++)
|
||||||
|
if (text[i] == '\n') {
|
||||||
|
start = i+1;
|
||||||
|
linenum++;
|
||||||
|
}
|
||||||
|
while (text[i] != '\n')
|
||||||
|
i++;
|
||||||
|
*line = malloc (i - start + 1);
|
||||||
|
memcpy (*line, text+start, i - start);
|
||||||
|
(*line)[i-start] = 0;
|
||||||
|
return linenum;
|
||||||
|
} else {
|
||||||
|
*line = strdup (GIB_DATA(cbuf)->ip->str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Buffer_Error (cbuf_t *cbuf, const char *type, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
int linenum;
|
||||||
|
dstring_t *message = dstring_newstr();
|
||||||
|
dvsprintf (message, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
Sys_Printf ( "---------------------\n"
|
||||||
|
"|GIB Execution Error|\n"
|
||||||
|
"---------------------\n"
|
||||||
|
"Type: %s\n",
|
||||||
|
type
|
||||||
|
);
|
||||||
|
if ((linenum = GIB_Buffer_Get_Line_Info (cbuf, &line)) != -1)
|
||||||
|
Sys_Printf ( "%s:%i: %s\n"
|
||||||
|
"-->%s\n",
|
||||||
|
GIB_DATA(cbuf)->script->file,
|
||||||
|
linenum,
|
||||||
|
message->str,
|
||||||
|
line
|
||||||
|
);
|
||||||
|
else
|
||||||
|
Sys_Printf ( "%s\n"
|
||||||
|
"-->%s\n",
|
||||||
|
message->str,
|
||||||
|
line
|
||||||
|
);
|
||||||
|
cbuf->state = CBUF_STATE_ERROR;
|
||||||
|
dstring_delete (message);
|
||||||
|
free (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cbuf_interpreter_t gib_interp = {
|
cbuf_interpreter_t gib_interp = {
|
||||||
GIB_Buffer_Construct,
|
GIB_Buffer_Construct,
|
||||||
GIB_Buffer_Destruct,
|
GIB_Buffer_Destruct,
|
||||||
|
GIB_Buffer_Reset,
|
||||||
GIB_Buffer_Add,
|
GIB_Buffer_Add,
|
||||||
GIB_Buffer_Insert,
|
GIB_Buffer_Insert,
|
||||||
GIB_Execute,
|
GIB_Execute,
|
||||||
|
|
|
@ -134,6 +134,16 @@ GIB_Return (const char *str)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Error (const char *type, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start (args, fmt);
|
||||||
|
GIB_Buffer_Error (cbuf_active, type, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GIB Builtin functions
|
GIB Builtin functions
|
||||||
|
|
||||||
|
@ -150,14 +160,14 @@ GIB_Function_f (void)
|
||||||
// Is the function program already tokenized?
|
// Is the function program already tokenized?
|
||||||
if (GIB_Argm (2)->delim != '{') {
|
if (GIB_Argm (2)->delim != '{') {
|
||||||
// Parse on the fly
|
// Parse on the fly
|
||||||
if (!(program = GIB_Parse_Lines (GIB_Argv(2), TREE_NORMAL))) {
|
if (!(program = GIB_Parse_Lines (GIB_Argv(2), 0, TREE_NORMAL))) {
|
||||||
// Error!
|
// Error!
|
||||||
Cbuf_Error ("parse", "Parse error while defining function '%s'.", GIB_Argv(1));
|
GIB_Error ("parse", "Parse error while defining function '%s'.", GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
program = GIB_Argm (2)->children;
|
program = GIB_Argm (2)->children;
|
||||||
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2), program, GIB_DATA(cbuf_active)->globals);
|
GIB_Function_Define (GIB_Argv(1), GIB_Argv(2), program, GIB_DATA(cbuf_active)->script, GIB_DATA(cbuf_active)->globals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,6 +227,15 @@ GIB_Domain_f (void)
|
||||||
GIB_DATA(cbuf_active)->globals = GIB_Domain_Get (GIB_Argv(1));
|
GIB_DATA(cbuf_active)->globals = GIB_Domain_Get (GIB_Argv(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GIB_Domain_Clear_f (void)
|
||||||
|
{
|
||||||
|
if (GIB_Argc() != 2)
|
||||||
|
GIB_USAGE ("domain");
|
||||||
|
else
|
||||||
|
Hash_FlushTable (GIB_Domain_Get (GIB_Argv(2)));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Return_f (void)
|
GIB_Return_f (void)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +278,7 @@ static void
|
||||||
GIB_Break_f (void)
|
GIB_Break_f (void)
|
||||||
{
|
{
|
||||||
if (!GIB_DATA(cbuf_active)->ip->jump) {
|
if (!GIB_DATA(cbuf_active)->ip->jump) {
|
||||||
Cbuf_Error ("loop", "Break command attempted outside of a loop.");
|
GIB_Error ("loop", "Break command attempted outside of a loop.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) // In a for loop?
|
if (!GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) // In a for loop?
|
||||||
|
@ -278,7 +297,7 @@ static void
|
||||||
GIB_Continue_f (void)
|
GIB_Continue_f (void)
|
||||||
{
|
{
|
||||||
if (!GIB_DATA(cbuf_active)->ip->jump) {
|
if (!GIB_DATA(cbuf_active)->ip->jump) {
|
||||||
Cbuf_Error ("loop", "Continue command attempted outside of a loop.");
|
GIB_Error ("loop", "Continue command attempted outside of a loop.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) {
|
if (GIB_DATA(cbuf_active)->ip->jump->flags & TREE_COND) {
|
||||||
|
@ -319,13 +338,18 @@ GIB_Function_Export_f (void)
|
||||||
GIB_USAGE ("function1 [function2 function3 ...]");
|
GIB_USAGE ("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));
|
GIB_Error ("function", "%s: function '%s' not found.", GIB_Argv(0), GIB_Argv (i));
|
||||||
else if (!f->exported) {
|
else if (!f->exported) {
|
||||||
|
if (Cmd_Exists (f->name)) {
|
||||||
|
GIB_Error ("export", "%s: A console command with the name '%s' already exists.", GIB_Argv(0), GIB_Argv(i));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
Cmd_AddCommand (f->name, GIB_Runexported_f, "Exported GIB function.");
|
Cmd_AddCommand (f->name, GIB_Runexported_f, "Exported GIB function.");
|
||||||
f->exported = true;
|
f->exported = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Length_f (void)
|
GIB_Length_f (void)
|
||||||
|
@ -374,24 +398,22 @@ GIB_Slice_f (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
static void
|
static void
|
||||||
GIB_Find_f (void)
|
GIB_Slice_Find_f (void)
|
||||||
{
|
{
|
||||||
dstring_t *ret;
|
char *res;
|
||||||
char *haystack, *res;
|
|
||||||
if (GIB_Argc() != 3) {
|
if (GIB_Argc() != 3) {
|
||||||
GIB_USAGE ("haystack needle");
|
GIB_USAGE ("haystack needle");
|
||||||
return;
|
return;
|
||||||
|
} else if (!GIB_CanReturn ())
|
||||||
|
return;
|
||||||
|
else if ((res = strstr(GIB_Argv(1), GIB_Argv(2)))) {
|
||||||
|
dsprintf (GIB_Return (0), "%lu", (unsigned long int)(res - GIB_Argv(1)));
|
||||||
|
dsprintf (GIB_Return (0), "%lu", (unsigned long int)(res - GIB_Argv(1))+strlen (GIB_Argv(2)));
|
||||||
}
|
}
|
||||||
haystack = GIB_Argv(1);
|
|
||||||
if ((res = strstr(haystack, GIB_Argv(2)))) {
|
|
||||||
if ((ret = GIB_Return (0)))
|
|
||||||
dsprintf (ret, "%lu", (unsigned long int)(res - haystack));
|
|
||||||
} else
|
|
||||||
GIB_Return ("-1");
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Split_f (void)
|
GIB_Split_f (void)
|
||||||
|
@ -431,7 +453,7 @@ GIB_Regex_Match_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
||||||
Cbuf_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
||||||
else if (regexec(reg, GIB_Argv(1), 0, 0, 0))
|
else if (regexec(reg, GIB_Argv(1), 0, 0, 0))
|
||||||
GIB_Return ("0");
|
GIB_Return ("0");
|
||||||
else
|
else
|
||||||
|
@ -454,7 +476,7 @@ GIB_Regex_Replace_f (void)
|
||||||
len = strlen (GIB_Argv(4));
|
len = strlen (GIB_Argv(4));
|
||||||
|
|
||||||
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
||||||
Cbuf_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
||||||
else if (strchr(GIB_Argv(3), 'g'))
|
else if (strchr(GIB_Argv(3), 'g'))
|
||||||
while (!regexec(reg, GIB_Argv(1)+ofs, 10, match, ofs > 0 ? REG_NOTBOL : 0) && match[0].rm_eo)
|
while (!regexec(reg, GIB_Argv(1)+ofs, 10, match, ofs > 0 ? REG_NOTBOL : 0) && match[0].rm_eo)
|
||||||
ofs += GIB_Regex_Apply_Match (match, GIB_Argd(1), ofs, GIB_Argv(4));
|
ofs += GIB_Regex_Apply_Match (match, GIB_Argd(1), ofs, GIB_Argv(4));
|
||||||
|
@ -468,22 +490,20 @@ GIB_Regex_Extract_f (void)
|
||||||
{
|
{
|
||||||
regex_t *reg;
|
regex_t *reg;
|
||||||
regmatch_t *match;
|
regmatch_t *match;
|
||||||
dstring_t *ret;
|
|
||||||
int i;
|
int i;
|
||||||
char o;
|
char o;
|
||||||
|
|
||||||
if (GIB_Argc() != 4) {
|
if (GIB_Argc() != 4) {
|
||||||
GIB_USAGE ("string regex options");
|
GIB_USAGE ("string regex options");
|
||||||
return;
|
return;
|
||||||
}
|
} else if (!GIB_CanReturn ())
|
||||||
|
return;
|
||||||
match = calloc (32, sizeof(regmatch_t));
|
match = calloc (32, sizeof(regmatch_t));
|
||||||
|
|
||||||
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
if (!(reg = GIB_Regex_Compile (GIB_Argv(2), REG_EXTENDED | GIB_Regex_Translate_Options (GIB_Argv(3)))))
|
||||||
Cbuf_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
GIB_Error ("regex", "%s: %s", GIB_Argv(0), GIB_Regex_Error ());
|
||||||
else if (!regexec(reg, GIB_Argv(1), 32, match, 0) && match[0].rm_eo) {
|
else if (!regexec(reg, GIB_Argv(1), 32, match, 0) && match[0].rm_eo) {
|
||||||
if (!(ret = GIB_Return(0)))
|
dsprintf (GIB_Return (0), "%lu", (unsigned long) match[0].rm_eo);
|
||||||
return;
|
|
||||||
dsprintf (ret, "%lu", (unsigned long) match[0].rm_eo);
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
if (match[i].rm_so != -1) {
|
if (match[i].rm_so != -1) {
|
||||||
o = GIB_Argv(1)[match[i].rm_eo];
|
o = GIB_Argv(1)[match[i].rm_eo];
|
||||||
|
@ -492,26 +512,24 @@ GIB_Regex_Extract_f (void)
|
||||||
GIB_Argv(1)[match[i].rm_eo] = o;
|
GIB_Argv(1)[match[i].rm_eo] = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
GIB_Return ("-1");
|
|
||||||
free (match);
|
free (match);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Thread_Create_f (void)
|
GIB_Thread_Create_f (void)
|
||||||
{
|
{
|
||||||
dstring_t *ret;
|
|
||||||
gib_function_t *f;
|
gib_function_t *f;
|
||||||
if (GIB_Argc() < 2)
|
if (GIB_Argc() < 2)
|
||||||
GIB_USAGE ("function [arg1 arg2 ...]");
|
GIB_USAGE ("function [arg1 arg2 ...]");
|
||||||
else if (!(f = GIB_Function_Find (GIB_Argv(1))))
|
else if (!(f = GIB_Function_Find (GIB_Argv(1))))
|
||||||
Cbuf_Error ("function", "thread::create: no function named '%s' exists.", GIB_Argv(1));
|
GIB_Error ("function", "%s: no function named '%s' exists.", GIB_Argv(0), GIB_Argv(1));
|
||||||
else {
|
else {
|
||||||
gib_thread_t *thread = GIB_Thread_New ();
|
gib_thread_t *thread = GIB_Thread_New ();
|
||||||
GIB_Function_Execute (thread->cbuf, f, cbuf_active->args->argv+1, cbuf_active->args->argc-1);
|
GIB_Function_Execute (thread->cbuf, f, cbuf_active->args->argv+1, cbuf_active->args->argc-1);
|
||||||
GIB_Thread_Add (thread);
|
GIB_Thread_Add (thread);
|
||||||
if ((ret = GIB_Return (0)))
|
if (GIB_CanReturn ())
|
||||||
dsprintf (ret, "%lu", thread->id);
|
dsprintf (GIB_Return(0), "%lu", thread->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,12 +540,30 @@ GIB_Thread_Kill_f (void)
|
||||||
GIB_USAGE ("id");
|
GIB_USAGE ("id");
|
||||||
else {
|
else {
|
||||||
gib_thread_t *thread;
|
gib_thread_t *thread;
|
||||||
|
cbuf_t *cur;
|
||||||
unsigned long int id = strtoul (GIB_Argv(1), 0, 10);
|
unsigned long int id = strtoul (GIB_Argv(1), 0, 10);
|
||||||
thread = GIB_Thread_Find (id);
|
thread = GIB_Thread_Find (id);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
Cbuf_Error ("thread", "thread.kill: thread %lu does not exist.", id);
|
GIB_Error ("thread", "%s: thread %lu does not exist.", GIB_Argv(0), id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
thread->trash = true;
|
||||||
|
// Set error condition on the top of the stack so the thread will exit if currently running
|
||||||
|
for (cur = thread->cbuf; cur->down && cur->down->state != CBUF_STATE_JUNK; cur = cur->down);
|
||||||
|
cur->state = CBUF_STATE_ERROR;
|
||||||
|
GIB_DATA(cur)->done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
GIB_Thread_List_f (void)
|
||||||
|
{
|
||||||
|
if (GIB_Argc() != 1)
|
||||||
|
GIB_USAGE ("");
|
||||||
|
else if (GIB_CanReturn()) {
|
||||||
|
gib_thread_t *cur;
|
||||||
|
for (cur = gib_threads; cur; cur = cur->next)
|
||||||
|
dsprintf (GIB_Return (0), "%lu", cur->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,9 +574,9 @@ GIB_Event_Register_f (void)
|
||||||
if (GIB_Argc() != 3)
|
if (GIB_Argc() != 3)
|
||||||
GIB_USAGE ("event function");
|
GIB_USAGE ("event function");
|
||||||
else if (!(func = GIB_Function_Find (GIB_Argv(2))) && GIB_Argv(2)[0])
|
else if (!(func = GIB_Function_Find (GIB_Argv(2))) && GIB_Argv(2)[0])
|
||||||
Cbuf_Error ("function", "Function %s not found.", GIB_Argv(2));
|
GIB_Error ("function", "Function %s not found.", GIB_Argv(2));
|
||||||
else if (GIB_Event_Register (GIB_Argv(1), func))
|
else if (GIB_Event_Register (GIB_Argv(1), func))
|
||||||
Cbuf_Error ("event", "Event %s not found.", GIB_Argv(1));
|
GIB_Error ("event", "Event %s not found.", GIB_Argv(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File access */
|
/* File access */
|
||||||
|
@ -586,13 +622,13 @@ GIB_File_Read_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!*GIB_Argv (1)) {
|
if (!*GIB_Argv (1)) {
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file",
|
||||||
"file::read: null filename provided");
|
"%s: null filename provided", GIB_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::read: access to %s denied", GIB_Argv(1));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(ret = GIB_Return (0)))
|
if (!(ret = GIB_Return (0)))
|
||||||
|
@ -608,8 +644,8 @@ GIB_File_Read_f (void)
|
||||||
Qclose (file);
|
Qclose (file);
|
||||||
}
|
}
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file",
|
||||||
"file::read: could not read %s: %s", path, strerror (errno));
|
"%s: could not read %s: %s", GIB_Argv(0), path, strerror (errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,19 +661,19 @@ GIB_File_Write_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!*GIB_Argv(1)) {
|
if (!*GIB_Argv(1)) {
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file",
|
||||||
"file::write: null filename provided");
|
"%s: null filename provided", GIB_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::write: access to %s denied", GIB_Argv(1));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path = GIB_Argv(1);
|
path = GIB_Argv(1);
|
||||||
if (!(file = Qopen (path, "w"))) {
|
if (!(file = Qopen (path, "w"))) {
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file",
|
||||||
"file::write: could not open %s for writing: %s", path, strerror (errno));
|
"%s: could not open %s for writing: %s", GIB_Argv(0), path, strerror (errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Qprintf (file, "%s", GIB_Argv (2));
|
Qprintf (file, "%s", GIB_Argv (2));
|
||||||
|
@ -657,8 +693,8 @@ GIB_File_Find_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::find: access to %s denied", GIB_Argv(1));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path = GIB_Argv(1);
|
path = GIB_Argv(1);
|
||||||
|
@ -674,8 +710,8 @@ GIB_File_Find_f (void)
|
||||||
}
|
}
|
||||||
directory = opendir (path);
|
directory = opendir (path);
|
||||||
if (!directory) {
|
if (!directory) {
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file",
|
||||||
"file.find: could not open directory %s: %s", path, strerror (errno));
|
"%s: could not open directory %s: %s", GIB_Argv(0), path, strerror (errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while ((entry = readdir (directory)))
|
while ((entry = readdir (directory)))
|
||||||
|
@ -694,21 +730,19 @@ GIB_File_Move_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::move: access to %s denied", GIB_Argv(1));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(2))) {
|
if (GIB_File_Transform_Path (GIB_Argd(2))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::move: access to %s denied", GIB_Argv(2));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path1 = GIB_Argv(1);
|
path1 = GIB_Argv(1);
|
||||||
path2 = GIB_Argv(2);
|
path2 = GIB_Argv(2);
|
||||||
if (Qrename (path1, path2))
|
if (Qrename (path1, path2))
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file", "%s: could not move %s to %s: %s", GIB_Argv(0), path1, path2, strerror(errno));
|
||||||
"file::move: could not move %s to %s: %s",
|
|
||||||
path1, path2, strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -721,15 +755,13 @@ GIB_File_Delete_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
if (GIB_File_Transform_Path (GIB_Argd(1))) {
|
||||||
Cbuf_Error ("access",
|
GIB_Error ("access",
|
||||||
"file::delete: access to %s denied", GIB_Argv(1));
|
"%s: access to %s denied", GIB_Argv(0), GIB_Argv(1));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path = GIB_Argv (1);
|
path = GIB_Argv (1);
|
||||||
if (Qremove(path))
|
if (Qremove(path))
|
||||||
Cbuf_Error ("file",
|
GIB_Error ("file", "%s: could not delete %s: %s", GIB_Argv(0), path, strerror(errno));
|
||||||
"file::delete: could not delete %s: %s",
|
|
||||||
path, strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -790,6 +822,7 @@ GIB_Builtin_Init (qboolean sandbox)
|
||||||
GIB_Builtin_Add ("local", GIB_Local_f);
|
GIB_Builtin_Add ("local", GIB_Local_f);
|
||||||
GIB_Builtin_Add ("global", GIB_Global_f);
|
GIB_Builtin_Add ("global", GIB_Global_f);
|
||||||
GIB_Builtin_Add ("domain", GIB_Domain_f);
|
GIB_Builtin_Add ("domain", GIB_Domain_f);
|
||||||
|
GIB_Builtin_Add ("domain::clear", GIB_Domain_Clear_f);
|
||||||
GIB_Builtin_Add ("return", GIB_Return_f);
|
GIB_Builtin_Add ("return", GIB_Return_f);
|
||||||
GIB_Builtin_Add ("for", GIB_For_f);
|
GIB_Builtin_Add ("for", GIB_For_f);
|
||||||
GIB_Builtin_Add ("break", GIB_Break_f);
|
GIB_Builtin_Add ("break", GIB_Break_f);
|
||||||
|
@ -797,12 +830,14 @@ GIB_Builtin_Init (qboolean sandbox)
|
||||||
GIB_Builtin_Add ("length", GIB_Length_f);
|
GIB_Builtin_Add ("length", GIB_Length_f);
|
||||||
GIB_Builtin_Add ("equal", GIB_Equal_f);
|
GIB_Builtin_Add ("equal", GIB_Equal_f);
|
||||||
GIB_Builtin_Add ("slice", GIB_Slice_f);
|
GIB_Builtin_Add ("slice", GIB_Slice_f);
|
||||||
|
GIB_Builtin_Add ("slice::find", GIB_Slice_Find_f);
|
||||||
GIB_Builtin_Add ("split", GIB_Split_f);
|
GIB_Builtin_Add ("split", GIB_Split_f);
|
||||||
GIB_Builtin_Add ("regex::match", GIB_Regex_Match_f);
|
GIB_Builtin_Add ("regex::match", GIB_Regex_Match_f);
|
||||||
GIB_Builtin_Add ("regex::replace", GIB_Regex_Replace_f);
|
GIB_Builtin_Add ("regex::replace", GIB_Regex_Replace_f);
|
||||||
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f);
|
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f);
|
||||||
GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f);
|
GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f);
|
||||||
GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f);
|
GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f);
|
||||||
|
GIB_Builtin_Add ("thread::list", GIB_Thread_List_f);
|
||||||
GIB_Builtin_Add ("event::register", GIB_Event_Register_f);
|
GIB_Builtin_Add ("event::register", GIB_Event_Register_f);
|
||||||
GIB_Builtin_Add ("file::read", GIB_File_Read_f);
|
GIB_Builtin_Add ("file::read", GIB_File_Read_f);
|
||||||
GIB_Builtin_Add ("file::write", GIB_File_Write_f);
|
GIB_Builtin_Add ("file::write", GIB_File_Write_f);
|
||||||
|
|
|
@ -207,14 +207,12 @@ GIB_Execute (cbuf_t *cbuf)
|
||||||
else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
|
else if ((b = GIB_Builtin_Find (cbuf->args->argv[0]->str))) {
|
||||||
b->func ();
|
b->func ();
|
||||||
} else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
|
} else if ((f = GIB_Function_Find (cbuf->args->argv[0]->str))) {
|
||||||
cbuf_t *new = Cbuf_New (&gib_interp);
|
cbuf_t *new = Cbuf_PushStack (&gib_interp);
|
||||||
cbuf->down = new;
|
|
||||||
new->up = cbuf;
|
|
||||||
cbuf->state = CBUF_STATE_STACK;
|
|
||||||
GIB_Function_Execute (new, f, cbuf->args->argv, cbuf->args->argc);
|
GIB_Function_Execute (new, f, cbuf->args->argv, cbuf->args->argc);
|
||||||
} else {
|
} else {
|
||||||
GIB_Execute_Generate_Composite (cbuf);
|
GIB_Execute_Generate_Composite (cbuf);
|
||||||
Cmd_Command (cbuf->args);
|
if (Cmd_Command (cbuf->args))
|
||||||
|
GIB_Error ("command", "No builtin, function, or console command named '%s' was found.", cbuf->args->argv[0]->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(g->ip = g->ip->next)) // No more commands
|
if (!(g->ip = g->ip->next)) // No more commands
|
||||||
|
@ -222,8 +220,4 @@ GIB_Execute (cbuf_t *cbuf)
|
||||||
if (cbuf->state) // Let the stack walker figure out what to do
|
if (cbuf->state) // Let the stack walker figure out what to do
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g->done = false;
|
|
||||||
g->program->refs--;
|
|
||||||
GIB_Tree_Free_Recursive (g->program);
|
|
||||||
g->program = g->ip = 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ GIB_Function_Get_Key (void *ele, void *ptr)
|
||||||
{
|
{
|
||||||
return ((gib_function_t *)ele)->name;
|
return ((gib_function_t *)ele)->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
GIB_Function_Free (void *ele, void *ptr)
|
GIB_Function_Free (void *ele, void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +83,11 @@ GIB_Function_Free (void *ele, void *ptr)
|
||||||
free ((void *)func->name);
|
free ((void *)func->name);
|
||||||
if (func->program)
|
if (func->program)
|
||||||
GIB_Tree_Free_Recursive (func->program);
|
GIB_Tree_Free_Recursive (func->program);
|
||||||
|
if (func->script && !(--func->script->refs)) {
|
||||||
|
free ((void *)func->script->text);
|
||||||
|
free ((void *)func->script->file);
|
||||||
|
free (func->script);
|
||||||
|
}
|
||||||
free (func);
|
free (func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,20 +99,25 @@ GIB_Function_Free (void *ele, void *ptr)
|
||||||
hash if needed.
|
hash if needed.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, hashtab_t *globals)
|
GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, gib_script_t *script, hashtab_t *globals)
|
||||||
{
|
{
|
||||||
gib_function_t *func;
|
gib_function_t *func;
|
||||||
|
|
||||||
program->refs++;
|
GIB_Tree_Ref (&program);
|
||||||
|
if (script)
|
||||||
|
script->refs++;
|
||||||
if (!gib_functions)
|
if (!gib_functions)
|
||||||
gib_functions = Hash_NewTable (1024, GIB_Function_Get_Key, GIB_Function_Free, 0);
|
gib_functions = Hash_NewTable (1024, GIB_Function_Get_Key, GIB_Function_Free, 0);
|
||||||
|
|
||||||
func = Hash_Find(gib_functions, name);
|
func = Hash_Find(gib_functions, name);
|
||||||
if (func) {
|
if (func) {
|
||||||
dstring_clearstr (func->text);
|
dstring_clearstr (func->text);
|
||||||
func->program->refs--;
|
GIB_Tree_Unref (&func->program);
|
||||||
GIB_Tree_Free_Recursive (func->program);
|
if (func->script && !(--func->script->refs)) {
|
||||||
|
free ((void *)func->script->text);
|
||||||
|
free ((void *)func->script->file);
|
||||||
|
free (func->script);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
func = GIB_Function_New (name);
|
func = GIB_Function_New (name);
|
||||||
Hash_Add (gib_functions, func);
|
Hash_Add (gib_functions, func);
|
||||||
|
@ -114,6 +125,7 @@ GIB_Function_Define (const char *name, const char *text, gib_tree_t *program, ha
|
||||||
dstring_appendstr (func->text, text);
|
dstring_appendstr (func->text, text);
|
||||||
func->program = program;
|
func->program = program;
|
||||||
func->globals = globals;
|
func->globals = globals;
|
||||||
|
func->script = script;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -162,8 +174,11 @@ GIB_Function_Prepare_Args (cbuf_t *cbuf, dstring_t **args, unsigned int argc)
|
||||||
void
|
void
|
||||||
GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, dstring_t **args, unsigned int argc)
|
GIB_Function_Execute (cbuf_t *cbuf, gib_function_t *func, dstring_t **args, unsigned int argc)
|
||||||
{
|
{
|
||||||
func->program->refs++;
|
GIB_Tree_Ref (&func->program);
|
||||||
|
if (func->script)
|
||||||
|
func->script->refs++;
|
||||||
GIB_Buffer_Set_Program (cbuf, func->program);
|
GIB_Buffer_Set_Program (cbuf, func->program);
|
||||||
|
GIB_DATA(cbuf)->script = func->script;
|
||||||
GIB_DATA(cbuf)->globals = func->globals;
|
GIB_DATA(cbuf)->globals = func->globals;
|
||||||
GIB_Function_Prepare_Args (cbuf, args, argc);
|
GIB_Function_Prepare_Args (cbuf, args, argc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,8 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
"$Id$";
|
"$Id$";
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "QF/qtypes.h"
|
#include "QF/qtypes.h"
|
||||||
#include "QF/cbuf.h"
|
#include "QF/cbuf.h"
|
||||||
#include "QF/quakefs.h"
|
#include "QF/quakefs.h"
|
||||||
|
@ -71,14 +73,14 @@ GIB_Exec_Override_f (void) {
|
||||||
Sys_Printf ("execing %s\n", Cmd_Argv (1));
|
Sys_Printf ("execing %s\n", Cmd_Argv (1));
|
||||||
if (!strcmp (Cmd_Argv (1) + strlen (Cmd_Argv(1)) - 4, ".gib") || cbuf_active->interpreter == &gib_interp) {
|
if (!strcmp (Cmd_Argv (1) + strlen (Cmd_Argv(1)) - 4, ".gib") || cbuf_active->interpreter == &gib_interp) {
|
||||||
// GIB script, put it in a new buffer on the stack
|
// GIB script, put it in a new buffer on the stack
|
||||||
cbuf_t *sub = Cbuf_New (&gib_interp);
|
cbuf_t *sub = Cbuf_PushStack (&gib_interp);
|
||||||
if (cbuf_active->down)
|
GIB_DATA(sub)->script = malloc (sizeof (gib_script_t));
|
||||||
Cbuf_DeleteStack (cbuf_active->down);
|
GIB_DATA(sub)->script->file = strdup (Cmd_Argv(1));
|
||||||
cbuf_active->down = sub;
|
GIB_DATA(sub)->script->text = strdup (f);
|
||||||
sub->up = cbuf_active;
|
GIB_DATA(sub)->script->refs = 1;
|
||||||
cbuf_active->state = CBUF_STATE_STACK;
|
|
||||||
Cbuf_AddText (sub, f);
|
Cbuf_AddText (sub, f);
|
||||||
//GIB_Parse_Strip_Comments (sub);
|
if (gib_parse_error && cbuf_active->interpreter == &gib_interp)
|
||||||
|
GIB_Error ("parse", "%s: Parse error while executing %s.", Cmd_Argv(0), Cmd_Argv(1));
|
||||||
} else
|
} else
|
||||||
Cbuf_InsertText (cbuf_active, f);
|
Cbuf_InsertText (cbuf_active, f);
|
||||||
Hunk_FreeToLowMark (mark);
|
Hunk_FreeToLowMark (mark);
|
||||||
|
|
|
@ -186,14 +186,36 @@ GIB_Parse_Match_Var (const char *str, unsigned int *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean gib_parse_error;
|
qboolean gib_parse_error;
|
||||||
|
unsigned int gib_parse_error_pos;
|
||||||
|
const char *gib_parse_error_msg;
|
||||||
|
|
||||||
|
static void
|
||||||
|
GIB_Parse_Error (const char *msg, unsigned int pos)
|
||||||
|
{
|
||||||
|
gib_parse_error = true;
|
||||||
|
gib_parse_error_msg = msg;
|
||||||
|
gib_parse_error_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GIB_Parse_ErrorMsg (void)
|
||||||
|
{
|
||||||
|
return gib_parse_error_msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
GIB_Parse_ErrorPos (void)
|
||||||
|
{
|
||||||
|
return gib_parse_error_pos;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Concatenation in stupid circumstances should generate errors
|
// FIXME: Concatenation in stupid circumstances should generate errors
|
||||||
|
|
||||||
static gib_tree_t *
|
static gib_tree_t *
|
||||||
GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_tree_t **embedded)
|
GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int pofs, gib_tree_flags_t flags, gib_tree_t **embedded)
|
||||||
{
|
{
|
||||||
char c, delim, *str;
|
char c, delim, *str;
|
||||||
unsigned int tstart;
|
unsigned int tstart, start;
|
||||||
gib_tree_t *nodes = 0, *cur, *new, *embs = 0, *tmp;
|
gib_tree_t *nodes = 0, *cur, *new, *embs = 0, *tmp;
|
||||||
gib_tree_t **node = &nodes;
|
gib_tree_t **node = &nodes;
|
||||||
qboolean cat = false;
|
qboolean cat = false;
|
||||||
|
@ -214,7 +236,8 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
if (!program[*i] || program[*i] == '\n' || program[*i] == ';')
|
if (!program[*i] || program[*i] == '\n' || program[*i] == ';')
|
||||||
break;
|
break;
|
||||||
// Save our start position
|
// Save our start position
|
||||||
tstart = *i + 1;
|
start = *i;
|
||||||
|
tstart = start + 1;
|
||||||
delim = program[*i];
|
delim = program[*i];
|
||||||
switch (delim) {
|
switch (delim) {
|
||||||
case '{':
|
case '{':
|
||||||
|
@ -250,8 +273,10 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c = 0;
|
||||||
cur = *node = GIB_Tree_New (flags);
|
cur = *node = GIB_Tree_New (flags);
|
||||||
|
cur->start = start + pofs;
|
||||||
|
cur->end = *i + pofs;
|
||||||
cur->delim = delim;
|
cur->delim = delim;
|
||||||
str = calloc (*i - tstart + 1, sizeof(char));
|
str = calloc (*i - tstart + 1, sizeof(char));
|
||||||
memcpy (str, program+tstart, *i - tstart);
|
memcpy (str, program+tstart, *i - tstart);
|
||||||
|
@ -260,12 +285,12 @@ GIB_Parse_Tokens (const char *program, unsigned int *i, unsigned int flags, gib_
|
||||||
// string would differ from the parsed program.
|
// string would differ from the parsed program.
|
||||||
if (cur->delim == '{' && !cat) {
|
if (cur->delim == '{' && !cat) {
|
||||||
// Try to parse sub-program
|
// Try to parse sub-program
|
||||||
if (!(new = GIB_Parse_Lines (str, flags)))
|
if (!(new = GIB_Parse_Lines (str, tstart+pofs, flags)))
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
cur->children = new;
|
cur->children = new;
|
||||||
// Check for embedded commands/variables
|
// Check for embedded commands/variables
|
||||||
} else if (cur->delim == ' ' || cur->delim == '(') {
|
} else if (cur->delim == ' ' || cur->delim == '(') {
|
||||||
if (!(cur->children = GIB_Parse_Embedded (str, flags, &new))) {
|
if (!(cur->children = GIB_Parse_Embedded (str, tstart+pofs, flags, &new))) {
|
||||||
// There could be no embedded elements, so check for a real error
|
// There could be no embedded elements, so check for a real error
|
||||||
if (gib_parse_error)
|
if (gib_parse_error)
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
|
@ -305,9 +330,10 @@ DONE:
|
||||||
*embedded = embs;
|
*embedded = embs;
|
||||||
return nodes;
|
return nodes;
|
||||||
ERROR:
|
ERROR:
|
||||||
|
if (c)
|
||||||
|
GIB_Parse_Error (va("Could not find match for '%c'.", c), *i+pofs);
|
||||||
if (nodes)
|
if (nodes)
|
||||||
GIB_Tree_Free_Recursive (nodes);
|
GIB_Tree_Free_Recursive (nodes);
|
||||||
gib_parse_error = true;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +344,14 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
unsigned int flags = line->flags;
|
unsigned int flags = line->flags;
|
||||||
while (!strcmp (line->children->str, "if") || !strcmp (line->children->str, "ifnot")) {
|
while (!strcmp (line->children->str, "if") || !strcmp (line->children->str, "ifnot")) {
|
||||||
// Sanity checking
|
// Sanity checking
|
||||||
if (!line->children->next || !line->children->next->next || !line->children->next->next->children || line->flags & TREE_EMBED) {
|
if (!line->children->next || !line->children->next->next) {
|
||||||
gib_parse_error = true;
|
GIB_Parse_Error ("Not enough arguments to 'if' statement.", line->start);
|
||||||
|
return line;
|
||||||
|
} else if (!line->children->next->next->children || line->children->next->next->delim != '{') {
|
||||||
|
GIB_Parse_Error ("First program block in 'if' statement not enclosed in braces or invalid.", line->start);
|
||||||
|
return line;
|
||||||
|
} else if (line->flags & TREE_EMBED) {
|
||||||
|
GIB_Parse_Error ("'if' statements may not be used in embedded commands.", line->start);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
// Set conditional flag
|
// Set conditional flag
|
||||||
|
@ -342,7 +374,7 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
if (p->children->next->next->next && !strcmp (p->children->next->next->next->str, "else")) {
|
if (p->children->next->next->next && !strcmp (p->children->next->next->next->str, "else")) {
|
||||||
// Sanity checking
|
// Sanity checking
|
||||||
if (!p->children->next->next->next->next) {
|
if (!p->children->next->next->next->next) {
|
||||||
gib_parse_error = true;
|
GIB_Parse_Error ("'if' statement contains 'else' but no secondary program block or command.", line->start);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
// Is "else" followed by a subprogram?
|
// Is "else" followed by a subprogram?
|
||||||
|
@ -372,12 +404,14 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
// If we have a while loop, handle that
|
// If we have a while loop, handle that
|
||||||
if (!strcmp (line->children->str, "while")) {
|
if (!strcmp (line->children->str, "while")) {
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (!line->children->next ||
|
if (!line->children->next || !line->children->next->next) {
|
||||||
!line->children->next->next ||
|
GIB_Parse_Error ("Not enough arguments to 'while' statement.", line->start);
|
||||||
line->children->next->next->delim != '{' ||
|
return line;
|
||||||
!line->children->next->next->children ||
|
} else if (!line->children->next->next->children || line->children->next->next->delim != '{') {
|
||||||
line->flags & TREE_EMBED) {
|
GIB_Parse_Error ("Program block in 'while' statement not enclosed in braces or invalid.", line->start);
|
||||||
gib_parse_error = true;
|
return line;
|
||||||
|
} else if (line->flags & TREE_EMBED) {
|
||||||
|
GIB_Parse_Error ("'while' statements may not be used in embedded commands.", line->start);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
// Set conditional flag
|
// Set conditional flag
|
||||||
|
@ -400,19 +434,20 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
gib_tree_t *tmp;
|
gib_tree_t *tmp;
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (!line->children->next || !line->children->next->next || strcmp (line->children->next->next->str, "in") || !line->children->next->next->next || !line->children->next->next->next->next) {
|
if (!line->children->next || !line->children->next->next || strcmp (line->children->next->next->str, "in") || !line->children->next->next->next || !line->children->next->next->next->next) {
|
||||||
gib_parse_error = true;
|
GIB_Parse_Error ("Malformed 'for' statement.", line->start);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
// Find last token in line (contains program block)
|
// Find last token in line (contains program block)
|
||||||
for (tmp = line->children->next->next->next->next; tmp->next; tmp = tmp->next);
|
for (tmp = line->children->next->next->next->next; tmp->next; tmp = tmp->next);
|
||||||
// More sanity
|
// More sanity
|
||||||
if (tmp->delim != '{' || !tmp->children) {
|
if (tmp->delim != '{' || !tmp->children) {
|
||||||
gib_parse_error = true;
|
GIB_Parse_Error ("Program block in 'for' statement not enclosed in braces or invalid.", line->start);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
p = line;
|
p = line;
|
||||||
// Move subprogram inline
|
// Move subprogram inline
|
||||||
line->next = tmp->children;
|
line->next = tmp->children;
|
||||||
|
tmp->children = 0;
|
||||||
// Find end of subprogram, set jump point back to top of loop as we go
|
// Find end of subprogram, set jump point back to top of loop as we go
|
||||||
for (; line->next; line = line->next)
|
for (; line->next; line = line->next)
|
||||||
if (!line->jump)
|
if (!line->jump)
|
||||||
|
@ -427,7 +462,7 @@ GIB_Parse_Semantic_Preprocess (gib_tree_t *line)
|
||||||
}
|
}
|
||||||
|
|
||||||
gib_tree_t *
|
gib_tree_t *
|
||||||
GIB_Parse_Lines (const char *program, unsigned int flags)
|
GIB_Parse_Lines (const char *program, unsigned int pofs, gib_tree_flags_t flags)
|
||||||
{
|
{
|
||||||
unsigned int i = 0, lstart;
|
unsigned int i = 0, lstart;
|
||||||
gib_tree_t *lines = 0, *cur, *tokens, **line = &lines, *embs;
|
gib_tree_t *lines = 0, *cur, *tokens, **line = &lines, *embs;
|
||||||
|
@ -440,13 +475,15 @@ GIB_Parse_Lines (const char *program, unsigned int flags)
|
||||||
break;
|
break;
|
||||||
lstart = i;
|
lstart = i;
|
||||||
// If we parse something useful...
|
// If we parse something useful...
|
||||||
if ((tokens = GIB_Parse_Tokens (program, &i, flags, &embs))) {
|
if ((tokens = GIB_Parse_Tokens (program, &i, pofs, flags, &embs))) {
|
||||||
// Link it in
|
// Link it in
|
||||||
cur = GIB_Tree_New (flags);
|
cur = GIB_Tree_New (flags);
|
||||||
cur->delim = '\n';
|
cur->delim = '\n';
|
||||||
str = calloc (i - lstart + 1, sizeof(char));
|
str = calloc (i - lstart + 1, sizeof(char));
|
||||||
memcpy (str, program+lstart, i - lstart);
|
memcpy (str, program+lstart, i - lstart);
|
||||||
cur->str = str;
|
cur->str = str;
|
||||||
|
cur->start = lstart + pofs;
|
||||||
|
cur->end = i + pofs;
|
||||||
cur->children = tokens;
|
cur->children = tokens;
|
||||||
// Line contains embedded commands?
|
// Line contains embedded commands?
|
||||||
if (embs) {
|
if (embs) {
|
||||||
|
@ -470,7 +507,7 @@ ERROR:
|
||||||
}
|
}
|
||||||
|
|
||||||
gib_tree_t *
|
gib_tree_t *
|
||||||
GIB_Parse_Embedded (const char *program, unsigned int flags, gib_tree_t **embedded)
|
GIB_Parse_Embedded (const char *program, unsigned int pofs, gib_tree_flags_t flags, gib_tree_t **embedded)
|
||||||
{
|
{
|
||||||
unsigned int i, n, t;
|
unsigned int i, n, t;
|
||||||
char c, d, *str;
|
char c, d, *str;
|
||||||
|
@ -500,12 +537,12 @@ GIB_Parse_Embedded (const char *program, unsigned int flags, gib_tree_t **embedd
|
||||||
str = calloc (i - n + 1, sizeof (char));
|
str = calloc (i - n + 1, sizeof (char));
|
||||||
memcpy (str, program+n, i - n);
|
memcpy (str, program+n, i - n);
|
||||||
cur->str = str;
|
cur->str = str;
|
||||||
|
cur->start = start + pofs;
|
||||||
t = 0;
|
cur->end = end + pofs;
|
||||||
if (!(tokens = GIB_Parse_Tokens (cur->str, &t, flags, &emb))) {
|
|
||||||
c = 0;
|
c = 0;
|
||||||
|
t = 0;
|
||||||
|
if (!(tokens = GIB_Parse_Tokens (cur->str, &t, start + pofs, flags, &emb)))
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
}
|
|
||||||
cur->children = tokens;
|
cur->children = tokens;
|
||||||
GIB_Parse_Semantic_Preprocess (cur)->next = *embedded;
|
GIB_Parse_Semantic_Preprocess (cur)->next = *embedded;
|
||||||
if (gib_parse_error)
|
if (gib_parse_error)
|
||||||
|
@ -561,7 +598,8 @@ GIB_Parse_Embedded (const char *program, unsigned int flags, gib_tree_t **embedd
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
ERROR:
|
ERROR:
|
||||||
gib_parse_error = true;
|
if (c)
|
||||||
|
GIB_Parse_Error (va ("Could not find match for '%c'.", c), i + pofs);
|
||||||
if (lines)
|
if (lines)
|
||||||
GIB_Tree_Free_Recursive (lines);
|
GIB_Tree_Free_Recursive (lines);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -47,6 +47,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include "QF/gib_parse.h"
|
#include "QF/gib_parse.h"
|
||||||
#include "QF/gib_vars.h"
|
#include "QF/gib_vars.h"
|
||||||
#include "QF/gib_process.h"
|
#include "QF/gib_process.h"
|
||||||
|
#include "QF/gib_builtin.h"
|
||||||
|
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ GIB_Process_Variable (dstring_t *token, unsigned int *i)
|
||||||
(*i)++;
|
(*i)++;
|
||||||
if (token->str[*i] == '{') {
|
if (token->str[*i] == '{') {
|
||||||
if ((c = GIB_Parse_Match_Brace (token->str, i))) {
|
if ((c = GIB_Parse_Match_Brace (token->str, i))) {
|
||||||
Cbuf_Error ("Parse", "Could not find match for %c.", c);
|
GIB_Error ("Parse", "Could not find match for %c.", c);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n += 2;
|
n += 2;
|
||||||
|
@ -71,9 +72,10 @@ GIB_Process_Variable (dstring_t *token, unsigned int *i)
|
||||||
} else {
|
} else {
|
||||||
for (; isalnum((byte) token->str[*i]) || token->str[*i] == '_'; (*i)++);
|
for (; isalnum((byte) token->str[*i]) || token->str[*i] == '_'; (*i)++);
|
||||||
if (token->str[*i] == '[') {
|
if (token->str[*i] == '[') {
|
||||||
if ((c = GIB_Parse_Match_Index (token->str, i)))
|
if ((c = GIB_Parse_Match_Index (token->str, i))) {
|
||||||
|
GIB_Error ("Parse", "Could not find match for %c.", c);
|
||||||
return -1;
|
return -1;
|
||||||
else
|
} else
|
||||||
(*i)++;
|
(*i)++;
|
||||||
}
|
}
|
||||||
n++;
|
n++;
|
||||||
|
@ -119,7 +121,7 @@ GIB_Process_Math (struct dstring_s *token, unsigned int i)
|
||||||
|
|
||||||
value = EXP_Evaluate (token->str+i);
|
value = EXP_Evaluate (token->str+i);
|
||||||
if (EXP_ERROR) {
|
if (EXP_ERROR) {
|
||||||
Cbuf_Error ("math", "Expression \"%s\" caused an error:\n%s", token->str, EXP_GetErrorMsg());
|
GIB_Error ("math", "Expression \"%s\" caused an error:\n%s", token->str, EXP_GetErrorMsg());
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
token->str[i] = 0;
|
token->str[i] = 0;
|
||||||
|
|
|
@ -115,12 +115,11 @@ GIB_Thread_Execute (void)
|
||||||
|
|
||||||
for (cur = gib_threads; cur; cur = tmp) {
|
for (cur = gib_threads; cur; cur = tmp) {
|
||||||
tmp = cur->next;
|
tmp = cur->next;
|
||||||
if (GIB_DATA(cur->cbuf)->program)
|
if (cur->trash) {
|
||||||
Cbuf_Execute_Stack (cur->cbuf);
|
|
||||||
else {
|
|
||||||
GIB_Thread_Remove (cur);
|
GIB_Thread_Remove (cur);
|
||||||
GIB_Thread_Delete (cur);
|
GIB_Thread_Delete (cur);
|
||||||
}
|
} else
|
||||||
|
Cbuf_Execute_Stack (cur->cbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,12 @@ static __attribute__ ((unused)) const char rcsid[] =
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "QF/sys.h"
|
||||||
#include "QF/qtypes.h"
|
#include "QF/qtypes.h"
|
||||||
#include "QF/gib_tree.h"
|
#include "QF/gib_tree.h"
|
||||||
|
|
||||||
gib_tree_t *
|
gib_tree_t *
|
||||||
GIB_Tree_New (unsigned int flags)
|
GIB_Tree_New (gib_tree_flags_t flags)
|
||||||
{
|
{
|
||||||
gib_tree_t *new = calloc (1, sizeof (gib_tree_t));
|
gib_tree_t *new = calloc (1, sizeof (gib_tree_t));
|
||||||
new->flags = flags;
|
new->flags = flags;
|
||||||
|
@ -60,13 +61,30 @@ GIB_Tree_Free_Recursive (gib_tree_t *tree)
|
||||||
return;
|
return;
|
||||||
for (; tree; tree = n) {
|
for (; tree; tree = n) {
|
||||||
n = tree->next;
|
n = tree->next;
|
||||||
if (tree->children) {
|
if (tree->children)
|
||||||
// Parent is about to bite the dust, meaning one less reference
|
// Parent is about to bite the dust, meaning one less reference
|
||||||
tree->children->refs--;
|
GIB_Tree_Unref (&tree->children);
|
||||||
GIB_Tree_Free_Recursive (tree->children);
|
|
||||||
}
|
|
||||||
if (tree->str)
|
if (tree->str)
|
||||||
free((void *) tree->str);
|
free((void *) tree->str);
|
||||||
free(tree);
|
free(tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Tree_Ref (gib_tree_t **tp)
|
||||||
|
{
|
||||||
|
(*tp)->refs++;
|
||||||
|
Sys_DPrintf ("Ref: %p %u\n", *tp, (*tp)->refs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GIB_Tree_Unref (gib_tree_t **tp)
|
||||||
|
{
|
||||||
|
Sys_DPrintf ("Unref: %p %u\n", *tp, (*tp)->refs-1);
|
||||||
|
if (!(--(*tp)->refs)) {
|
||||||
|
GIB_Tree_Free_Recursive (*tp);
|
||||||
|
*tp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -127,13 +127,28 @@ Cbuf_DeleteStack (cbuf_t *stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Cbuf_PushStack (cbuf_t *new)
|
Cbuf_Reset (cbuf_t *cbuf)
|
||||||
{
|
{
|
||||||
if (cbuf_active->down)
|
cbuf->resumetime = 0.0;
|
||||||
Cbuf_DeleteStack (cbuf_active->down);
|
cbuf->args->argc = 0;
|
||||||
|
if (cbuf->interpreter->reset)
|
||||||
|
cbuf->interpreter->reset (cbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
cbuf_t *
|
||||||
|
Cbuf_PushStack (cbuf_interpreter_t *interp)
|
||||||
|
{
|
||||||
|
cbuf_t *new;
|
||||||
|
if (cbuf_active->down) {
|
||||||
|
new = cbuf_active->down;
|
||||||
|
Cbuf_Reset (new);
|
||||||
|
new->state = CBUF_STATE_NORMAL;
|
||||||
|
} else
|
||||||
|
new = Cbuf_New (interp);
|
||||||
cbuf_active->down = new;
|
cbuf_active->down = new;
|
||||||
new->up = cbuf_active;
|
new->up = cbuf_active;
|
||||||
cbuf_active->state = CBUF_STATE_STACK;
|
cbuf_active->state = CBUF_STATE_STACK;
|
||||||
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -167,33 +182,27 @@ Cbuf_Execute_Stack (cbuf_t *cbuf)
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (sp = cbuf; sp->down; sp = sp->down);
|
for (sp = cbuf; sp->down && sp->down->state != CBUF_STATE_JUNK; sp = sp->down);
|
||||||
while (sp) {
|
while (sp) {
|
||||||
if (sp->down) {
|
|
||||||
Cbuf_Delete (sp->down);
|
|
||||||
sp->down = 0;
|
|
||||||
}
|
|
||||||
Cbuf_Execute (sp);
|
Cbuf_Execute (sp);
|
||||||
if (sp->state) {
|
if (sp->state) {
|
||||||
if (sp->state == CBUF_STATE_STACK) {
|
if (sp->state == CBUF_STATE_STACK) {
|
||||||
sp = sp->down;
|
sp = sp->down;
|
||||||
continue;
|
continue;
|
||||||
} else if (sp->state == CBUF_STATE_ERROR)
|
} else if (sp->state == CBUF_STATE_ERROR)
|
||||||
goto ERROR;
|
break;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
sp->state = CBUF_STATE_JUNK;
|
||||||
sp = sp->up;
|
sp = sp->up;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
ERROR:
|
|
||||||
if (cbuf->down) {
|
if (cbuf->down) {
|
||||||
Cbuf_DeleteStack (cbuf->down);
|
Cbuf_DeleteStack (cbuf->down);
|
||||||
cbuf->down = 0;
|
cbuf->down = 0;
|
||||||
}
|
}
|
||||||
// Tear it down and build it back up
|
Cbuf_Reset (cbuf);
|
||||||
cbuf->interpreter->destruct (cbuf);
|
|
||||||
cbuf->interpreter->construct (cbuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -202,24 +211,3 @@ Cbuf_Execute_Sets (cbuf_t *cbuf)
|
||||||
cbuf->interpreter->execute_sets (cbuf);
|
cbuf->interpreter->execute_sets (cbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Cbuf_Error (const char *class, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
dstring_t *message = dstring_newstr();
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
va_start (args, fmt);
|
|
||||||
dvsprintf (message, fmt, args);
|
|
||||||
va_end (args);
|
|
||||||
Sys_Printf (
|
|
||||||
"-----------------------------------\n"
|
|
||||||
"|Error in command buffer execution|\n"
|
|
||||||
"-----------------------------------\n"
|
|
||||||
"Type: %s\n\n"
|
|
||||||
"%s\n\n",
|
|
||||||
class,
|
|
||||||
message->str
|
|
||||||
);
|
|
||||||
cbuf_active->state = CBUF_STATE_ERROR;
|
|
||||||
dstring_delete (message);
|
|
||||||
}
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ Cmd_Args (int start)
|
||||||
return cmd_args->args[start];
|
return cmd_args->args[start];
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
Cmd_Command (cbuf_args_t *args)
|
Cmd_Command (cbuf_args_t *args)
|
||||||
{
|
{
|
||||||
cmd_function_t *cmd;
|
cmd_function_t *cmd;
|
||||||
|
@ -115,7 +115,7 @@ Cmd_Command (cbuf_args_t *args)
|
||||||
//cmd_source = src;
|
//cmd_source = src;
|
||||||
|
|
||||||
if (!args->argc)
|
if (!args->argc)
|
||||||
return; // no tokens
|
return 0; // no tokens
|
||||||
|
|
||||||
// check functions
|
// check functions
|
||||||
cmd = (cmd_function_t *) Hash_Find (cmd_hash, args->argv[0]->str);
|
cmd = (cmd_function_t *) Hash_Find (cmd_hash, args->argv[0]->str);
|
||||||
|
@ -123,16 +123,16 @@ Cmd_Command (cbuf_args_t *args)
|
||||||
if (cmd->function) {
|
if (cmd->function) {
|
||||||
cmd->function ();
|
cmd->function ();
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
// check cvars
|
// check cvars
|
||||||
if (Cvar_Command ())
|
if (Cvar_Command ())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (cbuf_active->strict)
|
if (cbuf_active->strict)
|
||||||
Cbuf_Error ("command", "Command '%s' not found.", args->argv[0]->str);
|
return -1;
|
||||||
else if (cmd_warncmd->int_val || developer->int_val)
|
else if (cmd_warncmd->int_val || developer->int_val)
|
||||||
Sys_Printf ("Unknown command \"%s\"\n", Cmd_Argv (0));
|
Sys_Printf ("Unknown command \"%s\"\n", Cmd_Argv (0));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Registers a command and handler function */
|
/* Registers a command and handler function */
|
||||||
|
|
|
@ -68,6 +68,13 @@ COM_destruct (cbuf_t *cbuf)
|
||||||
free(cbuf->data);
|
free(cbuf->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
COM_reset (cbuf_t *cbuf)
|
||||||
|
{
|
||||||
|
dstring_clearstr (DATA(cbuf)->buf);
|
||||||
|
dstring_clearstr (DATA(cbuf)->line);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
COM_add (cbuf_t *cbuf, const char *str)
|
COM_add (cbuf_t *cbuf, const char *str)
|
||||||
{
|
{
|
||||||
|
@ -232,6 +239,7 @@ COM_execute_sets (cbuf_t *cbuf)
|
||||||
cbuf_interpreter_t id_interp = {
|
cbuf_interpreter_t id_interp = {
|
||||||
COM_construct,
|
COM_construct,
|
||||||
COM_destruct,
|
COM_destruct,
|
||||||
|
COM_reset,
|
||||||
COM_add,
|
COM_add,
|
||||||
COM_insert,
|
COM_insert,
|
||||||
COM_execute,
|
COM_execute,
|
||||||
|
|
|
@ -681,10 +681,7 @@ Key_GIB_Bind_Get_f (void)
|
||||||
int t, k;
|
int t, k;
|
||||||
|
|
||||||
if (GIB_Argc() != 2) {
|
if (GIB_Argc() != 2) {
|
||||||
Cbuf_Error ("syntax",
|
GIB_USAGE ("key");
|
||||||
"bind::get: invalid syntax\n"
|
|
||||||
"usage: bind::get key"
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,12 +690,12 @@ Key_GIB_Bind_Get_f (void)
|
||||||
key = OK_TranslateKeyName (GIB_Argv (1));
|
key = OK_TranslateKeyName (GIB_Argv (1));
|
||||||
|
|
||||||
if ((t = Key_StringToIMTnum (imt)) == -1) {
|
if ((t = Key_StringToIMTnum (imt)) == -1) {
|
||||||
Cbuf_Error ("bind", "bind::get: invalid imt %s", imt);
|
GIB_Error ("bind", "bind::get: invalid imt %s", imt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((k = Key_StringToKeynum (key)) == -1) {
|
if ((k = Key_StringToKeynum (key)) == -1) {
|
||||||
Cbuf_Error ("bind", "bind::get: invalid key %s", key);
|
GIB_Error ("bind", "bind::get: invalid key %s", key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -409,9 +409,7 @@ Locs_Loc_Get (void)
|
||||||
location_t *location;
|
location_t *location;
|
||||||
|
|
||||||
if (GIB_Argc() != 1)
|
if (GIB_Argc() != 1)
|
||||||
Cbuf_Error ("syntax",
|
GIB_USAGE ("");
|
||||||
"loc::get: invalid syntax\n"
|
|
||||||
"usage: loc::get");
|
|
||||||
else {
|
else {
|
||||||
location = locs_find (cl.simorg);
|
location = locs_find (cl.simorg);
|
||||||
GIB_Return (location ? location->name : "unknown");
|
GIB_Return (location ? location->name : "unknown");
|
||||||
|
|
|
@ -55,6 +55,10 @@ Carne_Execute_Script (const char *path, cbuf_args_t *args)
|
||||||
if (f[0] == '#')
|
if (f[0] == '#')
|
||||||
for (; f[i] != '\n' && f[i+1]; i++);
|
for (; f[i] != '\n' && f[i+1]; i++);
|
||||||
Cbuf_AddText (mbuf, f+i);
|
Cbuf_AddText (mbuf, f+i);
|
||||||
|
GIB_DATA(mbuf)->script = malloc (sizeof (gib_script_t));
|
||||||
|
GIB_DATA(mbuf)->script->file = strdup (path);
|
||||||
|
GIB_DATA(mbuf)->script->text = strdup (f);
|
||||||
|
GIB_DATA(mbuf)->script->refs = 1;
|
||||||
free (f);
|
free (f);
|
||||||
}
|
}
|
||||||
Qclose (file);
|
Qclose (file);
|
||||||
|
@ -63,7 +67,10 @@ Carne_Execute_Script (const char *path, cbuf_args_t *args)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GIB_Parse_Strip_Comments (mbuf);
|
if (gib_parse_error)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GIB_Function_Prepare_Args (mbuf, args->argv, args->argc);
|
GIB_Function_Prepare_Args (mbuf, args->argv, args->argc);
|
||||||
|
|
||||||
|
@ -90,6 +97,7 @@ Carne_Execute_Stdin (void)
|
||||||
while (fgets(linebuf, sizeof(linebuf)-1, stdin)) {
|
while (fgets(linebuf, sizeof(linebuf)-1, stdin)) {
|
||||||
GIB_Thread_Execute ();
|
GIB_Thread_Execute ();
|
||||||
Cbuf_AddText (cbuf, linebuf);
|
Cbuf_AddText (cbuf, linebuf);
|
||||||
|
if (!gib_parse_error)
|
||||||
Cbuf_Execute_Stack (cbuf);
|
Cbuf_Execute_Stack (cbuf);
|
||||||
if (carne_done)
|
if (carne_done)
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue