py api - added PyC_UnicodeFromByteAndSize() to match PyUnicode_FromStringAndSize()
authorCampbell Barton <ideasman42@gmail.com>
Sat, 22 Oct 2011 10:49:35 +0000 (10:49 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 22 Oct 2011 10:49:35 +0000 (10:49 +0000)
also made RNA_property_string_get_alloc() return the length of the new string to avoid having to run strlen on it after.

15 files changed:
source/blender/editors/animation/anim_ipo_utils.c
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/python/generic/IDProp.c
source/blender/python/generic/py_capi_utils.c
source/blender/python/generic/py_capi_utils.h
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_rna.c

index 383e0ba..d18a3c3 100644 (file)
@@ -118,7 +118,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
                                PropertyRNA *nameprop= RNA_struct_name_property(ptr.type);
                                if (nameprop) {
                                        /* this gets a string which will need to be freed */
-                                       structname= RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0);
+                                       structname= RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
                                        free_structname= 1;
                                }
                                else
index a12d297..b7b572e 100644 (file)
@@ -1593,17 +1593,18 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
        if(but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
                PropertyType type;
                char *buf= NULL;
+               int buf_len;
 
                type= RNA_property_type(but->rnaprop);
 
                if(type == PROP_STRING) {
                        /* RNA string */
-                       buf= RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen);
+                       buf= RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen, &buf_len);
                }
                else if(type == PROP_POINTER) {
                        /* RNA pointer */
                        PointerRNA ptr= RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
-                       buf= RNA_struct_name_get_alloc(&ptr, str, maxlen);
+                       buf= RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
                }
 
                if(!buf) {
@@ -1611,7 +1612,7 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
                }
                else if(buf && buf != str) {
                        /* string was too long, we have to truncate */
-                       BLI_strncpy(str, buf, maxlen);
+                       memcpy(str, buf, MIN2(maxlen, buf_len+1));
                        MEM_freeN(buf);
                }
        }
index 2f423a3..be6c89e 100644 (file)
@@ -1221,7 +1221,7 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, const char *s
                        iconid= ui_id_icon_get((bContext*)C, id, 1);
                }
                else {
-                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
                        iconid = 0;
                }
 
index c6bc0f5..34f9849 100644 (file)
@@ -2085,7 +2085,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
        if(icon == ICON_NONE || icon == ICON_DOT)
                icon= 0;
 
-       namebuf= RNA_struct_name_get_alloc(itemptr, NULL, 0);
+       namebuf= RNA_struct_name_get_alloc(itemptr, NULL, 0, NULL);
        name= (namebuf)? namebuf: "";
 
        /* hardcoded types */
@@ -2270,7 +2270,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
 
                                if(found) {
                                        /* create button */
-                                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
+                                       name= RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
                                        icon= list_item_icon_get(C, &itemptr, rnaicon, 0);
                                        uiItemL(row, (name)? name: "", icon);
 
index 4a28603..309c5cf 100644 (file)
@@ -925,7 +925,7 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
 
                if(ptr->data) {
                        icon= RNA_struct_ui_icon(ptr->type);
-                       name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf));
+                       name= RNA_struct_name_get_alloc(ptr, namebuf, sizeof(namebuf), NULL);
 
                        if(name) {
                                if(!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene)
index 75b3eb9..3cf4de9 100644 (file)
@@ -169,7 +169,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(!prop)
                return OPERATOR_CANCELLED;
 
-       str= RNA_property_string_get_alloc(&ptr, prop, NULL, 0);
+       str= RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL);
 
        /* useful yet irritating feature, Shift+Click to open the file
         * Alt+Click to browse a folder in the OS's browser */
index 1d1abf8..30a7abd 100644 (file)
@@ -1021,7 +1021,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle
                                        /* tsenext= TREESTORE(temnext); */ /* UNUSED */
                                        
                                        nextptr= &temnext->rnaptr;
