Upgrade of runtime functions to support new pointer type checking scheme.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@177 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-02-02 04:35:41 +00:00
commit 8be06b60ce

View file

@ -1,8 +1,16 @@
/*********************************************************************** /***********************************************************************
* $Header$ * python.swg
* swig_lib/python/python.cfg
* *
* Contains variable linking and pointer type-checking code. * This file contains the runtime support for Python modules
* and includes code for managing global variables and pointer
* type checking.
*
* Author : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (c) 1999-2000, The University of Chicago
*
* This file may be freely redistributed without license or fee provided
* this copyright message remains intact.
************************************************************************/ ************************************************************************/
#include <string.h> #include <string.h>
@ -37,117 +45,94 @@ extern "C" {
#define SWIGSTATICRUNTIME(a) static a #define SWIGSTATICRUNTIME(a) static a
#endif #endif
/* Type information structure */
typedef struct _swig_type_info {
char *name;
void *(*converter)(void *);
struct _swig_type_info *next;
struct _swig_type_info *prev;
} _swig_type_info;
#ifdef SWIG_NOINCLUDE #ifdef SWIG_NOINCLUDE
extern void SWIG_MakePtr(char *, void *, char *); extern PyObject *SWIG_newvarlink();
extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *));
extern char *SWIG_GetPtr(char *, void **, char *);
extern char *SWIG_GetPtrObj(PyObject *, void **, char *);
extern void SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); extern void SWIG_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *));
extern PyObject *SWIG_newvarlink(void); extern _swig_type_info *SWIG_TypeRegister(_swig_type_info *);
extern _swig_type_info *SWIG_TypeCheck(char *, _swig_type_info *);
extern int SWIG_ConvertPtr(PyObject *, void **, _swig_type_info *);
extern void SWIG_MakePtr(char *c, void *, _swig_type_info *);
extern PyObject *SWIG_NewPointerObj(void *, _swig_type_info *);
/* External declarations when using runtime libraries */
#else #else
typedef struct { /* -----------------------------------------------------------------------------
char *name; * global variable support code.
PyObject *(*get_attr)(void); * ----------------------------------------------------------------------------- */
int (*set_attr)(PyObject *);
typedef struct swig_globalvar {
char *name; /* Name of global variable */
PyObject *(*get_attr)(void); /* Return the current value */
int (*set_attr)(PyObject *); /* Set the value */
struct swig_globalvar *next;
} swig_globalvar; } swig_globalvar;
typedef struct swig_varlinkobject { typedef struct swig_varlinkobject {
PyObject_HEAD PyObject_HEAD
swig_globalvar **vars; swig_globalvar *vars;
int nvars;
int maxvars;
} swig_varlinkobject; } swig_varlinkobject;
/* ----------------------------------------------------------------------
swig_varlink_repr()
Function for python repr method
---------------------------------------------------------------------- */
static PyObject * static PyObject *
swig_varlink_repr(swig_varlinkobject *v) swig_varlink_repr(swig_varlinkobject *v) {
{
v = v; v = v;
return PyString_FromString("<Global variables>"); return PyString_FromString("<Global variables>");
} }
/* ---------------------------------------------------------------------
swig_varlink_print()
Print out all of the global variable names
--------------------------------------------------------------------- */
static int static int
swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) {
{ swig_globalvar *var;
int i = 0;
flags = flags; flags = flags;
fprintf(fp,"Global variables { "); fprintf(fp,"Global variables { ");
while (v->vars[i]) { for (var = v->vars; var; var=var->next) {
fprintf(fp,"%s", v->vars[i]->name); fprintf(fp,"%s", var->name);
i++; if (var->next) fprintf(fp,", ");
if (v->vars[i]) fprintf(fp,", ");
} }
fprintf(fp," }\n"); fprintf(fp," }\n");
return 0; return 0;
} }
/* --------------------------------------------------------------------
swig_varlink_getattr
This function gets the value of a variable and returns it as a
PyObject. In our case, we'll be looking at the datatype and
converting into a number or string
-------------------------------------------------------------------- */
static PyObject * static PyObject *
swig_varlink_getattr(swig_varlinkobject *v, char *n) swig_varlink_getattr(swig_varlinkobject *v, char *n) {
{ swig_globalvar *var = v->vars;
int i = 0; while (var) {
char temp[128]; if (strcmp(var->name,n) == 0) {
return (*var->get_attr)();
while (v->vars[i]) {
if (strcmp(v->vars[i]->name,n) == 0) {
return (*v->vars[i]->get_attr)();
} }
i++; var = var->next;
} }
sprintf(temp,"C global variable %s not found.", n); PyErr_SetString(PyExc_NameError,"Unknown C global variable");
PyErr_SetString(PyExc_NameError,temp);
return NULL; return NULL;
} }
/* -------------------------------------------------------------------
swig_varlink_setattr()
This function sets the value of a variable.
------------------------------------------------------------------- */
static int static int
swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
{ swig_globalvar *var = v->vars;
char temp[128]; while (var) {
int i = 0; if (strcmp(var->name,n) == 0) {
while (v->vars[i]) { return (*var->set_attr)(p);
if (strcmp(v->vars[i]->name,n) == 0) {
return (*v->vars[i]->set_attr)(p);
} }
i++; var = var->next;
} }
sprintf(temp,"C global variable %s not found.", n); PyErr_SetString(PyExc_NameError,"Unknown C global variable");
PyErr_SetString(PyExc_NameError,temp);
return 1; return 1;
} }
statichere PyTypeObject varlinktype = { statichere PyTypeObject varlinktype = {
/* PyObject_HEAD_INIT(&PyType_Type) Note : This doesn't work on some machines */
PyObject_HEAD_INIT(0) PyObject_HEAD_INIT(0)
0, 0,
"varlink", /* Type name */ "swigvarlink", /* Type name */
sizeof(swig_varlinkobject), /* Basic size */ sizeof(swig_varlinkobject), /* Basic size */
0, /* Itemsize */ 0, /* Itemsize */
0, /* Deallocator */ 0, /* Deallocator */
@ -162,19 +147,13 @@ statichere PyTypeObject varlinktype = {
}; };
/* Create a variable linking object for use later */ /* Create a variable linking object for use later */
SWIGSTATICRUNTIME(PyObject *) SWIGSTATICRUNTIME(PyObject *)
SWIG_newvarlink(void) SWIG_newvarlink(void) {
{
swig_varlinkobject *result = 0; swig_varlinkobject *result = 0;
result = PyMem_NEW(swig_varlinkobject,1); result = PyMem_NEW(swig_varlinkobject,1);
varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */
result->ob_type = &varlinktype; result->ob_type = &varlinktype;
/* _Py_NewReference(result); Does not seem to be necessary */ result->vars = 0;
result->nvars = 0;
result->maxvars = 64;
result->vars = (swig_globalvar **) malloc(64*sizeof(swig_globalvar *));
result->vars[0] = 0;
result->ob_refcnt = 0; result->ob_refcnt = 0;
Py_XINCREF((PyObject *) result); Py_XINCREF((PyObject *) result);
return ((PyObject*) result); return ((PyObject*) result);
@ -182,155 +161,108 @@ SWIG_newvarlink(void)
SWIGSTATICRUNTIME(void) SWIGSTATICRUNTIME(void)
SWIG_addvarlink(PyObject *p, char *name, SWIG_addvarlink(PyObject *p, char *name,
PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
{
swig_varlinkobject *v; swig_varlinkobject *v;
swig_globalvar *gv;
v= (swig_varlinkobject *) p; v= (swig_varlinkobject *) p;
gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
if (v->nvars >= v->maxvars -1) { gv->name = (char *) malloc(strlen(name)+1);
v->maxvars = 2*v->maxvars; strcpy(gv->name,name);
v->vars = (swig_globalvar **) realloc(v->vars,v->maxvars*sizeof(swig_globalvar *)); gv->get_attr = get_attr;
if (v->vars == NULL) { gv->set_attr = set_attr;
fprintf(stderr,"SWIG : Fatal error in initializing Python module.\n"); gv->next = v->vars;
exit(1); v->vars = gv;
}
}
v->vars[v->nvars] = (swig_globalvar *) malloc(sizeof(swig_globalvar));
v->vars[v->nvars]->name = (char *) malloc(strlen(name)+1);
strcpy(v->vars[v->nvars]->name,name);
v->vars[v->nvars]->get_attr = get_attr;
v->vars[v->nvars]->set_attr = set_attr;
v->nvars++;
v->vars[v->nvars] = 0;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Pointer type-checking * Pointer type-checking
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
/* SWIG pointer structure */ static _swig_type_info *swig_types = 0;
typedef struct SwigPtrType {
char *name; /* Datatype name */
int len; /* Length (used for optimization) */
void *(*cast)(void *); /* Pointer casting function */
struct SwigPtrType *next; /* Linked list pointer */
} SwigPtrType;
/* Pointer cache structure */ /* Register type mappings with the type-checker */
typedef struct { SWIGSTATICRUNTIME(_swig_type_info *)
int stat; /* Status (valid) bit */ SWIG_TypeRegister(_swig_type_info *ti) {
SwigPtrType *tp; /* Pointer to type structure */ _swig_type_info *tc, *head, *ret, *next;
char name[256]; /* Given datatype name */ /* Check to see if this type has already been registered */
char mapped[256]; /* Equivalent name */ tc = swig_types;
} SwigCacheType; while (tc) {
if (strcmp(tc->name, ti->name) == 0) {
/* Already exists in the table. Just add additional types to the list */
head = tc;
next = tc->next;
goto l1;
}
tc = tc->prev;
}
head = ti;
next = 0;
static int SwigPtrMax = 64; /* Max entries that can be currently held */ /* Place in list */
static int SwigPtrN = 0; /* Current number of entries */ ti->prev = swig_types;
static int SwigPtrSort = 0; /* Status flag indicating sort */ swig_types = ti;
static int SwigStart[256]; /* Starting positions of types */
static SwigPtrType *SwigPtrTable = 0; /* Table containing pointer equivalences */
/* Cached values */ /* Build linked lists */
#define SWIG_CACHESIZE 8 l1:
#define SWIG_CACHEMASK 0x7 ret = head;
static SwigCacheType SwigCache[SWIG_CACHESIZE]; tc = ti + 1;
static int SwigCacheIndex = 0; while (tc->name) {
static int SwigLastCache = 0; head->next = tc;
tc->prev = head;
/* Sort comparison function */ head = tc;
static int swigsort(const void *data1, const void *data2) { tc++;
SwigPtrType *d1 = (SwigPtrType *) data1; }
SwigPtrType *d2 = (SwigPtrType *) data2; head->next = next;
return strcmp(d1->name,d2->name); return ret;
} }
/* Register a new datatype with the type-checker */ /* Check the typename */
SWIGSTATICRUNTIME(void) SWIGSTATICRUNTIME(_swig_type_info *)
SWIG_RegisterMapping(char *origtype, char *newtype, void *(*cast)(void *)) { SWIG_TypeCheck(char *c, _swig_type_info *ty) {
int i; _swig_type_info *s, *temp2;
SwigPtrType *t = 0,*t1; if (!ty) return 0; /* Void pointer */
s = ty->next; /* First element is always just the name */
/* Allocate the pointer table if necessary */ while (s) {
if (!SwigPtrTable) { if (strcmp(s->name,c) == 0) {
SwigPtrTable = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); if (s == ty->next) return s;
/* Move s to the top of the linked list */
s->prev->next = s->next;
if (s->next) {
s->next->prev = s->prev;
}
/* Insert s as second element in the list */
s->next = ty->next;
if (ty->next) ty->next->prev = s;
ty->next = s;
return s;
}
s = s->next;
}
return 0;
} }
/* Grow the table */ /* Convert a pointer value */
if (SwigPtrN >= SwigPtrMax) { SWIGSTATICRUNTIME(int)
SwigPtrMax = 2*SwigPtrMax; SWIG_ConvertPtr(PyObject *obj, void **ptr, _swig_type_info *ty) {
SwigPtrTable = (SwigPtrType *) realloc((char *) SwigPtrTable,SwigPtrMax*sizeof(SwigPtrType));
}
for (i = 0; i < SwigPtrN; i++) {
if (strcmp(SwigPtrTable[i].name,origtype) == 0) {
t = &SwigPtrTable[i];
break;
}
}
if (!t) {
t = &SwigPtrTable[SwigPtrN++];
t->name = origtype;
t->len = strlen(t->name);
t->cast = 0;
t->next = 0;
}
/* Check for existing entries */
while (t->next) {
if ((strcmp(t->name,newtype) == 0)) {
if (cast) t->cast = cast;
return;
}
t = t->next;
}
t1 = (SwigPtrType *) malloc(sizeof(SwigPtrType));
t1->name = newtype;
t1->len = strlen(t1->name);
t1->cast = cast;
t1->next = 0;
t->next = t1;
SwigPtrSort = 0;
}
/* Make a pointer value string */
SWIGSTATICRUNTIME(void)
SWIG_MakePtr(char *c, const void *ptr, char *type) {
static char hex[17] = "0123456789abcdef";
unsigned long p, s;
char result[24], *r;
r = result;
p = (unsigned long) ptr;
if (p > 0) {
while (p > 0) {
s = p & 0xf;
*(r++) = hex[s];
p = p >> 4;
}
*r = '_';
while (r >= result)
*(c++) = *(r--);
strcpy (c, type);
} else {
strcpy (c, "NULL");
}
}
/* Function for getting a pointer value */
SWIGSTATICRUNTIME(char *)
SWIG_GetPtr(char *c, void **ptr, char *t)
{
unsigned long p; unsigned long p;
char temp_type[256], *name;
int i, len, start, end;
SwigPtrType *sp,*tp;
SwigCacheType *cache;
register int d; register int d;
_swig_type_info *tc;
char *c;
if (!obj || (obj == Py_None)) {
*ptr = 0;
return 0;
}
if (!PyString_Check(obj)) {
obj = PyObject_GetAttrString(obj,"this");
if ((!obj) || !(PyString_Check(obj))) return -1;
}
c = PyString_AsString(obj);
p = 0; p = 0;
/* Pointer values must start with leading underscore */ /* Pointer values must start with leading underscore */
if (*c != '_') { if (*c != '_') {
*ptr = (void *) 0; *ptr = (void *) 0;
if (strcmp(c,"NULL") == 0) return (char *) 0; if (strcmp(c,"NULL") == 0) return 0;
else c;
} }
c++; c++;
/* Extract hex value from pointer */ /* Extract hex value from pointer */
@ -344,83 +276,57 @@ SWIG_GetPtr(char *c, void **ptr, char *t)
c++; c++;
} }
*ptr = (void *) p; *ptr = (void *) p;
if ((!t) || (strcmp(t,c)==0)) return (char *) 0; if (ty) {
tc = SWIG_TypeCheck(c,ty);
if (!SwigPtrSort) { if (!tc) {
qsort((void *) SwigPtrTable, SwigPtrN, sizeof(SwigPtrType), swigsort); char *temp = (char *) malloc(64+strlen(ty->name));
for (i = 0; i < 256; i++) SwigStart[i] = SwigPtrN; sprintf(temp,"Type error. Expected %s", ty->name);
for (i = SwigPtrN-1; i >= 0; i--) SwigStart[(int) (SwigPtrTable[i].name[1])] = i; PyErr_SetString(PyExc_TypeError, temp);
for (i = 255; i >= 1; i--) { free((char *) temp);
if (SwigStart[i-1] > SwigStart[i]) return -1;
SwigStart[i-1] = SwigStart[i];
} }
SwigPtrSort = 1; if (tc->converter) {
for (i = 0; i < SWIG_CACHESIZE; i++) SwigCache[i].stat = 0; *ptr = (*tc->converter)((void *) p);
}
/* First check cache for matches. Uses last cache value as starting point */
cache = &SwigCache[SwigLastCache];
for (i = 0; i < SWIG_CACHESIZE; i++) {
if (cache->stat && (strcmp(t,cache->name) == 0) && (strcmp(c,cache->mapped) == 0)) {
cache->stat++;
if (cache->tp->cast) *ptr = (*(cache->tp->cast))(*ptr);
return (char *) 0;
}
SwigLastCache = (SwigLastCache+1) & SWIG_CACHEMASK;
if (!SwigLastCache) cache = SwigCache;
else cache++;
}
/* Type mismatch. Look through type-mapping table */
start = SwigStart[(int) t[1]];
end = SwigStart[(int) t[1]+1];
sp = &SwigPtrTable[start];
/* Try to find a match */
while (start <= end) {
if (strncmp(t,sp->name,sp->len) == 0) {
name = sp->name;
len = sp->len;
tp = sp->next;
/* Try to find entry for our given datatype */
while(tp) {
if (tp->len >= 255) {
return c;
}
strcpy(temp_type,tp->name);
strncat(temp_type,t+len,255-tp->len);
if (strcmp(c,temp_type) == 0) {
strcpy(SwigCache[SwigCacheIndex].mapped,c);
strcpy(SwigCache[SwigCacheIndex].name,t);
SwigCache[SwigCacheIndex].stat = 1;
SwigCache[SwigCacheIndex].tp = tp;
SwigCacheIndex = SwigCacheIndex & SWIG_CACHEMASK;
/* Get pointer value */
*ptr = (void *) p;
if (tp->cast) *ptr = (*(tp->cast))(*ptr);
return (char *) 0;
}
tp = tp->next;
} }
} }
sp++; return 0;
start++;
}
return c;
} }
/* New object-based GetPointer function. This uses the Python abstract /* Take a pointer and convert it to a string */
* object interface to automatically dereference the 'this' attribute SWIGSTATICRUNTIME(void)
* of shadow objects. */ SWIG_MakePtr(char *c, void *ptr, _swig_type_info *ty) {
static char hex[17] = "0123456789abcdef";
SWIGSTATICRUNTIME(char *) unsigned long p, s;
SWIG_GetPtrObj(PyObject *obj, void **ptr, char *type) { char result[32], *r;
PyObject *sobj = obj; r = result;
char *str; p = (unsigned long) ptr;
if (!PyString_Check(obj)) { if (p > 0) {
sobj = PyObject_GetAttrString(obj,"this"); while (p > 0) {
if (!sobj) return ""; s = p & 0xf;
*(r++) = hex[s];
p = p >> 4;
} }
str = PyString_AsString(sobj); *r = '_';
return SWIG_GetPtr(str,ptr,type); while (r >= result)
*(c++) = *(r--);
strcpy (c, ty->name);
} else {
strcpy (c, "NULL");
}
}
/* Create a new pointer object */
SWIGSTATICRUNTIME(PyObject *)
SWIG_NewPointerObj(void *ptr, _swig_type_info *type) {
char result[512];
PyObject *robj;
if (!ptr) {
Py_INCREF(Py_None);
return Py_None;
}
SWIG_MakePtr(result,ptr,type);
robj = PyString_FromString(result);
return robj;
} }
#endif #endif