diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/makesdna/intern | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/makesdna/intern')
-rw-r--r-- | source/blender/makesdna/intern/CMakeLists.txt | 92 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_genfile.c | 2300 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_utils.c | 369 | ||||
-rw-r--r-- | source/blender/makesdna/intern/dna_utils.h | 32 | ||||
-rw-r--r-- | source/blender/makesdna/intern/makesdna.c | 2414 |
5 files changed, 2644 insertions, 2563 deletions
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 94caab26e29..a5a98386347 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -23,32 +23,32 @@ add_definitions(-DWITH_DNA_GHASH) blender_include_dirs( - ../../../../intern/guardedalloc - ../../../../intern/atomic - ../../blenlib - .. + ../../../../intern/guardedalloc + ../../../../intern/atomic + ../../blenlib + .. ) # ----------------------------------------------------------------------------- # Build makesdna executable set(SRC - dna_utils.c - makesdna.c - ../../blenlib/intern/BLI_ghash.c - ../../blenlib/intern/BLI_ghash_utils.c - ../../blenlib/intern/BLI_memarena.c - ../../blenlib/intern/BLI_mempool.c - ../../blenlib/intern/hash_mm2a.c # needed by 'BLI_ghash_utils.c', not used directly. - ../../../../intern/guardedalloc/intern/mallocn.c - ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c - ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c + dna_utils.c + makesdna.c + ../../blenlib/intern/BLI_ghash.c + ../../blenlib/intern/BLI_ghash_utils.c + ../../blenlib/intern/BLI_memarena.c + ../../blenlib/intern/BLI_mempool.c + ../../blenlib/intern/hash_mm2a.c # needed by 'BLI_ghash_utils.c', not used directly. + ../../../../intern/guardedalloc/intern/mallocn.c + ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c + ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c ) if(WIN32 AND NOT UNIX) - list(APPEND SRC - ../../../../intern/guardedalloc/intern/mmap_win.c - ) + list(APPEND SRC + ../../../../intern/guardedalloc/intern/mmap_win.c + ) endif() # SRC_DNA_INC is defined in the parent dir @@ -60,17 +60,17 @@ add_executable(makesdna ${SRC} ${SRC_DNA_INC}) # Output dna.c add_custom_command( - OUTPUT - ${CMAKE_CURRENT_BINARY_DIR}/dna.c - ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h - ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c - COMMAND - "$<TARGET_FILE:makesdna>" - ${CMAKE_CURRENT_BINARY_DIR}/dna.c - ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h - ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c - ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ - DEPENDS makesdna + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/dna.c + ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h + ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c + COMMAND + "$<TARGET_FILE:makesdna>" + ${CMAKE_CURRENT_BINARY_DIR}/dna.c + ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h + ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c + ${CMAKE_SOURCE_DIR}/source/blender/makesdna/ + DEPENDS makesdna ) @@ -85,23 +85,23 @@ set(INC_SYS ) set(SRC - dna_genfile.c - dna_utils.c - ${CMAKE_CURRENT_BINARY_DIR}/dna.c - ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c - ${SRC_DNA_INC} + dna_genfile.c + dna_utils.c + ${CMAKE_CURRENT_BINARY_DIR}/dna.c + ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c + ${SRC_DNA_INC} - dna_utils.h + dna_utils.h ) set(LIB ) set_source_files_properties( - ${CMAKE_CURRENT_BINARY_DIR}/dna.c - ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h - ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c - PROPERTIES GENERATED TRUE + ${CMAKE_CURRENT_BINARY_DIR}/dna.c + ${CMAKE_CURRENT_BINARY_DIR}/dna_type_offsets.h + ${CMAKE_CURRENT_BINARY_DIR}/dna_verify.c + PROPERTIES GENERATED TRUE ) blender_add_lib(bf_dna "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") @@ -118,14 +118,14 @@ set(INC_SYS ) set(SRC - ../../blenlib/intern/BLI_ghash.c - ../../blenlib/intern/BLI_ghash_utils.c - ../../blenlib/intern/BLI_linklist.c - ../../blenlib/intern/BLI_memarena.c - ../../blenlib/intern/BLI_mempool.c - ../../blenlib/intern/endian_switch.c - ../../blenlib/intern/hash_mm2a.c - ../../blenlib/intern/listbase.c + ../../blenlib/intern/BLI_ghash.c + ../../blenlib/intern/BLI_ghash_utils.c + ../../blenlib/intern/BLI_linklist.c + ../../blenlib/intern/BLI_memarena.c + ../../blenlib/intern/BLI_mempool.c + ../../blenlib/intern/endian_switch.c + ../../blenlib/intern/hash_mm2a.c + ../../blenlib/intern/listbase.c ) set(LIB 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); } /** \} */ diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c index 30c82367a37..425deaf121f 100644 --- a/source/blender/makesdna/intern/dna_utils.c +++ b/source/blender/makesdna/intern/dna_utils.c @@ -45,35 +45,35 @@ */ int DNA_elem_array_size(const char *str) { - int result = 1; - int current = 0; - while (true) { - char c = *str++; - switch (c) { - case '\0': - return result; - case '[': - current = 0; - break; - case ']': - result *= current; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - current = current * 10 + (c - '0'); - break; - default: - break; - } - } + int result = 1; + int current = 0; + while (true) { + char c = *str++; + switch (c) { + case '\0': + return result; + case '[': + current = 0; + break; + case ']': + result *= current; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + current = current * 10 + (c - '0'); + break; + default: + break; + } + } } /** \} */ @@ -84,28 +84,26 @@ int DNA_elem_array_size(const char *str) static bool is_identifier(const char c) { - return ((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - (c == '_')); + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || + (c == '_')); } uint DNA_elem_id_offset_start(const char *elem_full) { - uint elem_full_offset = 0; - while (!is_identifier(elem_full[elem_full_offset])) { - elem_full_offset++; - } - return elem_full_offset; + uint elem_full_offset = 0; + while (!is_identifier(elem_full[elem_full_offset])) { + elem_full_offset++; + } + return elem_full_offset; } uint DNA_elem_id_offset_end(const char *elem_full) { - uint elem_full_offset = 0; - while (is_identifier(elem_full[elem_full_offset])) { - elem_full_offset++; - } - return elem_full_offset; + uint elem_full_offset = 0; + while (is_identifier(elem_full[elem_full_offset])) { + elem_full_offset++; + } + return elem_full_offset; } /** @@ -113,79 +111,81 @@ uint DNA_elem_id_offset_end(const char *elem_full) */ uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src) { - const uint elem_src_offset = DNA_elem_id_offset_start(elem_src); - const char *elem_src_trim = elem_src + elem_src_offset; - const uint elem_src_trim_len = DNA_elem_id_offset_end(elem_src_trim); - memcpy(elem_dst, elem_src_trim, elem_src_trim_len); - elem_dst[elem_src_trim_len] = '\0'; - return elem_src_trim_len; + const uint elem_src_offset = DNA_elem_id_offset_start(elem_src); + const char *elem_src_trim = elem_src + elem_src_offset; + const uint elem_src_trim_len = DNA_elem_id_offset_end(elem_src_trim); + memcpy(elem_dst, elem_src_trim, elem_src_trim_len); + elem_dst[elem_src_trim_len] = '\0'; + return elem_src_trim_len; } uint DNA_elem_id_strip(char *elem) { - const uint elem_offset = DNA_elem_id_offset_start(elem); - const char *elem_trim = elem + elem_offset; - const uint elem_trim_len = DNA_elem_id_offset_end(elem_trim); - memmove(elem, elem_trim, elem_trim_len); - elem[elem_trim_len] = '\0'; - return elem_trim_len; + const uint elem_offset = DNA_elem_id_offset_start(elem); + const char *elem_trim = elem + elem_offset; + const uint elem_trim_len = DNA_elem_id_offset_end(elem_trim); + memmove(elem, elem_trim, elem_trim_len); + elem[elem_trim_len] = '\0'; + return elem_trim_len; } /** * Check if 'var' matches '*var[3]' for eg, * return true if it does, with start/end offsets. */ -bool DNA_elem_id_match( - const char *elem_search, const int elem_search_len, - const char *elem_full, - uint *r_elem_full_offset) +bool DNA_elem_id_match(const char *elem_search, + const int elem_search_len, + const char *elem_full, + uint *r_elem_full_offset) { - BLI_assert(strlen(elem_search) == elem_search_len); - const uint elem_full_offset = DNA_elem_id_offset_start(elem_full); - const char *elem_full_trim = elem_full + elem_full_offset; - if (strncmp(elem_search, elem_full_trim, elem_search_len) == 0) { - const char c = elem_full_trim[elem_search_len]; - if (c == '\0' || !is_identifier(c)) { - *r_elem_full_offset = elem_full_offset; - return true; - } - } - return false; + BLI_assert(strlen(elem_search) == elem_search_len); + const uint elem_full_offset = DNA_elem_id_offset_start(elem_full); + const char *elem_full_trim = elem_full + elem_full_offset; + if (strncmp(elem_search, elem_full_trim, elem_search_len) == 0) { + const char c = elem_full_trim[elem_search_len]; + if (c == '\0' || !is_identifier(c)) { + *r_elem_full_offset = elem_full_offset; + return true; + } + } + return false; } /** * Return a renamed dna name, allocated from \a mem_arena. */ -char *DNA_elem_id_rename( - struct MemArena *mem_arena, - const char *elem_src, const int elem_src_len, - const char *elem_dst, const int elem_dst_len, - const char *elem_src_full, const int elem_src_full_len, - const uint elem_src_full_offset_len) +char *DNA_elem_id_rename(struct MemArena *mem_arena, + const char *elem_src, + const int elem_src_len, + const char *elem_dst, + const int elem_dst_len, + const char *elem_src_full, + const int elem_src_full_len, + const uint elem_src_full_offset_len) { - BLI_assert(strlen(elem_src) == elem_src_len); - BLI_assert(strlen(elem_dst) == elem_dst_len); - BLI_assert(strlen(elem_src_full) == elem_src_full_len); - BLI_assert(DNA_elem_id_offset_start(elem_src_full) == elem_src_full_offset_len); - UNUSED_VARS_NDEBUG(elem_src); - - const int elem_final_len = (elem_src_full_len - elem_src_len) + elem_dst_len; - char *elem_dst_full = BLI_memarena_alloc(mem_arena, elem_final_len + 1); - uint i = 0; - if (elem_src_full_offset_len != 0) { - memcpy(elem_dst_full, elem_src_full, elem_src_full_offset_len); - i = elem_src_full_offset_len; - } - memcpy(&elem_dst_full[i], elem_dst, elem_dst_len + 1); - i += elem_dst_len; - uint elem_src_full_offset_end = elem_src_full_offset_len + elem_src_len; - if (elem_src_full[elem_src_full_offset_end] != '\0') { - const int elem_full_tail_len = (elem_src_full_len - elem_src_full_offset_end); - memcpy(&elem_dst_full[i], &elem_src_full[elem_src_full_offset_end], elem_full_tail_len + 1); - i += elem_full_tail_len; - } - BLI_assert((strlen(elem_dst_full) == elem_final_len) && (i == elem_final_len)); - return elem_dst_full; + BLI_assert(strlen(elem_src) == elem_src_len); + BLI_assert(strlen(elem_dst) == elem_dst_len); + BLI_assert(strlen(elem_src_full) == elem_src_full_len); + BLI_assert(DNA_elem_id_offset_start(elem_src_full) == elem_src_full_offset_len); + UNUSED_VARS_NDEBUG(elem_src); + + const int elem_final_len = (elem_src_full_len - elem_src_len) + elem_dst_len; + char *elem_dst_full = BLI_memarena_alloc(mem_arena, elem_final_len + 1); + uint i = 0; + if (elem_src_full_offset_len != 0) { + memcpy(elem_dst_full, elem_src_full, elem_src_full_offset_len); + i = elem_src_full_offset_len; + } + memcpy(&elem_dst_full[i], elem_dst, elem_dst_len + 1); + i += elem_dst_len; + uint elem_src_full_offset_end = elem_src_full_offset_len + elem_src_len; + if (elem_src_full[elem_src_full_offset_end] != '\0') { + const int elem_full_tail_len = (elem_src_full_len - elem_src_full_offset_end); + memcpy(&elem_dst_full[i], &elem_src_full[elem_src_full_offset_end], elem_full_tail_len + 1); + i += elem_full_tail_len; + } + BLI_assert((strlen(elem_dst_full) == elem_final_len) && (i == elem_final_len)); + return elem_dst_full; } /** \} */ @@ -196,86 +196,83 @@ char *DNA_elem_id_rename( static uint strhash_pair_p(const void *ptr) { - const char * const *pair = ptr; - return (BLI_ghashutil_strhash_p(pair[0]) ^ - BLI_ghashutil_strhash_p(pair[1])); + const char *const *pair = ptr; + return (BLI_ghashutil_strhash_p(pair[0]) ^ BLI_ghashutil_strhash_p(pair[1])); } static bool strhash_pair_cmp(const void *a, const void *b) { - const char * const *pair_a = a; - const char * const *pair_b = b; - return (STREQ(pair_a[0], pair_b[0]) && - STREQ(pair_a[1], pair_b[1])) ? false : true; + const char *const *pair_a = a; + const char *const *pair_b = b; + return (STREQ(pair_a[0], pair_b[0]) && STREQ(pair_a[1], pair_b[1])) ? false : true; } -void DNA_alias_maps( - enum eDNA_RenameDir version_dir, - GHash **r_struct_map, GHash **r_elem_map) +void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash **r_elem_map) { - GHash *struct_map_local = NULL; - if (r_struct_map) { - const char *data[][2] = { + GHash *struct_map_local = NULL; + if (r_struct_map) { + const char *data[][2] = { #define DNA_STRUCT_RENAME(old, new) {#old, #new}, #define DNA_STRUCT_RENAME_ELEM(struct_name, old, new) #include "dna_rename_defs.h" #undef DNA_STRUCT_RENAME #undef DNA_STRUCT_RENAME_ELEM - }; - - int elem_key, elem_val; - if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) { - elem_key = 0; - elem_val = 1; - } - else { - elem_key = 1; - elem_val = 0; - } - GHash *struct_map = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data)); - for (int i = 0; i < ARRAY_SIZE(data); i++) { - BLI_ghash_insert(struct_map, (void *)data[i][elem_key], (void *)data[i][elem_val]); - } - *r_struct_map = struct_map; - - /* We know the direction of this, for local use. */ - struct_map_local = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data)); - for (int i = 0; i < ARRAY_SIZE(data); i++) { - BLI_ghash_insert(struct_map_local, (void *)data[i][1], (void *)data[i][0]); - } - } - - if (r_elem_map != NULL) { - const char *data[][3] = { + }; + + int elem_key, elem_val; + if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) { + elem_key = 0; + elem_val = 1; + } + else { + elem_key = 1; + elem_val = 0; + } + GHash *struct_map = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data)); + for (int i = 0; i < ARRAY_SIZE(data); i++) { + BLI_ghash_insert(struct_map, (void *)data[i][elem_key], (void *)data[i][elem_val]); + } + *r_struct_map = struct_map; + + /* We know the direction of this, for local use. */ + struct_map_local = BLI_ghash_str_new_ex(__func__, ARRAY_SIZE(data)); + for (int i = 0; i < ARRAY_SIZE(data); i++) { + BLI_ghash_insert(struct_map_local, (void *)data[i][1], (void *)data[i][0]); + } + } + + if (r_elem_map != NULL) { + const char *data[][3] = { #define DNA_STRUCT_RENAME(old, new) #define DNA_STRUCT_RENAME_ELEM(struct_name, old, new) {#struct_name, #old, #new}, #include "dna_rename_defs.h" #undef DNA_STRUCT_RENAME #undef DNA_STRUCT_RENAME_ELEM - }; - - int elem_key, elem_val; - if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) { - elem_key = 1; - elem_val = 2; - } - else { - elem_key = 2; - elem_val = 1; - } - GHash *elem_map = BLI_ghash_new_ex(strhash_pair_p, strhash_pair_cmp, __func__, ARRAY_SIZE(data)); - for (int i = 0; i < ARRAY_SIZE(data); i++) { - const char **str_pair = MEM_mallocN(sizeof(char *) * 2, __func__); - str_pair[0] = BLI_ghash_lookup_default(struct_map_local, data[i][0], (void *)data[i][0]); - str_pair[1] = data[i][elem_key]; - BLI_ghash_insert(elem_map, str_pair, (void *)data[i][elem_val]); - } - *r_elem_map = elem_map; - } - - if (struct_map_local) { - BLI_ghash_free(struct_map_local, NULL, NULL); - } + }; + + int elem_key, elem_val; + if (version_dir == DNA_RENAME_ALIAS_FROM_STATIC) { + elem_key = 1; + elem_val = 2; + } + else { + elem_key = 2; + elem_val = 1; + } + GHash *elem_map = BLI_ghash_new_ex( + strhash_pair_p, strhash_pair_cmp, __func__, ARRAY_SIZE(data)); + for (int i = 0; i < ARRAY_SIZE(data); i++) { + const char **str_pair = MEM_mallocN(sizeof(char *) * 2, __func__); + str_pair[0] = BLI_ghash_lookup_default(struct_map_local, data[i][0], (void *)data[i][0]); + str_pair[1] = data[i][elem_key]; + BLI_ghash_insert(elem_map, str_pair, (void *)data[i][elem_val]); + } + *r_elem_map = elem_map; + } + + if (struct_map_local) { + BLI_ghash_free(struct_map_local, NULL, NULL); + } } #undef DNA_MAKESDNA @@ -299,34 +296,34 @@ void DNA_alias_maps( */ const char *DNA_struct_rename_legacy_hack_static_from_alias(const char *name) { - /* 'bScreen' replaces the old IrisGL 'Screen' struct */ - if (STREQ("bScreen", name)) { - return "Screen"; - } - /* Groups renamed to collections in 2.8 */ - if (STREQ("Collection", name)) { - return "Group"; - } - if (STREQ("CollectionObject", name)) { - return "GroupObject"; - } - return name; + /* 'bScreen' replaces the old IrisGL 'Screen' struct */ + if (STREQ("bScreen", name)) { + return "Screen"; + } + /* Groups renamed to collections in 2.8 */ + if (STREQ("Collection", name)) { + return "Group"; + } + if (STREQ("CollectionObject", name)) { + return "GroupObject"; + } + return name; } const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name) { - /* 'bScreen' replaces the old IrisGL 'Screen' struct */ - if (STREQ("Screen", name)) { - return "bScreen"; - } - /* Groups renamed to collections in 2.8 */ - if (STREQ("Group", name)) { - return "Collection"; - } - if (STREQ("GroupObject", name)) { - return "CollectionObject"; - } - return name; + /* 'bScreen' replaces the old IrisGL 'Screen' struct */ + if (STREQ("Screen", name)) { + return "bScreen"; + } + /* Groups renamed to collections in 2.8 */ + if (STREQ("Group", name)) { + return "Collection"; + } + if (STREQ("GroupObject", name)) { + return "CollectionObject"; + } + return name; } /** \} */ diff --git a/source/blender/makesdna/intern/dna_utils.h b/source/blender/makesdna/intern/dna_utils.h index 6e96cf43622..123dd30a2b9 100644 --- a/source/blender/makesdna/intern/dna_utils.h +++ b/source/blender/makesdna/intern/dna_utils.h @@ -30,25 +30,27 @@ uint DNA_elem_id_offset_start(const char *elem_full); uint DNA_elem_id_offset_end(const char *elem_full); uint DNA_elem_id_strip_copy(char *elem_dst, const char *elem_src); uint DNA_elem_id_strip(char *elem); -bool DNA_elem_id_match( - const char *elem_search, const int elem_search_len, - const char *elem_full, - uint *r_elem_full_offset); -char *DNA_elem_id_rename( - struct MemArena *mem_arena, - const char *elem_src, const int elem_src_len, - const char *elem_dst, const int elem_dst_len, - const char *elem_full_src, const int elem_full_src_len, - const uint elem_full_offset_start); +bool DNA_elem_id_match(const char *elem_search, + const int elem_search_len, + const char *elem_full, + uint *r_elem_full_offset); +char *DNA_elem_id_rename(struct MemArena *mem_arena, + const char *elem_src, + const int elem_src_len, + const char *elem_dst, + const int elem_dst_len, + const char *elem_full_src, + const int elem_full_src_len, + const uint elem_full_offset_start); /* When requesting version info, support both directions. */ enum eDNA_RenameDir { - DNA_RENAME_STATIC_FROM_ALIAS = -1, - DNA_RENAME_ALIAS_FROM_STATIC = 1, + DNA_RENAME_STATIC_FROM_ALIAS = -1, + DNA_RENAME_ALIAS_FROM_STATIC = 1, }; -void DNA_alias_maps( - enum eDNA_RenameDir version_dir, - struct GHash **r_struct_map, struct GHash **r_elem_map); +void DNA_alias_maps(enum eDNA_RenameDir version_dir, + struct GHash **r_struct_map, + struct GHash **r_elem_map); const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name); const char *DNA_struct_rename_legacy_hack_static_from_alias(const char *name); diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index cc5abadd0e8..fa7ead3cd96 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -52,7 +52,7 @@ #include "BLI_alloca.h" #include "BLI_ghash.h" #include "BLI_memarena.h" -#include "BLI_sys_types.h" /* for intptr_t support */ +#include "BLI_sys_types.h" /* for intptr_t support */ #include "dna_utils.h" @@ -62,79 +62,79 @@ /* headers around with more freedom. */ static const char *includefiles[] = { - /* if you add files here, please add them at the end - * of makesdna.c (this file) as well */ - "DNA_listBase.h", - "DNA_vec_types.h", - "DNA_ID.h", - "DNA_ipo_types.h", - "DNA_key_types.h", - "DNA_text_types.h", - "DNA_packedFile_types.h", - "DNA_gpu_types.h", - "DNA_camera_types.h", - "DNA_image_types.h", - "DNA_texture_types.h", - "DNA_light_types.h", - "DNA_material_types.h", - "DNA_vfont_types.h", - "DNA_meta_types.h", - "DNA_curve_types.h", - "DNA_mesh_types.h", - "DNA_meshdata_types.h", - "DNA_modifier_types.h", - "DNA_lattice_types.h", - "DNA_object_types.h", - "DNA_object_force_types.h", - "DNA_object_fluidsim_types.h", - "DNA_world_types.h", - "DNA_scene_types.h", - "DNA_view3d_types.h", - "DNA_view2d_types.h", - "DNA_space_types.h", - "DNA_userdef_types.h", - "DNA_screen_types.h", - "DNA_sdna_types.h", - "DNA_fileglobal_types.h", - "DNA_sequence_types.h", - "DNA_effect_types.h", - "DNA_outliner_types.h", - "DNA_sound_types.h", - "DNA_collection_types.h", - "DNA_armature_types.h", - "DNA_action_types.h", - "DNA_constraint_types.h", - "DNA_nla_types.h", - "DNA_node_types.h", - "DNA_color_types.h", - "DNA_brush_types.h", - "DNA_customdata_types.h", - "DNA_particle_types.h", - "DNA_cloth_types.h", - "DNA_gpencil_types.h", - "DNA_gpencil_modifier_types.h", - "DNA_shader_fx_types.h", - "DNA_windowmanager_types.h", - "DNA_anim_types.h", - "DNA_boid_types.h", - "DNA_smoke_types.h", - "DNA_speaker_types.h", - "DNA_movieclip_types.h", - "DNA_tracking_types.h", - "DNA_dynamicpaint_types.h", - "DNA_mask_types.h", - "DNA_rigidbody_types.h", - "DNA_freestyle_types.h", - "DNA_linestyle_types.h", - "DNA_cachefile_types.h", - "DNA_layer_types.h", - "DNA_workspace_types.h", - "DNA_lightprobe_types.h", - - /* see comment above before editing! */ - - /* empty string to indicate end of includefiles */ - "", + /* if you add files here, please add them at the end + * of makesdna.c (this file) as well */ + "DNA_listBase.h", + "DNA_vec_types.h", + "DNA_ID.h", + "DNA_ipo_types.h", + "DNA_key_types.h", + "DNA_text_types.h", + "DNA_packedFile_types.h", + "DNA_gpu_types.h", + "DNA_camera_types.h", + "DNA_image_types.h", + "DNA_texture_types.h", + "DNA_light_types.h", + "DNA_material_types.h", + "DNA_vfont_types.h", + "DNA_meta_types.h", + "DNA_curve_types.h", + "DNA_mesh_types.h", + "DNA_meshdata_types.h", + "DNA_modifier_types.h", + "DNA_lattice_types.h", + "DNA_object_types.h", + "DNA_object_force_types.h", + "DNA_object_fluidsim_types.h", + "DNA_world_types.h", + "DNA_scene_types.h", + "DNA_view3d_types.h", + "DNA_view2d_types.h", + "DNA_space_types.h", + "DNA_userdef_types.h", + "DNA_screen_types.h", + "DNA_sdna_types.h", + "DNA_fileglobal_types.h", + "DNA_sequence_types.h", + "DNA_effect_types.h", + "DNA_outliner_types.h", + "DNA_sound_types.h", + "DNA_collection_types.h", + "DNA_armature_types.h", + "DNA_action_types.h", + "DNA_constraint_types.h", + "DNA_nla_types.h", + "DNA_node_types.h", + "DNA_color_types.h", + "DNA_brush_types.h", + "DNA_customdata_types.h", + "DNA_particle_types.h", + "DNA_cloth_types.h", + "DNA_gpencil_types.h", + "DNA_gpencil_modifier_types.h", + "DNA_shader_fx_types.h", + "DNA_windowmanager_types.h", + "DNA_anim_types.h", + "DNA_boid_types.h", + "DNA_smoke_types.h", + "DNA_speaker_types.h", + "DNA_movieclip_types.h", + "DNA_tracking_types.h", + "DNA_dynamicpaint_types.h", + "DNA_mask_types.h", + "DNA_rigidbody_types.h", + "DNA_freestyle_types.h", + "DNA_linestyle_types.h", + "DNA_cachefile_types.h", + "DNA_layer_types.h", + "DNA_workspace_types.h", + "DNA_lightprobe_types.h", + + /* see comment above before editing! */ + + /* empty string to indicate end of includefiles */ + "", }; /* -------------------------------------------------------------------- */ @@ -166,10 +166,10 @@ static short **structs, *structdata; /** Versioning data */ static struct { - GHash *struct_map_alias_from_static; - GHash *struct_map_static_from_alias; - GHash *elem_map_alias_from_static; - GHash *elem_map_static_from_alias; + GHash *struct_map_alias_from_static; + GHash *struct_map_static_from_alias; + GHash *elem_map_alias_from_static; + GHash *elem_map_static_from_alias; } g_version_data = {NULL}; /** @@ -184,14 +184,18 @@ static int debugSDNA = 0; static int additional_slen_offset; #define DEBUG_PRINTF(debug_level, ...) \ - { if (debugSDNA > debug_level) { printf(__VA_ARGS__); } } ((void)0) - + { \ + if (debugSDNA > debug_level) { \ + printf(__VA_ARGS__); \ + } \ + } \ + ((void)0) /* stub for BLI_abort() */ #ifndef NDEBUG void BLI_system_backtrace(FILE *fp) { - (void)fp; + (void)fp; } #endif @@ -256,42 +260,42 @@ void print_struct_sizes(void); * Make DNA string (write to file). * \{ */ - static const char *version_struct_static_from_alias(const char *str) { - const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_static_from_alias, str); - if (str_test != NULL) { - return str_test; - } - return str; + const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_static_from_alias, str); + if (str_test != NULL) { + return str_test; + } + return str; } static const char *version_struct_alias_from_static(const char *str) { - const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_alias_from_static, str); - if (str_test != NULL) { - return str_test; - } - return str; + const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_alias_from_static, str); + if (str_test != NULL) { + return str_test; + } + return str; } -static const char *version_elem_static_from_alias( - const int strct, const char *elem_alias_full) +static const char *version_elem_static_from_alias(const int strct, const char *elem_alias_full) { - const uint elem_alias_full_len = strlen(elem_alias_full); - char *elem_alias = alloca(elem_alias_full_len + 1); - const int elem_alias_len = DNA_elem_id_strip_copy(elem_alias, elem_alias_full); - const char *str_pair[2] = {types[strct], elem_alias}; - const char *elem_static = BLI_ghash_lookup(g_version_data.elem_map_static_from_alias, str_pair); - if (elem_static != NULL) { - return DNA_elem_id_rename( - mem_arena, - elem_alias, elem_alias_len, - elem_static, strlen(elem_static), - elem_alias_full, elem_alias_full_len, - DNA_elem_id_offset_start(elem_alias_full)); - } - return elem_alias_full; + const uint elem_alias_full_len = strlen(elem_alias_full); + char *elem_alias = alloca(elem_alias_full_len + 1); + const int elem_alias_len = DNA_elem_id_strip_copy(elem_alias, elem_alias_full); + const char *str_pair[2] = {types[strct], elem_alias}; + const char *elem_static = BLI_ghash_lookup(g_version_data.elem_map_static_from_alias, str_pair); + if (elem_static != NULL) { + return DNA_elem_id_rename(mem_arena, + elem_alias, + elem_alias_len, + elem_static, + strlen(elem_static), + elem_alias_full, + elem_alias_full_len, + DNA_elem_id_offset_start(elem_alias_full)); + } + return elem_alias_full; } /** @@ -300,90 +304,90 @@ static const char *version_elem_static_from_alias( */ static bool is_name_legal(const char *name) { - const int name_size = strlen(name) + 1; - char *name_strip = alloca(name_size); - DNA_elem_id_strip_copy(name_strip, name); - - const char prefix[] = {'p', 'a', 'd'}; - - if (name[0] == '_') { - if (strncmp(&name_strip[1], prefix, sizeof(prefix)) != 0) { - fprintf(stderr, "Error: only '_pad' variables can start with an underscore, found '%s'\n", name); - return false; - } - } - else if (strncmp(name_strip, prefix, sizeof(prefix)) == 0) { - int i = sizeof(prefix); - if (name_strip[i] >= 'a' && name_strip[i] <= 'z') { - /* may be part of a word, allow that. */ - return true; - } - bool has_only_digit_or_none = true; - for (; name_strip[i]; i++) { - const char c = name_strip[i]; - if (!((c >= '0' && c <= '9') || c == '_')) { - has_only_digit_or_none = false; - break; - } - } - if (has_only_digit_or_none) { - /* found 'pad' or 'pad123'. */ - fprintf(stderr, "Error: padding variables must be formatted '_pad[number]', found '%s'\n", name); - return false; - } - } - return true; + const int name_size = strlen(name) + 1; + char *name_strip = alloca(name_size); + DNA_elem_id_strip_copy(name_strip, name); + + const char prefix[] = {'p', 'a', 'd'}; + + if (name[0] == '_') { + if (strncmp(&name_strip[1], prefix, sizeof(prefix)) != 0) { + fprintf( + stderr, "Error: only '_pad' variables can start with an underscore, found '%s'\n", name); + return false; + } + } + else if (strncmp(name_strip, prefix, sizeof(prefix)) == 0) { + int i = sizeof(prefix); + if (name_strip[i] >= 'a' && name_strip[i] <= 'z') { + /* may be part of a word, allow that. */ + return true; + } + bool has_only_digit_or_none = true; + for (; name_strip[i]; i++) { + const char c = name_strip[i]; + if (!((c >= '0' && c <= '9') || c == '_')) { + has_only_digit_or_none = false; + break; + } + } + if (has_only_digit_or_none) { + /* found 'pad' or 'pad123'. */ + fprintf( + stderr, "Error: padding variables must be formatted '_pad[number]', found '%s'\n", name); + return false; + } + } + return true; } - static int add_type(const char *str, int size) { - int nr; - char *cp; - - /* first do validity check */ - if (str[0] == 0) { - return -1; - } - else if (strchr(str, '*')) { - /* note: this is valid C syntax but we can't parse, complain! - * 'struct SomeStruct* somevar;' <-- correct but we cant handle right now. */ - return -1; - } - - str = version_struct_static_from_alias(str); - - /* search through type array */ - for (nr = 0; nr < nr_types; nr++) { - if (strcmp(str, types[nr]) == 0) { - if (size) { - types_size_native[nr] = size; - types_size_32[nr] = size; - types_size_64[nr] = size; - } - return nr; - } - } - - /* append new type */ - const int str_size = strlen(str) + 1; - cp = BLI_memarena_alloc(mem_arena, str_size); - memcpy(cp, str, str_size); - types[nr_types] = cp; - types_size_native[nr_types] = size; - types_size_32[nr_types] = size; - types_size_64[nr_types] = size; - - if (nr_types >= maxnr) { - printf("too many types\n"); - return nr_types - 1; - } - nr_types++; - - return nr_types - 1; + int nr; + char *cp; + + /* first do validity check */ + if (str[0] == 0) { + return -1; + } + else if (strchr(str, '*')) { + /* note: this is valid C syntax but we can't parse, complain! + * 'struct SomeStruct* somevar;' <-- correct but we cant handle right now. */ + return -1; + } + + str = version_struct_static_from_alias(str); + + /* search through type array */ + for (nr = 0; nr < nr_types; nr++) { + if (strcmp(str, types[nr]) == 0) { + if (size) { + types_size_native[nr] = size; + types_size_32[nr] = size; + types_size_64[nr] = size; + } + return nr; + } + } + + /* append new type */ + const int str_size = strlen(str) + 1; + cp = BLI_memarena_alloc(mem_arena, str_size); + memcpy(cp, str, str_size); + types[nr_types] = cp; + types_size_native[nr_types] = size; + types_size_32[nr_types] = size; + types_size_64[nr_types] = size; + + if (nr_types >= maxnr) { + printf("too many types\n"); + return nr_types - 1; + } + nr_types++; + + return nr_types - 1; } - /** * * Because of the weird way of tokenizing, we have to 'cast' function @@ -394,968 +398,1019 @@ static int add_type(const char *str, int size) * */ static int add_name(const char *str) { - int nr, i, j, k; - char *cp; - char buf[255]; /* stupid limit, change it :) */ - const char *name; - - additional_slen_offset = 0; - - if (str[0] == 0 /* || (str[1] == 0) */) { - return -1; - } - - if (str[0] == '(' && str[1] == '*') { - /* we handle function pointer and special array cases here, e.g. - * void (*function)(...) and float (*array)[..]. the array case - * name is still converted to (array *)() though because it is that - * way in old dna too, and works correct with elementsize() */ - int isfuncptr = (strchr(str + 1, '(')) != NULL; - - DEBUG_PRINTF(3, "\t\t\t\t*** Function pointer or multidim array pointer found\n"); - /* functionpointer: transform the type (sometimes) */ - i = 0; - - while (str[i] != ')') { - buf[i] = str[i]; - i++; - } - - /* Another number we need is the extra slen offset. This extra - * offset is the overshoot after a space. If there is no - * space, no overshoot should be calculated. */ - j = i; /* j at first closing brace */ - - DEBUG_PRINTF(3, "first brace after offset %d\n", i); - - j++; /* j beyond closing brace ? */ - while ((str[j] != 0) && (str[j] != ')')) { - DEBUG_PRINTF(3, "seen %c (%d)\n", str[j], str[j]); - j++; - } - DEBUG_PRINTF(3, "seen %c (%d)\n" "special after offset%d\n", str[j], str[j], j); - - if (!isfuncptr) { - /* multidimensional array pointer case */ - if (str[j] == 0) { - DEBUG_PRINTF(3, "offsetting for multidim array pointer\n"); - } - else { - printf("Error during tokening multidim array pointer\n"); - } - } - else if (str[j] == 0) { - DEBUG_PRINTF(3, "offsetting for space\n"); - /* get additional offset */ - k = 0; - while (str[j] != ')') { - j++; - k++; - } - DEBUG_PRINTF(3, "extra offset %d\n", k); - additional_slen_offset = k; - } - else if (str[j] == ')') { - DEBUG_PRINTF(3, "offsetting for brace\n"); - ; /* don't get extra offset */ - } - else { - printf("Error during tokening function pointer argument list\n"); - } - - /* - * Put )(void) at the end? Maybe )(). Should check this with - * old sdna. Actually, sometimes )(), sometimes )(void...) - * Alas.. such is the nature of brain-damage :( - * - * Sorted it out: always do )(), except for headdraw and - * windraw, part of ScrArea. This is important, because some - * linkers will treat different fp's differently when called - * !!! This has to do with interference in byte-alignment and - * the way args are pushed on the stack. - * - * */ - buf[i] = 0; - DEBUG_PRINTF(3, "Name before chomping: %s\n", buf); - if ((strncmp(buf, "(*headdraw", 10) == 0) || - (strncmp(buf, "(*windraw", 9) == 0) ) - { - buf[i] = ')'; - buf[i + 1] = '('; - buf[i + 2] = 'v'; - buf[i + 3] = 'o'; - buf[i + 4] = 'i'; - buf[i + 5] = 'd'; - buf[i + 6] = ')'; - buf[i + 7] = 0; - } - else { - buf[i] = ')'; - buf[i + 1] = '('; - buf[i + 2] = ')'; - buf[i + 3] = 0; - } - /* now precede with buf*/ - DEBUG_PRINTF(3, "\t\t\t\t\tProposing fp name %s\n", buf); - name = buf; - } - else { - /* normal field: old code */ - name = str; - } - - /* search name array */ - for (nr = 0; nr < nr_names; nr++) { - if (strcmp(name, names[nr]) == 0) { - return nr; - } - } - - /* Sanity check the name. */ - if (!is_name_legal(name)) { - return -1; - } - - /* Append new name. */ - const int name_size = strlen(name) + 1; - cp = BLI_memarena_alloc(mem_arena, name_size); - memcpy(cp, name, name_size); - names[nr_names] = cp; - - if (nr_names >= maxnr) { - printf("too many names\n"); - return nr_names - 1; - } - nr_names++; - - return nr_names - 1; + int nr, i, j, k; + char *cp; + char buf[255]; /* stupid limit, change it :) */ + const char *name; + + additional_slen_offset = 0; + + if (str[0] == 0 /* || (str[1] == 0) */) { + return -1; + } + + if (str[0] == '(' && str[1] == '*') { + /* we handle function pointer and special array cases here, e.g. + * void (*function)(...) and float (*array)[..]. the array case + * name is still converted to (array *)() though because it is that + * way in old dna too, and works correct with elementsize() */ + int isfuncptr = (strchr(str + 1, '(')) != NULL; + + DEBUG_PRINTF(3, "\t\t\t\t*** Function pointer or multidim array pointer found\n"); + /* functionpointer: transform the type (sometimes) */ + i = 0; + + while (str[i] != ')') { + buf[i] = str[i]; + i++; + } + + /* Another number we need is the extra slen offset. This extra + * offset is the overshoot after a space. If there is no + * space, no overshoot should be calculated. */ + j = i; /* j at first closing brace */ + + DEBUG_PRINTF(3, "first brace after offset %d\n", i); + + j++; /* j beyond closing brace ? */ + while ((str[j] != 0) && (str[j] != ')')) { + DEBUG_PRINTF(3, "seen %c (%d)\n", str[j], str[j]); + j++; + } + DEBUG_PRINTF(3, + "seen %c (%d)\n" + "special after offset%d\n", + str[j], + str[j], + j); + + if (!isfuncptr) { + /* multidimensional array pointer case */ + if (str[j] == 0) { + DEBUG_PRINTF(3, "offsetting for multidim array pointer\n"); + } + else { + printf("Error during tokening multidim array pointer\n"); + } + } + else if (str[j] == 0) { + DEBUG_PRINTF(3, "offsetting for space\n"); + /* get additional offset */ + k = 0; + while (str[j] != ')') { + j++; + k++; + } + DEBUG_PRINTF(3, "extra offset %d\n", k); + additional_slen_offset = k; + } + else if (str[j] == ')') { + DEBUG_PRINTF(3, "offsetting for brace\n"); + ; /* don't get extra offset */ + } + else { + printf("Error during tokening function pointer argument list\n"); + } + + /* + * Put )(void) at the end? Maybe )(). Should check this with + * old sdna. Actually, sometimes )(), sometimes )(void...) + * Alas.. such is the nature of brain-damage :( + * + * Sorted it out: always do )(), except for headdraw and + * windraw, part of ScrArea. This is important, because some + * linkers will treat different fp's differently when called + * !!! This has to do with interference in byte-alignment and + * the way args are pushed on the stack. + * + * */ + buf[i] = 0; + DEBUG_PRINTF(3, "Name before chomping: %s\n", buf); + if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) { + buf[i] = ')'; + buf[i + 1] = '('; + buf[i + 2] = 'v'; + buf[i + 3] = 'o'; + buf[i + 4] = 'i'; + buf[i + 5] = 'd'; + buf[i + 6] = ')'; + buf[i + 7] = 0; + } + else { + buf[i] = ')'; + buf[i + 1] = '('; + buf[i + 2] = ')'; + buf[i + 3] = 0; + } + /* now precede with buf*/ + DEBUG_PRINTF(3, "\t\t\t\t\tProposing fp name %s\n", buf); + name = buf; + } + else { + /* normal field: old code */ + name = str; + } + + /* search name array */ + for (nr = 0; nr < nr_names; nr++) { + if (strcmp(name, names[nr]) == 0) { + return nr; + } + } + + /* Sanity check the name. */ + if (!is_name_legal(name)) { + return -1; + } + + /* Append new name. */ + const int name_size = strlen(name) + 1; + cp = BLI_memarena_alloc(mem_arena, name_size); + memcpy(cp, name, name_size); + names[nr_names] = cp; + + if (nr_names >= maxnr) { + printf("too many names\n"); + return nr_names - 1; + } + nr_names++; + + return nr_names - 1; } static short *add_struct(int namecode) { - int len; - short *sp; - - if (nr_structs == 0) { - structs[0] = structdata; - } - else { - sp = structs[nr_structs - 1]; - len = sp[1]; - structs[nr_structs] = sp + 2 * len + 2; - } - - sp = structs[nr_structs]; - sp[0] = namecode; - - if (nr_structs >= maxnr) { - printf("too many structs\n"); - return sp; - } - nr_structs++; - - return sp; + int len; + short *sp; + + if (nr_structs == 0) { + structs[0] = structdata; + } + else { + sp = structs[nr_structs - 1]; + len = sp[1]; + structs[nr_structs] = sp + 2 * len + 2; + } + + sp = structs[nr_structs]; + sp[0] = namecode; + + if (nr_structs >= maxnr) { + printf("too many structs\n"); + return sp; + } + nr_structs++; + + return sp; } static int preprocess_include(char *maindata, const int maindata_len) { - int a, newlen, comment = 0; - char *cp, *temp, *md; - - /* note: len + 1, last character is a dummy to prevent - * comparisons using uninitialized memory */ - temp = MEM_mallocN(maindata_len + 1, "preprocess_include"); - temp[maindata_len] = ' '; - - memcpy(temp, maindata, maindata_len); - - /* remove all c++ comments */ - /* replace all enters/tabs/etc with spaces */ - cp = temp; - a = maindata_len; - comment = 0; - while (a--) { - if (cp[0] == '/' && cp[1] == '/') { - comment = 1; - } - else if (*cp == '\n') { - comment = 0; - } - if (comment || *cp < 32 || *cp > 128) *cp = 32; - cp++; - } - - - /* data from temp copy to maindata, remove comments and double spaces */ - cp = temp; - md = maindata; - newlen = 0; - comment = 0; - a = maindata_len; - while (a--) { - - if (cp[0] == '/' && cp[1] == '*') { - comment = 1; - cp[0] = cp[1] = 32; - } - if (cp[0] == '*' && cp[1] == '/') { - comment = 0; - cp[0] = cp[1] = 32; - } - - /* do not copy when: */ - if (comment) { - /* pass */ - } - else if (cp[0] == ' ' && cp[1] == ' ') { - /* pass */ - } - else if (cp[-1] == '*' && cp[0] == ' ') { - /* pointers with a space */ - } /* skip special keywords */ - else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { - /* single values are skipped already, so decrement 1 less */ - a -= 13; - cp += 13; - } - else { - md[0] = cp[0]; - md++; - newlen++; - } - cp++; - } - - MEM_freeN(temp); - return newlen; + int a, newlen, comment = 0; + char *cp, *temp, *md; + + /* note: len + 1, last character is a dummy to prevent + * comparisons using uninitialized memory */ + temp = MEM_mallocN(maindata_len + 1, "preprocess_include"); + temp[maindata_len] = ' '; + + memcpy(temp, maindata, maindata_len); + + /* remove all c++ comments */ + /* replace all enters/tabs/etc with spaces */ + cp = temp; + a = maindata_len; + comment = 0; + while (a--) { + if (cp[0] == '/' && cp[1] == '/') { + comment = 1; + } + else if (*cp == '\n') { + comment = 0; + } + if (comment || *cp < 32 || *cp > 128) + *cp = 32; + cp++; + } + + /* data from temp copy to maindata, remove comments and double spaces */ + cp = temp; + md = maindata; + newlen = 0; + comment = 0; + a = maindata_len; + while (a--) { + + if (cp[0] == '/' && cp[1] == '*') { + comment = 1; + cp[0] = cp[1] = 32; + } + if (cp[0] == '*' && cp[1] == '/') { + comment = 0; + cp[0] = cp[1] = 32; + } + + /* do not copy when: */ + if (comment) { + /* pass */ + } + else if (cp[0] == ' ' && cp[1] == ' ') { + /* pass */ + } + else if (cp[-1] == '*' && cp[0] == ' ') { + /* pointers with a space */ + } /* skip special keywords */ + else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { + /* single values are skipped already, so decrement 1 less */ + a -= 13; + cp += 13; + } + else { + md[0] = cp[0]; + md++; + newlen++; + } + cp++; + } + + MEM_freeN(temp); + return newlen; } static void *read_file_data(const char *filename, int *r_len) { #ifdef WIN32 - FILE *fp = fopen(filename, "rb"); + FILE *fp = fopen(filename, "rb"); #else - FILE *fp = fopen(filename, "r"); + FILE *fp = fopen(filename, "r"); #endif - void *data; - - if (!fp) { - *r_len = -1; - return NULL; - } - - fseek(fp, 0L, SEEK_END); - *r_len = ftell(fp); - fseek(fp, 0L, SEEK_SET); - - if (*r_len == -1) { - fclose(fp); - return NULL; - } - - data = MEM_mallocN(*r_len, "read_file_data"); - if (!data) { - *r_len = -1; - fclose(fp); - return NULL; - } - - if (fread(data, *r_len, 1, fp) != 1) { - *r_len = -1; - MEM_freeN(data); - fclose(fp); - return NULL; - } - - fclose(fp); - return data; + void *data; + + if (!fp) { + *r_len = -1; + return NULL; + } + + fseek(fp, 0L, SEEK_END); + *r_len = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + if (*r_len == -1) { + fclose(fp); + return NULL; + } + + data = MEM_mallocN(*r_len, "read_file_data"); + if (!data) { + *r_len = -1; + fclose(fp); + return NULL; + } + + if (fread(data, *r_len, 1, fp) != 1) { + *r_len = -1; + MEM_freeN(data); + fclose(fp); + return NULL; + } + + fclose(fp); + return data; } static int convert_include(const char *filename) { - /* read include file, skip structs with a '#' before it. - * store all data in temporal arrays. - */ - int maindata_len, count, slen, type, name, strct; - short *structpoin, *sp; - char *maindata, *mainend, *md, *md1; - bool skip_struct; - - md = maindata = read_file_data(filename, &maindata_len); - if (maindata_len == -1) { - fprintf(stderr, "Can't read file %s\n", filename); - return 1; - } - - maindata_len = preprocess_include(maindata, maindata_len); - mainend = maindata + maindata_len - 1; - - /* we look for '{' and then back to 'struct' */ - count = 0; - skip_struct = false; - while (count < maindata_len) { - - /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */ - if (md[0] == '#' && md[1] == ' ' && md[2] == '#') { - skip_struct = true; - } - - if (md[0] == '{') { - md[0] = 0; - if (skip_struct) { - skip_struct = false; - } - else { - if (md[-1] == ' ') { - md[-1] = 0; - } - md1 = md - 2; - while (*md1 != 32) { - /* to beginning of word */ - md1--; - } - md1++; - - /* we've got a struct name when... */ - if (strncmp(md1 - 7, "struct", 6) == 0) { - - strct = add_type(md1, 0); - if (strct == -1) { - fprintf(stderr, "File '%s' contains struct we cant parse \"%s\"\n", filename, md1); - return 1; - } - - structpoin = add_struct(strct); - sp = structpoin + 2; - - DEBUG_PRINTF(1, "\t|\t|-- detected struct %s\n", types[strct]); - - /* first lets make it all nice strings */ - md1 = md + 1; - while (*md1 != '}') { - if (md1 > mainend) { - break; - } - - if (*md1 == ',' || *md1 == ' ') { - *md1 = 0; - } - md1++; - } - - /* read types and names until first character that is not '}' */ - md1 = md + 1; - while (*md1 != '}') { - if (md1 > mainend) { - break; - } - - /* skip when it says 'struct' or 'unsigned' or 'const' */ - if (*md1) { - if (strncmp(md1, "struct", 6) == 0) { md1 += 7; } - if (strncmp(md1, "unsigned", 8) == 0) { md1 += 9; } - if (strncmp(md1, "const", 5) == 0) { md1 += 6; } - - /* we've got a type! */ - type = add_type(md1, 0); - if (type == -1) { - fprintf(stderr, "File '%s' contains struct we can't parse \"%s\"\n", filename, md1); - return 1; - } - - DEBUG_PRINTF(1, "\t|\t|\tfound type %s (", md1); - - md1 += strlen(md1); - - - /* read until ';' */ - while (*md1 != ';') { - if (md1 > mainend) { - break; - } - - if (*md1) { - /* We've got a name. slen needs - * correction for function - * pointers! */ - slen = (int) strlen(md1); - if (md1[slen - 1] == ';') { - md1[slen - 1] = 0; - - name = add_name(version_elem_static_from_alias(strct, md1)); - if (name == -1) { - fprintf(stderr, "File '%s' contains struct with name that can't be added \"%s\"\n", filename, md1); - return 1; - } - slen += additional_slen_offset; - sp[0] = type; - sp[1] = name; - - if (names[name] != NULL) { - DEBUG_PRINTF(1, "%s |", names[name]); - } - - structpoin[1]++; - sp += 2; - - md1 += slen; - break; - } - - name = add_name(version_elem_static_from_alias(strct, md1)); - if (name == -1) { - fprintf(stderr, "File '%s' contains struct with name that can't be added \"%s\"\n", filename, md1); - return 1; - } - slen += additional_slen_offset; - - sp[0] = type; - sp[1] = name; - if (names[name] != NULL) { - DEBUG_PRINTF(1, "%s ||", names[name]); - } - - structpoin[1]++; - sp += 2; - - md1 += slen; - } - md1++; - } - - DEBUG_PRINTF(1, ")\n"); - - } - md1++; - } - } - } - } - count++; - md++; - } - - MEM_freeN(maindata); - - return 0; + /* read include file, skip structs with a '#' before it. + * store all data in temporal arrays. + */ + int maindata_len, count, slen, type, name, strct; + short *structpoin, *sp; + char *maindata, *mainend, *md, *md1; + bool skip_struct; + + md = maindata = read_file_data(filename, &maindata_len); + if (maindata_len == -1) { + fprintf(stderr, "Can't read file %s\n", filename); + return 1; + } + + maindata_len = preprocess_include(maindata, maindata_len); + mainend = maindata + maindata_len - 1; + + /* we look for '{' and then back to 'struct' */ + count = 0; + skip_struct = false; + while (count < maindata_len) { + + /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */ + if (md[0] == '#' && md[1] == ' ' && md[2] == '#') { + skip_struct = true; + } + + if (md[0] == '{') { + md[0] = 0; + if (skip_struct) { + skip_struct = false; + } + else { + if (md[-1] == ' ') { + md[-1] = 0; + } + md1 = md - 2; + while (*md1 != 32) { + /* to beginning of word */ + md1--; + } + md1++; + + /* we've got a struct name when... */ + if (strncmp(md1 - 7, "struct", 6) == 0) { + + strct = add_type(md1, 0); + if (strct == -1) { + fprintf(stderr, "File '%s' contains struct we cant parse \"%s\"\n", filename, md1); + return 1; + } + + structpoin = add_struct(strct); + sp = structpoin + 2; + + DEBUG_PRINTF(1, "\t|\t|-- detected struct %s\n", types[strct]); + + /* first lets make it all nice strings */ + md1 = md + 1; + while (*md1 != '}') { + if (md1 > mainend) { + break; + } + + if (*md1 == ',' || *md1 == ' ') { + *md1 = 0; + } + md1++; + } + + /* read types and names until first character that is not '}' */ + md1 = md + 1; + while (*md1 != '}') { + if (md1 > mainend) { + break; + } + + /* skip when it says 'struct' or 'unsigned' or 'const' */ + if (*md1) { + if (strncmp(md1, "struct", 6) == 0) { + md1 += 7; + } + if (strncmp(md1, "unsigned", 8) == 0) { + md1 += 9; + } + if (strncmp(md1, "const", 5) == 0) { + md1 += 6; + } + + /* we've got a type! */ + type = add_type(md1, 0); + if (type == -1) { + fprintf( + stderr, "File '%s' contains struct we can't parse \"%s\"\n", filename, md1); + return 1; + } + + DEBUG_PRINTF(1, "\t|\t|\tfound type %s (", md1); + + md1 += strlen(md1); + + /* read until ';' */ + while (*md1 != ';') { + if (md1 > mainend) { + break; + } + + if (*md1) { + /* We've got a name. slen needs + * correction for function + * pointers! */ + slen = (int)strlen(md1); + if (md1[slen - 1] == ';') { + md1[slen - 1] = 0; + + name = add_name(version_elem_static_from_alias(strct, md1)); + if (name == -1) { + fprintf(stderr, + "File '%s' contains struct with name that can't be added \"%s\"\n", + filename, + md1); + return 1; + } + slen += additional_slen_offset; + sp[0] = type; + sp[1] = name; + + if (names[name] != NULL) { + DEBUG_PRINTF(1, "%s |", names[name]); + } + + structpoin[1]++; + sp += 2; + + md1 += slen; + break; + } + + name = add_name(version_elem_static_from_alias(strct, md1)); + if (name == -1) { + fprintf(stderr, + "File '%s' contains struct with name that can't be added \"%s\"\n", + filename, + md1); + return 1; + } + slen += additional_slen_offset; + + sp[0] = type; + sp[1] = name; + if (names[name] != NULL) { + DEBUG_PRINTF(1, "%s ||", names[name]); + } + + structpoin[1]++; + sp += 2; + + md1 += slen; + } + md1++; + } + + DEBUG_PRINTF(1, ")\n"); + } + md1++; + } + } + } + } + count++; + md++; + } + + MEM_freeN(maindata); + + return 0; } -static bool check_field_alignment(int firststruct, int structtype, int type, int len, - const char *name, const char *detail) +static bool check_field_alignment( + int firststruct, int structtype, int type, int len, const char *name, const char *detail) { - bool result = true; - if (type < firststruct && types_size_native[type] > 4 && (len % 8)) { - fprintf(stderr, "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n", - detail, types[structtype], name, len % 8); - result = false; - } - if (types_size_native[type] > 3 && (len % 4) ) { - fprintf(stderr, "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n", - detail, types[structtype], name, len % 4); - result = false; - } - if (types_size_native[type] == 2 && (len % 2) ) { - fprintf(stderr, "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n", - detail, types[structtype], name, len % 2); - result = false; - } - return result; + bool result = true; + if (type < firststruct && types_size_native[type] > 4 && (len % 8)) { + fprintf(stderr, + "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n", + detail, + types[structtype], + name, + len % 8); + result = false; + } + if (types_size_native[type] > 3 && (len % 4)) { + fprintf(stderr, + "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n", + detail, + types[structtype], + name, + len % 4); + result = false; + } + if (types_size_native[type] == 2 && (len % 2)) { + fprintf(stderr, + "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n", + detail, + types[structtype], + name, + len % 2); + result = false; + } + return result; } static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory) { - int unknown = nr_structs, lastunknown; - bool dna_error = false; - - /* Write test to verify sizes are accurate. */ - fprintf(file_verify, "/* Verify struct sizes and member offsets are as expected by DNA. */\n"); - fprintf(file_verify, "#include \"BLI_assert.h\"\n\n"); - fprintf(file_verify, "#define DNA_DEPRECATED\n"); - for (int i = 0; *(includefiles[i]) != '\0'; i++) { - fprintf(file_verify, "#include \"%s%s\"\n", base_directory, includefiles[i]); - } - fprintf(file_verify, "\n"); - - /* Multiple iterations to handle nested structs. */ - while (unknown) { - lastunknown = unknown; - unknown = 0; - - /* check all structs... */ - for (int a = 0; a < nr_structs; a++) { - const short *structpoin = structs[a]; - const int structtype = structpoin[0]; - const char *structname = version_struct_alias_from_static(types[structtype]); - - /* when length is not known... */ - if (types_size_native[structtype] == 0) { - - const short *sp = structpoin + 2; - int size_native = 0; - int size_32 = 0; - int size_64 = 0; - bool has_pointer = false; - - /* check all elements in struct */ - for (int b = 0; b < structpoin[1]; b++, sp += 2) { - int type = sp[0]; - const char *cp = names[sp[1]]; - int namelen = (int)strlen(cp); - - /* Write size verification to file. */ - { - char *name_static = alloca(namelen + 1); - DNA_elem_id_strip_copy(name_static, cp); - const char *str_pair[2] = {types[structtype], name_static}; - const char *name_alias = BLI_ghash_lookup(g_version_data.elem_map_alias_from_static, str_pair); - fprintf(file_verify, "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset verify\");\n", - structname, name_alias ? name_alias : name_static, size_native); - } - - /* is it a pointer or function pointer? */ - if (cp[0] == '*' || cp[1] == '*') { - has_pointer = 1; - /* has the name an extra length? (array) */ - int mul = 1; - if (cp[namelen - 1] == ']') { - mul = DNA_elem_array_size(cp); - } - - if (mul == 0) { - fprintf(stderr, "Zero array size found or could not parse %s: '%.*s'\n", - types[structtype], namelen + 1, cp); - dna_error = 1; - } - - /* 4-8 aligned/ */ - if (sizeof(void *) == 4) { - if (size_native % 4) { - fprintf(stderr, "Align pointer error in struct (size_native 4): %s %s\n", - types[structtype], cp); - dna_error = 1; - } - } - else { - if (size_native % 8) { - fprintf(stderr, "Align pointer error in struct (size_native 8): %s %s\n", - types[structtype], cp); - dna_error = 1; - } - } - - if (size_64 % 8) { - fprintf(stderr, "Align pointer error in struct (size_64 8): %s %s\n", - types[structtype], cp); - dna_error = 1; - } - - size_native += sizeof(void *) * mul; - size_32 += 4 * mul; - size_64 += 8 * mul; - - } - else if (cp[0] == '[') { - /* parsing can cause names "var" and "[3]" - * to be found for "float var [3]" */ - fprintf(stderr, "Parse error in struct, invalid member name: %s %s\n", - types[structtype], cp); - dna_error = 1; - } - else if (types_size_native[type]) { - /* has the name an extra length? (array) */ - int mul = 1; - if (cp[namelen - 1] == ']') { - mul = DNA_elem_array_size(cp); - } - - if (mul == 0) { - fprintf(stderr, "Zero array size found or could not parse %s: '%.*s'\n", - types[structtype], namelen + 1, cp); - dna_error = 1; - } - - /* struct alignment */ - if (type >= firststruct) { - if (sizeof(void *) == 8 && (size_native % 8) ) { - fprintf(stderr, "Align struct error: %s %s\n", - types[structtype], cp); - dna_error = 1; - } - } - - /* Check 2-4-8 aligned. */ - if (!check_field_alignment(firststruct, structtype, type, size_32, cp, "32 bit")) { - dna_error = 1; - } - if (!check_field_alignment(firststruct, structtype, type, size_64, cp, "64 bit")) { - dna_error = 1; - } - - size_native += mul * types_size_native[type]; - size_32 += mul * types_size_32[type]; - size_64 += mul * types_size_64[type]; - - } - else { - size_native = 0; - size_32 = 0; - size_64 = 0; - break; - } - } - - if (size_native == 0) { - unknown++; - } - else { - types_size_native[structtype] = size_native; - types_size_32[structtype] = size_32; - types_size_64[structtype] = size_64; - /* two ways to detect if a struct contains a pointer: - * has_pointer is set or size_native doesn't match any of 32/64bit lengths*/ - if (has_pointer || size_64 != size_native || size_32 != size_native) { - if (size_64 % 8) { - fprintf(stderr, "Sizeerror 8 in struct: %s (add %d bytes)\n", - types[structtype], size_64 % 8); - dna_error = 1; - } - } - - if (size_native % 4) { - fprintf(stderr, "Sizeerror 4 in struct: %s (add %d bytes)\n", - types[structtype], size_native % 4); - dna_error = 1; - } - - /* Write size verification to file. */ - fprintf(file_verify, "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n", structname, size_native); - } - } - } - - if (unknown == lastunknown) { - break; - } - } - - if (unknown) { - fprintf(stderr, "ERROR: still %d structs unknown\n", unknown); - - if (debugSDNA) { - fprintf(stderr, "*** Known structs :\n"); - - for (int a = 0; a < nr_structs; a++) { - const short *structpoin = structs[a]; - const int structtype = structpoin[0]; - - /* length unknown */ - if (types_size_native[structtype] != 0) { - fprintf(stderr, " %s\n", types[structtype]); - } - } - } - - - fprintf(stderr, "*** Unknown structs :\n"); - - for (int a = 0; a < nr_structs; a++) { - const short *structpoin = structs[a]; - const int structtype = structpoin[0]; - - /* length unknown yet */ - if (types_size_native[structtype] == 0) { - fprintf(stderr, " %s\n", types[structtype]); - } - } - - dna_error = 1; - } - - return dna_error; + int unknown = nr_structs, lastunknown; + bool dna_error = false; + + /* Write test to verify sizes are accurate. */ + fprintf(file_verify, "/* Verify struct sizes and member offsets are as expected by DNA. */\n"); + fprintf(file_verify, "#include \"BLI_assert.h\"\n\n"); + fprintf(file_verify, "#define DNA_DEPRECATED\n"); + for (int i = 0; *(includefiles[i]) != '\0'; i++) { + fprintf(file_verify, "#include \"%s%s\"\n", base_directory, includefiles[i]); + } + fprintf(file_verify, "\n"); + + /* Multiple iterations to handle nested structs. */ + while (unknown) { + lastunknown = unknown; + unknown = 0; + + /* check all structs... */ + for (int a = 0; a < nr_structs; a++) { + const short *structpoin = structs[a]; + const int structtype = structpoin[0]; + const char *structname = version_struct_alias_from_static(types[structtype]); + + /* when length is not known... */ + if (types_size_native[structtype] == 0) { + + const short *sp = structpoin + 2; + int size_native = 0; + int size_32 = 0; + int size_64 = 0; + bool has_pointer = false; + + /* check all elements in struct */ + for (int b = 0; b < structpoin[1]; b++, sp += 2) { + int type = sp[0]; + const char *cp = names[sp[1]]; + int namelen = (int)strlen(cp); + + /* Write size verification to file. */ + { + char *name_static = alloca(namelen + 1); + DNA_elem_id_strip_copy(name_static, cp); + const char *str_pair[2] = {types[structtype], name_static}; + const char *name_alias = BLI_ghash_lookup(g_version_data.elem_map_alias_from_static, + str_pair); + fprintf(file_verify, + "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset " + "verify\");\n", + structname, + name_alias ? name_alias : name_static, + size_native); + } + + /* is it a pointer or function pointer? */ + if (cp[0] == '*' || cp[1] == '*') { + has_pointer = 1; + /* has the name an extra length? (array) */ + int mul = 1; + if (cp[namelen - 1] == ']') { + mul = DNA_elem_array_size(cp); + } + + if (mul == 0) { + fprintf(stderr, + "Zero array size found or could not parse %s: '%.*s'\n", + types[structtype], + namelen + 1, + cp); + dna_error = 1; + } + + /* 4-8 aligned/ */ + if (sizeof(void *) == 4) { + if (size_native % 4) { + fprintf(stderr, + "Align pointer error in struct (size_native 4): %s %s\n", + types[structtype], + cp); + dna_error = 1; + } + } + else { + if (size_native % 8) { + fprintf(stderr, + "Align pointer error in struct (size_native 8): %s %s\n", + types[structtype], + cp); + dna_error = 1; + } + } + + if (size_64 % 8) { + fprintf(stderr, + "Align pointer error in struct (size_64 8): %s %s\n", + types[structtype], + cp); + dna_error = 1; + } + + size_native += sizeof(void *) * mul; + size_32 += 4 * mul; + size_64 += 8 * mul; + } + else if (cp[0] == '[') { + /* parsing can cause names "var" and "[3]" + * to be found for "float var [3]" */ + fprintf(stderr, + "Parse error in struct, invalid member name: %s %s\n", + types[structtype], + cp); + dna_error = 1; + } + else if (types_size_native[type]) { + /* has the name an extra length? (array) */ + int mul = 1; + if (cp[namelen - 1] == ']') { + mul = DNA_elem_array_size(cp); + } + + if (mul == 0) { + fprintf(stderr, + "Zero array size found or could not parse %s: '%.*s'\n", + types[structtype], + namelen + 1, + cp); + dna_error = 1; + } + + /* struct alignment */ + if (type >= firststruct) { + if (sizeof(void *) == 8 && (size_native % 8)) { + fprintf(stderr, "Align struct error: %s %s\n", types[structtype], cp); + dna_error = 1; + } + } + + /* Check 2-4-8 aligned. */ + if (!check_field_alignment(firststruct, structtype, type, size_32, cp, "32 bit")) { + dna_error = 1; + } + if (!check_field_alignment(firststruct, structtype, type, size_64, cp, "64 bit")) { + dna_error = 1; + } + + size_native += mul * types_size_native[type]; + size_32 += mul * types_size_32[type]; + size_64 += mul * types_size_64[type]; + } + else { + size_native = 0; + size_32 = 0; + size_64 = 0; + break; + } + } + + if (size_native == 0) { + unknown++; + } + else { + types_size_native[structtype] = size_native; + types_size_32[structtype] = size_32; + types_size_64[structtype] = size_64; + /* two ways to detect if a struct contains a pointer: + * has_pointer is set or size_native doesn't match any of 32/64bit lengths*/ + if (has_pointer || size_64 != size_native || size_32 != size_native) { + if (size_64 % 8) { + fprintf(stderr, + "Sizeerror 8 in struct: %s (add %d bytes)\n", + types[structtype], + size_64 % 8); + dna_error = 1; + } + } + + if (size_native % 4) { + fprintf(stderr, + "Sizeerror 4 in struct: %s (add %d bytes)\n", + types[structtype], + size_native % 4); + dna_error = 1; + } + + /* Write size verification to file. */ + fprintf(file_verify, + "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n", + structname, + size_native); + } + } + } + + if (unknown == lastunknown) { + break; + } + } + + if (unknown) { + fprintf(stderr, "ERROR: still %d structs unknown\n", unknown); + + if (debugSDNA) { + fprintf(stderr, "*** Known structs :\n"); + + for (int a = 0; a < nr_structs; a++) { + const short *structpoin = structs[a]; + const int structtype = structpoin[0]; + + /* length unknown */ + if (types_size_native[structtype] != 0) { + fprintf(stderr, " %s\n", types[structtype]); + } + } + } + + fprintf(stderr, "*** Unknown structs :\n"); + + for (int a = 0; a < nr_structs; a++) { + const short *structpoin = structs[a]; + const int structtype = structpoin[0]; + + /* length unknown yet */ + if (types_size_native[structtype] == 0) { + fprintf(stderr, " %s\n", types[structtype]); + } + } + + dna_error = 1; + } + + return dna_error; } #define MAX_DNA_LINE_LENGTH 20 static void dna_write(FILE *file, const void *pntr, const int size) { - static int linelength = 0; - int i; - const char *data; - - data = (const char *)pntr; - - for (i = 0; i < size; i++) { - fprintf(file, "%d, ", data[i]); - linelength++; - if (linelength >= MAX_DNA_LINE_LENGTH) { - fprintf(file, "\n"); - linelength = 0; - } - } + static int linelength = 0; + int i; + const char *data; + + data = (const char *)pntr; + + for (i = 0; i < size; i++) { + fprintf(file, "%d, ", data[i]); + linelength++; + if (linelength >= MAX_DNA_LINE_LENGTH) { + fprintf(file, "\n"); + linelength = 0; + } + } } void print_struct_sizes(void) { - int a, unknown = nr_structs, structtype; - /*int lastunknown;*/ /*UNUSED*/ - const short *structpoin; - printf("\n\n*** All detected structs:\n"); - - while (unknown) { - /*lastunknown = unknown;*/ /*UNUSED*/ - unknown = 0; - - /* check all structs... */ - for (a = 0; a < nr_structs; a++) { - structpoin = structs[a]; - structtype = structpoin[0]; - printf("\t%s\t:%d\n", types[structtype], types_size_native[structtype]); - } - } - - printf("*** End of list\n"); - + int a, unknown = nr_structs, structtype; + /*int lastunknown;*/ /*UNUSED*/ + const short *structpoin; + printf("\n\n*** All detected structs:\n"); + + while (unknown) { + /*lastunknown = unknown;*/ /*UNUSED*/ + unknown = 0; + + /* check all structs... */ + for (a = 0; a < nr_structs; a++) { + structpoin = structs[a]; + structtype = structpoin[0]; + printf("\t%s\t:%d\n", types[structtype], types_size_native[structtype]); + } + } + + printf("*** End of list\n"); } - -static int make_structDNA(const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify) +static int make_structDNA(const char *base_directory, + FILE *file, + FILE *file_offsets, + FILE *file_verify) { - int i; - const short *sp; - /* str contains filenames. Since we now include paths, I stretched */ - /* it a bit. Hope this is enough :) -nzc- */ - char str[SDNA_MAX_FILENAME_LENGTH]; - int firststruct; - - if (debugSDNA > 0) { - fflush(stdout); - printf("Running makesdna at debug level %d\n", debugSDNA); - } - - mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - - /* the longest known struct is 50k, so we assume 100k is sufficient! */ - structdata = MEM_callocN(maxdata, "structdata"); - - /* a maximum of 5000 variables, must be sufficient? */ - names = MEM_callocN(sizeof(char *) * maxnr, "names"); - types = MEM_callocN(sizeof(char *) * maxnr, "types"); - types_size_native = MEM_callocN(sizeof(short) * maxnr, "types_size_native"); - types_size_32 = MEM_callocN(sizeof(short) * maxnr, "types_size_32"); - types_size_64 = MEM_callocN(sizeof(short) * maxnr, "types_size_64"); - structs = MEM_callocN(sizeof(short *) * maxnr, "structs"); - - /* Build versioning data */ - DNA_alias_maps( - DNA_RENAME_ALIAS_FROM_STATIC, - &g_version_data.struct_map_alias_from_static, - &g_version_data.elem_map_alias_from_static); - DNA_alias_maps( - DNA_RENAME_STATIC_FROM_ALIAS, - &g_version_data.struct_map_static_from_alias, - &g_version_data.elem_map_static_from_alias); - - /** - * Insertion of all known types. - * - * \warning Order of function calls here must be aligned with #eSDNA_Type. - * \warning uint is not allowed! use in structs an unsigned int. - * \warning sizes must match #DNA_elem_type_size(). - */ - add_type("char", 1); /* SDNA_TYPE_CHAR */ - add_type("uchar", 1); /* SDNA_TYPE_UCHAR */ - add_type("short", 2); /* SDNA_TYPE_SHORT */ - add_type("ushort", 2); /* SDNA_TYPE_USHORT */ - add_type("int", 4); /* SDNA_TYPE_INT */ - - /* note, long isn't supported, - * these are place-holders to maintain alignment with eSDNA_Type*/ - add_type("long", 4); /* SDNA_TYPE_LONG */ - add_type("ulong", 4); /* SDNA_TYPE_ULONG */ - - add_type("float", 4); /* SDNA_TYPE_FLOAT */ - add_type("double", 8); /* SDNA_TYPE_DOUBLE */ - add_type("int64_t", 8); /* SDNA_TYPE_INT64 */ - add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */ - add_type("void", 0); /* SDNA_TYPE_VOID */ - - /* the defines above shouldn't be output in the padding file... */ - firststruct = nr_types; - - /* add all include files defined in the global array */ - /* Since the internal file+path name buffer has limited length, I do a */ - /* little test first... */ - /* Mind the breaking condition here! */ - DEBUG_PRINTF(0, "\tStart of header scan:\n"); - for (i = 0; *(includefiles[i]) != '\0'; i++) { - sprintf(str, "%s%s", base_directory, includefiles[i]); - DEBUG_PRINTF(0, "\t|-- Converting %s\n", str); - if (convert_include(str)) { - return 1; - } - } - DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", i); - - if (calculate_struct_sizes(firststruct, file_verify, base_directory)) { - /* error */ - return 1; - } - - /* FOR DEBUG */ - if (debugSDNA > 1) { - int a, b; - /* short *elem; */ - short num_types; - - printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs); - for (a = 0; a < nr_names; a++) { - printf(" %s\n", names[a]); - } - printf("\n"); - - sp = types_size_native; - for (a = 0; a < nr_types; a++, sp++) { - printf(" %s %d\n", types[a], *sp); - } - printf("\n"); - - for (a = 0; a < nr_structs; a++) { - sp = structs[a]; - printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]); - num_types = sp[1]; - sp += 2; - /* ? num_types was elem? */ - for (b = 0; b < num_types; b++, sp += 2) { - printf(" %s %s\n", types[sp[0]], names[sp[1]]); - } - } - } - - /* file writing */ - - DEBUG_PRINTF(0, "Writing file ... "); - - if (nr_names == 0 || nr_structs == 0) { - /* pass */ - } - else { - const char nil_bytes[4] = {0}; - int len, len_align; - - dna_write(file, "SDNA", 4); - - /* write names */ - dna_write(file, "NAME", 4); - len = nr_names; - dna_write(file, &len, 4); - /* write array */ - len = 0; - for (int nr = 0; nr < nr_names; nr++) { - int name_size = strlen(names[nr]) + 1; - dna_write(file, names[nr], name_size); - len += name_size; - } - len_align = (len + 3) & ~3; - if (len != len_align) { - dna_write(file, nil_bytes, len_align - len); - } - - /* write TYPES */ - dna_write(file, "TYPE", 4); - len = nr_types; - dna_write(file, &len, 4); - /* write array */ - len = 0; - for (int nr = 0; nr < nr_types; nr++) { - int type_size = strlen(types[nr]) + 1; - dna_write(file, types[nr], type_size); - len += type_size; - } - len_align = (len + 3) & ~3; - if (len != len_align) { - dna_write(file, nil_bytes, len_align - len); - } - - /* WRITE TYPELENGTHS */ - dna_write(file, "TLEN", 4); - - len = 2 * nr_types; - if (nr_types & 1) { - len += 2; - } - dna_write(file, types_size_native, len); - - /* WRITE STRUCTS */ - dna_write(file, "STRC", 4); - len = nr_structs; - dna_write(file, &len, 4); - - /* calc datablock size */ - sp = structs[nr_structs - 1]; - sp += 2 + 2 * (sp[1]); - len = (intptr_t) ((char *) sp - (char *) structs[0]); - len = (len + 3) & ~3; - - dna_write(file, structs[0], len); - - } - - /* write a simple enum with all structs offsets, - * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */ - { - fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n"); - fprintf(file_offsets, "enum {\n"); - for (i = 0; i < nr_structs; i++) { - const short *structpoin = structs[i]; - const int structtype = structpoin[0]; - fprintf(file_offsets, "\t_SDNA_TYPE_%s = %d,\n", version_struct_alias_from_static(types[structtype]), i); - } - fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", nr_structs); - fprintf(file_offsets, "};\n\n"); - } - - /* Check versioning errors which could cause duplicate names, - * do last because names are stripped. */ - { - GSet *names_unique = BLI_gset_str_new_ex(__func__, 512); - for (int struct_nr = 0; struct_nr < nr_structs; struct_nr++) { - sp = structs[struct_nr]; - const char *struct_name = types[sp[0]]; - const int len = sp[1]; - sp += 2; - for (int a = 0; a < len; a++, sp += 2) { - char *name = names[sp[1]]; - DNA_elem_id_strip(name); - if (!BLI_gset_add(names_unique, name)) { - fprintf(stderr, "Error: duplicate name found '%s.%s', " - "likely cause is 'dna_rename_defs.h'\n", - struct_name, name); - return 1; - } - } - BLI_gset_clear(names_unique, NULL); - } - BLI_gset_free(names_unique, NULL); - } - - MEM_freeN(structdata); - MEM_freeN(names); - MEM_freeN(types); - MEM_freeN(types_size_native); - MEM_freeN(types_size_32); - MEM_freeN(types_size_64); - MEM_freeN(structs); - - BLI_memarena_free(mem_arena); - - BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); - BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); - BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); - BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL); - - DEBUG_PRINTF(0, "done.\n"); - - return 0; + int i; + const short *sp; + /* str contains filenames. Since we now include paths, I stretched */ + /* it a bit. Hope this is enough :) -nzc- */ + char str[SDNA_MAX_FILENAME_LENGTH]; + int firststruct; + + if (debugSDNA > 0) { + fflush(stdout); + printf("Running makesdna at debug level %d\n", debugSDNA); + } + + mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + + /* the longest known struct is 50k, so we assume 100k is sufficient! */ + structdata = MEM_callocN(maxdata, "structdata"); + + /* a maximum of 5000 variables, must be sufficient? */ + names = MEM_callocN(sizeof(char *) * maxnr, "names"); + types = MEM_callocN(sizeof(char *) * maxnr, "types"); + types_size_native = MEM_callocN(sizeof(short) * maxnr, "types_size_native"); + types_size_32 = MEM_callocN(sizeof(short) * maxnr, "types_size_32"); + types_size_64 = MEM_callocN(sizeof(short) * maxnr, "types_size_64"); + structs = MEM_callocN(sizeof(short *) * maxnr, "structs"); + + /* Build versioning data */ + DNA_alias_maps(DNA_RENAME_ALIAS_FROM_STATIC, + &g_version_data.struct_map_alias_from_static, + &g_version_data.elem_map_alias_from_static); + DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, + &g_version_data.struct_map_static_from_alias, + &g_version_data.elem_map_static_from_alias); + + /** + * Insertion of all known types. + * + * \warning Order of function calls here must be aligned with #eSDNA_Type. + * \warning uint is not allowed! use in structs an unsigned int. + * \warning sizes must match #DNA_elem_type_size(). + */ + add_type("char", 1); /* SDNA_TYPE_CHAR */ + add_type("uchar", 1); /* SDNA_TYPE_UCHAR */ + add_type("short", 2); /* SDNA_TYPE_SHORT */ + add_type("ushort", 2); /* SDNA_TYPE_USHORT */ + add_type("int", 4); /* SDNA_TYPE_INT */ + + /* note, long isn't supported, + * these are place-holders to maintain alignment with eSDNA_Type*/ + add_type("long", 4); /* SDNA_TYPE_LONG */ + add_type("ulong", 4); /* SDNA_TYPE_ULONG */ + + add_type("float", 4); /* SDNA_TYPE_FLOAT */ + add_type("double", 8); /* SDNA_TYPE_DOUBLE */ + add_type("int64_t", 8); /* SDNA_TYPE_INT64 */ + add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */ + add_type("void", 0); /* SDNA_TYPE_VOID */ + + /* the defines above shouldn't be output in the padding file... */ + firststruct = nr_types; + + /* add all include files defined in the global array */ + /* Since the internal file+path name buffer has limited length, I do a */ + /* little test first... */ + /* Mind the breaking condition here! */ + DEBUG_PRINTF(0, "\tStart of header scan:\n"); + for (i = 0; *(includefiles[i]) != '\0'; i++) { + sprintf(str, "%s%s", base_directory, includefiles[i]); + DEBUG_PRINTF(0, "\t|-- Converting %s\n", str); + if (convert_include(str)) { + return 1; + } + } + DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", i); + + if (calculate_struct_sizes(firststruct, file_verify, base_directory)) { + /* error */ + return 1; + } + + /* FOR DEBUG */ + if (debugSDNA > 1) { + int a, b; + /* short *elem; */ + short num_types; + + printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs); + for (a = 0; a < nr_names; a++) { + printf(" %s\n", names[a]); + } + printf("\n"); + + sp = types_size_native; + for (a = 0; a < nr_types; a++, sp++) { + printf(" %s %d\n", types[a], *sp); + } + printf("\n"); + + for (a = 0; a < nr_structs; a++) { + sp = structs[a]; + printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]); + num_types = sp[1]; + sp += 2; + /* ? num_types was elem? */ + for (b = 0; b < num_types; b++, sp += 2) { + printf(" %s %s\n", types[sp[0]], names[sp[1]]); + } + } + } + + /* file writing */ + + DEBUG_PRINTF(0, "Writing file ... "); + + if (nr_names == 0 || nr_structs == 0) { + /* pass */ + } + else { + const char nil_bytes[4] = {0}; + int len, len_align; + + dna_write(file, "SDNA", 4); + + /* write names */ + dna_write(file, "NAME", 4); + len = nr_names; + dna_write(file, &len, 4); + /* write array */ + len = 0; + for (int nr = 0; nr < nr_names; nr++) { + int name_size = strlen(names[nr]) + 1; + dna_write(file, names[nr], name_size); + len += name_size; + } + len_align = (len + 3) & ~3; + if (len != len_align) { + dna_write(file, nil_bytes, len_align - len); + } + + /* write TYPES */ + dna_write(file, "TYPE", 4); + len = nr_types; + dna_write(file, &len, 4); + /* write array */ + len = 0; + for (int nr = 0; nr < nr_types; nr++) { + int type_size = strlen(types[nr]) + 1; + dna_write(file, types[nr], type_size); + len += type_size; + } + len_align = (len + 3) & ~3; + if (len != len_align) { + dna_write(file, nil_bytes, len_align - len); + } + + /* WRITE TYPELENGTHS */ + dna_write(file, "TLEN", 4); + + len = 2 * nr_types; + if (nr_types & 1) { + len += 2; + } + dna_write(file, types_size_native, len); + + /* WRITE STRUCTS */ + dna_write(file, "STRC", 4); + len = nr_structs; + dna_write(file, &len, 4); + + /* calc datablock size */ + sp = structs[nr_structs - 1]; + sp += 2 + 2 * (sp[1]); + len = (intptr_t)((char *)sp - (char *)structs[0]); + len = (len + 3) & ~3; + + dna_write(file, structs[0], len); + } + + /* write a simple enum with all structs offsets, + * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */ + { + fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n"); + fprintf(file_offsets, "enum {\n"); + for (i = 0; i < nr_structs; i++) { + const short *structpoin = structs[i]; + const int structtype = structpoin[0]; + fprintf(file_offsets, + "\t_SDNA_TYPE_%s = %d,\n", + version_struct_alias_from_static(types[structtype]), + i); + } + fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", nr_structs); + fprintf(file_offsets, "};\n\n"); + } + + /* Check versioning errors which could cause duplicate names, + * do last because names are stripped. */ + { + GSet *names_unique = BLI_gset_str_new_ex(__func__, 512); + for (int struct_nr = 0; struct_nr < nr_structs; struct_nr++) { + sp = structs[struct_nr]; + const char *struct_name = types[sp[0]]; + const int len = sp[1]; + sp += 2; + for (int a = 0; a < len; a++, sp += 2) { + char *name = names[sp[1]]; + DNA_elem_id_strip(name); + if (!BLI_gset_add(names_unique, name)) { + fprintf(stderr, + "Error: duplicate name found '%s.%s', " + "likely cause is 'dna_rename_defs.h'\n", + struct_name, + name); + return 1; + } + } + BLI_gset_clear(names_unique, NULL); + } + BLI_gset_free(names_unique, NULL); + } + + MEM_freeN(structdata); + MEM_freeN(names); + MEM_freeN(types); + MEM_freeN(types_size_native); + MEM_freeN(types_size_32); + MEM_freeN(types_size_64); + MEM_freeN(structs); + + BLI_memarena_free(mem_arena); + + BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL); + BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL); + BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL); + BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL); + + DEBUG_PRINTF(0, "done.\n"); + + return 0; } /** \} */ @@ -1368,80 +1423,80 @@ static int make_structDNA(const char *base_directory, FILE *file, FILE *file_off static void make_bad_file(const char *file, int line) { - FILE *fp = fopen(file, "w"); - fprintf(fp, - "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n", - __FILE__, line); - fclose(fp); + FILE *fp = fopen(file, "w"); + fprintf(fp, + "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n", + __FILE__, + line); + fclose(fp); } #ifndef BASE_HEADER -#define BASE_HEADER "../" +# define BASE_HEADER "../" #endif int main(int argc, char **argv) { - int return_status = 0; - - if (argc != 4 && argc != 5) { - printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]); - return_status = 1; - } - else { - FILE *file_dna = fopen(argv[1], "w"); - FILE *file_dna_offsets = fopen(argv[2], "w"); - FILE *file_dna_verify = fopen(argv[3], "w"); - if (!file_dna) { - printf("Unable to open file: %s\n", argv[1]); - return_status = 1; - } - else if (!file_dna_offsets) { - printf("Unable to open file: %s\n", argv[2]); - return_status = 1; - } - else if (!file_dna_verify) { - printf("Unable to open file: %s\n", argv[3]); - return_status = 1; - } - else { - const char *base_directory; - - if (argc == 5) { - base_directory = argv[4]; - } - else { - base_directory = BASE_HEADER; - } - - fprintf(file_dna, "extern const unsigned char DNAstr[];\n"); - fprintf(file_dna, "const unsigned char DNAstr[] = {\n"); - if (make_structDNA(base_directory, file_dna, file_dna_offsets, file_dna_verify)) { - /* error */ - fclose(file_dna); - file_dna = NULL; - make_bad_file(argv[1], __LINE__); - return_status = 1; - } - else { - fprintf(file_dna, "};\n"); - fprintf(file_dna, "extern const int DNAlen;\n"); - fprintf(file_dna, "const int DNAlen = sizeof(DNAstr);\n"); - } - } - - if (file_dna) { - fclose(file_dna); - } - if (file_dna_offsets) { - fclose(file_dna_offsets); - } - if (file_dna_verify) { - fclose(file_dna_verify); - } - } - - - return return_status; + int return_status = 0; + + if (argc != 4 && argc != 5) { + printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]); + return_status = 1; + } + else { + FILE *file_dna = fopen(argv[1], "w"); + FILE *file_dna_offsets = fopen(argv[2], "w"); + FILE *file_dna_verify = fopen(argv[3], "w"); + if (!file_dna) { + printf("Unable to open file: %s\n", argv[1]); + return_status = 1; + } + else if (!file_dna_offsets) { + printf("Unable to open file: %s\n", argv[2]); + return_status = 1; + } + else if (!file_dna_verify) { + printf("Unable to open file: %s\n", argv[3]); + return_status = 1; + } + else { + const char *base_directory; + + if (argc == 5) { + base_directory = argv[4]; + } + else { + base_directory = BASE_HEADER; + } + + fprintf(file_dna, "extern const unsigned char DNAstr[];\n"); + fprintf(file_dna, "const unsigned char DNAstr[] = {\n"); + if (make_structDNA(base_directory, file_dna, file_dna_offsets, file_dna_verify)) { + /* error */ + fclose(file_dna); + file_dna = NULL; + make_bad_file(argv[1], __LINE__); + return_status = 1; + } + else { + fprintf(file_dna, "};\n"); + fprintf(file_dna, "extern const int DNAlen;\n"); + fprintf(file_dna, "const int DNAlen = sizeof(DNAstr);\n"); + } + } + + if (file_dna) { + fclose(file_dna); + } + if (file_dna_offsets) { + fclose(file_dna_offsets); + } + if (file_dna_verify) { + fclose(file_dna_verify); + } + } + + return return_status; } /* handy but fails on struct bounds which makesdna doesn't care about @@ -1451,9 +1506,9 @@ int main(int argc, char **argv) /* extra safety check that we are aligned, * warnings here are easier to fix the makesdna's */ -#ifdef __GNUC__ -# pragma GCC diagnostic error "-Wpadded" -#endif +# ifdef __GNUC__ +# pragma GCC diagnostic error "-Wpadded" +# endif #endif /* if 0 */ @@ -1535,7 +1590,6 @@ int main(int argc, char **argv) /** \} */ - /* -------------------------------------------------------------------- */ /** \name DNA Renaming Sanity Check * |