Blender V4.3
py_capi_rna.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13/* Future-proof, See https://docs.python.org/3/c-api/arg.html#strings-and-buffers */
14#define PY_SSIZE_T_CLEAN
15
16#include <Python.h>
17
18#include "py_capi_rna.hh"
19
20#include "BLI_bitmap.h"
21#include "BLI_dynstr.h"
22
23#include "RNA_access.hh"
24
25#include "MEM_guardedalloc.h"
26
27/* -------------------------------------------------------------------- */
32{
33 DynStr *dynstr = BLI_dynstr_new();
34
35 /* We can't compare with the first element in the array
36 * since it may be a category (without an identifier). */
37 for (bool is_first = true; item->identifier; item++) {
38 if (item->identifier[0]) {
39 BLI_dynstr_appendf(dynstr, is_first ? "'%s'" : ", '%s'", item->identifier);
40 is_first = false;
41 }
42 }
43
44 char *cstring = BLI_dynstr_get_cstring(dynstr);
45 BLI_dynstr_free(dynstr);
46 return cstring;
47}
48
51/* -------------------------------------------------------------------- */
56 const char *identifier,
57 int *r_value,
58 const char *error_prefix)
59{
60 if (RNA_enum_value_from_id(item, identifier, r_value) == 0) {
61 const char *enum_str = pyrna_enum_repr(item);
62 PyErr_Format(
63 PyExc_ValueError, "%s: '%.200s' not found in (%s)", error_prefix, identifier, enum_str);
64 MEM_freeN((void *)enum_str);
65 return -1;
66 }
67
68 return 0;
69}
70
72 PyObject *value,
73 int type_size,
74 bool type_convert_sign,
75 int bitmap_size,
76 const char *error_prefix)
77{
78 /* Set looping. */
79 Py_ssize_t pos = 0;
80 Py_ssize_t hash = 0;
81 PyObject *key;
82
83 BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__);
84
85 while (_PySet_NextEntry(value, &pos, &key, &hash)) {
86 const char *param = PyUnicode_AsUTF8(key);
87 if (param == nullptr) {
88 PyErr_Format(PyExc_TypeError,
89 "%.200s expected a string, not %.200s",
90 error_prefix,
91 Py_TYPE(key)->tp_name);
92 goto error;
93 }
94
95 int ret;
96 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
97 goto error;
98 }
99
100 int index = ret;
101
102 if (type_convert_sign) {
103 if (type_size == 2) {
104 union {
105 signed short as_signed;
106 ushort as_unsigned;
107 } ret_convert;
108 ret_convert.as_signed = (signed short)ret;
109 index = int(ret_convert.as_unsigned);
110 }
111 else if (type_size == 1) {
112 union {
113 signed char as_signed;
114 uchar as_unsigned;
115 } ret_convert;
116 ret_convert.as_signed = (signed char)ret;
117 index = int(ret_convert.as_unsigned);
118 }
119 else {
121 }
122 }
123 BLI_assert(index < bitmap_size);
124 BLI_BITMAP_ENABLE(bitmap, index);
125 }
126
127 return bitmap;
128
129error:
130 MEM_freeN(bitmap);
131 return nullptr;
132}
133
135 PyObject *value,
136 int *r_value,
137 const char *error_prefix)
138{
139 /* Set of enum items, concatenate all values with OR. */
140 int ret, flag = 0;
141
142 /* Set looping. */
143 Py_ssize_t pos = 0;
144 Py_ssize_t hash = 0;
145 PyObject *key;
146
147 *r_value = 0;
148
149 while (_PySet_NextEntry(value, &pos, &key, &hash)) {
150 const char *param = PyUnicode_AsUTF8(key);
151
152 if (param == nullptr) {
153 PyErr_Format(PyExc_TypeError,
154 "%.200s expected a string, not %.200s",
155 error_prefix,
156 Py_TYPE(key)->tp_name);
157 return -1;
158 }
159
160 if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) {
161 return -1;
162 }
163
164 flag |= ret;
165 }
166
167 *r_value = flag;
168 return 0;
169}
170
171PyObject *pyrna_enum_bitfield_as_set(const EnumPropertyItem *items, int value)
172{
173 PyObject *ret = PySet_New(nullptr);
174 const char *identifier[RNA_ENUM_BITFLAG_SIZE + 1];
175
176 if (RNA_enum_bitflag_identifiers(items, value, identifier)) {
177 PyObject *item;
178 int index;
179 for (index = 0; identifier[index]; index++) {
180 item = PyUnicode_FromString(identifier[index]);
181 PySet_Add(ret, item);
182 Py_DECREF(item);
183 }
184 }
185
186 return ret;
187}
188
191/* -------------------------------------------------------------------- */
195int pyrna_enum_value_parse_string(PyObject *o, void *p)
196{
197 const char *identifier = PyUnicode_AsUTF8(o);
198 if (identifier == nullptr) {
199 PyErr_Format(PyExc_TypeError, "expected a string enum, not %.200s", Py_TYPE(o)->tp_name);
200 return 0;
201 }
202 BPy_EnumProperty_Parse *parse_data = static_cast<BPy_EnumProperty_Parse *>(p);
204 parse_data->items, identifier, &parse_data->value, "enum identifier") == -1)
205 {
206 return 0;
207 }
208
209 parse_data->value_orig = o;
210 parse_data->is_set = true;
211 return 1;
212}
213
214int pyrna_enum_bitfield_parse_set(PyObject *o, void *p)
215{
216 if (!PySet_Check(o)) {
217 PyErr_Format(PyExc_TypeError, "expected a set, not %.200s", Py_TYPE(o)->tp_name);
218 return 0;
219 }
220
221 BPy_EnumProperty_Parse *parse_data = static_cast<BPy_EnumProperty_Parse *>(p);
223 parse_data->items, o, &parse_data->value, "enum identifier set") == -1)
224 {
225 return 0;
226 }
227 parse_data->value_orig = o;
228 parse_data->is_set = true;
229 return 1;
230}
231
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition BLI_bitmap.h:41
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition BLI_bitmap.h:82
unsigned int BLI_bitmap
Definition BLI_bitmap.h:17
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition BLI_dynstr.c:149
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.c:37
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition BLI_dynstr.c:174
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
unsigned char uchar
unsigned short ushort
Read Guarded memory(de)allocation.
#define RNA_ENUM_BITFLAG_SIZE
Definition RNA_types.hh:125
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
static void error(const char *str)
#define hash
Definition noise.c:154
int pyrna_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value, const char *error_prefix)
int pyrna_enum_bitfield_parse_set(PyObject *o, void *p)
int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
PyObject * pyrna_enum_bitfield_as_set(const EnumPropertyItem *items, int value)
BLI_bitmap * pyrna_enum_bitmap_from_set(const EnumPropertyItem *items, PyObject *value, int type_size, bool type_convert_sign, int bitmap_size, const char *error_prefix)
char * pyrna_enum_repr(const EnumPropertyItem *item)
int pyrna_enum_value_parse_string(PyObject *o, void *p)
return ret
int RNA_enum_bitflag_identifiers(const EnumPropertyItem *item, const int value, const char **r_identifier)
bool RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *r_value)
const EnumPropertyItem * items
const char * identifier
Definition RNA_types.hh:506
uint8_t flag
Definition wm_window.cc:138