quakeforge/tools/carne/main.c
Brian Koropoff 687a0845b6 Introducing the GIB Object System (TM). This breaks scriptable HUD for now
and probably has enough bugs to leave the Orkin man scratching his head,
but it works and allows you to do neat things like write classes in GIB
(amazing!) and subclass builtin classes (which are Object and Thread at the
moment, Hash should be coming soon as a replacement for stem and leaf
variables).
2003-09-11 06:03:13 +00:00

133 lines
2.7 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "QF/cbuf.h"
#include "QF/cmd.h"
#include "QF/sys.h"
#include "QF/cvar.h"
#include "QF/zone.h"
#include "QF/quakefs.h"
#include "QF/quakeio.h"
#include "QF/gib.h"
#include "QF/dstring.h"
#include "QF/va.h"
#include "gib_thread.h"
#include "gib_parse.h"
static qboolean carne_done = false;
static int carne_exitcode = 0;
static void
Carne_GIB_Exit_f (void)
{
carne_done = true;
// Put it in wait mode so that Cbuf_Execute_Stack clears out
// we can then safely nuke the stack later
cbuf_active->state = CBUF_STATE_WAIT;
if (GIB_Argc() == 2)
carne_exitcode = atoi (GIB_Argv(1));
}
static int
Carne_Execute_Script (const char *path, cbuf_args_t *args)
{
QFile *file;
cbuf_t *mbuf = Cbuf_New (GIB_Interpreter ());
char *f;
int len, i;
file = Qopen (path, "r");
if (file) {
len = Qfilesize (file);
f = (char *) malloc (len + 1);
if (f) {
f[len] = 0;
Qread (file, f, len);
// If there is a hash-bang, strip it out
i = 0;
if (f[0] == '#')
for (; f[i] != '\n' && f[i+1]; 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);
}
Qclose (file);
} else {
printf ("Could not open %s for reading: %s\n", path, strerror(errno));
carne_exitcode = 1;
goto ERROR;
}
if (gib_parse_error) {
carne_exitcode = 2;
goto ERROR;
}
GIB_Function_Prepare_Args_D (mbuf, args->argv, args->argc);
// Main loop
while (1) {
GIB_Thread_Execute ();
Cbuf_Execute_Stack (mbuf);
// Check if there is anything left to do
if (carne_done || !GIB_DATA(mbuf)->program)
break;
}
ERROR:
Cbuf_DeleteStack (mbuf);
return carne_exitcode;
}
static int
Carne_Execute_Stdin (void)
{
char linebuf[1024];
cbuf_t *cbuf = Cbuf_New (GIB_Interpreter ());
memset (linebuf, 0, sizeof(linebuf));
while (fgets(linebuf, sizeof(linebuf)-1, stdin)) {
GIB_Thread_Execute ();
Cbuf_AddText (cbuf, linebuf);
if (!gib_parse_error)
Cbuf_Execute_Stack (cbuf);
if (carne_done)
break;
}
Cbuf_DeleteStack (cbuf);
return carne_exitcode;
}
int
main (int argc, char **argv)
{
cbuf_args_t *args;
int result, i;
// Initialize required QF subsystems
Cvar_Init_Hash ();
Cmd_Init_Hash ();
Cmd_Init ();
Cvar_Init ();
GIB_Init (false); // No sandbox
GIB_Builtin_Add ("exit", Carne_GIB_Exit_f);
if (argc > 1) {
// Prepare arguments
args = Cbuf_ArgsNew ();
for (i = 1; i < argc; i++)
Cbuf_ArgsAdd (args, argv[i]);
// Run the script
result = Carne_Execute_Script (argv[1], args);
Cbuf_ArgsDelete (args);
return result;
} else
return Carne_Execute_Stdin ();
}