diff options
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_access.c | 46 |
2 files changed, 58 insertions, 0 deletions
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index e855395482e..67605201a9f 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -490,6 +490,18 @@ char *RNA_path_append( char *RNA_path_back(const char *path); #endif +/** + * Search for the start of the 'rna array index' part of the given `rna_path`. + * + * Given the root RNA pointer and resolved RNA property, and the RNA path, return the first + * character in `rna_path` that is part of the array index for the given property. Return NULL if + * none can be found, e.g. because the property is not an RNA array. + * + * \param array_prop if not NULL, the PropertyRNA assumed to be the last one from the RNA path. + * Only used to ensure it is a valid array property. + */ +const char *RNA_path_array_index_token_find(const char *rna_path, const PropertyRNA *array_prop); + /* RNA_path_resolve() variants only ensure that a valid pointer (and optionally property) exist. */ /** diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 75579107465..312c0753ce7 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -5482,6 +5482,52 @@ static UNUSED_FUNCTION_WITH_RETURN_TYPE(char *, RNA_path_back)(const char *path) return result; } +const char *RNA_path_array_index_token_find(const char *rna_path, const PropertyRNA *array_prop) +{ + if (array_prop != NULL) { + if (!ELEM(array_prop->type, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { + BLI_assert(array_prop->arraydimension == 0); + return NULL; + } + if (array_prop->arraydimension == 0) { + return NULL; + } + } + + /* Valid 'array part' of a rna path can only have '[', ']' and digit characters. + * It may have more than one of those (e.g. `[12][1]`) in case of multi-dimensional arrays. */ + off_t rna_path_len = (off_t)strlen(rna_path); + if (rna_path[rna_path_len] != ']') { + return NULL; + } + const char *last_valid_index_token_start = NULL; + for (rna_path_len--; rna_path_len >= 0; rna_path_len--) { + switch (rna_path[rna_path_len]) { + case '[': + if (rna_path_len <= 0 || rna_path[rna_path_len - 1] != ']') { + return &rna_path[rna_path_len]; + } + last_valid_index_token_start = &rna_path[rna_path_len]; + rna_path_len--; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + default: + return last_valid_index_token_start; + } + } + return last_valid_index_token_start; +} + /* generic path search func * if its needed this could also reference the IDProperty direct */ typedef struct IDP_Chain { |