[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32013] trunk/blender/source/blender/ python/generic: python/c utility function for debugging, see http://wiki. blender.org/index.php/Dev:Doc/Debugging/PyFromC
Campbell Barton
ideasman42 at gmail.com
Sun Sep 19 16:02:45 CEST 2010
Revision: 32013
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32013
Author: campbellbarton
Date: 2010-09-19 16:02:45 +0200 (Sun, 19 Sep 2010)
Log Message:
-----------
python/c utility function for debugging, see http://wiki.blender.org/index.php/Dev:Doc/Debugging/PyFromC
Modified Paths:
--------------
trunk/blender/source/blender/python/generic/py_capi_utils.c
trunk/blender/source/blender/python/generic/py_capi_utils.h
Modified: trunk/blender/source/blender/python/generic/py_capi_utils.c
===================================================================
--- trunk/blender/source/blender/python/generic/py_capi_utils.c 2010-09-19 13:38:45 UTC (rev 32012)
+++ trunk/blender/source/blender/python/generic/py_capi_utils.c 2010-09-19 14:02:45 UTC (rev 32013)
@@ -291,3 +291,148 @@
Py_INCREF(interp->builtins); /* AddObject steals a reference */
return PyModule_GetDict(mod_main);
}
+
+
+/* Would be nice if python had this built in */
+void PyC_RunQuicky(const char *filepath, int n, ...)
+{
+ FILE *fp= fopen(filepath, "r");
+
+ if(fp) {
+ PyGILState_STATE gilstate= PyGILState_Ensure();
+
+ va_list vargs;
+
+ int *sizes= PyMem_MALLOC(sizeof(int) * (n / 2));
+ int i;
+
+ PyObject *py_dict = PyC_DefaultNameSpace(filepath);
+ PyObject *values= PyList_New(n / 2); /* namespace owns this, dont free */
+
+ PyObject *py_result, *ret;
+
+ 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 */
+
+ Py_DECREF(struct_mod);
+
+ va_start(vargs, n);
+ for (i=0; i * 2<n; i++) {
+ char *format = va_arg(vargs, char *);
+ void *ptr = va_arg(vargs, void *);
+
+ ret= PyObject_CallFunction(calcsize, "s", format);
+
+ if(ret) {
+ sizes[i]= PyLong_AsSsize_t(ret);
+ Py_DECREF(ret);
+ ret = PyObject_CallFunction(unpack, "sy#", format, (char *)ptr, sizes[i]);
+ }
+
+ if(ret == NULL) {
+ 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);
+
+ sizes[i]= 0;
+ }
+ else {
+ if(PyTuple_GET_SIZE(ret) == 1) {
+ /* convenience, convert single tuples into single values */
+ PyObject *tmp= PyTuple_GET_ITEM(ret, 0);
+ 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);
+
+ if(py_result) {
+
+ /* we could skip this but then only slice assignment would work
+ * better not be so strict */
+ values= PyDict_GetItemString(py_dict, "values");
+
+ if(values && PyList_Check(values)) {
+
+ /* dont use the result */
+ Py_DECREF(py_result);
+ py_result= NULL;
+
+ /* now get the values back */
+ va_start(vargs, n);
+ for (i=0; i*2 <n; i++) {
+ 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 */
+ item= PyList_GET_ITEM(values, i);
+ if(PyTuple_CheckExact(item)) {
+ int ofs= PyTuple_GET_SIZE(item);
+ item_new= PyTuple_New(ofs + 1);
+ while(ofs--) {
+ PyObject *member= PyTuple_GET_ITEM(item, ofs);
+ PyTuple_SET_ITEM(item_new, ofs + 1, member);
+ Py_INCREF(member);
+ }
+
+ PyTuple_SET_ITEM(item_new, 0, PyUnicode_FromString(format));
+ }
+ else {
+ item_new= Py_BuildValue("sO", format, item);
+ }
+
+ ret = PyObject_Call(pack, item_new, NULL);
+
+ if(ret) {
+ /* 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);
+ }
+}
Modified: trunk/blender/source/blender/python/generic/py_capi_utils.h
===================================================================
--- trunk/blender/source/blender/python/generic/py_capi_utils.h 2010-09-19 13:38:45 UTC (rev 32012)
+++ trunk/blender/source/blender/python/generic/py_capi_utils.h 2010-09-19 14:02:45 UTC (rev 32013)
@@ -38,5 +38,5 @@
/* name namespace function for bpy & bge */
PyObject * PyC_DefaultNameSpace(const char *filename);
-
+void PyC_RunQuicky(const char *filepath, int n, ...);
#endif // PY_CAPI_UTILS_H
More information about the Bf-blender-cvs
mailing list