-                                       name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf));
+                                       name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf), NULL);
                                        
                                        if(name) {
                                                /* if possible, use name as a key in the path */
index dda103b..925c457 100644 (file)
@@ -972,7 +972,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
                }
                else if(type == TSE_RNA_STRUCT) {
                        /* struct */
-                       te->name= RNA_struct_name_get_alloc(ptr, NULL, 0);
+                       te->name= RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
 
                        if(te->name)
                                te->flag |= TE_FREE_NAME;
index 1f45fe2..486e189 100644 (file)
@@ -648,7 +648,7 @@ PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifi
 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier);
 const struct ListBase *RNA_struct_type_functions(StructRNA *srna);
 
-char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen);
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len);
 
 /* Properties
  *
@@ -755,7 +755,7 @@ void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, fl
 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index);
 
 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value);
-char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen);
+char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len);
 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value);
 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop);
 void RNA_property_string_get_default(PointerRNA *ptr, PropertyRNA *prop, char *value);
index 149497c..c1c22af 100644 (file)
@@ -748,12 +748,12 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
        srna->blender_type= blender_type;
 }
 
-char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
+char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
 {
        PropertyRNA *nameprop;
 
        if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
-               return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
+               return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
 
        return NULL;
 }
@@ -2276,7 +2276,8 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
                strcpy(value, sprop->defaultvalue);
 }
 
-char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
+char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
+                                    char *fixedbuf, int fixedlen, int *r_len)
 {
        char *buf;
        int length;
@@ -2301,6 +2302,10 @@ char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fi
        BLI_assert(buf[length] == '\0');
 #endif
 
+       if (r_len) {
+               *r_len= length;
+       }
+
        return buf;
 }
 
@@ -2836,15 +2841,17 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, co
                PropertyRNA *nameprop;
                char name[256], *nameptr;
                int found= 0;
+               int keylen= strlen(key);
+               int namelen;
 
                RNA_property_collection_begin(ptr, prop, &iter);
                for(; iter.valid; RNA_property_collection_next(&iter)) {
                        if(iter.ptr.data && iter.ptr.type->nameproperty) {
                                nameprop= iter.ptr.type->nameproperty;
 
-                               nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
+                               nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
 
-                               if(strcmp(nameptr, key) == 0) {
+                               if((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
                                        *r_ptr= iter.ptr;
                                        found= 1;
                                }
@@ -4254,7 +4261,7 @@ char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, in
        PropertyRNA *prop= RNA_struct_find_property(ptr, name);
 
        if(prop) {
-               return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
+               return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen, NULL); /* TODO, pass length */
        }
        else {
                printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
@@ -5442,7 +5449,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
                }
                case PROP_STRING:
                {
-                       char *value= RNA_property_string_get_alloc(fromptr, prop, NULL, 0);
+                       char *value= RNA_property_string_get_alloc(fromptr, prop, NULL, 0, NULL);
                        RNA_property_string_set(ptr, prop, value);
                        MEM_freeN(value);
                        return 1;
index 1524812..541008e 100644 (file)
@@ -67,9 +67,9 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
        switch ( prop->type ) {
                case IDP_STRING:
 #ifdef USE_STRING_COERCE
-                       return PyC_UnicodeFromByte(IDP_Array(prop));
+            return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len);
 #else
-                       return PyUnicode_FromString(IDP_Array(prop));
+            return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len);
 #endif
                case IDP_INT:
                        return PyLong_FromLong( (long)prop->data.val );
@@ -485,9 +485,9 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
        switch (prop->type) {
                case IDP_STRING:
 #ifdef USE_STRING_COERCE
-                       return PyC_UnicodeFromByte(IDP_Array(prop));
+            return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len);
 #else
-                       return PyUnicode_FromString(IDP_Array(prop));
+            return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len);
 #endif
                        break;
                case IDP_FLOAT:
index 575495e..587ac69 100644 (file)
@@ -386,9 +386,9 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
        }
 }
 
