blob: 71eadd8db21a8b9c9c06855ace9c55d2539c2524 [file] [log] [blame]
/* -----------------------------------------------------------------------------
* type.c
*
* This file defines a new python type that contains information from
* the WAD stack trace.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 2000. The University of Chicago.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* See the file COPYING for a complete copy of the LGPL.
* ----------------------------------------------------------------------------- */
#include "wad.h"
#include "Python.h"
static char cvs[] = "$Header$";
typedef struct {
PyObject_HEAD
WadFrame *frame; /* Wad Stack frame object */
int count; /* Number of frames */
} wadobject;
staticforward PyTypeObject WadObjectType;
PyObject *
new_wadobject(WadFrame *f, int count) {
wadobject *self;
self = PyObject_NEW(wadobject, &WadObjectType);
if (self == NULL) return NULL;
self->frame = f;
if (count > 0) {
self->count = count;
} else {
self->count = 0;
while (f) {
self->count++;
f = f->next;
}
}
return (PyObject *) self;
}
/* release a wad object */
static void
wadobject_dealloc(wadobject *self) {
PyMem_DEL(self);
}
static char message[65536];
static PyObject *
wadobject_repr(wadobject *self) {
char *srcstr = 0;
WadFrame *fp = 0;
int n;
WadFrame *f = self->frame;
message[0] = 0;
/* Find the last exception frame */
n = self->count;
while (f && n) {
fp = f;
f= f->next;
n--;
}
if (fp) {
/* Now work backwards */
f = fp;
while (f) {
strcat(message, f->debug_str);
if (f->debug_srcstr) srcstr = f->debug_srcstr;
if (f == self->frame) break;
f = f->prev;
}
if (srcstr) {
strcat(message,"\n");
strcat(message, srcstr);
strcat(message,"\n");
}
}
return PyString_FromString(message);
}
static PyObject *
wadobject_str(wadobject *self) {
char *srcstr = 0;
int n;
WadFrame *f = self->frame;
n = self->count;
strcpy(message,"[ C stack trace ]\n\n");
/* Find the last exception frame */
while (!f->last && n) {
f= f->next;
n--;
}
/* Now work backwards */
if (n <= 0) {
f = f->prev;
}
while (f) {
strcat(message, f->debug_str);
if (f->debug_srcstr) srcstr = f->debug_srcstr;
if (self->frame == f) break;
f = f->prev;
}
if (srcstr) {
strcat(message,"\n");
strcat(message, srcstr);
strcat(message,"\n");
}
return PyString_FromString(message);
}
static int
wadobject_len(wadobject *self) {
int n = 0;
WadFrame *f = self->frame;
while (f) {
n++;
f = f->next;
}
return n;
}
static PyObject *
wadobject_getitem(wadobject *self, int n) {
int i;
WadFrame *f;
if (n < 0) {
n = self->count + n;
}
if ((n < 0) || (n >= self->count)) {
PyErr_SetString(PyExc_IndexError,"Stack frame out of range");
return NULL;
}
f = self->frame;
for (i = 0; i <n; i++) {
f = f->next;
}
return new_wadobject(f,1);
}
static PyObject *
wadobject_getslice(wadobject *self, int start, int end) {
int i;
WadFrame *f;
f = self->frame;
for (i = 0; i < start; i++) {
f = f->next;
}
return new_wadobject(f,(end-start));
}
static PyObject *
wadobject_getattr(wadobject *self, char *name) {
if (strcmp(name,"__NAME__") == 0) {
return Py_BuildValue("z", self->frame->sym_name);
} else if (strcmp(name,"__EXE__") == 0) {
return Py_BuildValue("z", self->frame->object->path);
} else if (strcmp(name,"__FILE__") == 0) {
return Py_BuildValue("z", self->frame->loc_srcfile);
} else if (strcmp(name,"__OBJECT__") == 0) {
return Py_BuildValue("z", self->frame->loc_objfile);
} else if (strcmp(name,"__LINE__") == 0) {
return Py_BuildValue("i", self->frame->loc_line);
} else if (strcmp(name,"__SOURCE__") == 0) {
return Py_BuildValue("z",self->frame->debug_srcstr);
} else if (strcmp(name,"__PC__") == 0) {
return PyLong_FromUnsignedLong(self->frame->pc);
} else if (strcmp(name,"__SP__") == 0) {
return PyLong_FromUnsignedLong(self->frame->sp);
} else if (strcmp(name,"__FP__") == 0) {
return PyLong_FromUnsignedLong(self->frame->fp);
} else if (strcmp(name,"__STACK__") == 0) {
return PyString_FromStringAndSize(self->frame->stack, self->frame->stack_size);
} else if (strcmp(name,"__NARGS__") == 0) {
return PyInt_FromLong(self->frame->debug_nargs);
} else if (strcmp(name,"__LAST__") == 0) {
return PyInt_FromLong(self->frame->last);
} else if (strcmp(name,"__WHERE__") == 0) {
return Py_BuildValue("z",self->frame->debug_str);
} else if (strcmp(name,"__WAD__") == 0) {
return PyInt_FromLong(1);
}
/* Put a check for local variables */
{
int i;
for (i = 0; i < 2; i++) {
WadLocal *loc;
if (i == 0) loc = self->frame->debug_locals;
else loc = self->frame->debug_args;
while (loc) {
if (strcmp(name,loc->name) == 0) {
switch(loc->type) {
case WAD_TYPE_INT32:
case WAD_TYPE_INT16:
case WAD_TYPE_INT8:
return PyLong_FromLong(wad_local_as_long(loc));
break;
case WAD_TYPE_UINT8:
case WAD_TYPE_UINT16:
case WAD_TYPE_UINT32:
return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc));
break;
case WAD_TYPE_CHAR:
return Py_BuildValue("c", (char) (PyLong_FromLong(wad_local_as_long(loc))));
break;
case WAD_TYPE_FLOAT:
case WAD_TYPE_DOUBLE:
return PyFloat_FromDouble(wad_local_as_double(loc));
break;
default:
return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc));
}
}
loc = loc->next;
}
}
}
PyErr_SetString(PyExc_NameError,"Unknown attribute.");
return NULL;
}
static PySequenceMethods wadobject_as_sequence = {
(inquiry) wadobject_len,
0,
0,
(intargfunc) wadobject_getitem, /* get item */
(intintargfunc) wadobject_getslice, /* get slice */
0,
0
};
static PyTypeObject WadObjectType = {
PyObject_HEAD_INIT(&PyType_Type)
0,
"WadObject",
sizeof(wadobject),
0,
(destructor) wadobject_dealloc,
0, /* printfunc */
(getattrfunc) wadobject_getattr,
(setattrfunc) 0,
(cmpfunc) 0,
(reprfunc) wadobject_repr,
0, /* number */
&wadobject_as_sequence, /* sequence */
0, /* mapping */
0, /* hash */
0, /* call */
(reprfunc) wadobject_str, /* str */
};