| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  |  * ***** 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 ***** | 
					
						
							| 
									
										
										
										
											2011-10-23 17:52:20 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  | /** \file blender/python/generic/py_capi_utils.c
 | 
					
						
							|  |  |  |  *  \ingroup pygen | 
					
						
							| 
									
										
										
										
											2011-11-05 08:40:07 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Extend upon CPython's API, filling in some gaps, these functions use PyC_ | 
					
						
							|  |  |  |  * prefix to distinguish them apart from CPython. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \note | 
					
						
							|  |  |  |  * This module should only depend on CPython, however it currently uses | 
					
						
							|  |  |  |  * BLI_string_utf8() for unicode conversion. | 
					
						
							| 
									
										
										
										
											2011-02-27 20:10:08 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | #include <Python.h>
 | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | #include <frameobject.h>
 | 
					
						
							| 
									
										
										
										
											2011-02-14 04:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  | #include "BLI_utildefines.h"  /* for bool */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | #include "py_capi_utils.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  | /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ | 
					
						
							|  |  |  | #include "BLI_string_utf8.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-18 10:18:35 +00:00
										 |  |  | #ifdef _WIN32 /* BLI_setenv */
 | 
					
						
							|  |  |  | #include "BLI_path_util.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | /* array utility function */ | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  | int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |                 const PyTypeObject *type, const bool is_double, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyObject *value_fast; | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  | 	Py_ssize_t value_len; | 
					
						
							|  |  |  | 	Py_ssize_t i; | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 22:07:58 +00:00
										 |  |  | 	if (!(value_fast = PySequence_Fast(value, error_prefix))) { | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 22:07:58 +00:00
										 |  |  | 	value_len = PySequence_Fast_GET_SIZE(value_fast); | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (value_len != length) { | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		Py_DECREF(value); | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "%.200s: invalid sequence length. expected %d, got %d", | 
					
						
							|  |  |  | 		             error_prefix, length, value_len); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* for each type */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (type == &PyFloat_Type) { | 
					
						
							|  |  |  | 		if (is_double) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 			double *array_double = array; | 
					
						
							|  |  |  | 			for (i = 0; i < length; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-03 22:07:58 +00:00
										 |  |  | 				array_double[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i)); | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 			float *array_float = array; | 
					
						
							|  |  |  | 			for (i = 0; i < length; i++) { | 
					
						
							| 
									
										
										
										
											2012-03-03 22:07:58 +00:00
										 |  |  | 				array_float[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i)); | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	else if (type == &PyLong_Type) { | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		/* could use is_double for 'long int' but no use now */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		int *array_int = array; | 
					
						
							|  |  |  | 		for (i = 0; i < length; i++) { | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  | 			array_int[i] = PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i)); | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	else if (type == &PyBool_Type) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		int *array_bool = array; | 
					
						
							|  |  |  | 		for (i = 0; i < length; i++) { | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  | 			array_bool[i] = (PyLong_AsLong(PySequence_Fast_GET_ITEM(value_fast, i)) != 0); | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		Py_DECREF(value_fast); | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "%s: internal error %s is invalid", | 
					
						
							|  |  |  | 		             error_prefix, type->tp_name); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_DECREF(value_fast); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "%s: one or more items could not be used as a %s", | 
					
						
							|  |  |  | 		             error_prefix, type->tp_name); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-05 14:56:37 +00:00
										 |  |  | /* array utility function */ | 
					
						
							|  |  |  | PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type, | 
					
						
							| 
									
										
										
										
											2013-01-07 05:26:12 +00:00
										 |  |  |                         const bool is_double, const char *error_prefix) | 
					
						
							| 
									
										
										
										
											2013-01-05 14:56:37 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	PyObject *tuple; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tuple = PyTuple_New(length); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* for each type */ | 
					
						
							|  |  |  | 	if (type == &PyFloat_Type) { | 
					
						
							|  |  |  | 		if (is_double) { | 
					
						
							|  |  |  | 			const double *array_double = array; | 
					
						
							|  |  |  | 			for (i = 0; i < length; ++i) { | 
					
						
							|  |  |  | 				PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i])); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			const float *array_float = array; | 
					
						
							|  |  |  | 			for (i = 0; i < length; ++i) { | 
					
						
							|  |  |  | 				PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i])); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (type == &PyLong_Type) { | 
					
						
							|  |  |  | 		/* could use is_double for 'long int' but no use now */ | 
					
						
							|  |  |  | 		const int *array_int = array; | 
					
						
							|  |  |  | 		for (i = 0; i < length; ++i) { | 
					
						
							|  |  |  | 			PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i])); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (type == &PyBool_Type) { | 
					
						
							|  |  |  | 		const int *array_bool = array; | 
					
						
							|  |  |  | 		for (i = 0; i < length; ++i) { | 
					
						
							|  |  |  | 			PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i])); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		Py_DECREF(tuple); | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "%s: internal error %s is invalid", | 
					
						
							|  |  |  | 		             error_prefix, type->tp_name); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tuple; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-06 16:46:00 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Caller needs to ensure tuple is uninitialized. | 
					
						
							|  |  |  |  * Handy for filling a typle with None for eg. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void PyC_Tuple_Fill(PyObject *tuple, PyObject *value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned int tot = PyTuple_GET_SIZE(tuple); | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < tot; i++) { | 
					
						
							|  |  |  | 		PyTuple_SET_ITEM(tuple, i, value); | 
					
						
							|  |  |  | 		Py_INCREF(value); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-06-17 05:45:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | /* for debugging */ | 
					
						
							| 
									
										
										
										
											2011-09-28 05:53:40 +00:00
										 |  |  | void PyC_ObSpit(const char *name, PyObject *var) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	fprintf(stderr, "<%s> : ", name); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	if (var == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		fprintf(stderr, "<NIL>"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyObject_Print(var, stderr, 0); | 
					
						
							|  |  |  | 		fprintf(stderr, " ref:%d ", (int)var->ob_refcnt); | 
					
						
							|  |  |  | 		fprintf(stderr, " ptr:%p", (void *)var); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		fprintf(stderr, " type:"); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 		if (Py_TYPE(var)) | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 			fprintf(stderr, "%s", Py_TYPE(var)->tp_name); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			fprintf(stderr, "<NIL>"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fprintf(stderr, "\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-28 05:53:40 +00:00
										 |  |  | void PyC_LineSpit(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-25 04:36:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	const char *filename; | 
					
						
							|  |  |  | 	int lineno; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 04:36:10 +00:00
										 |  |  | 	/* Note, allow calling from outside python (RNA) */ | 
					
						
							| 
									
										
										
										
											2013-09-18 23:21:24 +00:00
										 |  |  | 	if (!PyC_IsInterpreterActive()) { | 
					
						
							| 
									
										
										
										
											2011-03-25 04:36:10 +00:00
										 |  |  | 		fprintf(stderr, "python line lookup failed, interpreter inactive\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 	PyC_FileAndNum(&filename, &lineno); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	fprintf(stderr, "%s:%d\n", filename, lineno); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-19 09:55:49 +00:00
										 |  |  | void PyC_StackSpit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Note, allow calling from outside python (RNA) */ | 
					
						
							| 
									
										
										
										
											2013-09-18 23:21:24 +00:00
										 |  |  | 	if (!PyC_IsInterpreterActive()) { | 
					
						
							| 
									
										
										
										
											2012-07-19 09:55:49 +00:00
										 |  |  | 		fprintf(stderr, "python line lookup failed, interpreter inactive\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* lame but handy */ | 
					
						
							|  |  |  | 		PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							|  |  |  | 		PyRun_SimpleString("__import__('traceback').print_stack()"); | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | void PyC_FileAndNum(const char **filename, int *lineno) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 	PyFrameObject *frame; | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-26 06:55:09 +00:00
										 |  |  | 	if (filename) *filename = NULL; | 
					
						
							|  |  |  | 	if (lineno)   *lineno = -1; | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	if (!(frame = PyThreadState_GET()->frame)) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	/* when executing a script */ | 
					
						
							|  |  |  | 	if (filename) { | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 		*filename = _PyUnicode_AsString(frame->f_code->co_filename); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	/* when executing a module */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (filename && *filename == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		/* try an alternative method to get the filename - module based
 | 
					
						
							|  |  |  | 		 * references below are all borrowed (double checked) */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		PyObject *mod_name = PyDict_GetItemString(PyEval_GetGlobals(), "__name__"); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 		if (mod_name) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 			PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 			if (mod) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 				*filename = PyModule_GetFilename(mod); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* unlikely, fallback */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 			if (*filename == NULL) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 				*filename = _PyUnicode_AsString(mod_name); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	if (lineno) { | 
					
						
							| 
									
										
										
										
											2011-02-22 07:57:18 +00:00
										 |  |  | 		*lineno = PyFrame_GetLineNumber(frame); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-20 00:48:00 +00:00
										 |  |  | void PyC_FileAndNum_Safe(const char **filename, int *lineno) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-09-18 23:21:24 +00:00
										 |  |  | 	if (!PyC_IsInterpreterActive()) { | 
					
						
							| 
									
										
										
										
											2011-10-20 00:48:00 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyC_FileAndNum(filename, lineno); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | /* Would be nice if python had this built in */ | 
					
						
							|  |  |  | PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_ssize_t i; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyObject *item = o; | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	char *attr; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	va_list vargs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(vargs, n); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	for (i = 0; i < n; i++) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		attr = va_arg(vargs, char *); | 
					
						
							|  |  |  | 		item = PyObject_GetAttrString(item, attr); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (item)  | 
					
						
							|  |  |  | 			Py_DECREF(item); | 
					
						
							|  |  |  | 		else /* python will set the error value here */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	va_end(vargs); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */ | 
					
						
							|  |  |  | 	return item; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 03:47:37 +00:00
										 |  |  | PyObject *PyC_FrozenSetFromStrings(const char **strings) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const char **str; | 
					
						
							|  |  |  | 	PyObject *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = PyFrozenSet_New(NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (str = strings; *str; str++) { | 
					
						
							|  |  |  | 		PyObject *py_str = PyUnicode_FromString(*str); | 
					
						
							|  |  |  | 		PySet_Add(ret, py_str); | 
					
						
							|  |  |  | 		Py_DECREF(py_str); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-15 10:43:55 +00:00
										 |  |  | /* similar to PyErr_Format(),
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-02-25 16:49:59 +00:00
										 |  |  |  * implementation - we cant actually preprend the existing exception, | 
					
						
							| 
									
										
										
										
											2012-07-16 23:23:33 +00:00
										 |  |  |  * because it could have _any_ arguments given to it, so instead we get its | 
					
						
							| 
									
										
										
										
											2011-09-15 10:43:55 +00:00
										 |  |  |  * __str__ output and raise our own exception including it. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | PyObject *PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *error_value_prefix; | 
					
						
							|  |  |  | 	va_list args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	va_start(args, format); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	error_value_prefix = PyUnicode_FromFormatV(format, args); /* can fail and be NULL */ | 
					
						
							| 
									
										
										
										
											2011-09-15 10:43:55 +00:00
										 |  |  | 	va_end(args); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (PyErr_Occurred()) { | 
					
						
							| 
									
										
										
										
											2011-09-15 10:43:55 +00:00
										 |  |  | 		PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  | 		PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							|  |  |  | 		PyErr_Format(exception_type_prefix, | 
					
						
							|  |  |  | 		             "%S, %.200s(%S)", | 
					
						
							|  |  |  | 		             error_value_prefix, | 
					
						
							|  |  |  | 		             Py_TYPE(error_value)->tp_name, | 
					
						
							|  |  |  | 		             error_value | 
					
						
							|  |  |  | 		             ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_SetObject(exception_type_prefix, | 
					
						
							|  |  |  | 		                error_value_prefix | 
					
						
							|  |  |  | 		                ); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_XDECREF(error_value_prefix); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* dumb to always return NULL but matches PyErr_Format */ | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | /* returns the exception string as a new PyUnicode object, depends on external traceback module */ | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* this version uses traceback module but somehow fails on UI errors */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | PyObject *PyC_ExceptionBuffer(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyObject *traceback_mod = NULL; | 
					
						
							|  |  |  | 	PyObject *format_tb_func = NULL; | 
					
						
							|  |  |  | 	PyObject *ret = NULL; | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	if (!(traceback_mod = PyImport_ImportModule("traceback"))) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		goto error_cleanup; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	else if (!(format_tb_func = PyObject_GetAttrString(traceback_mod, "format_exc"))) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		goto error_cleanup; | 
					
						
							| 
									
										
										
										
											2011-03-19 11:12:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	ret = PyObject_CallObject(format_tb_func, NULL); | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (ret == Py_None) { | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 		Py_DECREF(ret); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		ret = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | error_cleanup: | 
					
						
							|  |  |  | 	/* could not import the module so print the error and close */ | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 	Py_XDECREF(traceback_mod); | 
					
						
							|  |  |  | 	Py_XDECREF(format_tb_func); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-03 06:46:31 +00:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | #else /* verbose, non-threadsafe version */
 | 
					
						
							|  |  |  | PyObject *PyC_ExceptionBuffer(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *stdout_backup = PySys_GetObject("stdout"); /* borrowed */ | 
					
						
							|  |  |  | 	PyObject *stderr_backup = PySys_GetObject("stderr"); /* borrowed */ | 
					
						
							|  |  |  | 	PyObject *string_io = NULL; | 
					
						
							|  |  |  | 	PyObject *string_io_buf = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyObject *string_io_mod = NULL; | 
					
						
							|  |  |  | 	PyObject *string_io_getvalue = NULL; | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	PyObject *error_type, *error_value, *error_traceback; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyErr_Occurred()) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Fetch(&error_type, &error_value, &error_traceback); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* import io
 | 
					
						
							|  |  |  | 	 * string_io = io.StringIO() | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	if (!(string_io_mod = PyImport_ImportModule("io"))) { | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 		goto error_cleanup; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	else if (!(string_io = PyObject_CallMethod(string_io_mod, (char *)"StringIO", NULL))) { | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 		goto error_cleanup; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	else if (!(string_io_getvalue = PyObject_GetAttrString(string_io, "getvalue"))) { | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 		goto error_cleanup; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 	Py_INCREF(stdout_backup); // since these were borrowed we don't want them freed when replaced.
 | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 	Py_INCREF(stderr_backup); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-09 00:41:09 +00:00
										 |  |  | 	PySys_SetObject("stdout", string_io); // both of these are freed when restoring
 | 
					
						
							| 
									
										
										
										
											2011-09-08 02:14:24 +00:00
										 |  |  | 	PySys_SetObject("stderr", string_io); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							|  |  |  | 	PyErr_Print(); /* print the error */ | 
					
						
							|  |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	string_io_buf = PyObject_CallObject(string_io_getvalue, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PySys_SetObject("stdout", stdout_backup); | 
					
						
							|  |  |  | 	PySys_SetObject("stderr", stderr_backup); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_DECREF(stdout_backup); /* now sys owns the ref again */ | 
					
						
							|  |  |  | 	Py_DECREF(stderr_backup); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Py_DECREF(string_io_mod); | 
					
						
							|  |  |  | 	Py_DECREF(string_io_getvalue); | 
					
						
							|  |  |  | 	Py_DECREF(string_io); /* free the original reference */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 	return string_io_buf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | error_cleanup: | 
					
						
							|  |  |  | 	/* could not import the module so print the error and close */ | 
					
						
							|  |  |  | 	Py_XDECREF(string_io_mod); | 
					
						
							|  |  |  | 	Py_XDECREF(string_io); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PyErr_Restore(error_type, error_value, error_traceback); | 
					
						
							|  |  |  | 	PyErr_Print(); /* print the error */ | 
					
						
							|  |  |  | 	PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* string conversion, escape non-unicode chars, coerce must be set to NULL */ | 
					
						
							| 
									
										
										
										
											2010-10-03 23:29:43 +00:00
										 |  |  | const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-03 14:09:18 +00:00
										 |  |  | 	const char *result; | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	result = _PyUnicode_AsString(py_str); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (result) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		/* 99% of the time this is enough but we better support non unicode
 | 
					
						
							|  |  |  | 		 * chars since blender doesnt limit this */ | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2011-09-27 04:07:48 +00:00
										 |  |  | 		PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-18 13:46:57 +00:00
										 |  |  | 		if (PyBytes_Check(py_str)) { | 
					
						
							| 
									
										
										
										
											2011-09-27 04:07:48 +00:00
										 |  |  | 			return PyBytes_AS_STRING(py_str); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-09-04 05:36:07 +00:00
										 |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | 		/* bug [#31856] oddly enough, Python3.2 --> 3.3 on Windows will throw an
 | 
					
						
							|  |  |  | 		 * exception here this needs to be fixed in python: | 
					
						
							|  |  |  | 		 * see: bugs.python.org/issue15859 */ | 
					
						
							|  |  |  | 		else if (!PyUnicode_Check(py_str)) { | 
					
						
							|  |  |  | 			PyErr_BadArgument(); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) { | 
					
						
							| 
									
										
										
										
											2011-11-22 14:05:08 +00:00
										 |  |  | 			return PyBytes_AS_STRING(*coerce); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-09-27 04:07:48 +00:00
										 |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-11-22 14:05:08 +00:00
										 |  |  | 			/* leave error raised from EncodeFS */ | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2011-09-27 04:07:48 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  | PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size) | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  | 	PyObject *result = PyUnicode_FromStringAndSize(str, size); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (result) { | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		/* 99% of the time this is enough but we better support non unicode
 | 
					
						
							|  |  |  | 		 * chars since blender doesnt limit this */ | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_Clear(); | 
					
						
							| 
									
										
										
										
											2010-12-05 09:20:18 +00:00
										 |  |  | 		/* this means paths will always be accessible once converted, on all OS's */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		result = PyUnicode_DecodeFSDefaultAndSize(str, size); | 
					
						
							| 
									
										
										
										
											2010-09-01 14:13:48 +00:00
										 |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 10:49:35 +00:00
										 |  |  | PyObject *PyC_UnicodeFromByte(const char *str) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyC_UnicodeFromByteAndSize(str, strlen(str)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | /*****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |  * Description: This function creates a new Python dictionary object. | 
					
						
							|  |  |  |  * note: dict is owned by sys.modules["__main__"] module, reference is borrowed | 
					
						
							|  |  |  |  * note: important we use the dict from __main__, this is what python expects | 
					
						
							|  |  |  |  *  for 'pickle' to work as well as strings like this... | 
					
						
							|  |  |  |  * >> foo = 10 | 
					
						
							|  |  |  |  * >> print(__import__("__main__").foo) | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2012-09-28 06:45:20 +00:00
										 |  |  |  * note: this overwrites __main__ which gives problems with nested calls. | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  |  * be sure to run PyC_MainModule_Backup & PyC_MainModule_Restore if there is | 
					
						
							|  |  |  |  * any chance that python is in the call stack. | 
					
						
							| 
									
										
										
										
											2012-03-09 18:28:30 +00:00
										 |  |  |  ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | PyObject *PyC_DefaultNameSpace(const char *filename) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyInterpreterState *interp = PyThreadState_GET()->interp; | 
					
						
							|  |  |  | 	PyObject *mod_main = PyModule_New("__main__"); | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | 	PyDict_SetItemString(interp->modules, "__main__", mod_main); | 
					
						
							|  |  |  | 	Py_DECREF(mod_main); /* sys.modules owns now */ | 
					
						
							|  |  |  | 	PyModule_AddStringConstant(mod_main, "__name__", "__main__"); | 
					
						
							| 
									
										
										
										
											2012-03-21 22:29:49 +00:00
										 |  |  | 	if (filename) { | 
					
						
							|  |  |  | 		/* __file__ mainly for nice UI'ness */ | 
					
						
							|  |  |  | 		PyModule_AddObject(mod_main, "__file__", PyUnicode_DecodeFSDefault(filename)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-09-18 15:30:03 +00:00
										 |  |  | 	PyModule_AddObject(mod_main, "__builtins__", interp->builtins); | 
					
						
							|  |  |  | 	Py_INCREF(interp->builtins); /* AddObject steals a reference */ | 
					
						
							|  |  |  | 	return PyModule_GetDict(mod_main); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-01 12:37:53 +00:00
										 |  |  | /* restore MUST be called after this */ | 
					
						
							|  |  |  | void PyC_MainModule_Backup(PyObject **main_mod) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyInterpreterState *interp = PyThreadState_GET()->interp; | 
					
						
							|  |  |  | 	*main_mod = PyDict_GetItemString(interp->modules, "__main__"); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 	Py_XINCREF(*main_mod); /* don't free */ | 
					
						
							| 
									
										
										
										
											2011-02-01 12:37:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PyC_MainModule_Restore(PyObject *main_mod) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyInterpreterState *interp = PyThreadState_GET()->interp; | 
					
						
							| 
									
										
										
										
											2011-02-01 12:37:53 +00:00
										 |  |  | 	PyDict_SetItemString(interp->modules, "__main__", main_mod); | 
					
						
							|  |  |  | 	Py_XDECREF(main_mod); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | /* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */ | 
					
						
							|  |  |  | void PyC_SetHomePath(const char *py_path_bundle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	if (py_path_bundle == NULL) { | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 		/* Common enough to have bundled *nix python but complain on OSX/Win */ | 
					
						
							|  |  |  | #if defined(__APPLE__) || defined(_WIN32)
 | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  | 		fprintf(stderr, "Warning! bundled python not found and is expected on this platform. " | 
					
						
							|  |  |  | 		        "(if you built with CMake: 'install' target may have not been built)\n"); | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* set the environment path */ | 
					
						
							|  |  |  | 	printf("found bundled python: %s\n", py_path_bundle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef __APPLE__
 | 
					
						
							|  |  |  | 	/* OSX allow file/directory names to contain : character (represented as / in the Finder)
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | 	 * but current Python lib (release 3.1.1) doesn't handle these correctly */ | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (strchr(py_path_bundle, ':')) | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 		printf("Warning : Blender application is located in a path containing : or / chars\
 | 
					
						
							| 
									
										
										
										
											2012-11-09 09:33:28 +00:00
										 |  |  | 		       \nThis may make python import function fail\n"); | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-19 10:10:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0 /* disable for now [#31506] - campbell */
 | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 	/* cmake/MSVC debug build crashes without this, why only
 | 
					
						
							| 
									
										
										
										
											2012-03-03 20:36:09 +00:00
										 |  |  | 	 * in this case is unknown.. */ | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-05-28 21:36:29 +00:00
										 |  |  | 		/*BLI_setenv("PYTHONPATH", py_path_bundle)*/; | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-05-19 10:10:49 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		static wchar_t py_path_bundle_wchar[1024]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */ | 
					
						
							|  |  |  | 		/* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-05 02:04:26 +00:00
										 |  |  | 		BLI_strncpy_wchar_from_utf8(py_path_bundle_wchar, py_path_bundle, | 
					
						
							|  |  |  | 		                            sizeof(py_path_bundle_wchar) / sizeof(wchar_t)); | 
					
						
							| 
									
										
										
										
											2011-04-18 08:27:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Py_SetPythonHome(py_path_bundle_wchar); | 
					
						
							|  |  |  | 		// printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar);
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-18 23:21:24 +00:00
										 |  |  | bool PyC_IsInterpreterActive(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (((PyThreadState *)_Py_atomic_load_relaxed(&_PyThreadState_Current)) != NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-28 10:02:10 +00:00
										 |  |  | /* Would be nice if python had this built in
 | 
					
						
							|  |  |  |  * See: http://wiki.blender.org/index.php/Dev:Doc/Tools/Debugging/PyFromC
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | void PyC_RunQuicky(const char *filepath, int n, ...) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	FILE *fp = fopen(filepath, "r"); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 	if (fp) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		PyGILState_STATE gilstate = PyGILState_Ensure(); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-21 05:46:41 +00:00
										 |  |  | 		va_list vargs; | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		int *sizes = PyMem_MALLOC(sizeof(int) * (n / 2)); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 		int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PyObject *py_dict = PyC_DefaultNameSpace(filepath); | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 		PyObject *values = PyList_New(n / 2); /* namespace owns this, don't free */ | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		PyObject *py_result, *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		PyObject *struct_mod = PyImport_ImportModule("struct"); | 
					
						
							|  |  |  | 		PyObject *calcsize = PyObject_GetAttrString(struct_mod, "calcsize"); /* struct.calcsize */ | 
					
						
							|  |  |  | 		PyObject *pack = PyObject_GetAttrString(struct_mod, "pack"); /* struct.pack */ | 
					
						
							|  |  |  | 		PyObject *unpack = PyObject_GetAttrString(struct_mod, "unpack"); /* struct.unpack */ | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Py_DECREF(struct_mod); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		va_start(vargs, n); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 		for (i = 0; i * 2 < n; i++) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 			char *format = va_arg(vargs, char *); | 
					
						
							|  |  |  | 			void *ptr = va_arg(vargs, void *); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 			ret = PyObject_CallFunction(calcsize, (char *)"s", format); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 			if (ret) { | 
					
						
							| 
									
										
										
										
											2012-11-21 02:28:36 +00:00
										 |  |  | 				sizes[i] = PyLong_AsLong(ret); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 				Py_DECREF(ret); | 
					
						
							| 
									
										
										
										
											2010-12-03 17:05:21 +00:00
										 |  |  | 				ret = PyObject_CallFunction(unpack, (char *)"sy#", format, (char *)ptr, sizes[i]); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 			if (ret == NULL) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 				printf("PyC_InlineRun error, line:%d\n", __LINE__); | 
					
						
							|  |  |  | 				PyErr_Print(); | 
					
						
							|  |  |  | 				PyErr_Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				PyList_SET_ITEM(values, i, Py_None); /* hold user */ | 
					
						
							|  |  |  | 				Py_INCREF(Py_None); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 06:55:09 +00:00
										 |  |  | 				sizes[i] = 0; | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 				if (PyTuple_GET_SIZE(ret) == 1) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 					/* convenience, convert single tuples into single values */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 					PyObject *tmp = PyTuple_GET_ITEM(ret, 0); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 					Py_INCREF(tmp); | 
					
						
							|  |  |  | 					Py_DECREF(ret); | 
					
						
							|  |  |  | 					ret = tmp; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				PyList_SET_ITEM(values, i, ret); /* hold user */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		va_end(vargs); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* set the value so we can access it */ | 
					
						
							|  |  |  | 		PyDict_SetItemString(py_dict, "values", values); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fclose(fp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 		if (py_result) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* we could skip this but then only slice assignment would work
 | 
					
						
							|  |  |  | 			 * better not be so strict */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 			values = PyDict_GetItemString(py_dict, "values"); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 			if (values && PyList_Check(values)) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 				/* don't use the result */ | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 				Py_DECREF(py_result); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 				py_result = NULL; | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* now get the values back */ | 
					
						
							|  |  |  | 				va_start(vargs, n); | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 				for (i = 0; i * 2 < n; i++) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 					char *format = va_arg(vargs, char *); | 
					
						
							|  |  |  | 					void *ptr = va_arg(vargs, void *); | 
					
						
							|  |  |  | 					 | 
					
						
							|  |  |  | 					PyObject *item; | 
					
						
							|  |  |  | 					PyObject *item_new; | 
					
						
							|  |  |  | 					/* prepend the string formatting and remake the tuple */ | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 					item = PyList_GET_ITEM(values, i); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 					if (PyTuple_CheckExact(item)) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 						int ofs = PyTuple_GET_SIZE(item); | 
					
						
							|  |  |  | 						item_new = PyTuple_New(ofs + 1); | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 						while (ofs--) { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 							PyObject *member = PyTuple_GET_ITEM(item, ofs); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 							PyTuple_SET_ITEM(item_new, ofs + 1, member); | 
					
						
							|  |  |  | 							Py_INCREF(member); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format)); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 						item_new = Py_BuildValue("sO", format, item); | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					ret = PyObject_Call(pack, item_new, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-13 01:29:08 +00:00
										 |  |  | 					if (ret) { | 
					
						
							| 
									
										
										
										
											2010-09-19 14:02:45 +00:00
										 |  |  | 						/* copy the bytes back into memory */ | 
					
						
							|  |  |  | 						memcpy(ptr, PyBytes_AS_STRING(ret), sizes[i]); | 
					
						
							|  |  |  | 						Py_DECREF(ret); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						printf("PyC_InlineRun error on arg '%d', line:%d\n", i, __LINE__); | 
					
						
							|  |  |  | 						PyC_ObSpit("failed converting:", item_new); | 
					
						
							|  |  |  | 						PyErr_Print(); | 
					
						
							|  |  |  | 						PyErr_Clear(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					Py_DECREF(item_new); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				va_end(vargs); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				printf("PyC_InlineRun error, 'values' not a list, line:%d\n", __LINE__); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			printf("PyC_InlineRun error line:%d\n", __LINE__); | 
					
						
							|  |  |  | 			PyErr_Print(); | 
					
						
							|  |  |  | 			PyErr_Clear(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Py_DECREF(calcsize); | 
					
						
							|  |  |  | 		Py_DECREF(pack); | 
					
						
							|  |  |  | 		Py_DECREF(unpack); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PyMem_FREE(sizes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PyGILState_Release(gilstate); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-20 22:04:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* generic function to avoid depending on RNA */ | 
					
						
							|  |  |  | void *PyC_RNA_AsPointer(PyObject *value, const char *type_name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-16 21:39:56 +00:00
										 |  |  | 	PyObject *as_pointer; | 
					
						
							|  |  |  | 	PyObject *pointer; | 
					
						
							| 
									
										
										
										
											2012-02-20 22:04:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-10 06:18:03 +00:00
										 |  |  | 	if (STREQ(Py_TYPE(value)->tp_name, type_name) && | 
					
						
							| 
									
										
										
										
											2012-02-20 22:04:29 +00:00
										 |  |  | 	    (as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL && | 
					
						
							|  |  |  | 	    PyCallable_Check(as_pointer)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		void *result = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* must be a 'type_name' object */ | 
					
						
							|  |  |  | 		pointer = PyObject_CallObject(as_pointer, NULL); | 
					
						
							|  |  |  | 		Py_DECREF(as_pointer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!pointer) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed"); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		result = PyLong_AsVoidPtr(pointer); | 
					
						
							|  |  |  | 		Py_DECREF(pointer); | 
					
						
							|  |  |  | 		if (!result) { | 
					
						
							|  |  |  | 			PyErr_SetString(PyExc_SystemError, "value.as_pointer() failed"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "expected '%.200s' type found '%.200s' instead", | 
					
						
							|  |  |  | 		             type_name, Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-22 09:15:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* PyC_FlagSet_* functions - so flags/sets can be interchanged in a generic way */ | 
					
						
							|  |  |  | #include "BLI_dynstr.h"
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char *PyC_FlagSet_AsString(PyC_FlagSet *item) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DynStr *dynstr = BLI_dynstr_new(); | 
					
						
							|  |  |  | 	PyC_FlagSet *e; | 
					
						
							|  |  |  | 	char *cstring; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (e = item; item->identifier; item++) { | 
					
						
							|  |  |  | 		BLI_dynstr_appendf(dynstr, (e == item) ? "'%s'" : ", '%s'", item->identifier); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cstring = BLI_dynstr_get_cstring(dynstr); | 
					
						
							|  |  |  | 	BLI_dynstr_free(dynstr); | 
					
						
							|  |  |  | 	return cstring; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *value) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	for ( ; item->identifier; item++) { | 
					
						
							| 
									
										
										
										
											2013-03-10 06:18:03 +00:00
										 |  |  | 		if (STREQ(item->identifier, identifier)) { | 
					
						
							| 
									
										
										
										
											2012-02-22 09:15:46 +00:00
										 |  |  | 			*value = item->value; | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int *value, const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (PyC_FlagSet_ValueFromID_int(item, identifier, value) == 0) { | 
					
						
							|  |  |  | 		const char *enum_str = PyC_FlagSet_AsString(item); | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_ValueError, | 
					
						
							|  |  |  | 		             "%s: '%.200s' not found in (%s)", | 
					
						
							|  |  |  | 		             error_prefix, identifier, enum_str); | 
					
						
							|  |  |  | 		MEM_freeN((void *)enum_str); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* set of enum items, concatenate all values with OR */ | 
					
						
							|  |  |  | 	int ret, flag = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* set looping */ | 
					
						
							|  |  |  | 	Py_ssize_t pos = 0; | 
					
						
							|  |  |  | 	Py_ssize_t hash = 0; | 
					
						
							|  |  |  | 	PyObject *key; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-06 03:33:11 +00:00
										 |  |  | 	if (!PySet_Check(value)) { | 
					
						
							|  |  |  | 		PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  | 		             "%.200s expected a set, not %.200s", | 
					
						
							|  |  |  | 		             error_prefix, Py_TYPE(value)->tp_name); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-22 09:15:46 +00:00
										 |  |  | 	*r_value = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (_PySet_NextEntry(value, &pos, &key, &hash)) { | 
					
						
							|  |  |  | 		const char *param = _PyUnicode_AsString(key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (param == NULL) { | 
					
						
							|  |  |  | 			PyErr_Format(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2012-10-06 03:33:11 +00:00
										 |  |  | 			             "%.200s set must contain strings, not %.200s", | 
					
						
							| 
									
										
										
										
											2012-02-22 09:15:46 +00:00
										 |  |  | 			             error_prefix, Py_TYPE(key)->tp_name); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		flag |= ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*r_value = flag; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *ret = PySet_New(NULL); | 
					
						
							|  |  |  | 	PyObject *pystr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for ( ; items->identifier; items++) { | 
					
						
							|  |  |  | 		if (items->value & flag) { | 
					
						
							|  |  |  | 			pystr = PyUnicode_FromString(items->identifier); | 
					
						
							|  |  |  | 			PySet_Add(ret, pystr); | 
					
						
							|  |  |  | 			Py_DECREF(pystr); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-10-17 09:58:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* compat only */ | 
					
						
							|  |  |  | #if PY_VERSION_HEX <  0x03030200
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyLong_AsInt(PyObject *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int overflow; | 
					
						
							|  |  |  | 	long result = PyLong_AsLongAndOverflow(obj, &overflow); | 
					
						
							|  |  |  | 	if (overflow || result > INT_MAX || result < INT_MIN) { | 
					
						
							|  |  |  | 		PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  | 		                "Python int too large to convert to C int"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return (int)result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 |