Start working on a qwaq console tool

The intention is it will hopefully become a debugger. It will certainly
help with development of the progs engine.
This commit is contained in:
Bill Currie 2020-02-26 22:10:59 +09:00
parent 62b541793d
commit 126f8502bd
9 changed files with 119 additions and 410 deletions

View file

@ -227,7 +227,10 @@ if test "x$ENABLE_tools_qfvis" = xyes; then
QF_NEED(libs,[util])
fi
if test "x$ENABLE_tools_qwaq" = xyes; then
QF_NEED(tools,[qwaq])
if test "x$HAVE_PANEL" = xyes -a "x$HAVE_PTHREAD" = xyes; then
QWAQ_TARGETS="$QWAQ_TARGETS qwaq-curses\$(EXEEXT)"
fi
QF_NEED(tools,[qfcc qwaq])
QF_NEED(libs,[ruamoko gamecode util])
fi
if test "x$ENABLE_tools_wad" = xyes; then

View file

@ -2,7 +2,7 @@ AC_ARG_ENABLE(curses,
[ --disable-curses disable curses support]
)
if test "x$enable_curses" != "xno"; then
AC_CHECK_HEADERS(curses.h)
AC_CHECK_HEADER(curses.h)
AC_CHECK_LIB(ncurses, initscr,
CURSES_LIBS=-lncurses,
AC_CHECK_LIB(pdcurses, initscr,
@ -13,7 +13,32 @@ if test "x$enable_curses" != "xno"; then
)
)
)
if test "x$CURSES_LIBS" != "x"; then
AC_DEFINE(HAVE_CURSES, 1, [Define if you have the ncurses library])
HAVE_CURSES=yes
else
HAVE_CURSES=no
fi
else
HAVE_CURSES=no
CURSES_LIBS=
fi
AC_SUBST(CURSES_LIBS)
if test "x$HAVE_CURSES" == "xyes"; then
AC_CHECK_HEADER(panel.h,
[AC_CHECK_LIB(panel, new_panel,
[AC_DEFINE(HAVE_PANEL, 1,
[Define if you have the ncurses panel library])
PANEL_LIBS=-lpanel
HAVE_PANEL=yes],
[HAVE_PANEL=no],
$CURSES_LIBS
)],
HAVE_PANEL=no,
[]
)
else
PANEL_LIBS=
fi
AC_SUBST(PANEL_LIBS)

View file

@ -2,21 +2,24 @@ QWAQ_LIBS=@QWAQ_LIBS@
QWAQ_DEPS=@QWAQ_DEPS@
QWAQ_INCS=@QWAQ_INCS@
AM_CPPFLAGS= -I$(top_srcdir)/include $(QWAQ_INCS)
AM_CPPFLAGS= -I$(top_srcdir)/include $(QWAQ_INCS) $(PTHREAD_CFLAGS)
QFCC_DEP=$(top_builddir)/tools/qfcc/source/qfcc$(EXEEXT)
QFCC=$(top_builddir)/tools/qfcc/source/qfcc
QCFLAGS=-qq -O -g -Werror --advanced --no-default-paths
noinst_PROGRAMS=qwaq @QWAQ_TARGETS@
noinst_DATA=qwaq.dat
noinst_PROGRAMS=@QWAQ_TARGETS@
noinst_DATA= #qwaq.dat
qwaq_dat_src= \
defs.qc main.qc test.r types.r
$e
qwaq_SOURCES= main.c builtins.c
qwaq_LDADD= $(QWAQ_LIBS)
qwaq_DEPENDENCIES= $(QWAQ_DEPS)
qwaq_curses_libs=
qwaq_curses_SOURCES=main.c qwaq-curses.c
qwaq_curses_LDADD= $(qwaq_curses_libs) $(QWAQ_LIBS) \
$(PANEL_LIBS) $(CURSES_LIBS) $(PTHREAD_LDFLAGS) $(DL_LIBS)
qwaq_curses_LDFLAGS=
qwaq_curses_DEPENDENCIES= $(qwaq_curses_libs) $(QWAQ_DEPS)
cl_plugin_libs= \
@client_static_plugin_libs@
@ -42,9 +45,9 @@ qwaq_x11_LDADD= $(qwaq_x11_libs) $(QWAQ_LIBS) \
qwaq_x11_LDFLAGS=
qwaq_x11_DEPENDENCIES= $(qwaq_x11_libs) $(QWAQ_DEPS)
qwaq.dat: progs.src $(qwaq_dat_src) $(QFCC_DEP) $(top_srcdir)/ruamoko/lib/Object.r
$(QFCC) $(QCFLAGS) -I$(top_srcdir)/ruamoko/include
#qwaq.dat: $(qwaq_dat_src) $(QFCC_DEP) $(top_srcdir)/ruamoko/lib/Object.r
# $(QFCC) $(QCFLAGS) -I$(top_srcdir)/ruamoko/include
EXTRA_PROGRAMS=qwaq-x11
EXTRA_PROGRAMS=qwaq-curses qwaq-x11
EXTRA_DIST=$(qwaq_dat_src) qwaq.h
CLEANFILES= *.dat *.sym

View file

@ -1,22 +0,0 @@
void (string str) print = #0;
int () errno = #0;
string (int err) strerror = #0;
int (...) open = #0; // string path, float flags[, float mode]
int (int handle) close = #0;
string read (int handle, int count, int *result) = #0;
int (int handle, string buffer, int count) write = #0;
int (int handle, int pos, int whence) seek = #0;
//void() traceon = #0; // turns statment trace on
//void() traceoff = #0;
void (...) printf = #0;
float time;
entity self;
.float nextthink;
.void() think;
.float frame;
.vector origin;

View file

@ -33,24 +33,27 @@
#include <stdlib.h>
#include <QF/cmd.h>
#include <QF/cvar.h>
#include <QF/progs.h>
#include <QF/quakefs.h>
#include "QF/cbuf.h"
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/gib.h"
#include "QF/idparse.h"
#include "QF/progs.h"
#include "QF/qargs.h"
#include "QF/quakefs.h"
#include "QF/ruamoko.h"
#include <QF/sys.h>
#include "QF/sys.h"
#include "QF/va.h"
#include <QF/zone.h>
#include "QF/zone.h"
#include "qwaq.h"
#define MAX_EDICTS 1024
static edict_t *edicts;
static int num_edicts;
static int reserved_edicts;
static progs_t pr;
cbuf_t *qwaq_cbuf;
static QFile *
open_file (const char *path, int *len)
{
@ -100,17 +103,18 @@ free_progs_mem (progs_t *pr, void *mem)
static void
init_qf (void)
{
Sys_Init ();
//Cvar_Get ("developer", "128", 0, 0, 0);
qwaq_cbuf = Cbuf_New (&id_interp);
Memory_Init (malloc (1024 * 1024), 1024 * 1024);
Sys_Init ();
COM_ParseConfig ();
//Cvar_Set (developer, "1");
Memory_Init (malloc (8 * 1024 * 1024), 8 * 1024 * 1024);
Cvar_Get ("pr_debug", "2", 0, 0, 0);
Cvar_Get ("pr_boundscheck", "0", 0, 0, 0);
pr.edicts = &edicts;
pr.num_edicts = &num_edicts;
pr.reserved_edicts = &reserved_edicts;
pr.load_file = load_file;
pr.allocate_progs_mem = allocate_progs_mem;
pr.free_progs_mem = free_progs_mem;
@ -119,7 +123,7 @@ init_qf (void)
PR_Init_Cvars ();
PR_Init (&pr);
RUA_Init (&pr, 0);
PR_Cmds_Init(&pr);
PR_Cmds_Init (&pr);
BI_Init (&pr);
}
@ -144,7 +148,7 @@ load_progs (const char *name)
}
int
main (int argc, char **argv)
main (int argc, const char **argv)
{
dfunction_t *dfunc;
func_t main_func = 0;
@ -152,6 +156,7 @@ main (int argc, char **argv)
string_t *pr_argv;
int pr_argc = 1, i;
COM_InitArgv (argc, argv);
init_qf ();
if (argc > 1)

View file

@ -1,114 +0,0 @@
string read_file (string filename)
{
local QFile file;
local string data = nil, d;
file = Qopen (filename, "rtz");
if (!file) {
printf ("Can't open %s for reading."
" Probably a bad hardcoded filename:)\n", filename);
return nil;
}
while ((d = Qgetline (file)))
data = data + d;
//FIXME can't read to a string, can't convert a pointer to a string ...
//Qread (file, data, 1023);
Qclose (file);
d = str_new ();
str_copy (d, data);
return d;
}
void test_plist (void)
{
local string data, l;
local plitem_t pl, item, i;
data = read_file ("/home/bill/.quakeforge/gamedir.conf");
pl = PL_GetPropertyList ("{" + data + "}");
l = PL_WritePropertyList (pl);
printf ("%s", data);
printf ("%s", l);
i = PL_ObjectForKey (pl, "QF");
item = PL_RemoveObjectForKey (pl, "QF");
l = PL_WritePropertyList (item);
printf ("%s", l);
PL_Free (item);
//Because i and item both point to the same plitem, and item has been,
//freed, freeing i will generate an error
//l = PL_WritePropertyList (i);
PL_Free (pl);
str_free (data);
}
void test_script (void)
{
local script_t script;
local string token;
local string data;
data = read_file ("progs.src");
script = Script_New ();
token = Script_Start (script, "progs.src", data);
while (Script_GetToken (script, 1)) {
printf ("%s\n", token);
}
Script_Delete (script);
str_free (data);
}
void () test_str =
{
local string a,b,c,d;
a = "testing ";
b = "temp ";
c = "strings ";
d = "\n";
print (a + b + c + d);
printf ("%i \"%.5s\" %3.4f %v\n", 14, "hi there", 3.1415926, '4 1 3');
};
void (...) dprint = #0;
int main (int argc, string *argv)
{
local int i;
local SEL sel;
dprint ("foo", "bar\n");
for (i = 0; i < argc; i++) {
print (argv[i]);
print ("\n");
}
local id foo = [[Foo alloc] init];
[foo run];
sel = sel_get_uid ("run");
if (sel) {
print ("found selector for `run'\n");
if ([foo respondsToSelector:sel])
print ("foo responds to `run'\n");
else
print ("foo does not repond to `run'\n");
} else
print ("did not find selector for `run'\n");
sel = sel_get_uid ("alloc");
if (sel) {
print ("found selector for `alloc'\n");
if ([Object instancesRespondToSelector:sel])
print ("Object instances respond to `alloc'\n");
else
print ("Object instances do not repond to `alloc'\n");
} else
print ("did not find selector for `alloc'\n");
sel = sel_get_uid ("run:with:me:");
if (sel) {
print ("found selector for `run:with:me:'\n");
if ([Object instancesRespondToSelector:sel])
print ("Object instances respond to `run:with:me:'\n");
else
print ("Object instances do not repond to `run:with:me:'\n");
} else
print ("did not find selector for `run:with:me:'\n");
test_str ();
test_script ();
test_plist ();
test_types ();
test_xdefs ();
return 0;
};

54
tools/qwaq/qwaq-curses.c Normal file
View file

@ -0,0 +1,54 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2001 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/progs.h"
#include "QF/sys.h"
#include "qwaq.h"
static builtin_t builtins[] = {
{0}
};
static void
bi_shutdown (void)
{
}
void
BI_Init (progs_t *pr)
{
PR_RegisterBuiltins (pr, builtins);
Sys_RegisterShutdown (bi_shutdown);
}

View file

@ -1,42 +0,0 @@
@interface Foo : Object
{
int x;
}
-run;
@end
@implementation Foo
+load
{
print ("+load\n");
return self;
}
+alloc
{
print ("+alloc\n");
return class_create_instance (self);
}
-init
{
print ("-init\n");
return [super init];
}
+ (void) initialize
{
print ("+initialize\n");
}
-run
{
print ("Hello world\n");
printf ("%i %p [%s %s]\n", self, &self.x, [self description],
__PRETTY_FUNCTION__);
return self;
}
@end

View file

@ -1,203 +0,0 @@
#include "runtime.h" //FIXME for PR_FindGlobal
typedef enum {
ev_void,
ev_string,
ev_float,
ev_vector,
ev_entity,
ev_field,
ev_func,
ev_pointer, // end of v6 types
ev_quat,
ev_integer,
ev_uinteger,
ev_short, // value is embedded in the opcode
ev_double,
ev_invalid, // invalid type. used for instruction checking
ev_type_count // not a type, gives number of types
} etype_t;
typedef enum {
ty_none, ///< func/field/pointer or not used
ty_struct,
ty_union,
ty_enum,
ty_array,
ty_class,
} ty_meta_e;
typedef struct qfot_fldptr_s {
etype_t type;
struct qfot_type_s *aux_type;
} qfot_fldptr_t;
typedef struct qfot_func_s {
etype_t type;
struct qfot_type_s *return_type;
int num_params;
struct qfot_type_s *param_types[1];
} qfot_func_t;
typedef struct qfot_var_s {
struct qfot_type_s *type;
string name;
int offset; // value for enum, 0 for union
} qfot_var_t;
typedef struct qfot_struct_s {
string tag;
int num_fields;
qfot_var_t fields[1];
} qfot_struct_t;
typedef struct qfot_array_s {
struct qfot_type_s *type;
int base;
int size;
} qfot_array_t;
typedef struct qfot_type_s {
ty_meta_e meta;
int size;
string encoding;
union {
etype_t type;
qfot_fldptr_t fldptr;
qfot_func_t func;
qfot_struct_t strct;
qfot_array_t array;
string class;
} t;
} qfot_type_t;
typedef struct qfot_type_encodings_s {
qfot_type_t *types;
int size;
} qfot_type_encodings_t;
typedef struct xdef_s {
qfot_type_t *type;
void *offset;
} xdef_t;
typedef struct pr_xdefs_s {
xdef_t *xdefs;
int num_xdefs;
} pr_xdefs_t;
qfot_type_t *
next_type (qfot_type_t *type)
{
int size = type.size;
if (!size)
size = 4;
return (qfot_type_t *) ((int *) type + size);
}
string ty_meta_name[6] = {
"basic",
"struct",
"union",
"enum",
"array",
"class",
};
string pr_type_name[ev_type_count] = {
"void",
"string",
"float",
"vector",
"entity",
"field",
"function",
"pointer",
"quaternion",
"integer",
"uinteger",
"short",
"double"
"invalid",
};
void
test_types (void)
{
qfot_type_encodings_t *encodings;
qfot_type_t *type;
int i;
encodings = PR_FindGlobal (".type_encodings");
if (!encodings) {
printf ("Can't find encodings\n");
return;
}
for (type = encodings.types;
((int *)type - (int *) encodings.types) < encodings.size;
type = next_type (type)) {
printf ("%p %-6s %-20s", type, ty_meta_name[type.meta],
type.encoding);
if (!type.size) {
printf ("\n");
continue;
}
switch (type.meta) {
case ty_none:
printf (" %-10s", pr_type_name[type.t.type]);
if (type.t.type == ev_func) {
int count = type.t.func.num_params;
printf ("%p %d", type.t.func.return_type, count);
if (count < 0)
count = ~count;
for (i = 0; i < count; i++)
printf (" %p", type.t.func.param_types[i]);
} else if (type.t.type == ev_pointer) {
printf (" *%p", type.t.fldptr.aux_type);
} else if (type.t.type == ev_field) {
printf (" .%p", type.t.fldptr.aux_type);
} else {
printf (" %p", type.t.fldptr.aux_type);
}
printf ("\n");
break;
case ty_struct:
case ty_union:
case ty_enum:
printf (" %s\n", type.t.strct.tag);
for (i = 0; i < type.t.strct.num_fields; i++) {
printf (" %p %4x %s\n",
type.t.strct.fields[i].type,
type.t.strct.fields[i].offset,
type.t.strct.fields[i].name);
}
break;
case ty_array:
printf (" %p %d %d\n", type.t.array.type,
type.t.array.base, type.t.array.size);
break;
case ty_class:
printf (" %s %p\n", type.t.class,
obj_lookup_class (type.t.class));
break;
}
}
}
void
test_xdefs (void)
{
pr_xdefs_t *xdefs;
int i;
xdefs = PR_FindGlobal (".xdefs");
if (!xdefs) {
printf ("Can't find xdefs\n");
return;
}
printf ("%p %i\n", xdefs.xdefs, xdefs.num_xdefs);
for (i = 0; i < xdefs.num_xdefs; i++) {
printf ("%p %p\n", xdefs.xdefs[i].type, xdefs.xdefs[i].offset);
}
}