12#include <fmt/format.h>
33#include "RNA_prototypes.hh"
40 if (
key.has_value()) {
52 if (
left.key.has_value() || right.
key.has_value()) {
70 const char *p = *path;
71 while (*p && !
ELEM(*p,
'.',
'[')) {
83 memcpy(buf, *path,
sizeof(
char) *
len);
120 const char *p = *path;
128 if (p_end ==
nullptr) {
142 while (*p && (*p !=
']')) {
168 p = (*path) +
len + 1;
171 memcpy(buf, *path,
sizeof(
char) *
len);
225 r_nextptr->
data =
nullptr;
230 intkey = atoi(token);
231 if (intkey == 0 && (token[0] !=
'0' || token[1] !=
'\0')) {
238 r_nextptr->
data =
nullptr;
242 if (token != fixedbuf) {
252 r_nextptr->
data =
nullptr;
277 for (
i = 0;
i < dim;
i++) {
286 if (token ==
nullptr) {
296 temp_index = atoi(token);
298 if (temp_index == 0 && (token[0] !=
'0' || token[1] !=
'\0')) {
299 if (token != fixedbuf) {
310 if (token ==
nullptr) {
321 if (token != fixedbuf) {
326 if (temp_index < 0 || temp_index >=
len[
i]) {
330 index_arr[
i] = temp_index;
344 for (
i = dim - 1;
i >= 0;
i--) {
345 flat_index += index_arr[
i] * totdim;
349 *r_index = flat_index;
383 const bool eval_pointer)
385 BLI_assert(r_item_ptr ==
nullptr || !eval_pointer);
392 const bool do_item_ptr = r_item_ptr !=
nullptr && !eval_pointer;
401 if (path ==
nullptr || *path ==
'\0') {
410 const bool use_id_prop = (*path ==
'[');
419 char *token = use_id_prop ?
429 if (group && quoted) {
437 if (token != fixedbuf) {
446 prop_elem = MEM_new<PropertyElemRNA>(__func__);
447 prop_elem->
ptr = curptr;
448 prop_elem->
prop = prop;
449 prop_elem->
index = -1;
463 if (do_item_ptr || eval_pointer || *path !=
'\0') {
467 if (eval_pointer || *path !=
'\0') {
484 if (eval_pointer || *path !=
'\0') {
493 if (r_index || prop_elem) {
499 prop_elem->
index = index;
515 if (r_item_ptr && do_item_ptr) {
516 *r_item_ptr = nextptr;
522 prop_elem = MEM_new<PropertyElemRNA>(__func__);
523 prop_elem->
ptr = curptr;
524 prop_elem->
prop = prop;
525 prop_elem->
index = index;
537 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr,
nullptr,
nullptr,
true)) {
541 return r_ptr->
data !=
nullptr;
547 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
true)) {
551 return r_ptr->
data !=
nullptr;
557 return rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
true);
565 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr,
nullptr,
nullptr,
false)) {
569 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
575 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index,
nullptr,
nullptr,
false)) {
579 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
588 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop,
nullptr, r_item_ptr,
nullptr,
false)) {
592 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
602 if (!
rna_path_parse(
ptr, path, r_ptr, r_prop, r_index, r_item_ptr,
nullptr,
false)) {
606 return r_ptr->
data !=
nullptr && *r_prop !=
nullptr;
610 return rna_path_parse(
ptr, path,
nullptr,
nullptr,
nullptr,
nullptr, r_elements,
false);
634 const bool has_key = (intkey > -1) || (strkey !=
nullptr);
640 const int strkey_esc_max_size = (strlen(strkey) * 2) + 1;
641 char *strkey_esc =
static_cast<char *
>(
BLI_array_alloca(strkey_esc, strkey_esc_max_size));
667 const char *previous, *current;
688 if (token != fixedbuf) {
695 if (token && token != fixedbuf) {
714 if (
i > 0 &&
result[
i - 1] ==
'.') {
724 if (array_prop !=
nullptr) {
736 if (
UNLIKELY(rna_path[0] ==
'\0')) {
739 size_t rna_path_len = strlen(rna_path) - 1;
740 if (rna_path[rna_path_len] !=
']') {
744 const char *last_valid_index_token_start =
nullptr;
745 while (rna_path_len--) {
746 switch (rna_path[rna_path_len]) {
748 if (rna_path_len <= 0 || rna_path[rna_path_len - 1] !=
']') {
749 return &rna_path[rna_path_len];
751 last_valid_index_token_start = &rna_path[rna_path_len];
766 return last_valid_index_token_start;
769 return last_valid_index_token_start;
785 bool is_first =
true;
794 link->
up = link_prev;
799 for (link = link_prev; link; link = link->
up) {
801 if (link->
index >= 0) {
827 char *path =
nullptr;
835 link.
up = parent_link;
841 iter = iter->
next,
i++)
843 if (needle == iter) {
880 if ((path =
rna_idp_path(&child_ptr, iter, needle, &link))) {
896 for (j = 0; j < iter->
len; j++,
array++) {
934 std::string string_path(path);
967 *r_path =
"node_tree";
970 *r_path =
"collection";
978 BLI_assert_msg(owner_id !=
nullptr,
"Missing handling of embedded id type.");
979 return (owner_id !=
nullptr) ? owner_id : id;
987 if (r_real_id !=
nullptr) {
988 *r_real_id =
nullptr;
994 if (r_real_id !=
nullptr) {
995 *r_real_id = real_id;
1001 return fmt::format(
"{}{}{}", prefix, path[0] ==
'[' ?
"" :
".", path);
1007 if (prefix[0] ==
'\0') {
1008 return std::nullopt;
1016 std::optional<std::string> ptrpath;
1018 if (!
ptr->owner_id || !
ptr->data) {
1019 return std::nullopt;
1023 if (
ptr->type->path) {
1041 return std::nullopt;
1049 return std::nullopt;
1068 const int index_dim,
1073 int i = totdims - 1;
1074 dimsize_step[
i + 1] = 1;
1075 dimsize_step[
i] = dimsize[
i];
1077 dimsize_step[
i] = dimsize[
i] * dimsize_step[
i + 1];
1079 while (++
i != index_dim) {
1080 int index_round = index / dimsize_step[
i + 1];
1081 r_index_multi[
i] = index_round;
1082 index -= (index_round * dimsize_step[
i + 1]);
1100 for (
int i = 0, offset = 0; (
i < index_dim) && (offset < index_str_len);
i++) {
1102 &index_str[offset], index_str_len - offset,
"[%d]", index_multi[
i]);
1118 if (index_dim == 0) {
1119 index_str[0] =
'\0';
1123 ptr, prop, index_dim, index, index_str,
sizeof(index_str));
1128 return fmt::format(
"{}.{}{}", path_prefix, propname, index_str);
1132 return fmt::format(
"{}[\"{}\"]{}", path_prefix, propname_esc, index_str);
1136 if (index_dim == 0) {
1140 return fmt::format(
"{}{}", propname, index_str);
1145 return fmt::format(
"[\"{}\"]{}", propname_esc, index_str);
1161 if (!
ptr->owner_id || !
ptr->data) {
1162 return std::nullopt;
1168 return std::nullopt;
1186 ptr, prop, index_dim, index);
1188 return std::nullopt;
1205 return std::nullopt;
1210 std::optional<std::string> path;
1224 MEM_delete(prop_elem);
1244 char lib_filepath_esc[(
sizeof(
id->lib->filepath) * 2) + 4];
1247 memcpy(lib_filepath_esc,
", \"", 3);
1250 memcpy(lib_filepath_esc + ofs,
"\"", 2);
1253 lib_filepath_esc[0] =
'\0';
1256 char id_esc[(
sizeof(
id->name) - 2) * 2];
1259 return fmt::format(
"bpy.data.{}[\"{}\"{}]{}{}",
1269 if (!
ptr->owner_id) {
1270 return std::nullopt;
1280 return fmt::format(
"{}.{}", id_path, data_path.value_or(
""));
1288 const char *data_delim;
1290 if (!
ptr->owner_id) {
1291 return std::nullopt;
1299 data_delim = ((*data_path)[0] ==
'[') ?
"" :
".";
1305 data_delim =
" ... ";
1313 return fmt::format(
"{}{}{}", id_path, data_delim, data_path.value_or(
""));
1315 return fmt::format(
"{}{}{}[{}]", id_path, data_delim, data_path.value_or(
""), index);
1329 if (!
ptr->owner_id) {
1330 return std::nullopt;
1341 data_path = prop_identifier;
1349 return fmt::format(
"{}[{}]", data_path.value_or(
""), index);
1357 const int index_dim = (index == -1) ? 0 : 1;
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define IDP_property_array_get(prop)
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()
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void BLI_addtail(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_MAX_ARRAY_LENGTH
#define RNA_MAX_ARRAY_DIMENSION
constexpr bool is_empty() const
constexpr StringRef drop_prefix(int64_t n) const
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
uint64_t get_default_hash(const T &v, const Args &...args)
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)
IDProperty * RNA_struct_system_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
std::optional< int > index
std::optional< std::string > key