590 lines
24 KiB
C++
590 lines
24 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef GLK_TADS_TADS2_DEBUG
|
|
#define GLK_TADS_TADS2_DEBUG
|
|
|
|
#include "glk/tads/tads2/lib.h"
|
|
#include "glk/tads/tads2/object.h"
|
|
#include "glk/tads/os_glk.h"
|
|
|
|
namespace Glk {
|
|
namespace TADS {
|
|
namespace TADS2 {
|
|
|
|
|
|
/* forward declarations */
|
|
struct bifcxdef;
|
|
struct toksdef;
|
|
struct toktdef;
|
|
struct tokcxdef;
|
|
|
|
/* stack frame record */
|
|
struct dbgfdef
|
|
{
|
|
struct runsdef *dbgfbp; /* base pointer of frame */
|
|
objnum dbgfself; /* 'self' object (MCMONINV for functions) */
|
|
objnum dbgftarg; /* actual target object */
|
|
prpnum dbgfprop; /* property being evalutated */
|
|
int dbgfargc; /* number of arguments */
|
|
int dbgfbif; /* set to built-in function number if in built-in */
|
|
uint dbgffr; /* offset in object of local frame symbol table */
|
|
uint dbgflin; /* OPCLINE operand of latest line */
|
|
};
|
|
typedef struct dbgfdef dbgfdef;
|
|
|
|
/* max number of frames to store in debug frame memory */
|
|
#define DBGMAXFRAME 100
|
|
|
|
/* maximum number of breakpoints set concurrently */
|
|
#define DBGBPMAX 50
|
|
|
|
/* breakpoint structure */
|
|
struct dbgbpdef
|
|
{
|
|
objnum dbgbpself; /* the "self" object for the breakpoint */
|
|
objnum dbgbptarg; /* actual target object for the breakpoint */
|
|
uint dbgbpofs; /* offset in object of the breakpoint */
|
|
uint dbgbpflg; /* breakpoint flags */
|
|
#define DBGBPFUSED 0x01 /* breakpoint has been set */
|
|
#define DBGBPFNAME 0x02 /* name of address has been stored */
|
|
#define DBGBPFCOND 0x04 /* breakpoint has a condition attached */
|
|
#define DBGBPFDISA 0x08 /* breakpoint is disabled */
|
|
#define DBGBPFCONDNAME 0x10 /* condition name string has been stored */
|
|
uint dbgbpnam; /* offset of address name within dbgcxnam buffer */
|
|
uint dbgbpcondnam; /* offset of condition string within buffer */
|
|
objnum dbgbpcond; /* object containing compiled condition for bp */
|
|
};
|
|
typedef struct dbgbpdef dbgbpdef;
|
|
|
|
/* maximum number of watch expressions set concurrently */
|
|
#define DBGWXMAX 30
|
|
|
|
/* watch expression structure */
|
|
struct dbgwxdef
|
|
{
|
|
objnum dbgwxobj; /* object containing compiled expression */
|
|
objnum dbgwxself; /* 'self' for the expression */
|
|
uint dbgwxnam; /* offset of expression text within dbgcxnam buffer */
|
|
uint dbgwxflg; /* flags for this watch expression slot */
|
|
#define DBGWXFUSED 0x01 /* watch slot is in use */
|
|
#define DBGWXFNAME 0x02 /* name of watch has been stored */
|
|
};
|
|
typedef struct dbgwxdef dbgwxdef;
|
|
|
|
/* amount of space for bp names (original address strings from user) */
|
|
#define DBGCXNAMSIZ 2048
|
|
|
|
/* debug context */
|
|
struct dbgcxdef
|
|
{
|
|
struct tiocxdef *dbgcxtio; /* text i/o context */
|
|
struct tokthdef *dbgcxtab; /* symbol table */
|
|
struct mcmcxdef *dbgcxmem; /* memory cache manager context */
|
|
struct errcxdef *dbgcxerr; /* error handling context */
|
|
struct lindef *dbgcxlin; /* chain of line sources */
|
|
int dbgcxfcn; /* number of frames in use */
|
|
int dbgcxdep; /* actual depth (if overflow frame buffer) */
|
|
int dbgcxfid; /* source file serial number */
|
|
dbgfdef dbgcxfrm[DBGMAXFRAME]; /* stack frames */
|
|
int dbgcxflg; /* flags for debug session */
|
|
#define DBGCXFSS 0x01 /* single-stepping source lines */
|
|
#define DBGCXFSO 0x02 /* stepping over a function/method call */
|
|
#define DBGCXFOK 0x04 /* debugger is linked in */
|
|
#define DBGCXFIND 0x08 /* in debugger - suppress stack trace on err */
|
|
#define DBGCXFGBP 0x10 /* global breakpoints in effect */
|
|
#define DBGCXFTRC 0x20 /* call tracing activated */
|
|
#define DBGCXFLIN2 0x40 /* new-style line records (line numbers) */
|
|
int dbgcxsof; /* frame depth at step-over time */
|
|
dbgbpdef dbgcxbp[DBGBPMAX]; /* breakpoints */
|
|
dbgwxdef dbgcxwx[DBGWXMAX]; /* watch expressions */
|
|
struct prscxdef *dbgcxprs; /* parsing context */
|
|
struct runcxdef *dbgcxrun; /* execution context */
|
|
uint dbgcxnamf; /* next free byte of dbgcxnam buffer */
|
|
uint dbgcxnams; /* size of dbgcxnam buffer */
|
|
char *dbgcxnam; /* space for bp address names */
|
|
char *dbgcxhstp; /* call history buffer */
|
|
uint dbgcxhstl; /* history buffer length */
|
|
uint dbgcxhstf; /* offset of next free byte of history */
|
|
|
|
/*
|
|
* This member is for the use of the user interface code. If the
|
|
* user interface implementation needs to store additional context,
|
|
* it can allocate a structure of its own (it should probably do
|
|
* this in dbguini()) and store a pointer to that structure here.
|
|
* Since the user interface entrypoints always have the debugger
|
|
* context passed as a parameter, the user interface code can
|
|
* recover its extra context information by following this pointer
|
|
* and casting it to its private structure type. The TADS code
|
|
* won't do anything with this pointer except initialize it to null
|
|
* when initializing the debugger context.
|
|
*/
|
|
void *dbgcxui;
|
|
};
|
|
typedef struct dbgcxdef dbgcxdef;
|
|
|
|
|
|
/* ======================================================================== */
|
|
/*
|
|
* Compiler interface. These routines are called by the compiler to
|
|
* inform the debug record generator about important events as
|
|
* compilation proceeds.
|
|
*/
|
|
|
|
|
|
/*
|
|
* Tell the current line source that we're compiling an executable
|
|
* line, and tell it the object number and offset of the code within the
|
|
* object.
|
|
*/
|
|
void dbgclin(struct tokcxdef *tokctx, objnum objn, uint ofs);
|
|
|
|
/* size of information given to line source via lincmpinf method */
|
|
#define DBGLINFSIZ 4
|
|
|
|
|
|
|
|
/* ======================================================================== */
|
|
/*
|
|
* Run-time interface. These routines are called by the run-time
|
|
* system to apprise the debugger of important events during execution.
|
|
*/
|
|
|
|
|
|
/*
|
|
* Determine if the debugger is present. Returns true if so, false if
|
|
* not. This should return false for any stand-alone version of the
|
|
* executable that isn't linked with the debugger. If this returns
|
|
* true, dbgucmd() must not have a trivial implementation -- dbgucmd()
|
|
* must at least let the user quit out of the game.
|
|
*
|
|
* This can be switched at either link time or compile time. If DBG_OFF
|
|
* is defined, we'll force this to return false; otherwise, we'll let
|
|
* the program define the appropriate implementation through the linker.
|
|
*/
|
|
#ifdef DBG_OFF
|
|
#define dbgpresent() (false)
|
|
#else
|
|
int dbgpresent();
|
|
#endif
|
|
|
|
|
|
/* add a debug tracing record */
|
|
/* void dbgenter(dbgcxdef *ctx, runsdef *bp, objnum self, objnum target,
|
|
prpnum prop, int binum, int argc); */
|
|
|
|
/* tell debugger where the current line's local frame table is located */
|
|
/* void dbgframe(dbgcxdef *ctx, uint ofsfr, ofslin); */
|
|
|
|
/*
|
|
* Single-step interrupt: the run-time has reached a new source line.
|
|
* ofs is the offset from the start of the object of the line record,
|
|
* and p is the current execution pointer. *p can be changed upon
|
|
* return, in which case the run-time will continue from the new
|
|
* position; however, the new address must be within the same function
|
|
* or method as it was originally.
|
|
*/
|
|
/* void dbgssi(dbgcxdef *ctx, uint ofs, int instr,
|
|
int err, uchar *noreg *p); */
|
|
|
|
/* pop debug trace level */
|
|
/* void dbgleave(dbgcxdef *ctx, int exittype); */
|
|
#define DBGEXRET 0 /* return with no value */
|
|
#define DBGEXVAL 1 /* return with a value */
|
|
#define DBGEXPASS 2 /* use 'pass' to exit a function */
|
|
|
|
/* dump the stack into text output */
|
|
/* void dbgdump(dbgcxdef *ctx); */
|
|
|
|
/* reset debug stack (throw away entire contents) */
|
|
/* void dbgrst(dbgcxdef *ctx); */
|
|
|
|
/* activate debugger if possible; returns TRUE if no debugger is present */
|
|
int dbgstart(dbgcxdef *ctx);
|
|
|
|
/* add a string to the history buffer */
|
|
void dbgaddhist(dbgcxdef *ctx, char *buf, int bufl);
|
|
|
|
/*
|
|
* Find a base pointer, given the object+offset of the frame. If the
|
|
* frame is not active, this routine signals ERR_INACTFR; otherwise, the
|
|
* bp value for the frame is returned.
|
|
*/
|
|
struct runsdef *dbgfrfind(dbgcxdef *ctx, objnum frobj, uint frofs);
|
|
|
|
|
|
/* ======================================================================== */
|
|
/*
|
|
* User Interface Support routines. These routines are called by the
|
|
* user interface layer to get information from the debugger and perform
|
|
* debugging operations.
|
|
*/
|
|
|
|
|
|
/* get a symbol name; returns length of name */
|
|
int dbgnam(dbgcxdef *ctx, char *outbuf, int typ, int val);
|
|
|
|
/*
|
|
* Get information about current line. It is assumed that the caller
|
|
* knows the size of the line information .
|
|
*/
|
|
void dbglget(dbgcxdef *ctx, uchar *buf);
|
|
|
|
/*
|
|
* Get information about a line in an enclosing stack frame. Level 0 is
|
|
* the current line, level 1 is the first enclosing frame, and so on.
|
|
* Returns 0 on success, non-zero if the frame level is invalid.
|
|
*/
|
|
int dbglgetlvl(dbgcxdef *ctx, uchar *buf, int level);
|
|
|
|
/*
|
|
* Set a breakpoint by symbolic address: "function" or
|
|
* "object.property". The string may contain whitespace characters
|
|
* around each symbol; it must be null-terminated. If an error occurs,
|
|
* the error number is returned. bpnum returns with the breakpoint
|
|
* number if err == 0. If the condition string is given (and is not an
|
|
* empty string), the condition is compiled in the scope of the
|
|
* breakpoint and attached as the breakpoint condition.
|
|
*/
|
|
int dbgbpset(dbgcxdef *ctx, char *addr, int *bpnum);
|
|
|
|
/*
|
|
* Set a breakpoint at an object + offset location. If 'toggle' is
|
|
* true, and there's already a breakpoint at the given location, we'll
|
|
* clear the breakpoint; in this case, *did_set will return false to
|
|
* indicate that an existing breakpoint was cleared rather than a new
|
|
* breakpoint created. *did_set will return true if a new breakpoint
|
|
* was set.
|
|
*/
|
|
int dbgbpat(dbgcxdef *ctx, objnum objn, objnum self,
|
|
uint ofs, int *bpnum, char *bpname, int toggle,
|
|
char *condition, int *did_set);
|
|
|
|
/*
|
|
* Set a breakpoint at an object + offset location, optionally with a
|
|
* condition, using an existing breakpoint slot. If the slot is already
|
|
* in use, we'll return an error.
|
|
*/
|
|
int dbgbpatid(dbgcxdef *ctx, int bpnum, objnum target, objnum self,
|
|
uint ofs, char *bpname, int toggle, char *cond,
|
|
int *did_set);
|
|
|
|
/*
|
|
* Determine if there's a breakpoint at a given code location. Fills in
|
|
* *bpnum with the breakpoint identifier and returns true if a
|
|
* breakpoint is found at the given location; returns false if there are
|
|
* no breakpoints matching the description.
|
|
*/
|
|
int dbgisbp(dbgcxdef *ctx, objnum target, objnum self, uint ofs, int *bpnum);
|
|
|
|
/*
|
|
* Determine if the given breakpoint is enabled
|
|
*/
|
|
int dbgisbpena(dbgcxdef *ctx, int bpnum);
|
|
|
|
/*
|
|
* Delete a breakpoint by breakpoint number (as returned from
|
|
* dbgbpset). Returns error number, or 0 for success.
|
|
*/
|
|
int dbgbpdel(dbgcxdef *ctx, int bpnum);
|
|
|
|
/* disable or enable a breakpoint, by breakpoint number; returns error num */
|
|
int dbgbpdis(dbgcxdef *ctx, int bpnum, int disable);
|
|
|
|
/*
|
|
* Set a new condition for the given breakpoint. Replaces any existing
|
|
* condition. If an error occurs, we'll leave the old condition as it
|
|
* was and return a non-zero error code; on success, we'll update the
|
|
* condition and return zero.
|
|
*/
|
|
int dbgbpsetcond(dbgcxdef *ctx, int bpnum, char *cond);
|
|
|
|
/* list breakpoints, using user callback to do display */
|
|
void dbgbplist(dbgcxdef *ctx,
|
|
void (*dispfn)(void *ctx, const char *str, int len),
|
|
void *dispctx);
|
|
|
|
/* enumerate breakpoints */
|
|
void dbgbpenum(dbgcxdef *ctx,
|
|
void (*cbfunc)(void *cbctx, int bpnum, const char *desc,
|
|
const char *cond, int disabled), void *cbctx);
|
|
|
|
/* call callback with lindef data for each breakpoint currently set */
|
|
void dbgbpeach(dbgcxdef *ctx,
|
|
void (*fn)(void *, int, uchar *, uint),
|
|
void *fnctx);
|
|
|
|
/*
|
|
* Get information on a specific breakpoint. Returns zero on success,
|
|
* non-zero on failure.
|
|
*/
|
|
int dbgbpgetinfo(dbgcxdef *ctx, int bpnum, char *descbuf, size_t descbuflen,
|
|
char *condbuf, size_t condbuflen);
|
|
|
|
/*
|
|
* Evaluate an expression (a text string to be parsed) at a particular
|
|
* stack context level; returns error number. Invokes the callback
|
|
* function repeatedly to display the value string, and ends the display
|
|
* with a newline. If showtype is true, we'll include a type name
|
|
* prefix, otherwise we'll simply display the value.
|
|
*/
|
|
int dbgeval(dbgcxdef *ctx, char *expr,
|
|
void (*dispfn)(void *dispctx, const char *str, int strl),
|
|
void *dispctx, int level, int showtype);
|
|
|
|
/*
|
|
* Evaluate an expression, extended version. For aggregate values
|
|
* (objects, lists), we'll invoke a callback function for each value
|
|
* contained by the aggregate value, passing the callback the name and
|
|
* relationship of the subitem. The relationship is simply the operator
|
|
* that should be used to join the parent expression and the subitem
|
|
* name to form the full subitem expression; for objects, it's ".", and
|
|
* for lists it's null (because for lists the subitem names will include
|
|
* brackets). 'speculative' is passed to dbgcompile; see the comments
|
|
* there for information on the purpose of this flag.
|
|
*/
|
|
int dbgevalext(dbgcxdef *ctx, char *expr,
|
|
void (*dispfn)(void *dispctx, const char *str, int strl),
|
|
void *dispctx, int level, int showtype, dattyp *dat,
|
|
void (*aggcb)(void *aggctx, const char *subname,
|
|
int subnamelen, const char *relationship),
|
|
void *aggctx, int speculative);
|
|
|
|
/*
|
|
* enumerate local variables at a given stack context level by calling
|
|
* the given function once for each local variable
|
|
*/
|
|
void dbgenumlcl(dbgcxdef *ctx, int level,
|
|
void (*func)(void *ctx, const char *lclnam, size_t lclnamlen),
|
|
void *cbctx);
|
|
|
|
/*
|
|
* Compile an expression in a given frame context. Returns an error
|
|
* number. Allocates a new object to contain the compiled code, and
|
|
* returns the object number in *objn; the caller is responsible for
|
|
* freeing the object when done with it.
|
|
*
|
|
* If 'speculative' is set to true, we'll prohibit the expression from
|
|
* making any assignments or calling any methods or functions. This
|
|
* mode can be used to try compiling an expression that the user could
|
|
* conceivably be interested in but has not expressly evaluated; for
|
|
* example, this can be used to implement "tooltip evaluation," where
|
|
* the debugger automatically shows a little pop-up window with the
|
|
* expression under the mouse cursor if the mouse cursor is left
|
|
* hovering over some text for a few moments. In such cases, since the
|
|
* user hasn't explicitly requested evaluation, it would be bad to make
|
|
* any changes to game state, hence the prohibition of assignments or
|
|
* calls.
|
|
*/
|
|
int dbgcompile(dbgcxdef *ctx, char *expr, dbgfdef *fr, objnum *objn,
|
|
int speculative);
|
|
|
|
/* display a stack traceback through a user callback */
|
|
void dbgstktr(dbgcxdef *ctx,
|
|
void (*dispfn)(void *dispctx, const char *str, int strl),
|
|
void *dispctx, int level, int toponly, int include_markers);
|
|
|
|
/* format a display of where execution is stopped into a buffer */
|
|
void dbgwhere(dbgcxdef *ctx, char *buf);
|
|
|
|
/* set a watch expression; returns error or 0 for success */
|
|
int dbgwxset(dbgcxdef *ctx, char *expr, int *wxnum, int level);
|
|
|
|
/* delete a watch expression */
|
|
int dbgwxdel(dbgcxdef *ctx, int wxnum);
|
|
|
|
/* update all watch expressions */
|
|
void dbgwxupd(dbgcxdef *ctx,
|
|
void (*dispfn)(void *dispctx, const char *txt, int len),
|
|
void *dispctx);
|
|
|
|
/* switch to a new active lindef */
|
|
void dbgswitch(struct lindef **linp, struct lindef *newlin);
|
|
|
|
|
|
|
|
/* ======================================================================== */
|
|
/*
|
|
* User Interface Routines. The routines are called by the debugger
|
|
* to perform user interaction.
|
|
*/
|
|
|
|
/*
|
|
* Debugger user interface initialization, phase one. TADS calls this
|
|
* routine during startup, before reading the .GAM file, to let the user
|
|
* interface perform any initialization it requires before the .GAM file
|
|
* is loaded.
|
|
*/
|
|
void dbguini(dbgcxdef *ctx, const char *game_filename);
|
|
|
|
/*
|
|
* Debugger user interface initialization, phase two. TADS calls this
|
|
* routine during startup, after read the .GAM file. The debugger user
|
|
* interface code can perform any required initialization that depends
|
|
* on the .GAM file having been read.
|
|
*/
|
|
void dbguini2(dbgcxdef *ctx);
|
|
|
|
/*
|
|
* Determine if the debugger can resume from a run-time error. This
|
|
* reflects the capabilities of the user interface of the debugger. In
|
|
* particular, if the UI provides a way to change the instruction
|
|
* pointer, then the debugger can resume from an error, since the user
|
|
* can always move past the run-time error and continue execution. If
|
|
* the UI doesn't let the user change the instruction pointer, resuming
|
|
* from an error won't work, since the program will keep hitting the
|
|
* same error and re-entering the debugger. If this returns false, the
|
|
* run-time will trap to the debugger on an error, but will simply abort
|
|
* the current command when the debugger returns. If this returns true,
|
|
* the run-time will trap to the debugger on an error with the
|
|
* instruction pointer set back to the start of the line containing the
|
|
* error, and will thus re-try the same line of code when the debugger
|
|
* returns, unless the debugger explicitly moves the instruction pointer
|
|
* before returning.
|
|
*/
|
|
int dbgu_err_resume(dbgcxdef *ctx);
|
|
|
|
/*
|
|
* Find a source file. origname is the name of the source file as it
|
|
* appears in the game's debugging information; this routine should
|
|
* figure out where the file actually is, and put the fully-qualified
|
|
* path to the file in fullname. The debugger calls this after it
|
|
* exhausts all of its other methods of finding a source file (such as
|
|
* searching the include path).
|
|
*
|
|
* Return true if the source file should be considered valid, false if
|
|
* not. Most implementations will simply return true if the file was
|
|
* found, false if not; however, this approach will cause the debugger
|
|
* to terminate with an error at start-up if the user hasn't set up the
|
|
* debugger's include path correctly before running the debugger. Some
|
|
* implementations, in particular GUI implementations, may wish to wait
|
|
* to find a file until the file is actually needed, rather than pester
|
|
* the user with file search dialogs repeatedly at start-up.
|
|
*
|
|
* must_find_file specifies how to respond if we can't find the file.
|
|
* If must_find_file is true, we should always return false if we can't
|
|
* find the file. If must_find_file is false, however, we can
|
|
* optionally return true even if we can't find the file. Doing so
|
|
* indicates that the debugger UI will defer locating the file until it
|
|
* is actually needed.
|
|
*
|
|
* If this routine returns true without actually finding the file, it
|
|
* should set fullname[0] to '\0' to indicate that fullname doesn't
|
|
* contain a valid filename.
|
|
*/
|
|
int dbgu_find_src(const char *origname, int origlen,
|
|
char *fullname, size_t full_len, int must_find_file);
|
|
|
|
|
|
/*
|
|
* Debugger user interface main command loop. If err is non-zero, the
|
|
* debugger was entered because a run-time error occurred; otherwise, if
|
|
* bphit is non-zero, it's the number of the breakpoint that was
|
|
* encountered; otherwise, the debugger was entered through a
|
|
* single-step of some kind. exec_ofs is the byte offset within the
|
|
* target object of the next instruction to be executed. This can be
|
|
* changed upon return, in which case execution will continue from the
|
|
* new offset, but the offset must be within the same method of the same
|
|
* object (or within the same function) as it was upon entry.
|
|
*/
|
|
void dbgucmd(dbgcxdef *ctx, int bphit, int err, unsigned int *exec_ofs);
|
|
|
|
/*
|
|
* Debugger UI - quitting game. The runtime calls this routine just
|
|
* before the play loop is about to terminate after the game code has
|
|
* called the "quit" built-in function. If the debugger wants, it can
|
|
* take control here (just as with dbgucmd()) for as long as it wants.
|
|
* If the debugger wants to restart the game, it should call bifrst().
|
|
* If this routine returns without signalling a RUN_RESTART error, TADS
|
|
* will terminate. If a RUN_RESTART error is signalled, TADS will
|
|
* resume the play loop.
|
|
*/
|
|
void dbguquitting(dbgcxdef *ctx);
|
|
|
|
/*
|
|
* debugger user interface termination - this routine is called when the
|
|
* debugger is about to terminate, so that the user interface can close
|
|
* itself down (close windows, release memory, etc)
|
|
*/
|
|
void dbguterm(dbgcxdef *ctx);
|
|
|
|
/*
|
|
* Debugger user interface: display an error. This is called mainly so
|
|
* that the debugger can display an error using special output
|
|
* formatting if the error occurs while debugging.
|
|
*/
|
|
void dbguerr(dbgcxdef *ctx, int errnum, char *msg);
|
|
|
|
/* turn hidden output tracing on/off */
|
|
void trchid(void);
|
|
void trcsho(void);
|
|
|
|
|
|
/* ======================================================================== */
|
|
/*
|
|
* optional debugger macros - these compile to nothing when compiling a
|
|
* version for use without the debugger
|
|
*/
|
|
|
|
#ifdef DBG_OFF
|
|
#define dbgenter(ctx, bp, self, target, prop, binum, argc)
|
|
#define dbgleave(ctx, exittype) ((void)0)
|
|
#define dbgdump(ctx) ((void)0)
|
|
#define dbgrst(ctx) ((void)0)
|
|
#define dbgframe(ctx, frofs, linofs)
|
|
#define dbgssi(ctx, ofs, instr, err, p) ((void)0)
|
|
#else /* DBG_OFF */
|
|
#define dbgenter(ctx, bp, self, target, prop, binum, argc) \
|
|
dbgent(ctx, bp, self, target, prop, binum, argc)
|
|
#define dbgleave(ctx, exittype) dbglv(ctx, exittype)
|
|
#define dbgdump(ctx) dbgds(ctx)
|
|
#define dbgrst(ctx) ((ctx)->dbgcxfcn = (ctx)->dbgcxdep = 0)
|
|
#define dbgframe(ctx, frofs, linofs) \
|
|
(((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgffr = (frofs)), \
|
|
((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgflin = (linofs)))
|
|
#define dbgssi(ctx, ofs, instr, err, p) dbgss(ctx, ofs, instr, err, p)
|
|
#endif /* DBG_OFF */
|
|
|
|
/* ======================================================================== */
|
|
/* private internal routines */
|
|
|
|
void dbgent(dbgcxdef *ctx, struct runsdef *bp, objnum self, objnum target,
|
|
prpnum prop, int binum, int argc);
|
|
|
|
void dbglv(dbgcxdef *ctx, int exittype);
|
|
|
|
void dbgds(dbgcxdef *ctx);
|
|
|
|
void dbgss(dbgcxdef *ctx, uint ofs, int instr, int err, uchar *noreg *p);
|
|
|
|
void dbgpval(struct dbgcxdef *ctx, struct runsdef *val,
|
|
void (*dispfn)(void *, const char *, int),
|
|
void *dispctx, int showtype);
|
|
|
|
int dbgtabsea(struct toktdef *tab, char *name, int namel, int hash,
|
|
struct toksdef *ret);
|
|
|
|
} // End of namespace TADS2
|
|
} // End of namespace TADS
|
|
} // End of namespace Glk
|
|
|
|
#endif
|