diff options
Diffstat (limited to 'source/blender/makesdna/intern/dna_genfile.c')
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 2300 |
1 files changed, 1164 insertions, 1136 deletions
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index 863aebd86e8..e8af1cbf36e 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -27,13 +27,12 @@ * SDNA and the SDNA of the current (running) version of Blender. */ - #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> -#include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN +#include "MEM_guardedalloc.h" // for MEM_freeN MEM_mallocN MEM_callocN #include "BLI_utildefines.h" #include "BLI_endian_switch.h" @@ -45,7 +44,7 @@ #endif #include "DNA_genfile.h" -#include "DNA_sdna_types.h" // for SDNA ;-) +#include "DNA_sdna_types.h" // for SDNA ;-) /** * \section dna_genfile Overview @@ -128,7 +127,6 @@ * - the sdna functions have several error prints builtin, always check blender running from a console. */ - #ifdef __BIG_ENDIAN__ /* Big Endian */ # define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) @@ -141,29 +139,29 @@ void DNA_sdna_free(SDNA *sdna) { - if (sdna->data_alloc) { - MEM_freeN((void *)sdna->data); - } + if (sdna->data_alloc) { + MEM_freeN((void *)sdna->data); + } - MEM_freeN((void *)sdna->names); - MEM_freeN((void *)sdna->names_array_len); - MEM_freeN((void *)sdna->types); - MEM_freeN(sdna->structs); + MEM_freeN((void *)sdna->names); + MEM_freeN((void *)sdna->names_array_len); + MEM_freeN((void *)sdna->types); + MEM_freeN(sdna->structs); #ifdef WITH_DNA_GHASH - if (sdna->structs_map) { - BLI_ghash_free(sdna->structs_map, NULL, NULL); - } + if (sdna->structs_map) { + BLI_ghash_free(sdna->structs_map, NULL, NULL); + } #endif - if (sdna->mem_arena) { - BLI_memarena_free(sdna->mem_arena); - } + if (sdna->mem_arena) { + BLI_memarena_free(sdna->mem_arena); + } - MEM_SAFE_FREE(sdna->alias.names); - MEM_SAFE_FREE(sdna->alias.types); + MEM_SAFE_FREE(sdna->alias.names); + MEM_SAFE_FREE(sdna->alias.types); - MEM_freeN(sdna); + MEM_freeN(sdna); } /** @@ -171,8 +169,8 @@ void DNA_sdna_free(SDNA *sdna) */ static bool ispointer(const char *name) { - /* check if pointer or function pointer */ - return (name[0] == '*' || (name[0] == '(' && name[1] == '*')); + /* check if pointer or function pointer */ + return (name[0] == '*' || (name[0] == '(' && name[1] == '*')); } /** @@ -184,39 +182,39 @@ static bool ispointer(const char *name) */ static int elementsize(const SDNA *sdna, short type, short name) { - int len; - const char *cp = sdna->names[name]; - len = 0; - - /* is it a pointer or function pointer? */ - if (ispointer(cp)) { - /* has the name an extra length? (array) */ - len = sdna->pointer_size * sdna->names_array_len[name]; - } - else if (sdna->types_size[type]) { - /* has the name an extra length? (array) */ - len = (int)sdna->types_size[type] * sdna->names_array_len[name]; - } - - return len; + int len; + const char *cp = sdna->names[name]; + len = 0; + + /* is it a pointer or function pointer? */ + if (ispointer(cp)) { + /* has the name an extra length? (array) */ + len = sdna->pointer_size * sdna->names_array_len[name]; + } + else if (sdna->types_size[type]) { + /* has the name an extra length? (array) */ + len = (int)sdna->types_size[type] * sdna->names_array_len[name]; + } + + return len; } #if 0 static void printstruct(SDNA *sdna, short strnr) { - /* is for debug */ - int b, nr; - short *sp; + /* is for debug */ + int b, nr; + short *sp; - sp = sdna->structs[strnr]; + sp = sdna->structs[strnr]; - printf("struct %s\n", sdna->types[sp[0]]); - nr = sp[1]; - sp += 2; + printf("struct %s\n", sdna->types[sp[0]]); + nr = sp[1]; + sp += 2; - for (b = 0; b < nr; b++, sp += 2) { - printf(" %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]); - } + for (b = 0; b < nr; b++, sp += 2) { + printf(" %s %s\n", sdna->types[sp[0]], sdna->names[sp[1]]); + } } #endif @@ -225,53 +223,53 @@ static void printstruct(SDNA *sdna, short strnr) */ int DNA_struct_find_nr_ex(const SDNA *sdna, const char *str, unsigned int *index_last) { - const short *sp = NULL; + const short *sp = NULL; - if (*index_last < sdna->nr_structs) { - sp = sdna->structs[*index_last]; - if (strcmp(sdna->types[sp[0]], str) == 0) { - return *index_last; - } - } + if (*index_last < sdna->nr_structs) { + sp = sdna->structs[*index_last]; + if (strcmp(sdna->types[sp[0]], str) == 0) { + return *index_last; + } + } #ifdef WITH_DNA_GHASH - { - void **index_p; - int a; - - index_p = BLI_ghash_lookup_p(sdna->structs_map, str); - - if (index_p) { - a = POINTER_AS_INT(*index_p); - *index_last = a; - } - else { - a = -1; - } - return a; - } + { + void **index_p; + int a; + + index_p = BLI_ghash_lookup_p(sdna->structs_map, str); + + if (index_p) { + a = POINTER_AS_INT(*index_p); + *index_last = a; + } + else { + a = -1; + } + return a; + } #else - { - int a; + { + int a; - for (a = 0; a < sdna->nr_structs; a++) { + for (a = 0; a < sdna->nr_structs; a++) { - sp = sdna->structs[a]; + sp = sdna->structs[a]; - if (strcmp(sdna->types[sp[0]], str) == 0) { - *index_last = a; - return a; - } - } - } - return -1; + if (strcmp(sdna->types[sp[0]], str) == 0) { + *index_last = a; + return a; + } + } + } + return -1; #endif } int DNA_struct_find_nr(const SDNA *sdna, const char *str) { - unsigned int index_last_dummy = UINT_MAX; - return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy); + unsigned int index_last_dummy = UINT_MAX; + return DNA_struct_find_nr_ex(sdna, str, &index_last_dummy); } /* ************************* END DIV ********************** */ @@ -280,270 +278,268 @@ int DNA_struct_find_nr(const SDNA *sdna, const char *str) BLI_INLINE const char *pad_up_4(const char *ptr) { - return (const char *)((((uintptr_t)ptr) + 3) & ~3); + return (const char *)((((uintptr_t)ptr) + 3) & ~3); } /** * In sdna->data the data, now we convert that to something understandable */ -static bool init_structDNA( - SDNA *sdna, bool do_endian_swap, - const char **r_error_message) +static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message) { - int *data, gravity_fix = -1; - short *sp; + int *data, gravity_fix = -1; + short *sp; - data = (int *)sdna->data; + data = (int *)sdna->data; - /* clear pointers incase of error */ - sdna->names = NULL; - sdna->types = NULL; - sdna->structs = NULL; + /* clear pointers incase of error */ + sdna->names = NULL; + sdna->types = NULL; + sdna->structs = NULL; #ifdef WITH_DNA_GHASH - sdna->structs_map = NULL; + sdna->structs_map = NULL; #endif - sdna->mem_arena = NULL; - - /* Lazy initialize. */ - memset(&sdna->alias, 0, sizeof(sdna->alias)); - - /* Struct DNA ('SDNA') */ - if (*data != MAKE_ID('S', 'D', 'N', 'A')) { - *r_error_message = "SDNA error in SDNA file"; - return false; - } - else { - const char *cp; - - data++; - /* Names array ('NAME') */ - if (*data == MAKE_ID('N', 'A', 'M', 'E')) { - data++; - - sdna->nr_names = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->nr_names); - } - sdna->nr_names_alloc = sdna->nr_names; - - data++; - sdna->names = MEM_callocN(sizeof(void *) * sdna->nr_names, "sdnanames"); - } - else { - *r_error_message = "NAME error in SDNA file"; - return false; - } - - cp = (char *)data; - for (int nr = 0; nr < sdna->nr_names; nr++) { - sdna->names[nr] = cp; - - /* "float gravity [3]" was parsed wrong giving both "gravity" and - * "[3]" members. we rename "[3]", and later set the type of - * "gravity" to "void" so the offsets work out correct */ - if (*cp == '[' && strcmp(cp, "[3]") == 0) { - if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) { - sdna->names[nr] = "gravity[3]"; - gravity_fix = nr; - } - } - while (*cp) { - cp++; - } - cp++; - } - - cp = pad_up_4(cp); - - /* Type names array ('TYPE') */ - data = (int *)cp; - if (*data == MAKE_ID('T', 'Y', 'P', 'E')) { - data++; - - sdna->nr_types = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->nr_types); - } - - data++; - sdna->types = MEM_callocN(sizeof(void *) * sdna->nr_types, "sdnatypes"); - } - else { - *r_error_message = "TYPE error in SDNA file"; - return false; - } - - cp = (char *)data; - for (int nr = 0; nr < sdna->nr_types; nr++) { - /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */ - sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp); - while (*cp) { - cp++; - } - cp++; - } - - cp = pad_up_4(cp); - - /* Type lengths array ('TLEN') */ - data = (int *)cp; - if (*data == MAKE_ID('T', 'L', 'E', 'N')) { - data++; - sp = (short *)data; - sdna->types_size = sp; - - if (do_endian_swap) { - BLI_endian_switch_int16_array(sp, sdna->nr_types); - } - - sp += sdna->nr_types; - } - else { - *r_error_message = "TLEN error in SDNA file"; - return false; - } - /* prevent BUS error */ - if (sdna->nr_types & 1) { - sp++; - } - - /* Struct array ('STRC') */ - data = (int *)sp; - if (*data == MAKE_ID('S', 'T', 'R', 'C')) { - data++; - - sdna->nr_structs = *data; - if (do_endian_swap) { - BLI_endian_switch_int32(&sdna->nr_structs); - } - - data++; - sdna->structs = MEM_callocN(sizeof(void *) * sdna->nr_structs, "sdnastrcs"); - } - else { - *r_error_message = "STRC error in SDNA file"; - return false; - } - - sp = (short *)data; - for (int nr = 0; nr < sdna->nr_structs; nr++) { - sdna->structs[nr] = sp; - - if (do_endian_swap) { - short a; - - BLI_endian_switch_int16(&sp[0]); - BLI_endian_switch_int16(&sp[1]); - - a = sp[1]; - sp += 2; - while (a--) { - BLI_endian_switch_int16(&sp[0]); - BLI_endian_switch_int16(&sp[1]); - sp += 2; - } - } - else { - sp += 2 * sp[1] + 2; - } - } - } - - { - /* second part of gravity problem, setting "gravity" type to void */ - if (gravity_fix > -1) { - for (int nr = 0; nr < sdna->nr_structs; nr++) { - sp = sdna->structs[nr]; - if (strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0) { - sp[10] = SDNA_TYPE_VOID; - } - } - } - } + sdna->mem_arena = NULL; + + /* Lazy initialize. */ + memset(&sdna->alias, 0, sizeof(sdna->alias)); + + /* Struct DNA ('SDNA') */ + if (*data != MAKE_ID('S', 'D', 'N', 'A')) { + *r_error_message = "SDNA error in SDNA file"; + return false; + } + else { + const char *cp; + + data++; + /* Names array ('NAME') */ + if (*data == MAKE_ID('N', 'A', 'M', 'E')) { + data++; + + sdna->nr_names = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_names); + } + sdna->nr_names_alloc = sdna->nr_names; + + data++; + sdna->names = MEM_callocN(sizeof(void *) * sdna->nr_names, "sdnanames"); + } + else { + *r_error_message = "NAME error in SDNA file"; + return false; + } + + cp = (char *)data; + for (int nr = 0; nr < sdna->nr_names; nr++) { + sdna->names[nr] = cp; + + /* "float gravity [3]" was parsed wrong giving both "gravity" and + * "[3]" members. we rename "[3]", and later set the type of + * "gravity" to "void" so the offsets work out correct */ + if (*cp == '[' && strcmp(cp, "[3]") == 0) { + if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) { + sdna->names[nr] = "gravity[3]"; + gravity_fix = nr; + } + } + while (*cp) { + cp++; + } + cp++; + } + + cp = pad_up_4(cp); + + /* Type names array ('TYPE') */ + data = (int *)cp; + if (*data == MAKE_ID('T', 'Y', 'P', 'E')) { + data++; + + sdna->nr_types = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_types); + } + + data++; + sdna->types = MEM_callocN(sizeof(void *) * sdna->nr_types, "sdnatypes"); + } + else { + *r_error_message = "TYPE error in SDNA file"; + return false; + } + + cp = (char *)data; + for (int nr = 0; nr < sdna->nr_types; nr++) { + /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */ + sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp); + while (*cp) { + cp++; + } + cp++; + } + + cp = pad_up_4(cp); + + /* Type lengths array ('TLEN') */ + data = (int *)cp; + if (*data == MAKE_ID('T', 'L', 'E', 'N')) { + data++; + sp = (short *)data; + sdna->types_size = sp; + + if (do_endian_swap) { + BLI_endian_switch_int16_array(sp, sdna->nr_types); + } + + sp += sdna->nr_types; + } + else { + *r_error_message = "TLEN error in SDNA file"; + return false; + } + /* prevent BUS error */ + if (sdna->nr_types & 1) { + sp++; + } + + /* Struct array ('STRC') */ + data = (int *)sp; + if (*data == MAKE_ID('S', 'T', 'R', 'C')) { + data++; + + sdna->nr_structs = *data; + if (do_endian_swap) { + BLI_endian_switch_int32(&sdna->nr_structs); + } + + data++; + sdna->structs = MEM_callocN(sizeof(void *) * sdna->nr_structs, "sdnastrcs"); + } + else { + *r_error_message = "STRC error in SDNA file"; + return false; + } + + sp = (short *)data; + for (int nr = 0; nr < sdna->nr_structs; nr++) { + sdna->structs[nr] = sp; + + if (do_endian_swap) { + short a; + + BLI_endian_switch_int16(&sp[0]); + BLI_endian_switch_int16(&sp[1]); + + a = sp[1]; + sp += 2; + while (a--) { + BLI_endian_switch_int16(&sp[0]); + BLI_endian_switch_int16(&sp[1]); + sp += 2; + } + } + else { + sp += 2 * sp[1] + 2; + } + } + } + + { + /* second part of gravity problem, setting "gravity" type to void */ + if (gravity_fix > -1) { + for (int nr = 0; nr < sdna->nr_structs; nr++) { + sp = sdna->structs[nr]; + if (strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0) { + sp[10] = SDNA_TYPE_VOID; + } + } + } + } #ifdef WITH_DNA_GHASH - { - /* create a ghash lookup to speed up */ - sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->nr_structs); - - for (intptr_t nr = 0; nr < sdna->nr_structs; nr++) { - sp = sdna->structs[nr]; - BLI_ghash_insert(sdna->structs_map, (void *)sdna->types[sp[0]], POINTER_FROM_INT(nr)); - } - } + { + /* create a ghash lookup to speed up */ + sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->nr_structs); + + for (intptr_t nr = 0; nr < sdna->nr_structs; nr++) { + sp = sdna->structs[nr]; + BLI_ghash_insert(sdna->structs_map, (void *)sdna->types[sp[0]], POINTER_FROM_INT(nr)); + } + } #endif - /* Calculate 'sdna->pointer_size' */ - { - const int nr = DNA_struct_find_nr(sdna, "ListBase"); - - /* should never happen, only with corrupt file for example */ - if (UNLIKELY(nr == -1)) { - *r_error_message = "ListBase struct error! Not found."; - return false; - } - - /* finally pointer_size: use struct ListBase to test it, never change the size of it! */ - sp = sdna->structs[nr]; - /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */ - - sdna->pointer_size = sdna->types_size[sp[0]] / 2; - - if (sp[1] != 2 || (sdna->pointer_size != 4 && sdna->pointer_size != 8)) { - *r_error_message = "ListBase struct error! Needs it to calculate pointerize."; - /* well, at least sizeof(ListBase) is error proof! (ton) */ - return false; - } - } - - /* Cache name size. */ - { - short *names_array_len = MEM_mallocN(sizeof(*names_array_len) * sdna->nr_names, __func__); - for (int i = 0; i < sdna->nr_names; i++) { - names_array_len[i] = DNA_elem_array_size(sdna->names[i]); - } - sdna->names_array_len = names_array_len; - } - - return true; + /* Calculate 'sdna->pointer_size' */ + { + const int nr = DNA_struct_find_nr(sdna, "ListBase"); + + /* should never happen, only with corrupt file for example */ + if (UNLIKELY(nr == -1)) { + *r_error_message = "ListBase struct error! Not found."; + return false; + } + + /* finally pointer_size: use struct ListBase to test it, never change the size of it! */ + sp = sdna->structs[nr]; + /* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */ + + sdna->pointer_size = sdna->types_size[sp[0]] / 2; + + if (sp[1] != 2 || (sdna->pointer_size != 4 && sdna->pointer_size != 8)) { + *r_error_message = "ListBase struct error! Needs it to calculate pointerize."; + /* well, at least sizeof(ListBase) is error proof! (ton) */ + return false; + } + } + + /* Cache name size. */ + { + short *names_array_len = MEM_mallocN(sizeof(*names_array_len) * sdna->nr_names, __func__); + for (int i = 0; i < sdna->nr_names; i++) { + names_array_len[i] = DNA_elem_array_size(sdna->names[i]); + } + sdna->names_array_len = names_array_len; + } + + return true; } /** * Constructs and returns a decoded SDNA structure from the given encoded SDNA data block. */ -SDNA *DNA_sdna_from_data( - const void *data, const int data_len, - bool do_endian_swap, bool data_alloc, - const char **r_error_message) +SDNA *DNA_sdna_from_data(const void *data, + const int data_len, + bool do_endian_swap, + bool data_alloc, + const char **r_error_message) { - SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna"); - const char *error_message = NULL; - - sdna->data_len = data_len; - if (data_alloc) { - char *data_copy = MEM_mallocN(data_len, "sdna_data"); - memcpy(data_copy, data, data_len); - sdna->data = data_copy; - } - else { - sdna->data = data; - } - sdna->data_alloc = data_alloc; - - - if (init_structDNA(sdna, do_endian_swap, &error_message)) { - return sdna; - } - else { - if (r_error_message == NULL) { - fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message); - } - else { - *r_error_message = error_message; - } - DNA_sdna_free(sdna); - return NULL; - } + SDNA *sdna = MEM_mallocN(sizeof(*sdna), "sdna"); + const char *error_message = NULL; + + sdna->data_len = data_len; + if (data_alloc) { + char *data_copy = MEM_mallocN(data_len, "sdna_data"); + memcpy(data_copy, data, data_len); + sdna->data = data_copy; + } + else { + sdna->data = data; + } + sdna->data_alloc = data_alloc; + + if (init_structDNA(sdna, do_endian_swap, &error_message)) { + return sdna; + } + else { + if (r_error_message == NULL) { + fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message); + } + else { + *r_error_message = error_message; + } + DNA_sdna_free(sdna); + return NULL; + } } /** @@ -555,19 +551,19 @@ static SDNA *g_sdna = NULL; void DNA_sdna_current_init(void) { - g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL); + g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL); } const struct SDNA *DNA_sdna_current_get(void) { - BLI_assert(g_sdna != NULL); - return g_sdna; + BLI_assert(g_sdna != NULL); + return g_sdna; } void DNA_sdna_current_free(void) { - DNA_sdna_free(g_sdna); - g_sdna = NULL; + DNA_sdna_free(g_sdna); + g_sdna = NULL; } /* ******************** END READ DNA ********************** */ @@ -580,138 +576,135 @@ void DNA_sdna_current_free(void) */ static void recurs_test_compflags(const SDNA *sdna, char *compflags, int structnr) { - int a, b, typenr, elems; - const short *sp; - const char *cp; - - /* check all structs, test if it's inside another struct */ - sp = sdna->structs[structnr]; - typenr = sp[0]; - - for (a = 0; a < sdna->nr_structs; a++) { - if ((a != structnr) && (compflags[a] == SDNA_CMP_EQUAL)) { - sp = sdna->structs[a]; - elems = sp[1]; - sp += 2; - for (b = 0; b < elems; b++, sp += 2) { - if (sp[0] == typenr) { - cp = sdna->names[sp[1]]; - if (!ispointer(cp)) { - compflags[a] = SDNA_CMP_NOT_EQUAL; - recurs_test_compflags(sdna, compflags, a); - } - } - } - } - } - + int a, b, typenr, elems; + const short *sp; + const char *cp; + + /* check all structs, test if it's inside another struct */ + sp = sdna->structs[structnr]; + typenr = sp[0]; + + for (a = 0; a < sdna->nr_structs; a++) { + if ((a != structnr) && (compflags[a] == SDNA_CMP_EQUAL)) { + sp = sdna->structs[a]; + elems = sp[1]; + sp += 2; + for (b = 0; b < elems; b++, sp += 2) { + if (sp[0] == typenr) { + cp = sdna->names[sp[1]]; + if (!ispointer(cp)) { + compflags[a] = SDNA_CMP_NOT_EQUAL; + recurs_test_compflags(sdna, compflags, a); + } + } + } + } + } } - /** * Constructs and returns an array of byte flags with one element for each struct in oldsdna, * indicating how it compares to newsdna: */ const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna) { - int a, b; - const short *sp_old, *sp_new; - const char *str1, *str2; - char *compflags; - - if (oldsdna->nr_structs == 0) { - printf("error: file without SDNA\n"); - return NULL; - } - - compflags = MEM_callocN(oldsdna->nr_structs, "compflags"); - - /* we check all structs in 'oldsdna' and compare them with - * the structs in 'newsdna' - */ - unsigned int newsdna_index_last = 0; - - for (a = 0; a < oldsdna->nr_structs; a++) { - sp_old = oldsdna->structs[a]; - - /* search for type in cur */ - int sp_new_index = DNA_struct_find_nr_ex(newsdna, oldsdna->types[sp_old[0]], &newsdna_index_last); - - /* The next indices will almost always match */ - newsdna_index_last++; - - if (sp_new_index != -1) { - sp_new = newsdna->structs[sp_new_index]; - /* initial assumption */ - compflags[a] = SDNA_CMP_NOT_EQUAL; - - /* compare length and amount of elems */ - if (sp_new[1] == sp_old[1]) { - if (newsdna->types_size[sp_new[0]] == oldsdna->types_size[sp_old[0]]) { - - /* same length, same amount of elems, now per type and name */ - b = sp_old[1]; - sp_old += 2; - sp_new += 2; - while (b > 0) { - str1 = newsdna->types[sp_new[0]]; - str2 = oldsdna->types[sp_old[0]]; - if (strcmp(str1, str2) != 0) { - break; - } - - str1 = newsdna->names[sp_new[1]]; - str2 = oldsdna->names[sp_old[1]]; - if (strcmp(str1, str2) != 0) { - break; - } - - /* same type and same name, now pointersize */ - if (ispointer(str1)) { - if (oldsdna->pointer_size != newsdna->pointer_size) { - break; - } - } - - b--; - sp_old += 2; - sp_new += 2; - } - if (b == 0) { - /* no differences found */ - compflags[a] = SDNA_CMP_EQUAL; - } - - } - } - - } - } - - /* first struct in util.h is struct Link, this is skipped in compflags (als # 0). - * was a bug, and this way dirty patched! Solve this later.... - */ - compflags[0] = SDNA_CMP_EQUAL; - - /* Because structs can be inside structs, we recursively - * set flags when a struct is altered - */ - for (a = 0; a < oldsdna->nr_structs; a++) { - if (compflags[a] == SDNA_CMP_NOT_EQUAL) { - recurs_test_compflags(oldsdna, compflags, a); - } - } + int a, b; + const short *sp_old, *sp_new; + const char *str1, *str2; + char *compflags; + + if (oldsdna->nr_structs == 0) { + printf("error: file without SDNA\n"); + return NULL; + } + + compflags = MEM_callocN(oldsdna->nr_structs, "compflags"); + + /* we check all structs in 'oldsdna' and compare them with + * the structs in 'newsdna' + */ + unsigned int newsdna_index_last = 0; + + for (a = 0; a < oldsdna->nr_structs; a++) { + sp_old = oldsdna->structs[a]; + + /* search for type in cur */ + int sp_new_index = DNA_struct_find_nr_ex( + newsdna, oldsdna->types[sp_old[0]], &newsdna_index_last); + + /* The next indices will almost always match */ + newsdna_index_last++; + + if (sp_new_index != -1) { + sp_new = newsdna->structs[sp_new_index]; + /* initial assumption */ + compflags[a] = SDNA_CMP_NOT_EQUAL; + + /* compare length and amount of elems */ + if (sp_new[1] == sp_old[1]) { + if (newsdna->types_size[sp_new[0]] == oldsdna->types_size[sp_old[0]]) { + + /* same length, same amount of elems, now per type and name */ + b = sp_old[1]; + sp_old += 2; + sp_new += 2; + while (b > 0) { + str1 = newsdna->types[sp_new[0]]; + str2 = oldsdna->types[sp_old[0]]; + if (strcmp(str1, str2) != 0) { + break; + } + + str1 = newsdna->names[sp_new[1]]; + str2 = oldsdna->names[sp_old[1]]; + if (strcmp(str1, str2) != 0) { + break; + } + + /* same type and same name, now pointersize */ + if (ispointer(str1)) { + if (oldsdna->pointer_size != newsdna->pointer_size) { + break; + } + } + + b--; + sp_old += 2; + sp_new += 2; + } + if (b == 0) { + /* no differences found */ + compflags[a] = SDNA_CMP_EQUAL; + } + } + } + } + } + + /* first struct in util.h is struct Link, this is skipped in compflags (als # 0). + * was a bug, and this way dirty patched! Solve this later.... + */ + compflags[0] = SDNA_CMP_EQUAL; + + /* Because structs can be inside structs, we recursively + * set flags when a struct is altered + */ + for (a = 0; a < oldsdna->nr_structs; a++) { + if (compflags[a] == SDNA_CMP_NOT_EQUAL) { + recurs_test_compflags(oldsdna, compflags, a); + } + } #if 0 - for (a = 0; a < oldsdna->nr_structs; a++) { - if (compflags[a] == SDNA_CMP_NOT_EQUAL) { - spold = oldsdna->structs[a]; - printf("changed: %s\n", oldsdna->types[spold[0]]); - } - } + for (a = 0; a < oldsdna->nr_structs; a++) { + if (compflags[a] == SDNA_CMP_NOT_EQUAL) { + spold = oldsdna->structs[a]; + printf("changed: %s\n", oldsdna->types[spold[0]]); + } + } #endif - return compflags; + return compflags; } /** @@ -719,17 +712,37 @@ const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna */ static eSDNA_Type sdna_type_nr(const char *dna_type) { - if (STR_ELEM(dna_type, "char", "const char")) { return SDNA_TYPE_CHAR; } - else if (STR_ELEM(dna_type, "uchar", "unsigned char")) { return SDNA_TYPE_UCHAR; } - else if (STR_ELEM(dna_type, "short")) { return SDNA_TYPE_SHORT; } - else if (STR_ELEM(dna_type, "ushort", "unsigned short")) { return SDNA_TYPE_USHORT; } - else if (STR_ELEM(dna_type, "int")) { return SDNA_TYPE_INT; } - else if (STR_ELEM(dna_type, "float")) { return SDNA_TYPE_FLOAT; } - else if (STR_ELEM(dna_type, "double")) { return SDNA_TYPE_DOUBLE; } - else if (STR_ELEM(dna_type, "int64_t")) { return SDNA_TYPE_INT64; } - else if (STR_ELEM(dna_type, "uint64_t")) { return SDNA_TYPE_UINT64; } - /* invalid! */ - else { return -1; } + if (STR_ELEM(dna_type, "char", "const char")) { + return SDNA_TYPE_CHAR; + } + else if (STR_ELEM(dna_type, "uchar", "unsigned char")) { + return SDNA_TYPE_UCHAR; + } + else if (STR_ELEM(dna_type, "short")) { + return SDNA_TYPE_SHORT; + } + else if (STR_ELEM(dna_type, "ushort", "unsigned short")) { + return SDNA_TYPE_USHORT; + } + else if (STR_ELEM(dna_type, "int")) { + return SDNA_TYPE_INT; + } + else if (STR_ELEM(dna_type, "float")) { + return SDNA_TYPE_FLOAT; + } + else if (STR_ELEM(dna_type, "double")) { + return SDNA_TYPE_DOUBLE; + } + else if (STR_ELEM(dna_type, "int64_t")) { + return SDNA_TYPE_INT64; + } + else if (STR_ELEM(dna_type, "uint64_t")) { + return SDNA_TYPE_UINT64; + } + /* invalid! */ + else { + return -1; + } } /** @@ -744,77 +757,92 @@ static eSDNA_Type sdna_type_nr(const char *dna_type) * \param olddata: Data of type otype to convert */ static void cast_elem( - const char *ctype, const char *otype, int name_array_len, - char *curdata, const char *olddata) + const char *ctype, const char *otype, int name_array_len, char *curdata, const char *olddata) { - double val = 0.0; - int curlen = 1, oldlen = 1; - - eSDNA_Type ctypenr, otypenr; - - if ( (otypenr = sdna_type_nr(otype)) == -1 || - (ctypenr = sdna_type_nr(ctype)) == -1) - { - return; - } - - /* define lengths */ - oldlen = DNA_elem_type_size(otypenr); - curlen = DNA_elem_type_size(ctypenr); - - while (name_array_len > 0) { - switch (otypenr) { - case SDNA_TYPE_CHAR: - val = *olddata; break; - case SDNA_TYPE_UCHAR: - val = *( (unsigned char *)olddata); break; - case SDNA_TYPE_SHORT: - val = *( (short *)olddata); break; - case SDNA_TYPE_USHORT: - val = *( (unsigned short *)olddata); break; - case SDNA_TYPE_INT: - val = *( (int *)olddata); break; - case SDNA_TYPE_FLOAT: - val = *( (float *)olddata); break; - case SDNA_TYPE_DOUBLE: - val = *( (double *)olddata); break; - case SDNA_TYPE_INT64: - val = *( (int64_t *)olddata); break; - case SDNA_TYPE_UINT64: - val = *( (uint64_t *)olddata); break; - } - - switch (ctypenr) { - case SDNA_TYPE_CHAR: - *curdata = val; break; - case SDNA_TYPE_UCHAR: - *( (unsigned char *)curdata) = val; break; - case SDNA_TYPE_SHORT: - *( (short *)curdata) = val; break; - case SDNA_TYPE_USHORT: - *( (unsigned short *)curdata) = val; break; - case SDNA_TYPE_INT: - *( (int *)curdata) = val; break; - case SDNA_TYPE_FLOAT: - if (otypenr < 2) { - val /= 255; - } - *( (float *)curdata) = val; break; - case SDNA_TYPE_DOUBLE: - if (otypenr < 2) { - val /= 255; - } - *( (double *)curdata) = val; break; - case SDNA_TYPE_INT64: - *( (int64_t *)curdata) = val; break; - case SDNA_TYPE_UINT64: - *( (uint64_t *)curdata) = val; break; - } - - olddata += oldlen; - curdata += curlen; - name_array_len--; - } + double val = 0.0; + int curlen = 1, oldlen = 1; + + eSDNA_Type ctypenr, otypenr; + + if ((otypenr = sdna_type_nr(otype)) == -1 || (ctypenr = sdna_type_nr(ctype)) == -1) { + return; + } + + /* define lengths */ + oldlen = DNA_elem_type_size(otypenr); + curlen = DNA_elem_type_size(ctypenr); + + while (name_array_len > 0) { + switch (otypenr) { + case SDNA_TYPE_CHAR: + val = *olddata; + break; + case SDNA_TYPE_UCHAR: + val = *((unsigned char *)olddata); + break; + case SDNA_TYPE_SHORT: + val = *((short *)olddata); + break; + case SDNA_TYPE_USHORT: + val = *((unsigned short *)olddata); + break; + case SDNA_TYPE_INT: + val = *((int *)olddata); + break; + case SDNA_TYPE_FLOAT: + val = *((float *)olddata); + break; + case SDNA_TYPE_DOUBLE: + val = *((double *)olddata); + break; + case SDNA_TYPE_INT64: + val = *((int64_t *)olddata); + break; + case SDNA_TYPE_UINT64: + val = *((uint64_t *)olddata); + break; + } + + switch (ctypenr) { + case SDNA_TYPE_CHAR: + *curdata = val; + break; + case SDNA_TYPE_UCHAR: + *((unsigned char *)curdata) = val; + break; + case SDNA_TYPE_SHORT: + *((short *)curdata) = val; + break; + case SDNA_TYPE_USHORT: + *((unsigned short *)curdata) = val; + break; + case SDNA_TYPE_INT: + *((int *)curdata) = val; + break; + case SDNA_TYPE_FLOAT: + if (otypenr < 2) { + val /= 255; + } + *((float *)curdata) = val; + break; + case SDNA_TYPE_DOUBLE: + if (otypenr < 2) { + val /= 255; + } + *((double *)curdata) = val; + break; + case SDNA_TYPE_INT64: + *((int64_t *)curdata) = val; + break; + case SDNA_TYPE_UINT64: + *((uint64_t *)curdata) = val; + break; + } + + olddata += oldlen; + curdata += curlen; + name_array_len--; + } } /** @@ -828,36 +856,36 @@ static void cast_elem( * \param curdata: Where to put converted data * \param olddata: Data to convert */ -static void cast_pointer(int curlen, int oldlen, int name_array_len, char *curdata, const char *olddata) +static void cast_pointer( + int curlen, int oldlen, int name_array_len, char *curdata, const char *olddata) { - int64_t lval; - - while (name_array_len > 0) { - - if (curlen == oldlen) { - memcpy(curdata, olddata, curlen); - } - else if (curlen == 4 && oldlen == 8) { - lval = *((int64_t *)olddata); - - /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender, - * pointers may lose uniqueness on truncation! (Hopefully this wont - * happen unless/until we ever get to multi-gigabyte .blend files...) */ - *((int *)curdata) = lval >> 3; - } - else if (curlen == 8 && oldlen == 4) { - *((int64_t *)curdata) = *((int *)olddata); - } - else { - /* for debug */ - printf("errpr: illegal pointersize!\n"); - } - - olddata += oldlen; - curdata += curlen; - name_array_len--; - - } + int64_t lval; + + while (name_array_len > 0) { + + if (curlen == oldlen) { + memcpy(curdata, olddata, curlen); + } + else if (curlen == 4 && oldlen == 8) { + lval = *((int64_t *)olddata); + + /* WARNING: 32-bit Blender trying to load file saved by 64-bit Blender, + * pointers may lose uniqueness on truncation! (Hopefully this wont + * happen unless/until we ever get to multi-gigabyte .blend files...) */ + *((int *)curdata) = lval >> 3; + } + else if (curlen == 8 && oldlen == 4) { + *((int64_t *)curdata) = *((int *)olddata); + } + else { + /* for debug */ + printf("errpr: illegal pointersize!\n"); + } + + olddata += oldlen; + curdata += curlen; + name_array_len--; + } } /** @@ -865,21 +893,21 @@ static void cast_pointer(int curlen, int oldlen, int name_array_len, char *curda */ static int elem_strcmp(const char *name, const char *oname) { - int a = 0; - - while (1) { - if (name[a] != oname[a]) { - return 1; - } - if (name[a] == '[' || oname[a] == '[') { - break; - } - if (name[a] == 0 || oname[a] == 0) { - break; - } - a++; - } - return 0; + int a = 0; + + while (1) { + if (name[a] != oname[a]) { + return 1; + } + if (name[a] == '[' || oname[a] == '[') { + break; + } + if (name[a] == 0 || oname[a] == 0) { + break; + } + a++; + } + return 0; } /** @@ -892,27 +920,23 @@ static int elem_strcmp(const char *name, const char *oname) * \param old: Pointer to struct information in sdna * \return true when existing, false otherwise. */ -static bool elem_exists( - const SDNA *sdna, - const char *type, - const char *name, - const short *old) +static bool elem_exists(const SDNA *sdna, const char *type, const char *name, const short *old) { - int a, elemcount; - const char *otype, *oname; - - /* in old is the old struct */ - elemcount = old[1]; - old += 2; - for (a = 0; a < elemcount; a++, old += 2) { - otype = sdna->types[old[0]]; - oname = sdna->names[old[1]]; - - if (elem_strcmp(name, oname) == 0) { /* name equal */ - return strcmp(type, otype) == 0; /* type equal */ - } - } - return false; + int a, elemcount; + const char *otype, *oname; + + /* in old is the old struct */ + elemcount = old[1]; + old += 2; + for (a = 0; a < elemcount; a++, old += 2) { + otype = sdna->types[old[0]]; + oname = sdna->names[old[1]]; + + if (elem_strcmp(name, oname) == 0) { /* name equal */ + return strcmp(type, otype) == 0; /* type equal */ + } + } + return false; } /** @@ -932,43 +956,42 @@ static bool elem_exists( * \param sppo: Optional place to return pointer to field info in sdna * \return Data address. */ -static const char *find_elem( - const SDNA *sdna, - const char *type, - const char *name, - const short *old, - const char *olddata, - const short **sppo) +static const char *find_elem(const SDNA *sdna, + const char *type, + const char *name, + const short *old, + const char *olddata, + const short **sppo) { - int a, elemcount, len; - const char *otype, *oname; + int a, elemcount, len; + const char *otype, *oname; - /* without arraypart, so names can differ: return old namenr and type */ + /* without arraypart, so names can differ: return old namenr and type */ - /* in old is the old struct */ - elemcount = old[1]; - old += 2; - for (a = 0; a < elemcount; a++, old += 2) { + /* in old is the old struct */ + elemcount = old[1]; + old += 2; + for (a = 0; a < elemcount; a++, old += 2) { - otype = sdna->types[old[0]]; - oname = sdna->names[old[1]]; + otype = sdna->types[old[0]]; + oname = sdna->names[old[1]]; - len = elementsize(sdna, old[0], old[1]); + len = elementsize(sdna, old[0], old[1]); - if (elem_strcmp(name, oname) == 0) { /* name equal */ - if (strcmp(type, otype) == 0) { /* type equal */ - if (sppo) { - *sppo = old; - } - return olddata; - } + if (elem_strcmp(name, oname) == 0) { /* name equal */ + if (strcmp(type, otype) == 0) { /* type equal */ + if (sppo) { + *sppo = old; + } + return olddata; + } - return NULL; - } + return NULL; + } - olddata += len; - } - return NULL; + olddata += len; + } + return NULL; } /** @@ -983,100 +1006,97 @@ static const char *find_elem( * \param old: pointer to struct info in oldsdna * \param olddata: struct contents laid out according to oldsdna */ -static void reconstruct_elem( - const SDNA *newsdna, - const SDNA *oldsdna, - const char *type, - const int new_name_nr, - char *curdata, - const short *old, - const char *olddata) +static void reconstruct_elem(const SDNA *newsdna, + const SDNA *oldsdna, + const char *type, + const int new_name_nr, + char *curdata, + const short *old, + const char *olddata) { - /* rules: test for NAME: - * - name equal: - * - cast type - * - name partially equal (array differs) - * - type equal: memcpy - * - types casten - * (nzc 2-4-2001 I want the 'unsigned' bit to be parsed as well. Where - * can I force this?) - */ - int a, elemcount, len, countpos, mul; - const char *otype, *oname, *cp; - - /* is 'name' an array? */ - const char *name = newsdna->names[new_name_nr]; - cp = name; - countpos = 0; - while (*cp && *cp != '[') { - cp++; countpos++; - } - if (*cp != '[') { - countpos = 0; - } - - /* in old is the old struct */ - elemcount = old[1]; - old += 2; - for (a = 0; a < elemcount; a++, old += 2) { - const int old_name_nr = old[1]; - otype = oldsdna->types[old[0]]; - oname = oldsdna->names[old[1]]; - len = elementsize(oldsdna, old[0], old[1]); - - if (strcmp(name, oname) == 0) { /* name equal */ - - if (ispointer(name)) { /* pointer of functionpointer afhandelen */ - cast_pointer(newsdna->pointer_size, oldsdna->pointer_size, - newsdna->names_array_len[new_name_nr], - curdata, olddata); - } - else if (strcmp(type, otype) == 0) { /* type equal */ - memcpy(curdata, olddata, len); - } - else { - cast_elem(type, otype, - newsdna->names_array_len[new_name_nr], - curdata, olddata); - } - - return; - } - else if (countpos != 0) { /* name is an array */ - - if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) { /* basis equal */ - const int new_name_array_len = newsdna->names_array_len[new_name_nr]; - const int old_name_array_len = oldsdna->names_array_len[old_name_nr]; - const int min_name_array_len = MIN2(new_name_array_len, old_name_array_len); - - if (ispointer(name)) { /* handle pointer or functionpointer */ - cast_pointer(newsdna->pointer_size, oldsdna->pointer_size, - min_name_array_len, - curdata, olddata); - } - else if (strcmp(type, otype) == 0) { /* type equal */ - /* size of single old array element */ - mul = len / old_name_array_len; - /* smaller of sizes of old and new arrays */ - mul *= min_name_array_len; - - memcpy(curdata, olddata, mul); - - if (old_name_array_len > new_name_array_len && strcmp(type, "char") == 0) { - /* string had to be truncated, ensure it's still null-terminated */ - curdata[mul - 1] = '\0'; - } - } - else { - cast_elem(type, otype, - min_name_array_len, - curdata, olddata); - } - return; - } - } - olddata += len; - } + /* rules: test for NAME: + * - name equal: + * - cast type + * - name partially equal (array differs) + * - type equal: memcpy + * - types casten + * (nzc 2-4-2001 I want the 'unsigned' bit to be parsed as well. Where + * can I force this?) + */ + int a, elemcount, len, countpos, mul; + const char *otype, *oname, *cp; + + /* is 'name' an array? */ + const char *name = newsdna->names[new_name_nr]; + cp = name; + countpos = 0; + while (*cp && *cp != '[') { + cp++; + countpos++; + } + if (*cp != '[') { + countpos = 0; + } + + /* in old is the old struct */ + elemcount = old[1]; + old += 2; + for (a = 0; a < elemcount; a++, old += 2) { + const int old_name_nr = old[1]; + otype = oldsdna->types[old[0]]; + oname = oldsdna->names[old[1]]; + len = elementsize(oldsdna, old[0], old[1]); + + if (strcmp(name, oname) == 0) { /* name equal */ + + if (ispointer(name)) { /* pointer of functionpointer afhandelen */ + cast_pointer(newsdna->pointer_size, + oldsdna->pointer_size, + newsdna->names_array_len[new_name_nr], + curdata, + olddata); + } + else if (strcmp(type, otype) == 0) { /* type equal */ + memcpy(curdata, olddata, len); + } + else { + cast_elem(type, otype, newsdna->names_array_len[new_name_nr], curdata, olddata); + } + + return; + } + else if (countpos != 0) { /* name is an array */ + + if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) { /* basis equal */ + const int new_name_array_len = newsdna->names_array_len[new_name_nr]; + const int old_name_array_len = oldsdna->names_array_len[old_name_nr]; + const int min_name_array_len = MIN2(new_name_array_len, old_name_array_len); + + if (ispointer(name)) { /* handle pointer or functionpointer */ + cast_pointer( + newsdna->pointer_size, oldsdna->pointer_size, min_name_array_len, curdata, olddata); + } + else if (strcmp(type, otype) == 0) { /* type equal */ + /* size of single old array element */ + mul = len / old_name_array_len; + /* smaller of sizes of old and new arrays */ + mul *= min_name_array_len; + + memcpy(curdata, olddata, mul); + + if (old_name_array_len > new_name_array_len && strcmp(type, "char") == 0) { + /* string had to be truncated, ensure it's still null-terminated */ + curdata[mul - 1] = '\0'; + } + } + else { + cast_elem(type, otype, min_name_array_len, curdata, olddata); + } + return; + } + } + olddata += len; + } } /** @@ -1092,109 +1112,107 @@ static void reconstruct_elem( * \param curSDNAnr: Index of current struct definition in newsdna * \param cur: Where to put converted struct contents */ -static void reconstruct_struct( - const SDNA *newsdna, - const SDNA *oldsdna, - const char *compflags, - - int oldSDNAnr, - const char *data, - int curSDNAnr, - char *cur) +static void reconstruct_struct(const SDNA *newsdna, + const SDNA *oldsdna, + const char *compflags, + + int oldSDNAnr, + const char *data, + int curSDNAnr, + char *cur) { - /* Recursive! - * Per element from cur_struct, read data from old_struct. - * If element is a struct, call recursive. - */ - int a, elemcount, elen, eleno, mul, mulo, firststructtypenr; - const short *spo, *spc, *sppo; - const char *type; - const char *cpo; - char *cpc; - const char *name; - - unsigned int oldsdna_index_last = UINT_MAX; - unsigned int cursdna_index_last = UINT_MAX; - - - if (oldSDNAnr == -1) { - return; - } - if (curSDNAnr == -1) { - return; - } - - if (compflags[oldSDNAnr] == SDNA_CMP_EQUAL) { - /* if recursive: test for equal */ - spo = oldsdna->structs[oldSDNAnr]; - elen = oldsdna->types_size[spo[0]]; - memcpy(cur, data, elen); - - return; - } - - firststructtypenr = *(newsdna->structs[0]); - - spo = oldsdna->structs[oldSDNAnr]; - spc = newsdna->structs[curSDNAnr]; - - elemcount = spc[1]; - - spc += 2; - cpc = cur; - for (a = 0; a < elemcount; a++, spc += 2) { /* convert each field */ - type = newsdna->types[spc[0]]; - name = newsdna->names[spc[1]]; - - elen = elementsize(newsdna, spc[0], spc[1]); - - /* Skip pad bytes which must start with '_pad', see makesdna.c 'is_name_legal'. - * for exact rules. Note that if we fail to skip a pad byte it's harmless, - * this just avoids unnecessary reconstruction. */ - if (name[0] == '_' || (name[0] == '*' && name[1] == '_')) { - cpc += elen; - } - else if (spc[0] >= firststructtypenr && !ispointer(name)) { - /* struct field type */ - - /* where does the old struct data start (and is there an old one?) */ - cpo = (char *)find_elem(oldsdna, type, name, spo, data, &sppo); - - if (cpo) { - oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); - curSDNAnr = DNA_struct_find_nr_ex(newsdna, type, &cursdna_index_last); - - /* array! */ - mul = newsdna->names_array_len[spc[1]]; - mulo = oldsdna->names_array_len[sppo[1]]; - - eleno = elementsize(oldsdna, sppo[0], sppo[1]); - - elen /= mul; - eleno /= mulo; - - while (mul--) { - reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc); - cpo += eleno; - cpc += elen; - - /* new struct array larger than old */ - mulo--; - if (mulo <= 0) { - break; - } - } - } - else { - cpc += elen; /* skip field no longer present */ - } - } - else { - /* non-struct field type */ - reconstruct_elem(newsdna, oldsdna, type, spc[1], cpc, spo, data); - cpc += elen; - } - } + /* Recursive! + * Per element from cur_struct, read data from old_struct. + * If element is a struct, call recursive. + */ + int a, elemcount, elen, eleno, mul, mulo, firststructtypenr; + const short *spo, *spc, *sppo; + const char *type; + const char *cpo; + char *cpc; + const char *name; + + unsigned int oldsdna_index_last = UINT_MAX; + unsigned int cursdna_index_last = UINT_MAX; + + if (oldSDNAnr == -1) { + return; + } + if (curSDNAnr == -1) { + return; + } + + if (compflags[oldSDNAnr] == SDNA_CMP_EQUAL) { + /* if recursive: test for equal */ + spo = oldsdna->structs[oldSDNAnr]; + elen = oldsdna->types_size[spo[0]]; + memcpy(cur, data, elen); + + return; + } + + firststructtypenr = *(newsdna->structs[0]); + + spo = oldsdna->structs[oldSDNAnr]; + spc = newsdna->structs[curSDNAnr]; + + elemcount = spc[1]; + + spc += 2; + cpc = cur; + for (a = 0; a < elemcount; a++, spc += 2) { /* convert each field */ + type = newsdna->types[spc[0]]; + name = newsdna->names[spc[1]]; + + elen = elementsize(newsdna, spc[0], spc[1]); + + /* Skip pad bytes which must start with '_pad', see makesdna.c 'is_name_legal'. + * for exact rules. Note that if we fail to skip a pad byte it's harmless, + * this just avoids unnecessary reconstruction. */ + if (name[0] == '_' || (name[0] == '*' && name[1] == '_')) { + cpc += elen; + } + else if (spc[0] >= firststructtypenr && !ispointer(name)) { + /* struct field type */ + + /* where does the old struct data start (and is there an old one?) */ + cpo = (char *)find_elem(oldsdna, type, name, spo, data, &sppo); + + if (cpo) { + oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); + curSDNAnr = DNA_struct_find_nr_ex(newsdna, type, &cursdna_index_last); + + /* array! */ + mul = newsdna->names_array_len[spc[1]]; + mulo = oldsdna->names_array_len[sppo[1]]; + + eleno = elementsize(oldsdna, sppo[0], sppo[1]); + + elen /= mul; + eleno /= mulo; + + while (mul--) { + reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc); + cpo += eleno; + cpc += elen; + + /* new struct array larger than old */ + mulo--; + if (mulo <= 0) { + break; + } + } + } + else { + cpc += elen; /* skip field no longer present */ + } + } + else { + /* non-struct field type */ + reconstruct_elem(newsdna, oldsdna, type, spc[1], cpc, spo, data); + cpc += elen; + } + } } /** @@ -1206,88 +1224,88 @@ static void reconstruct_struct( */ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data) { - /* Recursive! - * If element is a struct, call recursive. - */ - int a, mul, elemcount, elen, elena, firststructtypenr; - const short *spo, *spc; - char *cur; - const char *type, *name; - unsigned int oldsdna_index_last = UINT_MAX; - - if (oldSDNAnr == -1) { - return; - } - firststructtypenr = *(oldsdna->structs[0]); - - spo = spc = oldsdna->structs[oldSDNAnr]; - - elemcount = spo[1]; - - spc += 2; - cur = data; - - for (a = 0; a < elemcount; a++, spc += 2) { - type = oldsdna->types[spc[0]]; - name = oldsdna->names[spc[1]]; - const int old_name_array_len = oldsdna->names_array_len[spc[1]]; - - /* elementsize = including arraysize */ - elen = elementsize(oldsdna, spc[0], spc[1]); - - /* test: is type a struct? */ - if (spc[0] >= firststructtypenr && !ispointer(name)) { - /* struct field type */ - /* where does the old data start (is there one?) */ - char *cpo = (char *)find_elem(oldsdna, type, name, spo, data, NULL); - if (cpo) { - oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); - - mul = old_name_array_len; - elena = elen / mul; - - while (mul--) { - DNA_struct_switch_endian(oldsdna, oldSDNAnr, cpo); - cpo += elena; - } - } - } - else { - /* non-struct field type */ - if (ispointer(name)) { - if (oldsdna->pointer_size == 8) { - BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len); - } - } - else { - if (ELEM(spc[0], SDNA_TYPE_SHORT, SDNA_TYPE_USHORT)) { - - /* exception: variable called blocktype: derived from ID_ */ - bool skip = false; - if (name[0] == 'b' && name[1] == 'l') { - if (strcmp(name, "blocktype") == 0) { - skip = true; - } - } - - if (skip == false) { - BLI_endian_switch_int16_array((int16_t *)cur, old_name_array_len); - } - } - else if (ELEM(spc[0], SDNA_TYPE_INT, SDNA_TYPE_FLOAT)) { - /* note, intentionally ignore long/ulong here these could be 4 or 8 bits, - * but turns out we only used for runtime vars and - * only once for a struct type that's no longer used. */ - - BLI_endian_switch_int32_array((int32_t *)cur, old_name_array_len); - } - else if (ELEM(spc[0], SDNA_TYPE_INT64, SDNA_TYPE_UINT64, SDNA_TYPE_DOUBLE)) { - BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len); - } - } - } - cur += elen; - } + /* Recursive! + * If element is a struct, call recursive. + */ + int a, mul, elemcount, elen, elena, firststructtypenr; + const short *spo, *spc; + char *cur; + const char *type, *name; + unsigned int oldsdna_index_last = UINT_MAX; + + if (oldSDNAnr == -1) { + return; + } + firststructtypenr = *(oldsdna->structs[0]); + + spo = spc = oldsdna->structs[oldSDNAnr]; + + elemcount = spo[1]; + + spc += 2; + cur = data; + + for (a = 0; a < elemcount; a++, spc += 2) { + type = oldsdna->types[spc[0]]; + name = oldsdna->names[spc[1]]; + const int old_name_array_len = oldsdna->names_array_len[spc[1]]; + + /* elementsize = including arraysize */ + elen = elementsize(oldsdna, spc[0], spc[1]); + + /* test: is type a struct? */ + if (spc[0] >= firststructtypenr && !ispointer(name)) { + /* struct field type */ + /* where does the old data start (is there one?) */ + char *cpo = (char *)find_elem(oldsdna, type, name, spo, data, NULL); + if (cpo) { + oldSDNAnr = DNA_struct_find_nr_ex(oldsdna, type, &oldsdna_index_last); + + mul = old_name_array_len; + elena = elen / mul; + + while (mul--) { + DNA_struct_switch_endian(oldsdna, oldSDNAnr, cpo); + cpo += elena; + } + } + } + else { + /* non-struct field type */ + if (ispointer(name)) { + if (oldsdna->pointer_size == 8) { + BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len); + } + } + else { + if (ELEM(spc[0], SDNA_TYPE_SHORT, SDNA_TYPE_USHORT)) { + + /* exception: variable called blocktype: derived from ID_ */ + bool skip = false; + if (name[0] == 'b' && name[1] == 'l') { + if (strcmp(name, "blocktype") == 0) { + skip = true; + } + } + + if (skip == false) { + BLI_endian_switch_int16_array((int16_t *)cur, old_name_array_len); + } + } + else if (ELEM(spc[0], SDNA_TYPE_INT, SDNA_TYPE_FLOAT)) { + /* note, intentionally ignore long/ulong here these could be 4 or 8 bits, + * but turns out we only used for runtime vars and + * only once for a struct type that's no longer used. */ + + BLI_endian_switch_int32_array((int32_t *)cur, old_name_array_len); + } + else if (ELEM(spc[0], SDNA_TYPE_INT64, SDNA_TYPE_UINT64, SDNA_TYPE_DOUBLE)) { + BLI_endian_switch_int64_array((int64_t *)cur, old_name_array_len); + } + } + } + cur += elen; + } } /** @@ -1301,41 +1319,44 @@ void DNA_struct_switch_endian(const SDNA *oldsdna, int oldSDNAnr, char *data) * \param data: Array of struct data * \return An allocated reconstructed struct */ -void *DNA_struct_reconstruct( - const SDNA *newsdna, const SDNA *oldsdna, - const char *compflags, int oldSDNAnr, int blocks, const void *data) +void *DNA_struct_reconstruct(const SDNA *newsdna, + const SDNA *oldsdna, + const char *compflags, + int oldSDNAnr, + int blocks, + const void *data) { - int a, curSDNAnr, curlen = 0, oldlen; - const short *spo, *spc; - char *cur, *cpc; - const char *cpo; - const char *type; - - /* oldSDNAnr == structnr, we're looking for the corresponding 'cur' number */ - spo = oldsdna->structs[oldSDNAnr]; - type = oldsdna->types[spo[0]]; - oldlen = oldsdna->types_size[spo[0]]; - curSDNAnr = DNA_struct_find_nr(newsdna, type); - - /* init data and alloc */ - if (curSDNAnr != -1) { - spc = newsdna->structs[curSDNAnr]; - curlen = newsdna->types_size[spc[0]]; - } - if (curlen == 0) { - return NULL; - } - - cur = MEM_callocN(blocks * curlen, "reconstruct"); - cpc = cur; - cpo = data; - for (a = 0; a < blocks; a++) { - reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc); - cpc += curlen; - cpo += oldlen; - } - - return cur; + int a, curSDNAnr, curlen = 0, oldlen; + const short *spo, *spc; + char *cur, *cpc; + const char *cpo; + const char *type; + + /* oldSDNAnr == structnr, we're looking for the corresponding 'cur' number */ + spo = oldsdna->structs[oldSDNAnr]; + type = oldsdna->types[spo[0]]; + oldlen = oldsdna->types_size[spo[0]]; + curSDNAnr = DNA_struct_find_nr(newsdna, type); + + /* init data and alloc */ + if (curSDNAnr != -1) { + spc = newsdna->structs[curSDNAnr]; + curlen = newsdna->types_size[spc[0]]; + } + if (curlen == 0) { + return NULL; + } + + cur = MEM_callocN(blocks * curlen, "reconstruct"); + cpc = cur; + cpo = data; + for (a = 0; a < blocks; a++) { + reconstruct_struct(newsdna, oldsdna, compflags, oldSDNAnr, cpo, curSDNAnr, cpc); + cpc += curlen; + cpo += oldlen; + } + + return cur; } /** @@ -1344,149 +1365,156 @@ void *DNA_struct_reconstruct( */ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const char *name) { - const int SDNAnr = DNA_struct_find_nr(sdna, stype); - const short * const spo = sdna->structs[SDNAnr]; - const char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL); - BLI_assert(SDNAnr != -1); - return (int)((intptr_t)cp); + const int SDNAnr = DNA_struct_find_nr(sdna, stype); + const short *const spo = sdna->structs[SDNAnr]; + const char *const cp = find_elem(sdna, vartype, name, spo, NULL, NULL); + BLI_assert(SDNAnr != -1); + return (int)((intptr_t)cp); } bool DNA_struct_find(const SDNA *sdna, const char *stype) { - return DNA_struct_find_nr(sdna, stype) != -1; + return DNA_struct_find_nr(sdna, stype) != -1; } -bool DNA_struct_elem_find(const SDNA *sdna, const char *stype, const char *vartype, const char *name) +bool DNA_struct_elem_find(const SDNA *sdna, + const char *stype, + const char *vartype, + const char *name) { - const int SDNAnr = DNA_struct_find_nr(sdna, stype); + const int SDNAnr = DNA_struct_find_nr(sdna, stype); - if (SDNAnr != -1) { - const short * const spo = sdna->structs[SDNAnr]; - const bool found = elem_exists(sdna, vartype, name, spo); + if (SDNAnr != -1) { + const short *const spo = sdna->structs[SDNAnr]; + const bool found = elem_exists(sdna, vartype, name, spo); - if (found) { - return true; - } - } - return false; + if (found) { + return true; + } + } + return false; } - /** * Returns the size in bytes of a primitive type. */ int DNA_elem_type_size(const eSDNA_Type elem_nr) { - /* should contain all enum types */ - switch (elem_nr) { - case SDNA_TYPE_CHAR: - case SDNA_TYPE_UCHAR: - return 1; - case SDNA_TYPE_SHORT: - case SDNA_TYPE_USHORT: - return 2; - case SDNA_TYPE_INT: - case SDNA_TYPE_FLOAT: - return 4; - case SDNA_TYPE_DOUBLE: - case SDNA_TYPE_INT64: - case SDNA_TYPE_UINT64: - return 8; - } - - /* weak */ - return 8; + /* should contain all enum types */ + switch (elem_nr) { + case SDNA_TYPE_CHAR: + case SDNA_TYPE_UCHAR: + return 1; + case SDNA_TYPE_SHORT: + case SDNA_TYPE_USHORT: + return 2; + case SDNA_TYPE_INT: + case SDNA_TYPE_FLOAT: + return 4; + case SDNA_TYPE_DOUBLE: + case SDNA_TYPE_INT64: + case SDNA_TYPE_UINT64: + return 8; + } + + /* weak */ + return 8; } /* -------------------------------------------------------------------- */ /** \name Version Patch DNA * \{ */ -static bool DNA_sdna_patch_struct_nr( - SDNA *sdna, const int struct_name_old_nr, const char *struct_name_new) +static bool DNA_sdna_patch_struct_nr(SDNA *sdna, + const int struct_name_old_nr, + const char *struct_name_new) { - BLI_assert(DNA_struct_find_nr(DNA_sdna_current_get(), struct_name_new) != -1); - const short *sp = sdna->structs[struct_name_old_nr]; + BLI_assert(DNA_struct_find_nr(DNA_sdna_current_get(), struct_name_new) != -1); + const short *sp = sdna->structs[struct_name_old_nr]; #ifdef WITH_DNA_GHASH - BLI_ghash_remove(sdna->structs_map, (void *)sdna->types[sp[0]], NULL, NULL); - BLI_ghash_insert(sdna->structs_map, (void *)struct_name_new, POINTER_FROM_INT(struct_name_old_nr)); + BLI_ghash_remove(sdna->structs_map, (void *)sdna->types[sp[0]], NULL, NULL); + BLI_ghash_insert( + sdna->structs_map, (void *)struct_name_new, POINTER_FROM_INT(struct_name_old_nr)); #endif - sdna->types[sp[0]] = struct_name_new; - return true; + sdna->types[sp[0]] = struct_name_new; + return true; } /** * Rename a struct */ -bool DNA_sdna_patch_struct( - SDNA *sdna, const char *struct_name_old, const char *struct_name_new) +bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char *struct_name_new) { - const int struct_name_old_nr = DNA_struct_find_nr(sdna, struct_name_old); - if (struct_name_old_nr != -1) { - return DNA_sdna_patch_struct_nr(sdna, struct_name_old_nr, struct_name_new); - } - return false; + const int struct_name_old_nr = DNA_struct_find_nr(sdna, struct_name_old); + if (struct_name_old_nr != -1) { + return DNA_sdna_patch_struct_nr(sdna, struct_name_old_nr, struct_name_new); + } + return false; } /* Make public if called often with same struct (avoid duplicate look-ups). */ -static bool DNA_sdna_patch_struct_member_nr( - SDNA *sdna, const int struct_name_nr, const char *elem_old, const char *elem_new) +static bool DNA_sdna_patch_struct_member_nr(SDNA *sdna, + const int struct_name_nr, + const char *elem_old, + const char *elem_new) { - /* These names aren't handled here (it's not used). - * Ensure they are never used or we get out of sync arrays. */ - BLI_assert(sdna->alias.names == NULL); - const int elem_old_len = strlen(elem_old); - const int elem_new_len = strlen(elem_new); - BLI_assert(elem_new != NULL); - short *sp = sdna->structs[struct_name_nr]; - for (int elem_index = sp[1]; elem_index > 0; elem_index--, sp += 2) { - const char *elem_old_full = sdna->names[sp[1]]; - /* Start & end offsets in 'elem_old_full'. */ - uint elem_old_full_offset_start; - if (DNA_elem_id_match(elem_old, elem_old_len, elem_old_full, &elem_old_full_offset_start)) { - if (sdna->mem_arena == NULL) { - sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - } - const char *elem_new_full = DNA_elem_id_rename( - sdna->mem_arena, - elem_old, elem_old_len, - elem_new, elem_new_len, - elem_old_full, strlen(elem_old_full), - elem_old_full_offset_start); - - if (sdna->nr_names == sdna->nr_names_alloc) { - sdna->nr_names_alloc += 64; - sdna->names = MEM_recallocN( - sdna->names, sizeof(*sdna->names) * sdna->nr_names_alloc); - sdna->names_array_len = MEM_recallocN( - (void *)sdna->names_array_len, sizeof(*sdna->names_array_len) * sdna->nr_names_alloc); - } - const short name_nr_prev = sp[1]; - sp[1] = sdna->nr_names++; - sdna->names[sp[1]] = elem_new_full; - sdna->names_array_len[sp[1]] = sdna->names_array_len[name_nr_prev]; - - return true; - } - } - return false; + /* These names aren't handled here (it's not used). + * Ensure they are never used or we get out of sync arrays. */ + BLI_assert(sdna->alias.names == NULL); + const int elem_old_len = strlen(elem_old); + const int elem_new_len = strlen(elem_new); + BLI_assert(elem_new != NULL); + short *sp = sdna->structs[struct_name_nr]; + for (int elem_index = sp[1]; elem_index > 0; elem_index--, sp += 2) { + const char *elem_old_full = sdna->names[sp[1]]; + /* Start & end offsets in 'elem_old_full'. */ + uint elem_old_full_offset_start; + if (DNA_elem_id_match(elem_old, elem_old_len, elem_old_full, &elem_old_full_offset_start)) { + if (sdna->mem_arena == NULL) { + sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + } + const char *elem_new_full = DNA_elem_id_rename(sdna->mem_arena, + elem_old, + elem_old_len, + elem_new, + elem_new_len, + elem_old_full, + strlen(elem_old_full), + elem_old_full_offset_start); + + if (sdna->nr_names == sdna->nr_names_alloc) { + sdna->nr_names_alloc += 64; + sdna->names = MEM_recallocN(sdna->names, sizeof(*sdna->names) * sdna->nr_names_alloc); + sdna->names_array_len = MEM_recallocN( + (void *)sdna->names_array_len, sizeof(*sdna->names_array_len) * sdna->nr_names_alloc); + } + const short name_nr_prev = sp[1]; + sp[1] = sdna->nr_names++; + sdna->names[sp[1]] = elem_new_full; + sdna->names_array_len[sp[1]] = sdna->names_array_len[name_nr_prev]; + + return true; + } + } + return false; } /** * Replace \a elem_old with \a elem_new for struct \a struct_name * handles search & replace, maintaining surrounding non-identifier characters such as pointer & array size. */ -bool DNA_sdna_patch_struct_member( - SDNA *sdna, const char *struct_name, const char *elem_old, const char *elem_new) +bool DNA_sdna_patch_struct_member(SDNA *sdna, + const char *struct_name, + const char *elem_old, + const char *elem_new) { - const int struct_name_nr = DNA_struct_find_nr(sdna, struct_name); - if (struct_name_nr != -1) { - return DNA_sdna_patch_struct_member_nr(sdna, struct_name_nr, elem_old, elem_new); - } - return false; + const int struct_name_nr = DNA_struct_find_nr(sdna, struct_name); + if (struct_name_nr != -1) { + return DNA_sdna_patch_struct_member_nr(sdna, struct_name_nr, elem_old, elem_new); + } + return false; } /** \} */ - /* -------------------------------------------------------------------- */ /** \name Versioning (Forward Compatible) * @@ -1501,114 +1529,114 @@ bool DNA_sdna_patch_struct_member( */ static void sdna_expand_names(SDNA *sdna) { - int names_expand_len = 0; - for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { - const short *sp = sdna->structs[struct_nr]; - names_expand_len += sp[1]; - } - const char **names_expand = MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__); - - int names_expand_index = 0; - for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { - /* We can't edit this memory 'sdna->structs' points to (readonly datatoc file). */ - const short *sp = sdna->structs[struct_nr]; - short *sp_expand = BLI_memarena_alloc(sdna->mem_arena, sizeof(short[2]) * (1 + sp[1])); - memcpy(sp_expand, sp, sizeof(short[2]) * (1 + sp[1])); - sdna->structs[struct_nr] = sp_expand; - const int names_len = sp[1]; - sp += 2; - sp_expand += 2; - for (int i = 0; i < names_len; i++, sp += 2, sp_expand += 2) { - names_expand[names_expand_index] = sdna->names[sp[1]]; - BLI_assert(names_expand_index < SHRT_MAX); - sp_expand[1] = names_expand_index; - names_expand_index++; - } - } - MEM_freeN((void *)sdna->names); - sdna->names = names_expand; - sdna->nr_names = names_expand_len; + int names_expand_len = 0; + for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { + const short *sp = sdna->structs[struct_nr]; + names_expand_len += sp[1]; + } + const char **names_expand = MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__); + + int names_expand_index = 0; + for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { + /* We can't edit this memory 'sdna->structs' points to (readonly datatoc file). */ + const short *sp = sdna->structs[struct_nr]; + short *sp_expand = BLI_memarena_alloc(sdna->mem_arena, sizeof(short[2]) * (1 + sp[1])); + memcpy(sp_expand, sp, sizeof(short[2]) * (1 + sp[1])); + sdna->structs[struct_nr] = sp_expand; + const int names_len = sp[1]; + sp += 2; + sp_expand += 2; + for (int i = 0; i < names_len; i++, sp += 2, sp_expand += 2) { + names_expand[names_expand_index] = sdna->names[sp[1]]; + BLI_assert(names_expand_index < SHRT_MAX); + sp_expand[1] = names_expand_index; + names_expand_index++; + } + } + MEM_freeN((void *)sdna->names); + sdna->names = names_expand; + sdna->nr_names = names_expand_len; } -static const char *dna_sdna_alias_alias_from_static_elem_full( - SDNA *sdna, GHash *elem_map_alias_from_static, - const char *struct_name_static, const char *elem_static_full) +static const char *dna_sdna_alias_alias_from_static_elem_full(SDNA *sdna, + GHash *elem_map_alias_from_static, + const char *struct_name_static, + const char *elem_static_full) { - const int elem_static_full_len = strlen(elem_static_full); - char *elem_static = alloca(elem_static_full_len + 1); - const int elem_static_len = DNA_elem_id_strip_copy(elem_static, elem_static_full); - const char *str_pair[2] = {struct_name_static, elem_static}; - const char *elem_alias = BLI_ghash_lookup(elem_map_alias_from_static, str_pair); - if (elem_alias) { - return DNA_elem_id_rename( - sdna->mem_arena, - elem_static, elem_static_len, - elem_alias, strlen(elem_alias), - elem_static_full, elem_static_full_len, - DNA_elem_id_offset_start(elem_static_full)); - } - return NULL; + const int elem_static_full_len = strlen(elem_static_full); + char *elem_static = alloca(elem_static_full_len + 1); + const int elem_static_len = DNA_elem_id_strip_copy(elem_static, elem_static_full); + const char *str_pair[2] = {struct_name_static, elem_static}; + const char *elem_alias = BLI_ghash_lookup(elem_map_alias_from_static, str_pair); + if (elem_alias) { + return DNA_elem_id_rename(sdna->mem_arena, + elem_static, + elem_static_len, + elem_alias, + strlen(elem_alias), + elem_static_full, + elem_static_full_len, + DNA_elem_id_offset_start(elem_static_full)); + } + return NULL; } void DNA_sdna_alias_data_ensure(SDNA *sdna) { - /* We may want this to be optional later. */ - const bool use_legacy_hack = true; - - if (sdna->mem_arena == NULL) { - sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - } - - GHash *struct_map_alias_from_static; - GHash *elem_map_alias_from_static; - - DNA_alias_maps( - DNA_RENAME_ALIAS_FROM_STATIC, - &struct_map_alias_from_static, - &elem_map_alias_from_static); - - - if (sdna->alias.types == NULL) { - sdna->alias.types = MEM_mallocN(sizeof(*sdna->alias.types) * sdna->nr_types, __func__); - for (int type_nr = 0; type_nr < sdna->nr_types; type_nr++) { - const char *struct_name_static = sdna->types[type_nr]; - - if (use_legacy_hack) { - struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static); - } - - sdna->alias.types[type_nr] = BLI_ghash_lookup_default( - struct_map_alias_from_static, struct_name_static, (void *)struct_name_static); - } - } - - if (sdna->alias.names == NULL) { - sdna_expand_names(sdna); - sdna->alias.names = MEM_mallocN(sizeof(*sdna->alias.names) * sdna->nr_names, __func__); - for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { - const short *sp = sdna->structs[struct_nr]; - const char *struct_name_static = sdna->types[sp[0]]; - - if (use_legacy_hack) { - struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static); - } - - const int dna_struct_names_len = sp[1]; - sp += 2; - for (int a = 0; a < dna_struct_names_len; a++, sp += 2) { - const char *elem_alias_full = dna_sdna_alias_alias_from_static_elem_full( - sdna, elem_map_alias_from_static, struct_name_static, sdna->names[sp[1]]); - if (elem_alias_full != NULL) { - sdna->alias.names[sp[1]] = elem_alias_full; - } - else { - sdna->alias.names[sp[1]] = sdna->names[sp[1]]; - } - } - } - } - BLI_ghash_free(struct_map_alias_from_static, NULL, NULL); - BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL); + /* We may want this to be optional later. */ + const bool use_legacy_hack = true; + + if (sdna->mem_arena == NULL) { + sdna->mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + } + + GHash *struct_map_alias_from_static; + GHash *elem_map_alias_from_static; + + DNA_alias_maps( + DNA_RENAME_ALIAS_FROM_STATIC, &struct_map_alias_from_static, &elem_map_alias_from_static); + + if (sdna->alias.types == NULL) { + sdna->alias.types = MEM_mallocN(sizeof(*sdna->alias.types) * sdna->nr_types, __func__); + for (int type_nr = 0; type_nr < sdna->nr_types; type_nr++) { + const char *struct_name_static = sdna->types[type_nr]; + + if (use_legacy_hack) { + struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static); + } + + sdna->alias.types[type_nr] = BLI_ghash_lookup_default( + struct_map_alias_from_static, struct_name_static, (void *)struct_name_static); + } + } + + if (sdna->alias.names == NULL) { + sdna_expand_names(sdna); + sdna->alias.names = MEM_mallocN(sizeof(*sdna->alias.names) * sdna->nr_names, __func__); + for (int struct_nr = 0; struct_nr < sdna->nr_structs; struct_nr++) { + const short *sp = sdna->structs[struct_nr]; + const char *struct_name_static = sdna->types[sp[0]]; + + if (use_legacy_hack) { + struct_name_static = DNA_struct_rename_legacy_hack_alias_from_static(struct_name_static); + } + + const int dna_struct_names_len = sp[1]; + sp += 2; + for (int a = 0; a < dna_struct_names_len; a++, sp += 2) { + const char *elem_alias_full = dna_sdna_alias_alias_from_static_elem_full( + sdna, elem_map_alias_from_static, struct_name_static, sdna->names[sp[1]]); + if (elem_alias_full != NULL) { + sdna->alias.names[sp[1]] = elem_alias_full; + } + else { + sdna->alias.names[sp[1]] = sdna->names[sp[1]]; + } + } + } + } + BLI_ghash_free(struct_map_alias_from_static, NULL, NULL); + BLI_ghash_free(elem_map_alias_from_static, MEM_freeN, NULL); } /** \} */ |