mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 18:31:27 +00:00
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:
parent
62b541793d
commit
126f8502bd
9 changed files with 119 additions and 410 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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)
|
||||
|
|
|
@ -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
54
tools/qwaq/qwaq-curses.c
Normal 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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue