[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [31701] trunk/blender: bugfix [#23285] Exporters not available whel using special characters in path name
Campbell Barton
ideasman42 at gmail.com
Wed Sep 1 16:13:49 CEST 2010
Revision: 31701
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31701
Author: campbellbarton
Date: 2010-09-01 16:13:48 +0200 (Wed, 01 Sep 2010)
Log Message:
-----------
bugfix [#23285] Exporters not available whel using special characters in path name
- ID properties now suopport non utf-8 strings for their values but not their keys.
- moved utility functions into py_capi_utils.c from bpy_utils and bpy_rna.
- import/export paths have to be printed with repr() or %r, so non utf-8 chars are escaped.
Modified Paths:
--------------
trunk/blender/release/scripts/op/io_scene_x3d/export_x3d.py
trunk/blender/source/blender/python/generic/IDProp.c
trunk/blender/source/blender/python/intern/bpy_props.c
trunk/blender/source/blender/python/intern/bpy_rna.c
trunk/blender/source/blender/python/intern/bpy_util.c
trunk/blender/source/blender/python/intern/bpy_util.h
Added Paths:
-----------
trunk/blender/source/blender/python/generic/py_capi_utils.c
trunk/blender/source/blender/python/generic/py_capi_utils.h
Modified: trunk/blender/release/scripts/op/io_scene_x3d/export_x3d.py
===================================================================
--- trunk/blender/release/scripts/op/io_scene_x3d/export_x3d.py 2010-09-01 13:55:41 UTC (rev 31700)
+++ trunk/blender/release/scripts/op/io_scene_x3d/export_x3d.py 2010-09-01 14:13:48 UTC (rev 31701)
@@ -136,12 +136,12 @@
def writeHeader(self):
#bfile = sys.expandpath( Blender.Get('filepath') ).replace('<', '<').replace('>', '>')
- bfile = self.filepath.replace('<', '<').replace('>', '>') # use outfile name
+ bfile = repr(os.path.basename(self.filepath).replace('<', '<').replace('>', '>'))[1:-1] # use outfile name
self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
self.file.write("<head>\n")
- self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % os.path.basename(bfile))
+ self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % bfile)
# self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % bpy.app.version_string)
# self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
@@ -781,7 +781,7 @@
EXPORT_TRI= False,\
):
- print("Info: starting X3D export to " + self.filepath + "...")
+ print("Info: starting X3D export to %r..." % self.filepath)
self.writeHeader()
# self.writeScript()
self.writeNavigationInfo(scene)
@@ -879,7 +879,7 @@
self.texNames={}
self.matNames={}
self.indentLevel=0
- print("Info: finished X3D export to %s\n" % self.filepath)
+ print("Info: finished X3D export to %r" % self.filepath)
def cleanStr(self, name, prefix='rsvd_'):
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
Modified: trunk/blender/source/blender/python/generic/IDProp.c
===================================================================
--- trunk/blender/source/blender/python/generic/IDProp.c 2010-09-01 13:55:41 UTC (rev 31700)
+++ trunk/blender/source/blender/python/generic/IDProp.c 2010-09-01 14:13:48 UTC (rev 31701)
@@ -27,6 +27,15 @@
#include "IDProp.h"
#include "MEM_guardedalloc.h"
+#define USE_STRING_COERCE
+
+#ifdef USE_STRING_COERCE
+#include "py_capi_utils.h"
+#endif
+
+PyObject * PyC_UnicodeFromByte(const char *str);
+const char * PuC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */
+
/*** Function to wrap ID properties ***/
PyObject *BPy_Wrap_IDProperty(ID *id, IDProperty *prop, IDProperty *parent);
@@ -46,7 +55,11 @@
{
switch ( prop->type ) {
case IDP_STRING:
- return PyUnicode_FromString( prop->data.pointer );
+#ifdef USE_STRING_COERCE
+ return PyC_UnicodeFromByte(prop->data.pointer);
+#else
+ return PyUnicode_FromString(prop->data.pointer);
+#endif
case IDP_INT:
return PyLong_FromLong( (long)prop->data.val );
case IDP_FLOAT:
@@ -105,10 +118,25 @@
PyErr_SetString(PyExc_TypeError, "expected a string!");
return -1;
}
+#ifdef USE_STRING_COERCE
+ {
+ int alloc_len;
+ PyObject *value_coerce= NULL;
+ st= (char *)PuC_UnicodeAsByte(value, &value_coerce);
+ alloc_len= strlen(st) + 1;
+
+ st = _PyUnicode_AsString(value);
+ IDP_ResizeArray(prop, alloc_len);
+ memcpy(prop->data.pointer, st, alloc_len);
+ Py_XDECREF(value_coerce);
+ }
+#else
st = _PyUnicode_AsString(value);
IDP_ResizeArray(prop, strlen(st)+1);
strcpy(prop->data.pointer, st);
+#endif
+
return 0;
}
@@ -281,8 +309,15 @@
val.i = (int) PyLong_AsSsize_t(ob);
prop = IDP_New(IDP_INT, val, name);
} else if (PyUnicode_Check(ob)) {
+#ifdef USE_STRING_COERCE
+ PyObject *value_coerce= NULL;
+ val.str = (char *)PuC_UnicodeAsByte(ob, &value_coerce);
+ prop = IDP_New(IDP_STRING, val, name);
+ Py_XDECREF(value_coerce);
+#else
val.str = _PyUnicode_AsString(ob);
prop = IDP_New(IDP_STRING, val, name);
+#endif
} else if (PySequence_Check(ob)) {
PyObject *item;
int i;
@@ -432,7 +467,11 @@
{
switch (prop->type) {
case IDP_STRING:
+#ifdef USE_STRING_COERCE
+ return PyC_UnicodeFromByte(prop->data.pointer);
+#else
return PyUnicode_FromString(prop->data.pointer);
+#endif
break;
case IDP_FLOAT:
return PyFloat_FromDouble(*((float*)&prop->data.val));
Added: trunk/blender/source/blender/python/generic/py_capi_utils.c
===================================================================
--- trunk/blender/source/blender/python/generic/py_capi_utils.c (rev 0)
+++ trunk/blender/source/blender/python/generic/py_capi_utils.c 2010-09-01 14:13:48 UTC (rev 31701)
@@ -0,0 +1,271 @@
+/*
+ * $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 "py_capi_utils.h"
+
+/* for debugging */
+void PyC_ObSpit(char *name, PyObject *var) {
+ fprintf(stderr, "<%s> : ", name);
+ if (var==NULL) {
+ 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:");
+ if(Py_TYPE(var))
+ fprintf(stderr, "%s", Py_TYPE(var)->tp_name);
+ else
+ fprintf(stderr, "<NIL>");
+ }
+ fprintf(stderr, "\n");
+}
+
+void PyC_LineSpit(void) {
+ const char *filename;
+ int lineno;
+
+ PyErr_Clear();
+ PyC_FileAndNum(&filename, &lineno);
+
+ fprintf(stderr, "%s:%d\n", filename, lineno);
+}
+
+void PyC_FileAndNum(const char **filename, int *lineno)
+{
+ PyObject *getframe, *frame;
+ PyObject *f_lineno= NULL, *co_filename= NULL;
+
+ if (filename) *filename= NULL;
+ if (lineno) *lineno = -1;
+
+ getframe = PySys_GetObject("_getframe"); // borrowed
+ if (getframe==NULL) {
+ PyErr_Clear();
+ return;
+ }
+
+ frame = PyObject_CallObject(getframe, NULL);
+ if (frame==NULL) {
+ PyErr_Clear();
+ return;
+ }
+
+ /* when executing a script */
+ if (filename) {
+ co_filename= PyC_Object_GetAttrStringArgs(frame, 1, "f_code", "co_filename");
+ if (co_filename==NULL) {
+ PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename");
+ Py_DECREF(frame);
+ return;
+ }
+
+ *filename = _PyUnicode_AsString(co_filename);
+ Py_DECREF(co_filename);
+ }
+
+ /* when executing a module */
+ if(filename && *filename == NULL) {
+ /* try an alternative method to get the filename - module based
+ * references below are all borrowed (double checked) */
+ PyObject *mod_name= PyDict_GetItemString(PyEval_GetGlobals(), "__name__");
+ if(mod_name) {
+ PyObject *mod= PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
+ if(mod) {
+ *filename= PyModule_GetFilename(mod);
+ }
+
+ /* unlikely, fallback */
+ if(*filename == NULL) {
+ *filename= _PyUnicode_AsString(mod_name);
+ }
+ }
+ }
+
+
+ if (lineno) {
+ f_lineno= PyObject_GetAttrString(frame, "f_lineno");
+ if (f_lineno==NULL) {
+ PyErr_SetString(PyExc_SystemError, "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);
+}
+
+/* Would be nice if python had this built in */
+PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
+{
+ Py_ssize_t i;
+ PyObject *item= o;
+ char *attr;
+
+ va_list vargs;
+
+ va_start(vargs, n);
+ for (i=0; i<n; i++) {
+ 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;
+}
+
+/* returns the exception string as a new PyUnicode object, depends on external StringIO module */
+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;
+ PyObject *string_io_mod= NULL;
+ PyObject *string_io_getvalue= NULL;
+
+ 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()
+ */
+
+ if(! (string_io_mod= PyImport_ImportModule("io")) ) {
+ goto error_cleanup;
+ } else if (! (string_io = PyObject_CallMethod(string_io_mod, "StringIO", NULL))) {
+ goto error_cleanup;
+ } else if (! (string_io_getvalue= PyObject_GetAttrString(string_io, "getvalue"))) {
+ goto error_cleanup;
+ }
+
+ Py_INCREF(stdout_backup); // since these were borrowed we dont want them freed when replaced.
+ Py_INCREF(stderr_backup);
+
+ PySys_SetObject("stdout", string_io); // both of these are free'd when restoring
+ 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);
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list