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