RNA path: add util to find the char in an RNA path where the array indexing starts.

Usefull to easily trim away the 'aray index' part of an RNA path, e.g.
when searching for an FCurve (which never contains that index part in
its RNA path).
This commit is contained in:
Bastien Montagne 2022-06-10 15:50:30 +02:00
parent 07341d7b32
commit f5d0a40122
2 changed files with 58 additions and 0 deletions

View File

@ -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. */
/**

View File

@ -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 {