-PyObject *PyC_UnicodeFromByte(const char *str)
+PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
 {
-       PyObject *result= PyUnicode_FromString(str);
+    PyObject *result= PyUnicode_FromStringAndSize(str, size);
        if (result) {
                /* 99% of the time this is enough but we better support non unicode
                 * chars since blender doesnt limit this */
@@ -397,11 +397,16 @@ PyObject *PyC_UnicodeFromByte(const char *str)
        else {
                PyErr_Clear();
                /* this means paths will always be accessible once converted, on all OS's */
-               result= PyUnicode_DecodeFSDefault(str);
+               result= PyUnicode_DecodeFSDefaultAndSize(str, size);
                return result;
        }
 }
 
+PyObject *PyC_UnicodeFromByte(const char *str)
+{
+       return PyC_UnicodeFromByteAndSize(str, strlen(str));
+}
+
 /*****************************************************************************
 * Description: This function creates a new Python dictionary object.
 * note: dict is owned by sys.modules["__main__"] module, reference is borrowed
index f38ce20..ccd001a 100644 (file)
@@ -40,8 +40,9 @@ void                  PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python
 int                            PyC_AsArray(void *array, PyObject *value, const int length, const PyTypeObject *type, const short is_double, const char *error_prefix);
 
 /* follow http://www.python.org/dev/peps/pep-0383/ */
-PyObject *             PyC_UnicodeFromByte(const char *str);
-const char *   PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */
+PyObject *      PyC_UnicodeFromByte(const char *str);
+PyObject *      PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size);
+const char *    PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce); /* coerce must be NULL */
 
 /* name namespace function for bpy & bge */
 PyObject *             PyC_DefaultNameSpace(const char *filename);
index 90156a9..7a39cfc 100644 (file)
@@ -203,9 +203,9 @@ void BPY_python_start(int argc, const char **argv)
        /* allow to use our own included python */
        PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL));
 
-       /* Python 3.2 now looks for '2.58/python/include/python3.2d/pyconfig.h' to parse
-        * from the 'sysconfig' module which is used by 'site', so for now disable site.
-        * alternatively we could copy the file. */
+       /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to
+        * parse from the 'sysconfig' module which is used by 'site',
+        * so for now disable site. alternatively we could copy the file. */
        Py_NoSiteFlag= 1;
 
        Py_Initialize();
@@ -215,8 +215,11 @@ void BPY_python_start(int argc, const char **argv)
        {
                int i;
                PyObject *py_argv= PyList_New(argc);
-               for (i=0; i<argc; i++)
-                       PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); /* should fix bug #20021 - utf path name problems, by replacing PyUnicode_FromString */
+               for (i=0; i<argc; i++) {
+                       /* should fix bug #20021 - utf path name problems, by replacing
+                        * PyUnicode_FromString, with this one */
+                       PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i]));
+               }
 
                PySys_SetObject("argv", py_argv);
                Py_DECREF(py_argv);
index a630690..70e7ba0 100644 (file)
@@ -810,7 +810,7 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self)
        }
 
        /* print name if available */
-       name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE);
+       name= RNA_struct_name_get_alloc(&self->ptr, NULL, 0, NULL);
        if (name) {
                ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>",
                                          RNA_struct_identifier(self->ptr.type),
@@ -901,7 +901,7 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
        /* if a pointer, try to print name of pointer target too */
        if (RNA_property_type(self->prop) == PROP_POINTER) {
                ptr= RNA_property_pointer_get(&self->ptr, self->prop);
-               name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE);
+               name= RNA_struct_name_get_alloc(&ptr, NULL, 0, NULL);
 
                if (name) {
                        ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>",
@@ -1257,14 +1257,22 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val)
                                ret= PyUnicode_FromString(enum_item->identifier);
                        }
                        else {
-                               const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, FALSE);
+                               const char *ptr_name= RNA_struct_name_get_alloc(ptr, NULL, 0, NULL);
 
                                /* prefer not fail silently incase of api errors, maybe disable it later */
