Merged changes in the trunk up to revision 35203.
Conflicts resolved: source/creator/creator.c source/blender/python/intern/bpy.c
This commit is contained in:
		@@ -27,6 +27,12 @@
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** \file BPY_extern.h
 | 
			
		||||
 *  \ingroup python
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef BPY_EXTERN_H
 | 
			
		||||
#define BPY_EXTERN_H
 | 
			
		||||
 | 
			
		||||
@@ -72,7 +78,7 @@ void BPY_python_end( void );
 | 
			
		||||
 | 
			
		||||
/* 2.5 UI Scripts */
 | 
			
		||||
int		BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports);
 | 
			
		||||
int		BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports);
 | 
			
		||||
int		BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump);
 | 
			
		||||
void	BPY_text_free_code(struct Text *text);
 | 
			
		||||
void	BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date
 | 
			
		||||
void	BPY_modules_load_user(struct bContext *C);
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ set(INC
 | 
			
		||||
	../../blenlib
 | 
			
		||||
	../../makesdna
 | 
			
		||||
	../../blenkernel
 | 
			
		||||
	../../blenloader
 | 
			
		||||
	../../../../intern/guardedalloc
 | 
			
		||||
	../../../../extern/glew/include
 | 
			
		||||
	${PYTHON_INCLUDE_DIRS}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -115,6 +115,7 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
 | 
			
		||||
	Py_RETURN_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0 /* UNUSED, currenly assignment overwrites into new properties, rather then setting in-place */
 | 
			
		||||
static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
 | 
			
		||||
{
 | 
			
		||||
	switch (prop->type) {
 | 
			
		||||
@@ -183,6 +184,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static PyObject *BPy_IDGroup_GetName(BPy_IDProperty *self, void *UNUSED(closure))
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -325,13 +325,27 @@ PyObject *BaseMathObject_getWrapped(BaseMathObject *self, void *UNUSED(closure))
 | 
			
		||||
	return PyBool_FromLong((self->wrapped == Py_WRAP) ? 1:0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseMathObject_dealloc(BaseMathObject * self)
 | 
			
		||||
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	Py_VISIT(self->cb_user);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int BaseMathObject_clear(BaseMathObject *self)
 | 
			
		||||
{
 | 
			
		||||
	Py_CLEAR(self->cb_user);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseMathObject_dealloc(BaseMathObject *self)
 | 
			
		||||
{
 | 
			
		||||
	/* only free non wrapped */
 | 
			
		||||
	if(self->wrapped != Py_WRAP)
 | 
			
		||||
	if(self->wrapped != Py_WRAP) {
 | 
			
		||||
		PyMem_Free(self->data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BaseMathObject_clear(self);
 | 
			
		||||
 | 
			
		||||
	Py_XDECREF(self->cb_user);
 | 
			
		||||
	Py_TYPE(self)->tp_free(self); // PyObject_DEL(self); // breaks subtypes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,9 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
PyObject *BaseMathObject_getOwner( BaseMathObject * self, void * );
 | 
			
		||||
PyObject *BaseMathObject_getWrapped( BaseMathObject *self, void * );
 | 
			
		||||
 | 
			
		||||
int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg);
 | 
			
		||||
int BaseMathObject_clear(BaseMathObject *self);
 | 
			
		||||
void BaseMathObject_dealloc(BaseMathObject * self);
 | 
			
		||||
 | 
			
		||||
PyMODINIT_FUNC BPyInit_mathutils(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -475,10 +475,10 @@ PyTypeObject color_Type = {
 | 
			
		||||
	NULL,							//tp_getattro
 | 
			
		||||
	NULL,							//tp_setattro
 | 
			
		||||
	NULL,							//tp_as_buffer
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
 | 
			
		||||
	color_doc, //tp_doc
 | 
			
		||||
	NULL,							//tp_traverse
 | 
			
		||||
	NULL,							//tp_clear
 | 
			
		||||
	(traverseproc)BaseMathObject_traverse,	//tp_traverse
 | 
			
		||||
	(inquiry)BaseMathObject_clear,	//tp_clear
 | 
			
		||||
	(richcmpfunc)Color_richcmpr,	//tp_richcompare
 | 
			
		||||
	0,								//tp_weaklistoffset
 | 
			
		||||
	NULL,							//tp_iter
 | 
			
		||||
@@ -513,28 +513,31 @@ PyObject *newColorObject(float *col, int type, PyTypeObject *base_type)
 | 
			
		||||
{
 | 
			
		||||
	ColorObject *self;
 | 
			
		||||
 | 
			
		||||
	if(base_type)	self = (ColorObject *)base_type->tp_alloc(base_type, 0);
 | 
			
		||||
	else			self = PyObject_NEW(ColorObject, &color_Type);
 | 
			
		||||
	self= base_type ?	(ColorObject *)base_type->tp_alloc(base_type, 0) :
 | 
			
		||||
						(ColorObject *)PyObject_GC_New(ColorObject, &color_Type);
 | 
			
		||||
 | 
			
		||||
	/* init callbacks as NULL */
 | 
			
		||||
	self->cb_user= NULL;
 | 
			
		||||
	self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
	if(self) {
 | 
			
		||||
		/* init callbacks as NULL */
 | 
			
		||||
		self->cb_user= NULL;
 | 
			
		||||
		self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
 | 
			
		||||
	if(type == Py_WRAP){
 | 
			
		||||
		self->col = col;
 | 
			
		||||
		self->wrapped = Py_WRAP;
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == Py_NEW){
 | 
			
		||||
		self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
 | 
			
		||||
		if(col)
 | 
			
		||||
			copy_v3_v3(self->col, col);
 | 
			
		||||
		else
 | 
			
		||||
			zero_v3(self->col);
 | 
			
		||||
		if(type == Py_WRAP){
 | 
			
		||||
			self->col = col;
 | 
			
		||||
			self->wrapped = Py_WRAP;
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == Py_NEW){
 | 
			
		||||
			self->col = PyMem_Malloc(COLOR_SIZE * sizeof(float));
 | 
			
		||||
			if(col)
 | 
			
		||||
				copy_v3_v3(self->col, col);
 | 
			
		||||
			else
 | 
			
		||||
				zero_v3(self->col);
 | 
			
		||||
 | 
			
		||||
		self->wrapped = Py_NEW;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		return NULL;
 | 
			
		||||
			self->wrapped = Py_NEW;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Color(): invalid type");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (PyObject *)self;
 | 
			
		||||
 
 | 
			
		||||
@@ -608,10 +608,10 @@ PyTypeObject euler_Type = {
 | 
			
		||||
	NULL,							//tp_getattro
 | 
			
		||||
	NULL,							//tp_setattro
 | 
			
		||||
	NULL,							//tp_as_buffer
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
 | 
			
		||||
	euler_doc, //tp_doc
 | 
			
		||||
	NULL,							//tp_traverse
 | 
			
		||||
	NULL,							//tp_clear
 | 
			
		||||
	(traverseproc)BaseMathObject_traverse,	//tp_traverse
 | 
			
		||||
	(inquiry)BaseMathObject_clear,	//tp_clear
 | 
			
		||||
	(richcmpfunc)Euler_richcmpr,	//tp_richcompare
 | 
			
		||||
	0,								//tp_weaklistoffset
 | 
			
		||||
	NULL,							//tp_iter
 | 
			
		||||
@@ -646,31 +646,37 @@ PyObject *newEulerObject(float *eul, short order, int type, PyTypeObject *base_t
 | 
			
		||||
{
 | 
			
		||||
	EulerObject *self;
 | 
			
		||||
 | 
			
		||||
	if(base_type)	self = (EulerObject *)base_type->tp_alloc(base_type, 0);
 | 
			
		||||
	else			self = PyObject_NEW(EulerObject, &euler_Type);
 | 
			
		||||
	self= base_type ?	(EulerObject *)base_type->tp_alloc(base_type, 0) :
 | 
			
		||||
						(EulerObject *)PyObject_GC_New(EulerObject, &euler_Type);
 | 
			
		||||
 | 
			
		||||
	/* init callbacks as NULL */
 | 
			
		||||
	self->cb_user= NULL;
 | 
			
		||||
	self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
	if(self) {
 | 
			
		||||
		/* init callbacks as NULL */
 | 
			
		||||
		self->cb_user= NULL;
 | 
			
		||||
		self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
 | 
			
		||||
	if(type == Py_WRAP) {
 | 
			
		||||
		self->eul = eul;
 | 
			
		||||
		self->wrapped = Py_WRAP;
 | 
			
		||||
	}
 | 
			
		||||
	else if (type == Py_NEW){
 | 
			
		||||
		self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
 | 
			
		||||
		if(eul)
 | 
			
		||||
			copy_v3_v3(self->eul, eul);
 | 
			
		||||
		else
 | 
			
		||||
			zero_v3(self->eul);
 | 
			
		||||
		if(type == Py_WRAP) {
 | 
			
		||||
			self->eul = eul;
 | 
			
		||||
			self->wrapped = Py_WRAP;
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == Py_NEW) {
 | 
			
		||||
			self->eul = PyMem_Malloc(EULER_SIZE * sizeof(float));
 | 
			
		||||
			if(eul) {
 | 
			
		||||
				copy_v3_v3(self->eul, eul);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				zero_v3(self->eul);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		self->wrapped = Py_NEW;
 | 
			
		||||
	}
 | 
			
		||||
	else{
 | 
			
		||||
		return NULL;
 | 
			
		||||
			self->wrapped = Py_NEW;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Euler(): invalid type");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		self->order= order;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	self->order= order;
 | 
			
		||||
	return (PyObject *)self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1775,10 +1775,10 @@ PyTypeObject matrix_Type = {
 | 
			
		||||
	NULL,								/*tp_getattro*/
 | 
			
		||||
	NULL,								/*tp_setattro*/
 | 
			
		||||
	NULL,								/*tp_as_buffer*/
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
 | 
			
		||||
	matrix_doc,							/*tp_doc*/
 | 
			
		||||
	NULL,								/*tp_traverse*/
 | 
			
		||||
	NULL,								/*tp_clear*/
 | 
			
		||||
	(traverseproc)BaseMathObject_traverse,	//tp_traverse
 | 
			
		||||
	(inquiry)BaseMathObject_clear,	//tp_clear
 | 
			
		||||
	(richcmpfunc)Matrix_richcmpr,		/*tp_richcompare*/
 | 
			
		||||
	0,									/*tp_weaklistoffset*/
 | 
			
		||||
	NULL,								/*tp_iter*/
 | 
			
		||||
@@ -1826,52 +1826,58 @@ PyObject *newMatrixObject(float *mat, const unsigned short rowSize, const unsign
 | 
			
		||||
	int x, row, col;
 | 
			
		||||
 | 
			
		||||
	/*matrix objects can be any 2-4row x 2-4col matrix*/
 | 
			
		||||
	if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4){
 | 
			
		||||
	if(rowSize < 2 || rowSize > 4 || colSize < 2 || colSize > 4) {
 | 
			
		||||
		PyErr_SetString(PyExc_RuntimeError, "matrix(): row and column sizes must be between 2 and 4");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(base_type)	self = (MatrixObject *)base_type->tp_alloc(base_type, 0);
 | 
			
		||||
	else			self = PyObject_NEW(MatrixObject, &matrix_Type);
 | 
			
		||||
	self= base_type ?	(MatrixObject *)base_type->tp_alloc(base_type, 0) :
 | 
			
		||||
						(MatrixObject *)PyObject_GC_New(MatrixObject, &matrix_Type);
 | 
			
		||||
 | 
			
		||||
	self->row_size = rowSize;
 | 
			
		||||
	self->col_size = colSize;
 | 
			
		||||
	if(self) {
 | 
			
		||||
		self->row_size = rowSize;
 | 
			
		||||
		self->col_size = colSize;
 | 
			
		||||
 | 
			
		||||
	/* init callbacks as NULL */
 | 
			
		||||
	self->cb_user= NULL;
 | 
			
		||||
	self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
		/* init callbacks as NULL */
 | 
			
		||||
		self->cb_user= NULL;
 | 
			
		||||
		self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
 | 
			
		||||
	if(type == Py_WRAP){
 | 
			
		||||
		self->contigPtr = mat;
 | 
			
		||||
		/*pointer array points to contigous memory*/
 | 
			
		||||
		for(x = 0; x < rowSize; x++) {
 | 
			
		||||
			self->matrix[x] = self->contigPtr + (x * colSize);
 | 
			
		||||
		if(type == Py_WRAP){
 | 
			
		||||
			self->contigPtr = mat;
 | 
			
		||||
			/*pointer array points to contigous memory*/
 | 
			
		||||
			for(x = 0; x < rowSize; x++) {
 | 
			
		||||
				self->matrix[x] = self->contigPtr + (x * colSize);
 | 
			
		||||
			}
 | 
			
		||||
			self->wrapped = Py_WRAP;
 | 
			
		||||
		}
 | 
			
		||||
		self->wrapped = Py_WRAP;
 | 
			
		||||
	}else if (type == Py_NEW){
 | 
			
		||||
		self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
 | 
			
		||||
		if(self->contigPtr == NULL) { /*allocation failure*/
 | 
			
		||||
			PyErr_SetString(PyExc_MemoryError, "matrix(): problem allocating pointer space");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		/*pointer array points to contigous memory*/
 | 
			
		||||
		for(x = 0; x < rowSize; x++) {
 | 
			
		||||
			self->matrix[x] = self->contigPtr + (x * colSize);
 | 
			
		||||
		}
 | 
			
		||||
		/*parse*/
 | 
			
		||||
		if(mat) {	/*if a float array passed*/
 | 
			
		||||
			for(row = 0; row < rowSize; row++) {
 | 
			
		||||
				for(col = 0; col < colSize; col++) {
 | 
			
		||||
					self->matrix[row][col] = mat[(row * colSize) + col];
 | 
			
		||||
		else if (type == Py_NEW){
 | 
			
		||||
			self->contigPtr = PyMem_Malloc(rowSize * colSize * sizeof(float));
 | 
			
		||||
			if(self->contigPtr == NULL) { /*allocation failure*/
 | 
			
		||||
				PyErr_SetString(PyExc_MemoryError, "matrix(): problem allocating pointer space");
 | 
			
		||||
				return NULL;
 | 
			
		||||
			}
 | 
			
		||||
			/*pointer array points to contigous memory*/
 | 
			
		||||
			for(x = 0; x < rowSize; x++) {
 | 
			
		||||
				self->matrix[x] = self->contigPtr + (x * colSize);
 | 
			
		||||
			}
 | 
			
		||||
			/*parse*/
 | 
			
		||||
			if(mat) {	/*if a float array passed*/
 | 
			
		||||
				for(row = 0; row < rowSize; row++) {
 | 
			
		||||
					for(col = 0; col < colSize; col++) {
 | 
			
		||||
						self->matrix[row][col] = mat[(row * colSize) + col];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (rowSize == colSize ) { /*or if no arguments are passed return identity matrix for square matrices */
 | 
			
		||||
			PyObject *ret_dummy= Matrix_identity(self);
 | 
			
		||||
			Py_DECREF(ret_dummy);
 | 
			
		||||
			else if (rowSize == colSize ) { /*or if no arguments are passed return identity matrix for square matrices */
 | 
			
		||||
				PyObject *ret_dummy= Matrix_identity(self);
 | 
			
		||||
				Py_DECREF(ret_dummy);
 | 
			
		||||
			}
 | 
			
		||||
			self->wrapped = Py_NEW;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Matrix(): invalid type");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		self->wrapped = Py_NEW;
 | 
			
		||||
	}else{ /*bad type*/
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	return (PyObject *) self;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1044,10 +1044,10 @@ PyTypeObject quaternion_Type = {
 | 
			
		||||
	NULL,								//tp_getattro
 | 
			
		||||
	NULL,								//tp_setattro
 | 
			
		||||
	NULL,								//tp_as_buffer
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, //tp_flags
 | 
			
		||||
	quaternion_doc, //tp_doc
 | 
			
		||||
	NULL,								//tp_traverse
 | 
			
		||||
	NULL,								//tp_clear
 | 
			
		||||
	(traverseproc)BaseMathObject_traverse,	//tp_traverse
 | 
			
		||||
	(inquiry)BaseMathObject_clear,	//tp_clear
 | 
			
		||||
	(richcmpfunc)Quaternion_richcmpr,	//tp_richcompare
 | 
			
		||||
	0,								//tp_weaklistoffset
 | 
			
		||||
	NULL,								//tp_iter
 | 
			
		||||
@@ -1082,26 +1082,31 @@ PyObject *newQuaternionObject(float *quat, int type, PyTypeObject *base_type)
 | 
			
		||||
{
 | 
			
		||||
	QuaternionObject *self;
 | 
			
		||||
 | 
			
		||||
	if(base_type)	self = (QuaternionObject *)base_type->tp_alloc(base_type, 0);
 | 
			
		||||
	else			self = PyObject_NEW(QuaternionObject, &quaternion_Type);
 | 
			
		||||
	self= base_type ?	(QuaternionObject *)base_type->tp_alloc(base_type, 0) :
 | 
			
		||||
						(QuaternionObject *)PyObject_GC_New(QuaternionObject, &quaternion_Type);
 | 
			
		||||
 | 
			
		||||
	/* init callbacks as NULL */
 | 
			
		||||
	self->cb_user= NULL;
 | 
			
		||||
	self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
	if(self) {
 | 
			
		||||
		/* init callbacks as NULL */
 | 
			
		||||
		self->cb_user= NULL;
 | 
			
		||||
		self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
 | 
			
		||||
	if(type == Py_WRAP){
 | 
			
		||||
		self->quat = quat;
 | 
			
		||||
		self->wrapped = Py_WRAP;
 | 
			
		||||
	}else if (type == Py_NEW){
 | 
			
		||||
		self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
 | 
			
		||||
		if(!quat) { //new empty
 | 
			
		||||
			unit_qt(self->quat);
 | 
			
		||||
		}else{
 | 
			
		||||
			QUATCOPY(self->quat, quat);
 | 
			
		||||
		if(type == Py_WRAP){
 | 
			
		||||
			self->quat = quat;
 | 
			
		||||
			self->wrapped = Py_WRAP;
 | 
			
		||||
		}
 | 
			
		||||
		else if (type == Py_NEW){
 | 
			
		||||
			self->quat = PyMem_Malloc(QUAT_SIZE * sizeof(float));
 | 
			
		||||
			if(!quat) { //new empty
 | 
			
		||||
				unit_qt(self->quat);
 | 
			
		||||
			}else{
 | 
			
		||||
				QUATCOPY(self->quat, quat);
 | 
			
		||||
			}
 | 
			
		||||
			self->wrapped = Py_NEW;
 | 
			
		||||
		}
 | 
			
		||||
		else{
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Quaternion(): invalid type");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		self->wrapped = Py_NEW;
 | 
			
		||||
	}else{ //bad type
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	return (PyObject *) self;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2162,14 +2162,15 @@ PyTypeObject vector_Type = {
 | 
			
		||||
	NULL,                       /* PyBufferProcs *tp_as_buffer; */
 | 
			
		||||
 | 
			
		||||
  /*** Flags to define presence of optional/expanded features ***/
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 | 
			
		||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, 
 | 
			
		||||
	vector_doc,                       /*  char *tp_doc;  Documentation string */
 | 
			
		||||
  /*** Assigned meaning in release 2.0 ***/
 | 
			
		||||
 | 
			
		||||
	/* call function for all accessible objects */
 | 
			
		||||
	NULL,                       /* traverseproc tp_traverse; */
 | 
			
		||||
	(traverseproc)BaseMathObject_traverse,	//tp_traverse
 | 
			
		||||
 | 
			
		||||
	/* delete references to contained objects */
 | 
			
		||||
	NULL,                       /* inquiry tp_clear; */
 | 
			
		||||
	(inquiry)BaseMathObject_clear,	//tp_clear
 | 
			
		||||
 | 
			
		||||
  /***  Assigned meaning in release 2.1 ***/
 | 
			
		||||
  /*** rich comparisons ***/
 | 
			
		||||
@@ -2218,35 +2219,42 @@ PyObject *newVectorObject(float *vec, const int size, const int type, PyTypeObje
 | 
			
		||||
{
 | 
			
		||||
	VectorObject *self;
 | 
			
		||||
 | 
			
		||||
	if(size > 4 || size < 2)
 | 
			
		||||
	if(size > 4 || size < 2) {
 | 
			
		||||
		PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(base_type)	self = (VectorObject *)base_type->tp_alloc(base_type, 0);
 | 
			
		||||
	else			self = PyObject_NEW(VectorObject, &vector_Type);
 | 
			
		||||
	self= base_type ?	(VectorObject *)base_type->tp_alloc(base_type, 0) :
 | 
			
		||||
						(VectorObject *)PyObject_GC_New(VectorObject, &vector_Type);
 | 
			
		||||
 | 
			
		||||
	self->size = size;
 | 
			
		||||
	
 | 
			
		||||
	/* init callbacks as NULL */
 | 
			
		||||
	self->cb_user= NULL;
 | 
			
		||||
	self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
	if(self) {
 | 
			
		||||
		self->size = size;
 | 
			
		||||
 | 
			
		||||
	if(type == Py_WRAP) {
 | 
			
		||||
		self->vec = vec;
 | 
			
		||||
		self->wrapped = Py_WRAP;
 | 
			
		||||
	} else if (type == Py_NEW) {
 | 
			
		||||
		self->vec= PyMem_Malloc(size * sizeof(float));
 | 
			
		||||
		if(vec) {
 | 
			
		||||
			memcpy(self->vec, vec, size * sizeof(float));
 | 
			
		||||
		/* init callbacks as NULL */
 | 
			
		||||
		self->cb_user= NULL;
 | 
			
		||||
		self->cb_type= self->cb_subtype= 0;
 | 
			
		||||
 | 
			
		||||
		if(type == Py_WRAP) {
 | 
			
		||||
			self->vec = vec;
 | 
			
		||||
			self->wrapped = Py_WRAP;
 | 
			
		||||
		}
 | 
			
		||||
		else { /* new empty */
 | 
			
		||||
			fill_vn(self->vec, size, 0.0f);
 | 
			
		||||
			if(size == 4) { /* do the homogenous thing */
 | 
			
		||||
				self->vec[3] = 1.0f;
 | 
			
		||||
		else if (type == Py_NEW) {
 | 
			
		||||
			self->vec= PyMem_Malloc(size * sizeof(float));
 | 
			
		||||
			if(vec) {
 | 
			
		||||
				memcpy(self->vec, vec, size * sizeof(float));
 | 
			
		||||
			}
 | 
			
		||||
			else { /* new empty */
 | 
			
		||||
				fill_vn(self->vec, size, 0.0f);
 | 
			
		||||
				if(size == 4) { /* do the homogenous thing */
 | 
			
		||||
					self->vec[3] = 1.0f;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			self->wrapped = Py_NEW;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid type");
 | 
			
		||||
			return NULL;
 | 
			
		||||
		}
 | 
			
		||||
		self->wrapped = Py_NEW;
 | 
			
		||||
	}else{ /*bad type*/
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	return (PyObject *) self;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * Blender.Noise BPython module implementation.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <Python.h>
 | 
			
		||||
#include <frameobject.h>
 | 
			
		||||
 | 
			
		||||
#include "py_capi_utils.h"
 | 
			
		||||
 | 
			
		||||
@@ -54,39 +55,34 @@ void PyC_LineSpit(void) {
 | 
			
		||||
	fprintf(stderr, "%s:%d\n", filename, lineno);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* python 3.2 only, copied from frameobjec.c */
 | 
			
		||||
#if PY_VERSION_HEX <  0x03020000
 | 
			
		||||
int
 | 
			
		||||
PyFrame_GetLineNumber(PyFrameObject *f)
 | 
			
		||||
{
 | 
			
		||||
    if (f->f_trace)
 | 
			
		||||
        return f->f_lineno;
 | 
			
		||||
    else
 | 
			
		||||
        return PyCode_Addr2Line(f->f_code, f->f_lasti);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void PyC_FileAndNum(const char **filename, int *lineno)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *getframe, *frame;
 | 
			
		||||
	PyObject *f_lineno= NULL, *co_filename= NULL;
 | 
			
		||||
	PyFrameObject *frame;
 | 
			
		||||
	
 | 
			
		||||
	if (filename)	*filename= NULL;
 | 
			
		||||
	if (lineno)		*lineno = -1;
 | 
			
		||||
	
 | 
			
		||||
	getframe = PySys_GetObject("_getframe"); // borrowed
 | 
			
		||||
	if (getframe==NULL) {
 | 
			
		||||
		PyErr_Clear();
 | 
			
		||||
 | 
			
		||||
	if (!(frame= PyThreadState_GET()->frame)) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	frame = PyObject_CallObject(getframe, NULL);
 | 
			
		||||
	if (frame==NULL) {
 | 
			
		||||
		PyErr_Clear();
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* when executing a script */
 | 
			
		||||
	if (filename) {
 | 
			
		||||
		co_filename= PyC_Object_GetAttrStringArgs(frame, 2, "f_code", "co_filename");
 | 
			
		||||
		if (co_filename==NULL) {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_code.co_filename");
 | 
			
		||||
			Py_DECREF(frame);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		*filename = _PyUnicode_AsString(co_filename);
 | 
			
		||||
		Py_DECREF(co_filename);
 | 
			
		||||
		*filename = _PyUnicode_AsString(frame->f_code->co_filename);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* when executing a module */
 | 
			
		||||
	if(filename && *filename == NULL) {
 | 
			
		||||
		/* try an alternative method to get the filename - module based
 | 
			
		||||
@@ -104,21 +100,10 @@ void PyC_FileAndNum(const char **filename, int *lineno)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	
 | 
			
		||||
	if (lineno) {
 | 
			
		||||
		f_lineno= PyObject_GetAttrString(frame, "f_lineno");
 | 
			
		||||
		if (f_lineno==NULL) {
 | 
			
		||||
			PyErr_SetString(PyExc_RuntimeError, "Could not access sys._getframe().f_lineno");
 | 
			
		||||
			Py_DECREF(frame);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		*lineno = (int)PyLong_AsSsize_t(f_lineno);
 | 
			
		||||
		Py_DECREF(f_lineno);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Py_DECREF(frame);
 | 
			
		||||
	if (lineno) {
 | 
			
		||||
		*lineno = PyFrame_GetLineNumber(frame);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Would be nice if python had this built in */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ set(INC
 | 
			
		||||
	../../makesdna
 | 
			
		||||
	../../makesrna
 | 
			
		||||
	../../blenkernel
 | 
			
		||||
	../../blenloader
 | 
			
		||||
	../../windowmanager
 | 
			
		||||
	../../editors/include
 | 
			
		||||
	../../freestyle/intern/python
 | 
			
		||||
@@ -48,6 +49,7 @@ set(SRC
 | 
			
		||||
	bpy_rna.c
 | 
			
		||||
	bpy_rna_array.c
 | 
			
		||||
	bpy_rna_callback.c
 | 
			
		||||
	bpy_traceback.c
 | 
			
		||||
	bpy_util.c
 | 
			
		||||
	stubs.c
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +61,7 @@ set(SRC
 | 
			
		||||
	bpy_props.h
 | 
			
		||||
	bpy_rna.h
 | 
			
		||||
	bpy_rna_callback.h
 | 
			
		||||
	bpy_traceback.h
 | 
			
		||||
	bpy_util.h
 | 
			
		||||
	../BPY_extern.h
 | 
			
		||||
)
 | 
			
		||||
@@ -68,4 +71,8 @@ if(WITH_BUILDINFO)
 | 
			
		||||
	add_definitions(-DBUILD_DATE)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(WITH_PYTHON_MODULE)
 | 
			
		||||
	add_definitions(-DWITH_PYTHON_MODULE)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
blender_add_lib(bf_python "${SRC}" "${INC}")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -55,6 +55,8 @@
 | 
			
		||||
 | 
			
		||||
#include "BPy_Freestyle.h"
 | 
			
		||||
 | 
			
		||||
PyObject *bpy_package_py= NULL;
 | 
			
		||||
 | 
			
		||||
static char bpy_script_paths_doc[] =
 | 
			
		||||
".. function:: script_paths()\n"
 | 
			
		||||
"\n"
 | 
			
		||||
@@ -163,7 +165,7 @@ static PyMethodDef meth_bpy_script_paths = {"script_paths", (PyCFunction)bpy_scr
 | 
			
		||||
static PyMethodDef meth_bpy_blend_paths = {"blend_paths", (PyCFunction)bpy_blend_paths, METH_VARARGS|METH_KEYWORDS, bpy_blend_paths_doc};
 | 
			
		||||
static PyMethodDef meth_bpy_user_resource = {"user_resource", (PyCFunction)bpy_user_resource, METH_VARARGS|METH_KEYWORDS, NULL};
 | 
			
		||||
 | 
			
		||||
static void bpy_import_test(const char *modname)
 | 
			
		||||
static PyObject *bpy_import_test(const char *modname)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *mod= PyImport_ImportModuleLevel((char *)modname, NULL, NULL, NULL, 0);
 | 
			
		||||
	if(mod) {
 | 
			
		||||
@@ -173,6 +175,8 @@ static void bpy_import_test(const char *modname)
 | 
			
		||||
		PyErr_Print();
 | 
			
		||||
		PyErr_Clear();
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	return mod;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
@@ -238,5 +242,5 @@ void BPy_init_modules( void )
 | 
			
		||||
	PyModule_AddObject(mod, meth_bpy_unregister_class.ml_name, (PyObject *)PyCFunction_New(&meth_bpy_unregister_class, NULL));
 | 
			
		||||
 | 
			
		||||
	/* add our own modules dir, this is a python package */
 | 
			
		||||
	bpy_import_test("bpy");
 | 
			
		||||
	bpy_package_py= bpy_import_test("bpy");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -22,4 +22,4 @@
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK ***** */
 | 
			
		||||
 
 | 
			
		||||
void BPy_init_modules( void );
 | 
			
		||||
 
 | 
			
		||||
extern PyObject *bpy_package_py;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -35,6 +35,7 @@
 | 
			
		||||
#include "bpy.h"
 | 
			
		||||
#include "bpy_rna.h"
 | 
			
		||||
#include "bpy_util.h"
 | 
			
		||||
#include "bpy_traceback.h"
 | 
			
		||||
 | 
			
		||||
#include "DNA_space_types.h"
 | 
			
		||||
#include "DNA_text_types.h"
 | 
			
		||||
@@ -157,6 +158,7 @@ void BPY_modules_update(bContext *C)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* must be called before Py_Initialize */
 | 
			
		||||
#ifndef WITH_PYTHON_MODULE
 | 
			
		||||
static void bpy_python_start_path(void)
 | 
			
		||||
{
 | 
			
		||||
	char *py_path_bundle= BLI_get_folder(BLENDER_PYTHON, NULL);
 | 
			
		||||
@@ -195,8 +197,7 @@ static void bpy_python_start_path(void)
 | 
			
		||||
		// printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void BPY_context_set(bContext *C)
 | 
			
		||||
{
 | 
			
		||||
@@ -219,8 +220,9 @@ static struct _inittab bpy_internal_modules[]= {
 | 
			
		||||
/* call BPY_context_set first */
 | 
			
		||||
void BPY_python_start(int argc, const char **argv)
 | 
			
		||||
{
 | 
			
		||||
#ifndef WITH_PYTHON_MODULE
 | 
			
		||||
	PyThreadState *py_tstate = NULL;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* not essential but nice to set our name */
 | 
			
		||||
	static wchar_t bprogname_wchar[FILE_MAXDIR+FILE_MAXFILE]; /* python holds a reference */
 | 
			
		||||
	utf8towchar(bprogname_wchar, bprogname);
 | 
			
		||||
@@ -252,8 +254,13 @@ void BPY_python_start(int argc, const char **argv)
 | 
			
		||||
	
 | 
			
		||||
	/* Initialize thread support (also acquires lock) */
 | 
			
		||||
	PyEval_InitThreads();
 | 
			
		||||
#else
 | 
			
		||||
	(void)argc;
 | 
			
		||||
	(void)argv;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	PyImport_ExtendInittab(bpy_internal_modules);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* bpy.* and lets us import it */
 | 
			
		||||
	BPy_init_modules();
 | 
			
		||||
 | 
			
		||||
@@ -281,8 +288,10 @@ void BPY_python_start(int argc, const char **argv)
 | 
			
		||||
	
 | 
			
		||||
	pyrna_alloc_types();
 | 
			
		||||
 | 
			
		||||
#ifndef WITH_PYTHON_MODULE
 | 
			
		||||
	py_tstate = PyGILState_GetThisThreadState();
 | 
			
		||||
	PyEval_ReleaseThread(py_tstate);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BPY_python_end(void)
 | 
			
		||||
@@ -319,6 +328,18 @@ void BPY_python_end(void)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void python_script_error_jump_text(struct Text *text)
 | 
			
		||||
{
 | 
			
		||||
	int lineno;
 | 
			
		||||
	int offset;
 | 
			
		||||
	python_script_error_jump(text->id.name+2, &lineno, &offset);
 | 
			
		||||
	if(lineno != -1) {
 | 
			
		||||
		/* select the line with the error */
 | 
			
		||||
		txt_move_to(text, lineno - 1, INT_MAX, FALSE);
 | 
			
		||||
		txt_move_to(text, lineno - 1, offset, TRUE);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* super annoying, undo _PyModule_Clear(), bug [#23871] */
 | 
			
		||||
#define PYMODULE_CLEAR_WORKAROUND
 | 
			
		||||
 | 
			
		||||
@@ -332,7 +353,7 @@ typedef struct {
 | 
			
		||||
} PyModuleObject;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
 | 
			
		||||
static int python_script_exec(bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const short do_jump)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *main_mod= NULL;
 | 
			
		||||
	PyObject *py_dict= NULL, *py_result= NULL;
 | 
			
		||||
@@ -361,6 +382,9 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
 | 
			
		||||
			MEM_freeN( buf );
 | 
			
		||||
 | 
			
		||||
			if(PyErr_Occurred()) {
 | 
			
		||||
				if(do_jump) {
 | 
			
		||||
					python_script_error_jump_text(text);
 | 
			
		||||
				}
 | 
			
		||||
				BPY_text_free_code(text);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -406,6 +430,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!py_result) {
 | 
			
		||||
		if(text) {
 | 
			
		||||
			if(do_jump) {
 | 
			
		||||
				python_script_error_jump_text(text);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		BPy_errors_to_report(reports);
 | 
			
		||||
	} else {
 | 
			
		||||
		Py_DECREF( py_result );
 | 
			
		||||
@@ -434,13 +463,13 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, st
 | 
			
		||||
/* Can run a file or text block */
 | 
			
		||||
int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports)
 | 
			
		||||
{
 | 
			
		||||
	return python_script_exec(C, filepath, NULL, reports);
 | 
			
		||||
	return python_script_exec(C, filepath, NULL, reports, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports)
 | 
			
		||||
int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump)
 | 
			
		||||
{
 | 
			
		||||
	return python_script_exec(C, NULL, text, reports);
 | 
			
		||||
	return python_script_exec(C, NULL, text, reports, do_jump);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BPY_DECREF(void *pyob_ptr)
 | 
			
		||||
@@ -659,3 +688,102 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
 | 
			
		||||
	return done;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef WITH_PYTHON_MODULE
 | 
			
		||||
#include "BLI_storage.h"
 | 
			
		||||
/* TODO, reloading the module isnt functional at the moment. */
 | 
			
		||||
 | 
			
		||||
extern int main_python(int argc, const char **argv);
 | 
			
		||||
static struct PyModuleDef bpy_proxy_def = {
 | 
			
		||||
	PyModuleDef_HEAD_INIT,
 | 
			
		||||
	"bpy",  /* m_name */
 | 
			
		||||
	NULL,  /* m_doc */
 | 
			
		||||
	0,  /* m_size */
 | 
			
		||||
	NULL,  /* m_methods */
 | 
			
		||||
	NULL,  /* m_reload */
 | 
			
		||||
	NULL,  /* m_traverse */
 | 
			
		||||
	NULL,  /* m_clear */
 | 
			
		||||
	NULL,  /* m_free */
 | 
			
		||||
};	
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    PyObject_HEAD
 | 
			
		||||
    /* Type-specific fields go here. */
 | 
			
		||||
	PyObject *mod;
 | 
			
		||||
} dealloc_obj;
 | 
			
		||||
 | 
			
		||||
/* call once __file__ is set */
 | 
			
		||||
void bpy_module_delay_init(PyObject *bpy_proxy)
 | 
			
		||||
{
 | 
			
		||||
	const int argc= 1;
 | 
			
		||||
	const char *argv[2];
 | 
			
		||||
 | 
			
		||||
	const char *filename_rel= PyModule_GetFilename(bpy_proxy); /* can be relative */
 | 
			
		||||
	char filename_abs[1024];
 | 
			
		||||
 | 
			
		||||
	BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
 | 
			
		||||
	BLI_path_cwd(filename_abs);
 | 
			
		||||
	
 | 
			
		||||
	argv[0]= filename_abs;
 | 
			
		||||
	argv[1]= NULL;
 | 
			
		||||
	
 | 
			
		||||
	// printf("module found %s\n", argv[0]);
 | 
			
		||||
 | 
			
		||||
	main_python(argc, argv);
 | 
			
		||||
 | 
			
		||||
	/* initialized in BPy_init_modules() */
 | 
			
		||||
	PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dealloc_obj_dealloc(PyObject *self);
 | 
			
		||||
 | 
			
		||||
static PyTypeObject dealloc_obj_Type = {{{0}}};
 | 
			
		||||
 | 
			
		||||
/* use our own dealloc so we can free a property if we use one */
 | 
			
		||||
static void dealloc_obj_dealloc(PyObject *self)
 | 
			
		||||
{
 | 
			
		||||
	bpy_module_delay_init(((dealloc_obj *)self)->mod);
 | 
			
		||||
 | 
			
		||||
	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
 | 
			
		||||
	dealloc_obj_Type.tp_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PyMODINIT_FUNC
 | 
			
		||||
PyInit_bpy(void)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *bpy_proxy= PyModule_Create(&bpy_proxy_def);
 | 
			
		||||
	
 | 
			
		||||
	/* Problem:
 | 
			
		||||
	 * 1) this init function is expected to have a private member defined - 'md_def'
 | 
			
		||||
	 *    but this is only set for C defined modules (not py packages)
 | 
			
		||||
	 *    so we cant return 'bpy_package_py' as is.
 | 
			
		||||
	 *
 | 
			
		||||
	 * 2) there is a 'bpy' C module for python to load which is basically all of blender,
 | 
			
		||||
	 *    and there is scripts/bpy/__init__.py, 
 | 
			
		||||
	 *    we may end up having to rename this module so there is no naming conflict here eg:
 | 
			
		||||
	 *    'from blender import bpy'
 | 
			
		||||
	 *
 | 
			
		||||
	 * 3) we dont know the filename at this point, workaround by assigning a dummy value
 | 
			
		||||
	 *    which calls back when its freed so the real loading can take place.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/* assign an object which is freed after __file__ is assigned */
 | 
			
		||||
	dealloc_obj *dob;
 | 
			
		||||
	
 | 
			
		||||
	/* assign dummy type */
 | 
			
		||||
	dealloc_obj_Type.tp_name = "dealloc_obj";
 | 
			
		||||
	dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
 | 
			
		||||
	dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
 | 
			
		||||
	dealloc_obj_Type.tp_flags = Py_TPFLAGS_DEFAULT;
 | 
			
		||||
	
 | 
			
		||||
	if(PyType_Ready(&dealloc_obj_Type) < 0)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	dob= (dealloc_obj *) dealloc_obj_Type.tp_alloc(&dealloc_obj_Type, 0);
 | 
			
		||||
	dob->mod= bpy_proxy; /* borrow */
 | 
			
		||||
	PyModule_AddObject(bpy_proxy, "__file__", (PyObject *)dob); /* borrow */
 | 
			
		||||
 | 
			
		||||
	return bpy_proxy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
 | 
			
		||||
#include <Python.h>
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <float.h> /* FLT_MIN/MAX */
 | 
			
		||||
 | 
			
		||||
#include "bpy_rna.h"
 | 
			
		||||
@@ -655,7 +656,7 @@ static long pyrna_prop_hash(BPy_PropertyRNA *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* use our own dealloc so we can free a property if we use one */
 | 
			
		||||
static void pyrna_struct_dealloc( BPy_StructRNA *self )
 | 
			
		||||
static void pyrna_struct_dealloc(BPy_StructRNA *self)
 | 
			
		||||
{
 | 
			
		||||
	if (self->freeptr && self->ptr.data) {
 | 
			
		||||
		IDP_FreeProperty(self->ptr.data);
 | 
			
		||||
@@ -663,9 +664,37 @@ static void pyrna_struct_dealloc( BPy_StructRNA *self )
 | 
			
		||||
		self->ptr.data= NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
    if (self->in_weakreflist != NULL) {
 | 
			
		||||
        PyObject_ClearWeakRefs((PyObject *)self);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
 | 
			
		||||
	Py_TYPE(self)->tp_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* use our own dealloc so we can free a property if we use one */
 | 
			
		||||
static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
 | 
			
		||||
{
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
    if (self->in_weakreflist != NULL) {
 | 
			
		||||
        PyObject_ClearWeakRefs((PyObject *)self);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
 | 
			
		||||
	Py_TYPE(self)->tp_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pyrna_prop_array_dealloc(BPy_PropertyRNA *self)
 | 
			
		||||
{
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
    if (self->in_weakreflist != NULL) {
 | 
			
		||||
        PyObject_ClearWeakRefs((PyObject *)self);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
 | 
			
		||||
	Py_TYPE(self)->tp_free(self);
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
 | 
			
		||||
@@ -1013,26 +1042,12 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (RNA_property_array_check(ptr, prop)) {
 | 
			
		||||
 | 
			
		||||
		/* char error_str[512]; */
 | 
			
		||||
		int ok= 1;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_MATHUTILS
 | 
			
		||||
		if(MatrixObject_Check(value)) {
 | 
			
		||||
			MatrixObject *mat = (MatrixObject*)value;
 | 
			
		||||
			if(!BaseMath_ReadCallback(mat))
 | 
			
		||||
				return -1;
 | 
			
		||||
		} else /* continue... */
 | 
			
		||||
#endif // USE_MATHUTILS
 | 
			
		||||
		if (!PySequence_Check(value)) {
 | 
			
		||||
			PyErr_Format(PyExc_TypeError, "%.200s RNA array assignment to %.200s.%.200s expected a sequence, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), Py_TYPE(value)->tp_name);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		/* done getting the length */
 | 
			
		||||
		ok= pyrna_py_to_array(ptr, prop, data, value, error_prefix);
 | 
			
		||||
 | 
			
		||||
		if (!ok) {
 | 
			
		||||
			/* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -2246,8 +2261,8 @@ static char pyrna_struct_keyframe_insert_doc[] =
 | 
			
		||||
"   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
 | 
			
		||||
"   :type group: str\n"
 | 
			
		||||
"   :return: Success of keyframe insertion.\n"
 | 
			
		||||
"   :rtype: boolean";
 | 
			
		||||
 | 
			
		||||
"   :rtype: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
 | 
			
		||||
{
 | 
			
		||||
	/* args, pyrna_struct_keyframe_parse handles these */
 | 
			
		||||
@@ -2289,8 +2304,8 @@ static char pyrna_struct_keyframe_delete_doc[] =
 | 
			
		||||
"   :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
 | 
			
		||||
"   :type group: str\n"
 | 
			
		||||
"   :return: Success of keyframe deleation.\n"
 | 
			
		||||
"   :rtype: boolean";
 | 
			
		||||
 | 
			
		||||
"   :rtype: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
 | 
			
		||||
{
 | 
			
		||||
	/* args, pyrna_struct_keyframe_parse handles these */
 | 
			
		||||
@@ -2329,8 +2344,8 @@ static char pyrna_struct_driver_add_doc[] =
 | 
			
		||||
"   :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
 | 
			
		||||
"   :type index: int\n"
 | 
			
		||||
"   :return: The driver(s) added.\n"
 | 
			
		||||
"   :rtype: :class:`FCurve` or list if index is -1 with an array property.";
 | 
			
		||||
 | 
			
		||||
"   :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	const char *path, *path_full;
 | 
			
		||||
@@ -2401,8 +2416,8 @@ static char pyrna_struct_driver_remove_doc[] =
 | 
			
		||||
"   :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
 | 
			
		||||
"   :type index: int\n"
 | 
			
		||||
"   :return: Success of driver removal.\n"
 | 
			
		||||
"   :rtype: boolean";
 | 
			
		||||
 | 
			
		||||
"   :rtype: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	const char *path, *path_full;
 | 
			
		||||
@@ -2438,8 +2453,8 @@ static char pyrna_struct_is_property_set_doc[] =
 | 
			
		||||
"   Check if a property is set, use for testing operator properties.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   :return: True when the property has been set.\n"
 | 
			
		||||
"   :rtype: boolean";
 | 
			
		||||
 | 
			
		||||
"   :rtype: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	PropertyRNA *prop;
 | 
			
		||||
@@ -2478,8 +2493,8 @@ static char pyrna_struct_is_property_hidden_doc[] =
 | 
			
		||||
"   Check if a property is hidden.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   :return: True when the property is hidden.\n"
 | 
			
		||||
"   :rtype: boolean";
 | 
			
		||||
 | 
			
		||||
"   :rtype: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	PropertyRNA *prop;
 | 
			
		||||
@@ -2504,8 +2519,8 @@ static char pyrna_struct_path_resolve_doc[] =
 | 
			
		||||
"   :arg path: path which this property resolves.\n"
 | 
			
		||||
"   :type path: string\n"
 | 
			
		||||
"   :arg coerce: optional argument, when True, the property will be converted into its python representation.\n"
 | 
			
		||||
"   :type coerce: boolean\n";
 | 
			
		||||
 | 
			
		||||
"   :type coerce: boolean\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	const char *path;
 | 
			
		||||
@@ -2555,8 +2570,8 @@ static char pyrna_struct_path_from_id_doc[] =
 | 
			
		||||
"   :arg property: Optional property name which can be used if the path is to a property of this object.\n"
 | 
			
		||||
"   :type property: string\n"
 | 
			
		||||
"   :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given).\n"
 | 
			
		||||
"   :rtype: str";
 | 
			
		||||
 | 
			
		||||
"   :rtype: str\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_path_from_id(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	const char *name= NULL;
 | 
			
		||||
@@ -2598,8 +2613,8 @@ static char pyrna_prop_path_from_id_doc[] =
 | 
			
		||||
"   Returns the data path from the ID to this property (string).\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   :return: The path from :class:`bpy_struct.id_data` to this property.\n"
 | 
			
		||||
"   :rtype: str";
 | 
			
		||||
 | 
			
		||||
"   :rtype: str\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self)
 | 
			
		||||
{
 | 
			
		||||
	const char *path;
 | 
			
		||||
@@ -2625,8 +2640,8 @@ static char pyrna_struct_type_recast_doc[] =
 | 
			
		||||
"   Return a new instance, this is needed because types such as textures can be changed at runtime.\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   :return: a new instance of this object with the type initialized again.\n"
 | 
			
		||||
"   :rtype: subclass of :class:`bpy_struct`";
 | 
			
		||||
 | 
			
		||||
"   :rtype: subclass of :class:`bpy_struct`\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_type_recast(BPy_StructRNA *self)
 | 
			
		||||
{
 | 
			
		||||
	PointerRNA r_ptr;
 | 
			
		||||
@@ -3244,10 +3259,10 @@ static char pyrna_struct_get_doc[] =
 | 
			
		||||
"   :arg key: The key assosiated with the custom property.\n"
 | 
			
		||||
"   :type key: string\n"
 | 
			
		||||
"   :arg default: Optional argument for the value to return if *key* is not found.\n"
 | 
			
		||||
// "   :type default: Undefined\n"
 | 
			
		||||
"   :type default: Undefined\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n";
 | 
			
		||||
 | 
			
		||||
"   .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties.\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_get(BPy_StructRNA *self, PyObject *args)
 | 
			
		||||
{
 | 
			
		||||
	IDProperty *group, *idprop;
 | 
			
		||||
@@ -3283,8 +3298,8 @@ static char pyrna_struct_as_pointer_doc[] =
 | 
			
		||||
"   :return: int (memory address).\n"
 | 
			
		||||
"   :rtype: int\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"   .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules.\n";
 | 
			
		||||
 | 
			
		||||
"   .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules.\n"
 | 
			
		||||
;
 | 
			
		||||
static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
 | 
			
		||||
{
 | 
			
		||||
	return PyLong_FromVoidPtr(self->ptr.data);
 | 
			
		||||
@@ -3937,6 +3952,16 @@ static PyObject * pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* for testing */
 | 
			
		||||
	/*
 | 
			
		||||
	{
 | 
			
		||||
		const char *fn;
 | 
			
		||||
		int lineno;
 | 
			
		||||
		PyC_FileAndNum(&fn, &lineno);
 | 
			
		||||
		printf("pyrna_func_call > %.200s.%.200s : %.200s:%d\n", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), fn, lineno);
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
	/* include the ID pointer for pyrna_param_to_py() so we can include the
 | 
			
		||||
	 * ID pointer on return values, this only works when returned values have
 | 
			
		||||
	 * the same ID as the functions. */
 | 
			
		||||
@@ -4228,10 +4253,10 @@ PyTypeObject pyrna_struct_meta_idprop_Type = {
 | 
			
		||||
PyTypeObject pyrna_struct_Type = {
 | 
			
		||||
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
	"bpy_struct",			/* tp_name */
 | 
			
		||||
	sizeof( BPy_StructRNA ),	/* tp_basicsize */
 | 
			
		||||
	sizeof(BPy_StructRNA),	/* tp_basicsize */
 | 
			
		||||
	0,			/* tp_itemsize */
 | 
			
		||||
	/* methods */
 | 
			
		||||
	( destructor ) pyrna_struct_dealloc,/* tp_dealloc */
 | 
			
		||||
	(destructor) pyrna_struct_dealloc,/* tp_dealloc */
 | 
			
		||||
	NULL,                       /* printfunc tp_print; */
 | 
			
		||||
	NULL,						/* getattrfunc tp_getattr; */
 | 
			
		||||
	NULL,						/* setattrfunc tp_setattr; */
 | 
			
		||||
@@ -4271,8 +4296,11 @@ PyTypeObject pyrna_struct_Type = {
 | 
			
		||||
	(richcmpfunc)pyrna_struct_richcmp,	/* richcmpfunc tp_richcompare; */
 | 
			
		||||
 | 
			
		||||
  /***  weak reference enabler ***/
 | 
			
		||||
	0,                          /* long tp_weaklistoffset; */
 | 
			
		||||
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	offsetof(BPy_StructRNA, in_weakreflist),	/* long tp_weaklistoffset; */
 | 
			
		||||
#else
 | 
			
		||||
	0,
 | 
			
		||||
#endif
 | 
			
		||||
  /*** Added in release 2.2 ***/
 | 
			
		||||
	/*   Iterators */
 | 
			
		||||
	NULL,                       /* getiterfunc tp_iter; */
 | 
			
		||||
@@ -4307,11 +4335,11 @@ PyTypeObject pyrna_struct_Type = {
 | 
			
		||||
PyTypeObject pyrna_prop_Type = {
 | 
			
		||||
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
	"bpy_prop",		/* tp_name */
 | 
			
		||||
	sizeof( BPy_PropertyRNA ),			/* tp_basicsize */
 | 
			
		||||
	sizeof(BPy_PropertyRNA),			/* tp_basicsize */
 | 
			
		||||
	0,			/* tp_itemsize */
 | 
			
		||||
	/* methods */
 | 
			
		||||
	NULL,						/* tp_dealloc */
 | 
			
		||||
	NULL,                   /* printfunc tp_print; */
 | 
			
		||||
	(destructor) pyrna_prop_dealloc, /* tp_dealloc */
 | 
			
		||||
	NULL,						/* printfunc tp_print; */
 | 
			
		||||
	NULL,						/* getattrfunc tp_getattr; */
 | 
			
		||||
	NULL,                       /* setattrfunc tp_setattr; */
 | 
			
		||||
	NULL,						/* tp_compare */ /* DEPRECATED in python 3.0! */
 | 
			
		||||
@@ -4352,7 +4380,11 @@ PyTypeObject pyrna_prop_Type = {
 | 
			
		||||
	(richcmpfunc)pyrna_prop_richcmp,	/* richcmpfunc tp_richcompare; */
 | 
			
		||||
 | 
			
		||||
  /***  weak reference enabler ***/
 | 
			
		||||
	0,                          /* long tp_weaklistoffset; */
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	offsetof(BPy_PropertyRNA, in_weakreflist),	/* long tp_weaklistoffset; */
 | 
			
		||||
#else
 | 
			
		||||
	0,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /*** Added in release 2.2 ***/
 | 
			
		||||
	/*   Iterators */
 | 
			
		||||
@@ -4387,10 +4419,10 @@ PyTypeObject pyrna_prop_Type = {
 | 
			
		||||
PyTypeObject pyrna_prop_array_Type = {
 | 
			
		||||
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
	"bpy_prop_array",		/* tp_name */
 | 
			
		||||
	sizeof( BPy_PropertyArrayRNA ),			/* tp_basicsize */
 | 
			
		||||
	0,			/* tp_itemsize */
 | 
			
		||||
	sizeof(BPy_PropertyArrayRNA),			/* tp_basicsize */
 | 
			
		||||
	0,							/* tp_itemsize */
 | 
			
		||||
	/* methods */
 | 
			
		||||
	NULL,						/* tp_dealloc */
 | 
			
		||||
	(destructor)pyrna_prop_array_dealloc, /* tp_dealloc */
 | 
			
		||||
	NULL,                       /* printfunc tp_print; */
 | 
			
		||||
	NULL,						/* getattrfunc tp_getattr; */
 | 
			
		||||
	NULL,                       /* setattrfunc tp_setattr; */
 | 
			
		||||
@@ -4432,8 +4464,11 @@ PyTypeObject pyrna_prop_array_Type = {
 | 
			
		||||
	NULL, /* subclassed */		/* richcmpfunc tp_richcompare; */
 | 
			
		||||
 | 
			
		||||
  /***  weak reference enabler ***/
 | 
			
		||||
	0,                          /* long tp_weaklistoffset; */
 | 
			
		||||
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	offsetof(BPy_PropertyArrayRNA, in_weakreflist),	/* long tp_weaklistoffset; */
 | 
			
		||||
#else
 | 
			
		||||
	0,
 | 
			
		||||
#endif
 | 
			
		||||
  /*** Added in release 2.2 ***/
 | 
			
		||||
	/*   Iterators */
 | 
			
		||||
	(getiterfunc)pyrna_prop_array_iter,	/* getiterfunc tp_iter; */
 | 
			
		||||
@@ -4467,10 +4502,10 @@ PyTypeObject pyrna_prop_array_Type = {
 | 
			
		||||
PyTypeObject pyrna_prop_collection_Type = {
 | 
			
		||||
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
	"bpy_prop_collection",		/* tp_name */
 | 
			
		||||
	sizeof( BPy_PropertyRNA ),			/* tp_basicsize */
 | 
			
		||||
	sizeof(BPy_PropertyRNA),			/* tp_basicsize */
 | 
			
		||||
	0,			/* tp_itemsize */
 | 
			
		||||
	/* methods */
 | 
			
		||||
	NULL,						/* tp_dealloc */
 | 
			
		||||
	(destructor)pyrna_prop_dealloc, /* tp_dealloc */
 | 
			
		||||
	NULL,                       /* printfunc tp_print; */
 | 
			
		||||
	NULL,						/* getattrfunc tp_getattr; */
 | 
			
		||||
	NULL,                       /* setattrfunc tp_setattr; */
 | 
			
		||||
@@ -4512,7 +4547,11 @@ PyTypeObject pyrna_prop_collection_Type = {
 | 
			
		||||
	NULL, /* subclassed */		/* richcmpfunc tp_richcompare; */
 | 
			
		||||
 | 
			
		||||
  /***  weak reference enabler ***/
 | 
			
		||||
	0,                          /* long tp_weaklistoffset; */
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	offsetof(BPy_PropertyRNA, in_weakreflist),	/* long tp_weaklistoffset; */
 | 
			
		||||
#else
 | 
			
		||||
	0,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /*** Added in release 2.2 ***/
 | 
			
		||||
	/*   Iterators */
 | 
			
		||||
@@ -4548,10 +4587,10 @@ PyTypeObject pyrna_prop_collection_Type = {
 | 
			
		||||
static PyTypeObject pyrna_prop_collection_idprop_Type = {
 | 
			
		||||
	PyVarObject_HEAD_INIT(NULL, 0)
 | 
			
		||||
	"bpy_prop_collection_idprop",		/* tp_name */
 | 
			
		||||
	sizeof( BPy_PropertyRNA ),			/* tp_basicsize */
 | 
			
		||||
	0,			/* tp_itemsize */
 | 
			
		||||
	sizeof(BPy_PropertyRNA),			/* tp_basicsize */
 | 
			
		||||
	0,							/* tp_itemsize */
 | 
			
		||||
	/* methods */
 | 
			
		||||
	NULL,						/* tp_dealloc */
 | 
			
		||||
	(destructor)pyrna_prop_dealloc, /* tp_dealloc */
 | 
			
		||||
	NULL,                       /* printfunc tp_print; */
 | 
			
		||||
	NULL,						/* getattrfunc tp_getattr; */
 | 
			
		||||
	NULL,                       /* setattrfunc tp_setattr; */
 | 
			
		||||
@@ -4593,7 +4632,11 @@ static PyTypeObject pyrna_prop_collection_idprop_Type = {
 | 
			
		||||
	NULL, /* subclassed */		/* richcmpfunc tp_richcompare; */
 | 
			
		||||
 | 
			
		||||
  /***  weak reference enabler ***/
 | 
			
		||||
	0,                          /* long tp_weaklistoffset; */
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	offsetof(BPy_PropertyRNA, in_weakreflist),	/* long tp_weaklistoffset; */
 | 
			
		||||
#else
 | 
			
		||||
	0,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /*** Added in release 2.2 ***/
 | 
			
		||||
	/*   Iterators */
 | 
			
		||||
@@ -4834,6 +4877,9 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
 | 
			
		||||
		else {
 | 
			
		||||
			fprintf(stderr, "Could not make type\n");
 | 
			
		||||
			pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
			pyrna->in_weakreflist= NULL;
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -4870,11 +4916,17 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyRNA, type);
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
		pyrna->in_weakreflist= NULL;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		pyrna = (BPy_PropertyRNA *) PyObject_NEW(BPy_PropertyArrayRNA, &pyrna_prop_array_Type);
 | 
			
		||||
		((BPy_PropertyArrayRNA *)pyrna)->arraydim= 0;
 | 
			
		||||
		((BPy_PropertyArrayRNA *)pyrna)->arrayoffset= 0;
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
		((BPy_PropertyArrayRNA *)pyrna)->in_weakreflist= NULL;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( !pyrna ) {
 | 
			
		||||
@@ -5019,7 +5071,7 @@ PyObject *BPY_rna_types(void)
 | 
			
		||||
 | 
			
		||||
	if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0)  {
 | 
			
		||||
		pyrna_basetype_Type.tp_name = "RNA_Types";
 | 
			
		||||
		pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
 | 
			
		||||
		pyrna_basetype_Type.tp_basicsize = sizeof(BPy_BaseTypeRNA);
 | 
			
		||||
		pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
 | 
			
		||||
		pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
 | 
			
		||||
		pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
 | 
			
		||||
@@ -5033,7 +5085,9 @@ PyObject *BPY_rna_types(void)
 | 
			
		||||
	/* avoid doing this lookup for every getattr */
 | 
			
		||||
	RNA_blender_rna_pointer_create(&self->ptr);
 | 
			
		||||
	self->prop = RNA_struct_find_property(&self->ptr, "structs");
 | 
			
		||||
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	self->in_weakreflist= NULL;
 | 
			
		||||
#endif
 | 
			
		||||
	return (PyObject *)self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -5415,7 +5469,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
 | 
			
		||||
	/* testing, for correctness, not operator and not draw function */
 | 
			
		||||
	const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !RNA_struct_is_a(ptr->type, &RNA_Operator);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	py_class= RNA_struct_py_type_get(ptr->type);
 | 
			
		||||
	
 | 
			
		||||
	/* rare case. can happen when registering subclasses */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -39,21 +39,33 @@ extern PyTypeObject pyrna_prop_collection_Type;
 | 
			
		||||
#define BPy_PropertyRNA_Check(v)		(PyObject_TypeCheck(v, &pyrna_prop_Type))
 | 
			
		||||
#define BPy_PropertyRNA_CheckExact(v)	(Py_TYPE(v) == &pyrna_prop_Type)
 | 
			
		||||
 | 
			
		||||
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
 | 
			
		||||
// #define USE_WEAKREFS
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	PyObject_HEAD /* required python macro   */
 | 
			
		||||
	PointerRNA ptr;
 | 
			
		||||
	PointerRNA	ptr;
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	PyObject *in_weakreflist;
 | 
			
		||||
#endif
 | 
			
		||||
} BPy_DummyPointerRNA;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	PyObject_HEAD /* required python macro   */
 | 
			
		||||
	PointerRNA ptr;
 | 
			
		||||
	int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	PyObject *in_weakreflist;
 | 
			
		||||
#endif
 | 
			
		||||
} BPy_StructRNA;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
	PyObject_HEAD /* required python macro   */
 | 
			
		||||
	PointerRNA ptr;
 | 
			
		||||
	PropertyRNA *prop;
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	PyObject *in_weakreflist;
 | 
			
		||||
#endif
 | 
			
		||||
} BPy_PropertyRNA;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
@@ -64,6 +76,9 @@ typedef struct {
 | 
			
		||||
	/* Arystan: this is a hack to allow sub-item r/w access like: face.uv[n][m] */
 | 
			
		||||
	int arraydim; /* array dimension, e.g: 0 for face.uv, 2 for face.uv[n][m], etc. */
 | 
			
		||||
	int arrayoffset; /* array first item offset, e.g. if face.uv is [4][2], arrayoffset for face.uv[n] is 2n */
 | 
			
		||||
#ifdef USE_WEAKREFS
 | 
			
		||||
	PyObject *in_weakreflist;
 | 
			
		||||
#endif
 | 
			
		||||
} BPy_PropertyArrayRNA;
 | 
			
		||||
 | 
			
		||||
/* cheap trick */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -98,7 +98,7 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
 | 
			
		||||
				Py_DECREF(item);
 | 
			
		||||
 | 
			
		||||
				/* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */
 | 
			
		||||
				PyErr_Format(PyExc_TypeError, "expected sequence items of type %s, not %s", item_type_str, Py_TYPE(item)->tp_name);
 | 
			
		||||
				PyErr_Format(PyExc_TypeError, "%s expected sequence items of type %s, not %s", error_prefix, item_type_str, Py_TYPE(item)->tp_name);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -110,21 +110,22 @@ static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns the number of items in a single- or multi-dimensional sequence. */
 | 
			
		||||
static int count_items(PyObject *seq)
 | 
			
		||||
static int count_items(PyObject *seq, int dim)
 | 
			
		||||
{
 | 
			
		||||
	int totitem= 0;
 | 
			
		||||
 | 
			
		||||
	if (PySequence_Check(seq)) {
 | 
			
		||||
	if(dim > 1) {
 | 
			
		||||
		const int seq_size= PySequence_Size(seq);
 | 
			
		||||
		int i;
 | 
			
		||||
		for (i= 0; i < seq_size; i++) {
 | 
			
		||||
			PyObject *item= PySequence_GetItem(seq, i);
 | 
			
		||||
			totitem += count_items(item);
 | 
			
		||||
			totitem += count_items(item, dim - 1);
 | 
			
		||||
			Py_DECREF(item);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		totitem= 1;
 | 
			
		||||
	else {
 | 
			
		||||
		totitem= PySequence_Size(seq);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return totitem;
 | 
			
		||||
}
 | 
			
		||||
@@ -135,8 +136,8 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
 | 
			
		||||
	int dimsize[MAX_ARRAY_DIMENSION];
 | 
			
		||||
	int tot, totdim, len;
 | 
			
		||||
 | 
			
		||||
	tot= count_items(rvalue);
 | 
			
		||||
	totdim= RNA_property_array_dimension(ptr, prop, dimsize);
 | 
			
		||||
	tot= count_items(rvalue, totdim - lvalue_dim);
 | 
			
		||||
 | 
			
		||||
	if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
 | 
			
		||||
		if (RNA_property_array_length(ptr, prop) != tot) {
 | 
			
		||||
@@ -186,7 +187,7 @@ static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA
 | 
			
		||||
 | 
			
		||||
		if (tot != len) {
 | 
			
		||||
			/* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */
 | 
			
		||||
			PyErr_Format(PyExc_ValueError, "%s sequence must have %d items total, not %d", error_prefix, len, tot);
 | 
			
		||||
			PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, sequence must have %d items total, not %d", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), len, tot);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -315,7 +316,7 @@ static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, i
 | 
			
		||||
 | 
			
		||||
	if(lvalue_dim == totdim) { /* single item, assign directly */
 | 
			
		||||
		if(!check_item_type(py)) {
 | 
			
		||||
			PyErr_Format(PyExc_TypeError, "%s expected a %s type, not %s", error_prefix, item_type_str, Py_TYPE(py)->tp_name);
 | 
			
		||||
			PyErr_Format(PyExc_TypeError, "%s %.200s.%.200s, expected a %s type, not %s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), item_type_str, Py_TYPE(py)->tp_name);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										151
									
								
								source/blender/python/intern/bpy_traceback.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								source/blender/python/intern/bpy_traceback.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * 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 the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <Python.h>
 | 
			
		||||
#include <frameobject.h>
 | 
			
		||||
 | 
			
		||||
#include "bpy_traceback.h"
 | 
			
		||||
 | 
			
		||||
static const char *traceback_filepath(PyTracebackObject *tb)
 | 
			
		||||
{
 | 
			
		||||
	return _PyUnicode_AsString(tb->tb_frame->f_code->co_filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* copied from pythonrun.c, 3.2.0 */
 | 
			
		||||
static int
 | 
			
		||||
parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
 | 
			
		||||
                   int *lineno, int *offset, const char **text)
 | 
			
		||||
{
 | 
			
		||||
    long hold;
 | 
			
		||||
    PyObject *v;
 | 
			
		||||
 | 
			
		||||
    /* old style errors */
 | 
			
		||||
    if (PyTuple_Check(err))
 | 
			
		||||
        return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
 | 
			
		||||
                                lineno, offset, text);
 | 
			
		||||
 | 
			
		||||
    /* new style errors.  `err' is an instance */
 | 
			
		||||
 | 
			
		||||
    if (! (v = PyObject_GetAttrString(err, "msg")))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    *message = v;
 | 
			
		||||
 | 
			
		||||
    if (!(v = PyObject_GetAttrString(err, "filename")))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    if (v == Py_None)
 | 
			
		||||
        *filename = NULL;
 | 
			
		||||
    else if (! (*filename = _PyUnicode_AsString(v)))
 | 
			
		||||
        goto finally;
 | 
			
		||||
 | 
			
		||||
    Py_DECREF(v);
 | 
			
		||||
    if (!(v = PyObject_GetAttrString(err, "lineno")))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    hold = PyLong_AsLong(v);
 | 
			
		||||
    Py_DECREF(v);
 | 
			
		||||
    v = NULL;
 | 
			
		||||
    if (hold < 0 && PyErr_Occurred())
 | 
			
		||||
        goto finally;
 | 
			
		||||
    *lineno = (int)hold;
 | 
			
		||||
 | 
			
		||||
    if (!(v = PyObject_GetAttrString(err, "offset")))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    if (v == Py_None) {
 | 
			
		||||
        *offset = -1;
 | 
			
		||||
        Py_DECREF(v);
 | 
			
		||||
        v = NULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        hold = PyLong_AsLong(v);
 | 
			
		||||
        Py_DECREF(v);
 | 
			
		||||
        v = NULL;
 | 
			
		||||
        if (hold < 0 && PyErr_Occurred())
 | 
			
		||||
            goto finally;
 | 
			
		||||
        *offset = (int)hold;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!(v = PyObject_GetAttrString(err, "text")))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    if (v == Py_None)
 | 
			
		||||
        *text = NULL;
 | 
			
		||||
    else if (!PyUnicode_Check(v) ||
 | 
			
		||||
             !(*text = _PyUnicode_AsString(v)))
 | 
			
		||||
        goto finally;
 | 
			
		||||
    Py_DECREF(v);
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
finally:
 | 
			
		||||
    Py_XDECREF(v);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
/* end copied function! */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *exception, *value;
 | 
			
		||||
	PyTracebackObject *tb;
 | 
			
		||||
 | 
			
		||||
	*lineno= -1;
 | 
			
		||||
	*offset= 0;
 | 
			
		||||
 | 
			
		||||
	PyErr_Fetch(&exception, &value, (PyObject **)&tb);
 | 
			
		||||
 | 
			
		||||
	if(exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
 | 
			
		||||
		/* no traceback available when SyntaxError.
 | 
			
		||||
		 * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
 | 
			
		||||
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
 | 
			
		||||
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */
 | 
			
		||||
 | 
			
		||||
		if(value) { /* should always be true */
 | 
			
		||||
			PyObject *message;
 | 
			
		||||
	        const char *filename, *text;
 | 
			
		||||
 | 
			
		||||
			if(parse_syntax_error(value, &message, &filename, lineno, offset, &text)) {
 | 
			
		||||
				/* python adds a '/', prefix, so check for both */
 | 
			
		||||
				if(	(strcmp(filename, filepath) == 0) || 
 | 
			
		||||
					((filename[0] == '\\' || filename[0] == '/') && strcmp(filename + 1, filepath) == 0)
 | 
			
		||||
				) {
 | 
			
		||||
					/* good */
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					*lineno= -1;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				*lineno= -1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* this avoids an abort in Python 2.3's garbage collecting */
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
 | 
			
		||||
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */
 | 
			
		||||
		PyErr_Print();
 | 
			
		||||
 | 
			
		||||
		for(tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; tb= tb->tb_next) {
 | 
			
		||||
			if(strcmp(traceback_filepath(tb), filepath) != 0) {
 | 
			
		||||
				*lineno= tb->tb_lineno;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								source/blender/python/intern/bpy_traceback.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								source/blender/python/intern/bpy_traceback.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 *
 | 
			
		||||
 * 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 the Free Software Foundation,
 | 
			
		||||
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * ***** END GPL LICENSE BLOCK *****
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BPY_TRACEBACK_H
 | 
			
		||||
#define BPY_TRACEBACK_H
 | 
			
		||||
 | 
			
		||||
void python_script_error_jump(const char *filepath, int *lineno, int *offset);
 | 
			
		||||
 | 
			
		||||
#endif // BPY_TRACEBACK_H
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -36,94 +36,6 @@ static bContext*	__py_context = NULL;
 | 
			
		||||
bContext*	BPy_GetContext(void) { return __py_context; }
 | 
			
		||||
void		BPy_SetContext(bContext *C) { __py_context= C; }
 | 
			
		||||
 | 
			
		||||
int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs)
 | 
			
		||||
{
 | 
			
		||||
	PyObject *item, *fitem;
 | 
			
		||||
	PyObject *py_arg_count;
 | 
			
		||||
	int i, arg_count;
 | 
			
		||||
 | 
			
		||||
	if (base_class) {
 | 
			
		||||
		if (!PyObject_IsSubclass(class, base_class)) {
 | 
			
		||||
			PyObject *name= PyObject_GetAttrString(base_class, "__name__");
 | 
			
		||||
			PyErr_Format(PyExc_AttributeError, "expected %s subclass of class \"%s\"", class_type, name ? _PyUnicode_AsString(name):"<UNKNOWN>");
 | 
			
		||||
			Py_XDECREF(name);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	for(i= 0;class_attrs->name; class_attrs++, i++) {
 | 
			
		||||
		item = PyObject_GetAttrString(class, class_attrs->name);
 | 
			
		||||
 | 
			
		||||
		if (py_class_attrs)
 | 
			
		||||
			py_class_attrs[i]= item;
 | 
			
		||||
		
 | 
			
		||||
		if (item==NULL) {
 | 
			
		||||
			if ((class_attrs->flag & BPY_CLASS_ATTR_OPTIONAL)==0) {
 | 
			
		||||
				PyErr_Format(PyExc_AttributeError, "expected %s class to have an \"%s\" attribute", class_type, class_attrs->name);
 | 
			
		||||
				return -1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			PyErr_Clear();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			Py_DECREF(item); /* no need to keep a ref, the class owns it */
 | 
			
		||||
 | 
			
		||||
			if((item==Py_None) && (class_attrs->flag & BPY_CLASS_ATTR_NONE_OK)) {
 | 
			
		||||
				/* dont do anything, this is ok, dont bother checking other types */
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				switch(class_attrs->type) {
 | 
			
		||||
				case 's':
 | 
			
		||||
					if (PyUnicode_Check(item)==0) {
 | 
			
		||||
						PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a string", class_type, class_attrs->name);
 | 
			
		||||
						return -1;
 | 
			
		||||
					}
 | 
			
		||||
					if(class_attrs->len != -1 && class_attrs->len < PyUnicode_GetSize(item)) {
 | 
			
		||||
						PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute string to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
 | 
			
		||||
						return -1;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					break;
 | 
			
		||||
				case 'l':
 | 
			
		||||
					if (PyList_Check(item)==0) {
 | 
			
		||||
						PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a list", class_type, class_attrs->name);
 | 
			
		||||
						return -1;
 | 
			
		||||
					}
 | 
			
		||||
					if(class_attrs->len != -1 && class_attrs->len < PyList_GET_SIZE(item)) {
 | 
			
		||||
						PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute list to be shorter then %d", class_type, class_attrs->name, class_attrs->len);
 | 
			
		||||
						return -1;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case 'f':
 | 
			
		||||
					if (PyMethod_Check(item))
 | 
			
		||||
						fitem= PyMethod_Function(item); /* py 2.x */
 | 
			
		||||
					else
 | 
			
		||||
						fitem= item; /* py 3.x */
 | 
			
		||||
 | 
			
		||||
					if (PyFunction_Check(fitem)==0) {
 | 
			
		||||
						PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" attribute to be a function", class_type, class_attrs->name);
 | 
			
		||||
						return -1;
 | 
			
		||||
					}
 | 
			
		||||
					if (class_attrs->arg_count >= 0) { /* -1 if we dont care*/
 | 
			
		||||
						py_arg_count = PyObject_GetAttrString(PyFunction_GET_CODE(fitem), "co_argcount");
 | 
			
		||||
						arg_count = PyLong_AsSsize_t(py_arg_count);
 | 
			
		||||
						Py_DECREF(py_arg_count);
 | 
			
		||||
 | 
			
		||||
						if (arg_count != class_attrs->arg_count) {
 | 
			
		||||
							PyErr_Format(PyExc_AttributeError, "expected %s class \"%s\" function to have %d args", class_type, class_attrs->name, class_attrs->arg_count);
 | 
			
		||||
							return -1;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char *BPy_enum_as_string(EnumPropertyItem *item)
 | 
			
		||||
{
 | 
			
		||||
	DynStr *dynstr= BLI_dynstr_new();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
@@ -34,24 +34,8 @@
 | 
			
		||||
struct EnumPropertyItem;
 | 
			
		||||
struct ReportList;
 | 
			
		||||
 | 
			
		||||
/* Class type checking, use for checking classes can be added as operators, panels etc */
 | 
			
		||||
typedef struct BPY_class_attr_check {
 | 
			
		||||
	const char	*name;		/* name of the class attribute */
 | 
			
		||||
	char		type;		/* 's' = string, 'f' = function, 'l' = list, (add as needed) */
 | 
			
		||||
	int			arg_count;	/* only for function types, -1 for undefined, includes self arg */
 | 
			
		||||
	int 		len;		/* only for string types currently */
 | 
			
		||||
	int			flag;		/* other options */
 | 
			
		||||
} BPY_class_attr_check;
 | 
			
		||||
 | 
			
		||||
/* BPY_class_attr_check, flag */
 | 
			
		||||
#define BPY_CLASS_ATTR_OPTIONAL 1
 | 
			
		||||
#define BPY_CLASS_ATTR_NONE_OK	2
 | 
			
		||||
 | 
			
		||||
int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_class, BPY_class_attr_check* class_attrs, PyObject **py_class_attrs);
 | 
			
		||||
 | 
			
		||||
char *BPy_enum_as_string(struct EnumPropertyItem *item);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL}
 | 
			
		||||
 | 
			
		||||
/* error reporting */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/**
 | 
			
		||||
/*
 | 
			
		||||
 * $Id$
 | 
			
		||||
 *
 | 
			
		||||
 * ***** BEGIN GPL LICENSE BLOCK *****
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user