diff options
author | Campbell Barton <campbell@blender.org> | 2022-03-11 06:42:39 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-03-11 06:42:39 +0300 |
commit | 1032f111d087e7ba77c16a4af78704019714bd6a (patch) | |
tree | 7e633bae3a64e48a938d36d62901538592b105f4 | |
parent | f527d6582b2998df1ed2f68772941b1638adbc53 (diff) |
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.
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 31 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 26 |
2 files changed, 44 insertions, 13 deletions
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 { |