forked from bartvdbraak/blender
Cleanup for RNA_path_resolve_full.
* Moved collection key parsing and array index parsing into their own functions, to make the main path loop easier to follow. * Unified boolean return values.
This commit is contained in:
parent
4d47e75223
commit
fe094eaf20
@ -3902,6 +3902,145 @@ bool RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prop
|
|||||||
return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
|
return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool path_resolve_collection_key(const char **path, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_nextptr)
|
||||||
|
{
|
||||||
|
char fixedbuf[256], *token;
|
||||||
|
int intkey;
|
||||||
|
|
||||||
|
/* end of path, ok */
|
||||||
|
if (!(**path))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (**path == '[') {
|
||||||
|
/* resolve the lookup with [] brackets */
|
||||||
|
token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
|
||||||
|
|
||||||
|
if (!token)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* check for "" to see if it is a string */
|
||||||
|
if (rna_token_strip_quotes(token)) {
|
||||||
|
if (RNA_property_collection_lookup_string(ptr, prop, token + 1, r_nextptr)) {
|
||||||
|
/* pass */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r_nextptr->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* otherwise do int lookup */
|
||||||
|
intkey = atoi(token);
|
||||||
|
if (intkey == 0 && (token[0] != '0' || token[1] != '\0')) {
|
||||||
|
return false; /* we can be sure the fixedbuf was used in this case */
|
||||||
|
}
|
||||||
|
if (RNA_property_collection_lookup_int(ptr, prop, intkey, r_nextptr)) {
|
||||||
|
/* pass */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r_nextptr->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token != fixedbuf) {
|
||||||
|
MEM_freeN(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (RNA_property_collection_type_get(ptr, prop, r_nextptr)) {
|
||||||
|
/* pass */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* ensure we quit on invalid values */
|
||||||
|
r_nextptr->data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r_nextptr->data != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool path_resolve_array_index(const char **path, PointerRNA *ptr, PropertyRNA *prop, int *r_index)
|
||||||
|
{
|
||||||
|
char fixedbuf[256], *token;
|
||||||
|
int index_arr[RNA_MAX_ARRAY_DIMENSION] = {0};
|
||||||
|
int len[RNA_MAX_ARRAY_DIMENSION];
|
||||||
|
const int dim = RNA_property_array_dimension(ptr, prop, len);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*r_index = -1;
|
||||||
|
|
||||||
|
/* end of path, ok */
|
||||||
|
if (!(**path))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (i = 0; i < dim; i++) {
|
||||||
|
int temp_index = -1;
|
||||||
|
|
||||||
|
/* multi index resolve */
|
||||||
|
if (**path == '[') {
|
||||||
|
token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 1);
|
||||||
|
|
||||||
|
if (token == NULL) {
|
||||||
|
/* invalid syntax blah[] */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* check for "" to see if it is a string */
|
||||||
|
else if (rna_token_strip_quotes(token)) {
|
||||||
|
temp_index = RNA_property_array_item_index(prop, *(token + 1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* otherwise do int lookup */
|
||||||
|
temp_index = atoi(token);
|
||||||
|
|
||||||
|
if (temp_index == 0 && (token[0] != '0' || token[1] != '\0')) {
|
||||||
|
if (token != fixedbuf) {
|
||||||
|
MEM_freeN(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (dim == 1) {
|
||||||
|
/* location.x || scale.X, single dimension arrays only */
|
||||||
|
token = rna_path_token(path, fixedbuf, sizeof(fixedbuf), 0);
|
||||||
|
if (token == NULL) {
|
||||||
|
/* invalid syntax blah.. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
temp_index = RNA_property_array_item_index(prop, *token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token != fixedbuf) {
|
||||||
|
MEM_freeN(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* out of range */
|
||||||
|
if (temp_index < 0 || temp_index >= len[i])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
index_arr[i] = temp_index;
|
||||||
|
/* end multi index resolve */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arrays always contain numbers so further values are not valid */
|
||||||
|
if (**path)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* flatten index over all dimensions */
|
||||||
|
{
|
||||||
|
int totdim = 1;
|
||||||
|
int flat_index = 0;
|
||||||
|
|
||||||
|
for (i = dim - 1; i >= 0; i--) {
|
||||||
|
flat_index += index_arr[i] * totdim;
|
||||||
|
totdim *= len[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_index = flat_index;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path
|
/* Resolve the given RNA Path to find the pointer and/or property + array index indicated by fully resolving the path
|
||||||
* ! Assumes all pointers provided are valid
|
* ! Assumes all pointers provided are valid
|
||||||
* > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
|
* > returns: True if path can be resolved to a valid "pointer + property" OR "pointer only"
|
||||||
@ -3912,13 +4051,13 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
|
|||||||
PointerRNA curptr;
|
PointerRNA curptr;
|
||||||
PointerRNA nextptr; /* keep uninitialized, helps expose bugs in collection accessor functions */
|
PointerRNA nextptr; /* keep uninitialized, helps expose bugs in collection accessor functions */
|
||||||
char fixedbuf[256], *token;
|
char fixedbuf[256], *token;
|
||||||
int type, intkey;
|
int type;
|
||||||
|
|
||||||
prop = NULL;
|
prop = NULL;
|
||||||
curptr = *ptr;
|
curptr = *ptr;
|
||||||
|
|
||||||
if (path == NULL || *path == '\0')
|
if (path == NULL || *path == '\0')
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
while (*path) {
|
while (*path) {
|
||||||
int use_id_prop = (*path == '[') ? 1 : 0;
|
int use_id_prop = (*path == '[') ? 1 : 0;
|
||||||
@ -3930,7 +4069,7 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
|
|||||||
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
|
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
|
||||||
|
|
||||||
if (!token)
|
if (!token)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if (use_id_prop) { /* look up property name in current struct */
|
if (use_id_prop) { /* look up property name in current struct */
|
||||||
IDProperty *group = RNA_struct_idprops(&curptr, 0);
|
IDProperty *group = RNA_struct_idprops(&curptr, 0);
|
||||||
@ -3945,7 +4084,7 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
|
|||||||
MEM_freeN(token);
|
MEM_freeN(token);
|
||||||
|
|
||||||
if (!prop)
|
if (!prop)
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
type = RNA_property_type(prop);
|
type = RNA_property_type(prop);
|
||||||
|
|
||||||
@ -3955,159 +4094,34 @@ bool RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr,
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case PROP_POINTER:
|
case PROP_POINTER:
|
||||||
nextptr = RNA_property_pointer_get(&curptr, prop);
|
nextptr = RNA_property_pointer_get(&curptr, prop);
|
||||||
|
if (nextptr.data == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (nextptr.data) {
|
curptr = nextptr;
|
||||||
curptr = nextptr;
|
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
|
||||||
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
|
if (index) *index = -1;
|
||||||
if (index) *index = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case PROP_COLLECTION:
|
case PROP_COLLECTION:
|
||||||
if (*path) {
|
if (!path_resolve_collection_key(&path, &curptr, prop, &nextptr))
|
||||||
if (*path == '[') {
|
return false;
|
||||||
/* resolve the lookup with [] brackets */
|
|
||||||
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
|
|
||||||
|
|
||||||
if (!token)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* check for "" to see if it is a string */
|
|
||||||
if (rna_token_strip_quotes(token)) {
|
|
||||||
if (RNA_property_collection_lookup_string(&curptr, prop, token + 1, &nextptr)) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nextptr.data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* otherwise do int lookup */
|
|
||||||
intkey = atoi(token);
|
|
||||||
if (intkey == 0 && (token[0] != '0' || token[1] != '\0')) {
|
|
||||||
return 0; /* we can be sure the fixedbuf was used in this case */
|
|
||||||
}
|
|
||||||
if (RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr)) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nextptr.data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token != fixedbuf) {
|
|
||||||
MEM_freeN(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PointerRNA c_ptr;
|
|
||||||
|
|
||||||
if (RNA_property_collection_type_get(&curptr, prop, &c_ptr)) {
|
|
||||||
nextptr = c_ptr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* ensure we quit on invalid values */
|
|
||||||
nextptr.data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextptr.data) {
|
|
||||||
curptr = nextptr;
|
|
||||||
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
|
|
||||||
if (index) *index = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
curptr = nextptr;
|
||||||
|
prop = NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
|
||||||
|
if (index) *index = -1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (index == NULL)
|
if (index) {
|
||||||
break;
|
if (!path_resolve_array_index(&path, &curptr, prop, index))
|
||||||
|
return false;
|
||||||
*index = -1;
|
|
||||||
|
|
||||||
if (*path) {
|
|
||||||
int index_arr[RNA_MAX_ARRAY_DIMENSION] = {0};
|
|
||||||
int len[RNA_MAX_ARRAY_DIMENSION];
|
|
||||||
const int dim = RNA_property_array_dimension(&curptr, prop, len);
|
|
||||||
int i, temp_index;
|
|
||||||
|
|
||||||
for (i = 0; i < dim; i++) {
|
|
||||||
temp_index = -1;
|
|
||||||
|
|
||||||
/* multi index resolve */
|
|
||||||
if (*path == '[') {
|
|
||||||
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
|
|
||||||
|
|
||||||
if (token == NULL) {
|
|
||||||
/* invalid syntax blah[] */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* check for "" to see if it is a string */
|
|
||||||
else if (rna_token_strip_quotes(token)) {
|
|
||||||
temp_index = RNA_property_array_item_index(prop, *(token + 1));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* otherwise do int lookup */
|
|
||||||
temp_index = atoi(token);
|
|
||||||
|
|
||||||
if (temp_index == 0 && (token[0] != '0' || token[1] != '\0')) {
|
|
||||||
if (token != fixedbuf) {
|
|
||||||
MEM_freeN(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (dim == 1) {
|
|
||||||
/* location.x || scale.X, single dimension arrays only */
|
|
||||||
token = rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
|
|
||||||
if (token == NULL) {
|
|
||||||
/* invalid syntax blah.. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
temp_index = RNA_property_array_item_index(prop, *token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token != fixedbuf) {
|
|
||||||
MEM_freeN(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* out of range */
|
|
||||||
if (temp_index < 0 || temp_index >= len[i])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
index_arr[i] = temp_index;
|
|
||||||
/* end multi index resolve */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* arrays always contain numbers so further values are not valid */
|
|
||||||
if (*path) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int totdim = 1;
|
|
||||||
int flat_index = 0;
|
|
||||||
|
|
||||||
for (i = dim - 1; i >= 0; i--) {
|
|
||||||
flat_index += index_arr[i] * totdim;
|
|
||||||
totdim *= len[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
*index = flat_index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_ptr = curptr;
|
*r_ptr = curptr;
|
||||||
*r_prop = prop;
|
*r_prop = prop;
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user