12#include <fmt/format.h>
32#include "RNA_prototypes.hh"
39 if (left.path != right.path) {
43 if (left.key.has_value() || right.key.has_value()) {
44 return left.key == right.key;
47 return left.index == right.index;
61 const char *p = *path;
62 while (*p && !
ELEM(*p,
'.',
'[')) {
73 char *buf = (
len + 1 < fixedlen) ? fixedbuf :
75 memcpy(buf, *path,
sizeof(
char) *
len);
112 const char *p = *path;
120 if (p_end ==
nullptr) {
134 while (*p && (*p !=
']')) {
153 char *buf = (
len + 1 < fixedlen) ? fixedbuf :
161 p = (*path) +
len + 1;
164 memcpy(buf, *path,
sizeof(
char) *
len);
218 r_nextptr->
data =
nullptr;
223 intkey = atoi(token);
224 if (intkey == 0 && (token[0] !=
'0' || token[1] !=
'\0')) {
231 r_nextptr->
data =
nullptr;
235 if (token != fixedbuf) {
245 r_nextptr->
data =
nullptr;
270 for (i = 0; i < dim; i++) {
279 if (token ==
nullptr) {
289 temp_index = atoi(token);
291 if (temp_index == 0 && (token[0] !=
'0' || token[1] !=
'\0')) {
292 if (token != fixedbuf) {
303 if (token ==
nullptr) {
314 if (token != fixedbuf) {
319 if (temp_index < 0 || temp_index >=
len[i]) {
323 index_arr[i] = temp_index;
337 for (i = dim - 1; i >= 0; i--) {
338 flat_index += index_arr[i] * totdim;
342 *r_index = flat_index;
376 const bool eval_pointer)
378 BLI_assert(r_item_ptr ==
nullptr || !eval_pointer);
385 const bool do_item_ptr = r_item_ptr !=
nullptr && !eval_pointer;
394 if (path ==
nullptr || *path ==
'\0') {
403 const bool use_id_prop = (*path ==
'[');
412 char *token = use_id_prop ?
422 if (group && quoted) {
430 if (token != fixedbuf) {
439 prop_elem = MEM_new<PropertyElemRNA>(__func__);
440 prop_elem->
ptr = curptr;
441 prop_elem->
prop = prop;
442 prop_elem->
index = -1;
456 if (do_item_ptr || eval_pointer || *path !=
'\0') {
460 if (eval_pointer || *path !=
'\0') {
477 if (eval_pointer || *path !=
'\0') {
486 if (r_index || prop_elem) {
492 prop_elem->
index = index;
508 if (r_item_ptr && do_item_ptr) {
509 *r_item_ptr = nextptr;
515 prop_elem = MEM_new<PropertyElemRNA>(__func__);
516 prop_elem->
ptr = curptr;
517 prop_elem->
prop = prop;
518 prop_elem->
index = index;
530 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr,
nullptr,
nullptr,
true)) {
534 return r_ptr->
data !=
nullptr;
540 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
true)) {
544 return r_ptr->
data !=
nullptr;
550 return rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
true);
558 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr,
nullptr,
nullptr,
false)) {
562 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
568 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
false)) {
572 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
581 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr, r_item_ptr,
nullptr,
false)) {
585 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
595 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index, r_item_ptr,
nullptr,
false)) {
599 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
603 return rna_path_parse(
ptr, path,
nullptr,
nullptr,
nullptr,
nullptr, r_elements,
false);
627 const bool has_key = (intkey > -1) || (strkey !=
nullptr);
633 const int strkey_esc_max_size = (strlen(strkey) * 2) + 1;
634 char *strkey_esc =
static_cast<char *
>(
BLI_array_alloca(strkey_esc, strkey_esc_max_size));
660 const char *previous, *current;
681 if (token != fixedbuf) {
688 if (token && token != fixedbuf) {
707 if (i > 0 && result[i - 1] ==
'.') {
717 if (array_prop !=
nullptr) {
729 if (
UNLIKELY(rna_path[0] ==
'\0')) {
732 size_t rna_path_len = size_t(strlen(rna_path)) - 1;
733 if (rna_path[rna_path_len] !=
']') {
737 const char *last_valid_index_token_start =
nullptr;
738 while (rna_path_len--) {
739 switch (rna_path[rna_path_len]) {
741 if (rna_path_len <= 0 || rna_path[rna_path_len - 1] !=
']') {
742 return &rna_path[rna_path_len];
744 last_valid_index_token_start = &rna_path[rna_path_len];
759 return last_valid_index_token_start;
762 return last_valid_index_token_start;
778 bool is_first =
true;
787 link->
up = link_prev;
792 for (link = link_prev; link; link = link->
up) {
794 if (link->
index >= 0) {
820 char *path =
nullptr;
828 link.
up = parent_link;
834 iter = iter->
next, i++)
836 if (needle == iter) {
873 if ((path =
rna_idp_path(&child_ptr, iter, needle, &link))) {
889 for (j = 0; j < iter->
len; j++,
array++) {
927 std::string string_path(path);
958 switch (
GS(id->name)) {
960 *r_path =
"node_tree";
963 *r_path =
"collection";
971 BLI_assert_msg(owner_id !=
nullptr,
"Missing handling of embedded id type.");
972 return (owner_id !=
nullptr) ? owner_id : id;
980 if (r_real_id !=
nullptr) {
981 *r_real_id =
nullptr;
987 if (r_real_id !=
nullptr) {
988 *r_real_id = real_id;
994 return fmt::format(
"{}{}{}", prefix, path[0] ==
'[' ?
"" :
".", path);
1000 if (prefix[0] ==
'\0') {
1001 return std::nullopt;
1009 std::optional<std::string> ptrpath;
1012 return std::nullopt;
1034 return std::nullopt;
1042 return std::nullopt;
1061 const int index_dim,
1066 int i = totdims - 1;
1067 dimsize_step[i + 1] = 1;
1068 dimsize_step[i] = dimsize[i];
1070 dimsize_step[i] = dimsize[i] * dimsize_step[i + 1];
1072 while (++i != index_dim) {
1073 int index_round = index / dimsize_step[i + 1];
1074 r_index_multi[i] = index_round;
1075 index -= (index_round * dimsize_step[i + 1]);
1093 for (
int i = 0, offset = 0; (i < index_dim) && (offset < index_str_len); i++) {
1095 &index_str[offset], index_str_len - offset,
"[%d]", index_multi[i]);
1111 if (index_dim == 0) {
1112 index_str[0] =
'\0';
1116 ptr, prop, index_dim, index, index_str,
sizeof(index_str));
1121 return fmt::format(
"{}.{}{}", path_prefix, propname, index_str);
1125 return fmt::format(
"{}[\"{}\"]{}", path_prefix, propname_esc, index_str);
1129 if (index_dim == 0) {
1133 return fmt::format(
"{}{}", propname, index_str);
1138 return fmt::format(
"[\"{}\"]{}", propname_esc, index_str);
1155 return std::nullopt;
1161 return std::nullopt;
1179 ptr, prop, index_dim, index);
1181 return std::nullopt;
1198 return std::nullopt;
1203 std::optional<std::string> path;
1217 MEM_delete(prop_elem);
1237 char lib_filepath_esc[(
sizeof(
id->lib->filepath) * 2) + 4];
1240 memcpy(lib_filepath_esc,
", \"", 3);
1242 ofs +=
BLI_str_escape(lib_filepath_esc + ofs, id->lib->filepath,
sizeof(lib_filepath_esc));
1243 memcpy(lib_filepath_esc + ofs,
"\"", 2);
1246 lib_filepath_esc[0] =
'\0';
1249 char id_esc[(
sizeof(
id->name) - 2) * 2];
1252 return fmt::format(
"bpy.data.{}[\"{}\"{}]{}{}",
1263 return std::nullopt;
1273 return fmt::format(
"{}.{}", id_path, data_path.value_or(
""));
1281 const char *data_delim;
1284 return std::nullopt;
1292 data_delim = ((*data_path)[0] ==
'[') ?
"" :
".";
1298 data_delim =
" ... ";
1306 return fmt::format(
"{}{}{}", id_path, data_delim, data_path.value_or(
""));
1308 return fmt::format(
"{}{}{}[{}]", id_path, data_delim, data_path.value_or(
""), index);
1323 return std::nullopt;
1334 data_path = prop_identifier;
1342 return fmt::format(
"{}[{}]", data_path.value_or(
""), index);
1350 const int index_dim = (index == -1) ? 0 : 1;
#define IDP_IDPArray(prop)
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
const char * BKE_idtype_idcode_to_name_plural(short idcode)
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert=true)
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_msg(a, msg)
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format,...) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
size_t size_t size_t const char * BLI_str_escape_find_quote(const char *str) ATTR_NONNULL(1)
size_t size_t size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy) ATTR_NONNULL(1
#define SNPRINTF(dst, format,...)
size_t BLI_snprintf_rlen(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define UNUSED_FUNCTION_WITH_RETURN_TYPE(rtype, x)
ID and Library types, which are fundamental for SDNA.
#define ID_IS_LINKED(_id)
Read Guarded memory(de)allocation.
#define RNA_POINTER_INVALIDATE(ptr)
#define RNA_MAX_ARRAY_LENGTH
#define RNA_MAX_ARRAY_DIMENSION
constexpr bool is_empty() const
constexpr StringRef drop_prefix(int64_t n) const
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_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
bool RNA_property_array_check(PropertyRNA *prop)
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
bool RNA_struct_is_ID(const StructRNA *type)
PropertyRNA * rna_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PropertyType RNA_property_type(PropertyRNA *prop)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty * RNA_struct_idprops(PointerRNA *ptr, bool create)
int RNA_property_array_dimension(const PointerRNA *ptr, PropertyRNA *prop, int length[])
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
bool RNA_pointer_is_null(const PointerRNA *ptr)
bool RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
int RNA_property_array_item_index(PropertyRNA *prop, char name)
const char * RNA_property_identifier(const PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
StructRNA RNA_PropertyGroup
static bool rna_path_parse_array_index(const char **path, PointerRNA *ptr, PropertyRNA *prop, int *r_index)
std::optional< std::string > RNA_path_from_struct_to_idproperty(PointerRNA *ptr, const IDProperty *needle)
std::optional< std::string > RNA_path_from_ID_to_struct(const PointerRNA *ptr)
std::optional< std::string > RNA_path_full_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index)
std::optional< std::string > RNA_path_from_real_ID_to_struct(Main *bmain, const PointerRNA *ptr, ID **r_real)
std::optional< std::string > RNA_path_from_real_ID_to_property_index(Main *bmain, const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, ID **r_real_id)
static char * rna_path_token_in_brackets(const char **path, char *fixedbuf, int fixedlen, bool *r_quoted)
std::optional< std::string > RNA_path_full_property_py_ex(const PointerRNA *ptr, PropertyRNA *prop, int index, bool use_fallback)
static bool rna_path_parse(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index, PointerRNA *r_item_ptr, ListBase *r_elements, const bool eval_pointer)
bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, ListBase *r_elements)
std::optional< std::string > RNA_path_resolve_from_type_to_property(const PointerRNA *ptr, PropertyRNA *prop, const StructRNA *type)
bool RNA_path_resolve_full_maybe_null(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
ID * RNA_find_real_ID_and_path(ID *id, const char **r_path)
std::optional< std::string > RNA_path_full_struct_py(const PointerRNA *ptr)
bool RNA_path_resolve_property_and_item_pointer(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, PointerRNA *r_item_ptr)
bool operator==(const RNAPath &left, const RNAPath &right)
static char * rna_path_token(const char **path, char *fixedbuf, int fixedlen)
std::string RNA_path_full_ID_py(ID *id)
static std::string rna_path_from_ptr_to_property_index_ex(const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, const blender::StringRef path_prefix)
static std::optional< std::string > rna_path_from_ID_to_idpgroup(const PointerRNA *ptr)
static std::optional< std::string > rna_prepend_real_ID_path(Main *, ID *id, const blender::StringRef path, ID **r_real_id)
const char * RNA_path_array_index_token_find(const char *rna_path, const PropertyRNA *array_prop)
static char * rna_idp_path_create(IDP_Chain *child_link)
bool RNA_path_resolve_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
std::optional< std::string > RNA_path_from_ID_to_property_index(const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index)
static bool rna_path_parse_collection_key(const char **path, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_nextptr)
std::string RNA_path_property_py(const PointerRNA *ptr, PropertyRNA *prop, int index)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
static void rna_path_array_multi_string_from_flat_index(const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index, char *index_str, int index_str_len)
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
bool RNA_path_resolve_property_and_item_pointer_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index, PointerRNA *r_item_ptr)
std::optional< std::string > RNA_path_struct_property_py(PointerRNA *ptr, PropertyRNA *prop, int index)
std::string RNA_path_from_ptr_to_property_index(const PointerRNA *ptr, PropertyRNA *prop, int index_dim, int index)
bool RNA_path_resolve(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
char * RNA_path_append(const char *path, const PointerRNA *, PropertyRNA *prop, int intkey, const char *strkey)
static void rna_path_array_multi_from_flat_index(const int dimsize[RNA_MAX_ARRAY_LENGTH], const int totdims, const int index_dim, int index, int r_index_multi[RNA_MAX_ARRAY_LENGTH])
static char * rna_idp_path(PointerRNA *ptr, const IDProperty *haystack, const IDProperty *needle, IDP_Chain *parent_link)
unsigned int arraydimension