[Bf-blender-cvs] [1032f111d08] master: RNA: support functions returning allocated strings

Campbell Barton noreply at git.blender.org
Fri Mar 11 05:26:16 CET 2022


Commit: 1032f111d087e7ba77c16a4af78704019714bd6a
Author: Campbell Barton
Date:   Fri Mar 11 14:42:39 2022 +1100
Branches: master
https://developer.blender.org/rB1032f111d087e7ba77c16a4af78704019714bd6a

RNA: support functions returning allocated strings

Now it's possible for a C/RNA function to return a dynamic string,
The PROP_NEVER_NULL flag is also supported so a NULL string returns
None in Python.

===================================================================

M	source/blender/makesrna/intern/makesrna.c
M	source/blender/python/intern/bpy_rna.c

===================================================================

diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 20261fb9eeb..3ea7f8e0df6 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2362,7 +2362,12 @@ static void rna_def_struct_function_prototype_cpp(FILE *f,
     pout = (flag_parameter & PARM_OUTPUT);
 
     if (flag & PROP_DYNAMIC) {
-      ptrstr = pout ? "**" : "*";
+      if (type == PROP_STRING) {
+        ptrstr = pout ? "*" : "";
+      }
+      else {
+        ptrstr = pout ? "**" : "*";
+      }
     }
     else if (type == PROP_POINTER) {
       ptrstr = pout ? "*" : "";
@@ -2853,7 +2858,12 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
       /* XXX only arrays and strings are allowed to be dynamic, is this checked anywhere? */
     }
     else if (cptr || (flag & PROP_DYNAMIC)) {
-      ptrstr = pout ? "**" : "*";
+      if (type == PROP_STRING) {
+        ptrstr = pout ? "*" : "";
+      }
+      else {
+        ptrstr = pout ? "**" : "*";
+      }
       /* Fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack,
        * pass a pointer to it. */
     }
@@ -2933,8 +2943,14 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
     else {
       const char *data_str;
       if (cptr || (flag & PROP_DYNAMIC)) {
-        ptrstr = "**";
-        valstr = "*";
+        if (type == PROP_STRING) {
+          ptrstr = "*";
+          valstr = "";
+        }
+        else {
+          ptrstr = "**";
+          valstr = "*";
+        }
       }
       else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) {
         ptrstr = "**";
@@ -3531,7 +3547,12 @@ static void rna_generate_static_parameter_prototypes(FILE *f,
     }
 
     if (cptr || (flag & PROP_DYNAMIC)) {
-      ptrstr = pout ? "**" : "*";
+      if (type == PROP_STRING) {
+        ptrstr = pout ? "*" : "";
+      }
+      else {
+        ptrstr = pout ? "**" : "*";
+      }
     }
     else if (type == PROP_POINTER || dparm->prop->arraydimension) {
       ptrstr = "*";
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index f6ad105f173..2a52253eece 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -5898,26 +5898,36 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
       case PROP_STRING: {
         const char *data_ch;
         const int subtype = RNA_property_subtype(prop);
+        size_t data_ch_len;
 
-        if (flag & PROP_THICK_WRAP) {
-          data_ch = (char *)data;
+        if (flag & PROP_DYNAMIC) {
+          ParameterDynAlloc *data_alloc = data;
+          data_ch = data_alloc->array;
+          data_ch_len = data_alloc->array_tot;
+          BLI_assert((data_ch == NULL) || strlen(data_ch) == data_ch_len);
         }
         else {
-          data_ch = *(char **)data;
+          data_ch = (flag & PROP_THICK_WRAP) ? (char *)data : *(char **)data;
+          data_ch_len = data_ch ? 0 : strlen(data_ch);
         }
 
+        if (UNLIKELY(data_ch == NULL)) {
+          BLI_assert((flag & PROP_NEVER_NULL) == 0);
+          ret = Py_None;
+          Py_INCREF(ret);
+        }
 #ifdef USE_STRING_COERCE
-        if (subtype == PROP_BYTESTRING) {
-          ret = PyBytes_FromString(data_ch);
+        else if (subtype == PROP_BYTESTRING) {
+          ret = PyBytes_FromStringAndSize(data_ch, data_ch_len);
         }
         else if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME)) {
-          ret = PyC_UnicodeFromByte(data_ch);
+          ret = PyC_UnicodeFromByteAndSize(data_ch, data_ch_len);
         }
         else {
-          ret = PyUnicode_FromString(data_ch);
+          ret = PyUnicode_FromStringAndSize(data_ch, data_ch_len);
         }
 #else
-        if (subtype == PROP_BYTESTRING) {
+        else if (subtype == PROP_BYTESTRING) {
           ret = PyBytes_FromString(buf);
         }
         else {



More information about the Bf-blender-cvs mailing list