-                               printf("RNA Warning: Current value \"%d\" matches no enum in '%s', '%s', '%s'\n", val, RNA_struct_identifier(ptr->type), ptr_name, RNA_property_identifier(prop));
+                               printf("RNA Warning: Current value \"%d\" "
+                                          "matches no enum in '%s', '%s', '%s'\n",
+                                          val, RNA_struct_identifier(ptr->type),
+                                          ptr_name, RNA_property_identifier(prop));
 
 #if 0                  // gives python decoding errors while generating docs :(
                                char error_str[256];
-                               BLI_snprintf(error_str, sizeof(error_str), "RNA Warning: Current value \"%d\" matches no enum in '%s', '%s', '%s'", val, RNA_struct_identifier(ptr->type), ptr_name, RNA_property_identifier(prop));
+                               BLI_snprintf(error_str, sizeof(error_str),
+                                                        "RNA Warning: Current value \"%d\" "
+                                                        "matches no enum in '%s', '%s', '%s'",
+                                                        val, RNA_struct_identifier(ptr->type),
+                                                        ptr_name, RNA_property_identifier(prop));
+
                                PyErr_Warn(PyExc_RuntimeWarning, error_str);
 #endif
 
@@ -1311,19 +1319,20 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
        {
                int subtype= RNA_property_subtype(prop);
                const char *buf;
+               int buf_len;
                char buf_fixed[32];
 
-               buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed));
+               buf= RNA_property_string_get_alloc(ptr, prop, buf_fixed, sizeof(buf_fixed), &buf_len);
 #ifdef USE_STRING_COERCE
                /* only file paths get special treatment, they may contain non utf-8 chars */
                if (ELEM3(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
-                       ret= PyC_UnicodeFromByte(buf);
+                       ret= PyC_UnicodeFromByteAndSize(buf, buf_len);
                }
                else {
-                       ret= PyUnicode_FromString(buf);
+                       ret= PyUnicode_FromStringAndSize(buf, buf_len);
                }
 #else // USE_STRING_COERCE
-               ret= PyUnicode_FromString(buf);
+               ret= PyUnicode_FromStringAndSize(buf, buf_len);
 #endif // USE_STRING_COERCE
                if (buf_fixed != buf) {
                        MEM_freeN((void *)buf);
@@ -3127,14 +3136,15 @@ static void pyrna_dir_members_rna(PyObject *list, PointerRNA *ptr)
                 * Collect RNA attributes
                 */
                char name[256], *nameptr;
+               int namelen;
 
                iterprop= RNA_struct_iterator_property(ptr->type);
 
                RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
-                       nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+                       nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
 
                        if (nameptr) {
-                               pystring= PyUnicode_FromString(nameptr);
+                               pystring= PyUnicode_FromStringAndSize(nameptr, namelen);
                                PyList_Append(list, pystring);
                                Py_DECREF(pystring);
 
@@ -3716,13 +3726,14 @@ static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self)
        PyObject *ret= PyList_New(0);
        PyObject *item;
        char name[256], *nameptr;
+       int namelen;
 
        RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
-               nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+               nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
 
                if (nameptr) {
                        /* add to python list */
-                       item= PyUnicode_FromString(nameptr);
+                       item= PyUnicode_FromStringAndSize(nameptr, namelen);
                        PyList_Append(ret, item);
                        Py_DECREF(item);
                        /* done */
@@ -3751,15 +3762,16 @@ static PyObject *pyrna_prop_collection_items(BPy_PropertyRNA *self)
        PyObject *ret= PyList_New(0);
        PyObject *item;
        char name[256], *nameptr;
+       int namelen;
        int i= 0;
 
        RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
                if (itemptr.data) {
                        /* add to python list */
                        item= PyTuple_New(2);
-                       nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name));
+                       nameptr= RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
                        if (nameptr) {
-                               PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(nameptr));
+                               PyTuple_SET_ITEM(item, 0, PyUnicode_FromStringAndSize(nameptr, namelen));
                                if (name != nameptr)
                                        MEM_freeN(nameptr);
                        }