27#define DNA_DEPRECATED_ALLOW
48#define SDNA_MAX_FILENAME_LENGTH 255
53#include "dna_includes_as_strings.h"
109#define DEBUG_PRINTF(debug_level, ...) \
111 if (debugSDNA > debug_level) { \
112 printf(__VA_ARGS__); \
144static int add_member(
const char *member_name);
172static void dna_write(FILE *file,
const void *pntr,
const int size);
188 const char *identifier,
189 const size_t identifier_len)
191 if (strncmp(
str, identifier, identifier_len) == 0) {
193 if (isdigit(
str[identifier_len]) || isalpha(
str[identifier_len]) ||
194 (
str[identifier_len] ==
'_'))
205 const size_t identifier_len = strlen(identifier);
211 const size_t identifier_len = strlen(identifier);
213 (*str_ptr) += identifier_len;
221 const char *type_static =
static_cast<const char *
>(
223 if (type_static !=
nullptr) {
231 const char *type_alias =
static_cast<const char *
>(
233 if (type_alias !=
nullptr) {
240 const char *member_alias_full)
242 const uint member_alias_full_len = strlen(member_alias_full);
243 char *member_alias =
static_cast<char *
>(alloca(member_alias_full_len + 1));
245 const char *str_pair[2] = {
types[type_index], member_alias};
246 const char *member_static =
static_cast<const char *
>(
248 if (member_static !=
nullptr) {
253 strlen(member_static),
255 member_alias_full_len,
258 return member_alias_full;
267 const int name_size = strlen(
name) + 1;
268 char *name_strip =
static_cast<char *
>(alloca(name_size));
271 const char prefix[] = {
'p',
'a',
'd'};
273 if (
name[0] ==
'_') {
274 if (strncmp(&name_strip[1], prefix,
sizeof(prefix)) != 0) {
276 stderr,
"Error: only '_pad' variables can start with an underscore, found '%s'\n",
name);
280 else if (strncmp(name_strip, prefix,
sizeof(prefix)) == 0) {
281 int i =
sizeof(prefix);
282 if (name_strip[
i] >=
'a' && name_strip[
i] <=
'z') {
286 bool has_only_digit_or_none =
true;
287 for (; name_strip[
i];
i++) {
288 const char c = name_strip[
i];
289 if (!((c >=
'0' && c <=
'9') || c ==
'_')) {
290 has_only_digit_or_none =
false;
294 if (has_only_digit_or_none) {
297 stderr,
"Error: padding variables must be formatted '_pad[number]', found '%s'\n",
name);
307 if (type_name[0] == 0) {
310 if (strchr(type_name,
'*')) {
319 for (
int type_index = 0; type_index <
types_num; type_index++) {
333 const int type_name_len = strlen(type_name) + 1;
335 memcpy(cp, type_name, type_name_len);
343 printf(
"too many types\n");
364 if (member_name[0] == 0 ) {
368 if (member_name[0] ==
'(' && member_name[1] ==
'*') {
373 int isfuncptr = (strchr(member_name + 1,
'(')) !=
nullptr;
375 DEBUG_PRINTF(3,
"\t\t\t\t*** Function pointer or multidim array pointer found\n");
379 while (member_name[
i] !=
')') {
380 buf[
i] = member_name[
i];
392 while ((member_name[j] != 0) && (member_name[j] !=
')')) {
393 DEBUG_PRINTF(3,
"seen %c (%d)\n", member_name[j], member_name[j]);
398 "special after offset%d\n",
405 if (member_name[j] == 0) {
406 DEBUG_PRINTF(3,
"offsetting for multi-dimensional array pointer\n");
409 printf(
"Error during tokenizing multi-dimensional array pointer\n");
412 else if (member_name[j] == 0) {
416 while (member_name[j] !=
')') {
423 else if (member_name[j] ==
')') {
428 printf(
"Error during tokening function pointer argument list\n");
444 if ((strncmp(buf,
"(*headdraw", 10) == 0) || strncmp(buf,
"(*windraw", 9) == 0) {
461 DEBUG_PRINTF(3,
"\t\t\t\t\tProposing fp name %s\n", buf);
470 for (
int member_index = 0; member_index <
members_num; member_index++) {
482 const int name_len = strlen(
name) + 1;
484 memcpy(cp,
name, name_len);
488 printf(
"too many names\n");
503 const int len = sp[1];
511 printf(
"too many structs\n");
523 for (; *
str && *start;
str++, start++) {
524 if (*
str != *start) {
529 return (*start ==
'\0');
543 while (*
str ==
' ') {
554 while ((
str = strchr(
str,
'#'))) {
556 while (*
str ==
' ') {
571 temp[maindata_len] =
' ';
573 memcpy(temp, maindata, maindata_len);
578 int a = maindata_len;
579 bool comment =
false;
581 if (cp[0] ==
'/' && cp[1] ==
'/') {
584 else if (*cp ==
'\n') {
587 if (comment || *cp < 32 || *cp > 128) {
594 const char *cpp_block_start =
"ifdef __cplusplus";
595 const char *cpp_block_end =
"endif";
603 int square_bracket_level = 0;
604 bool skip_until_closing_brace =
false;
607 if (cp[0] ==
'/' && cp[1] ==
'*') {
612 if (cp[0] ==
'*' && cp[1] ==
'/') {
618 if (comment ==
false) {
620 square_bracket_level++;
622 else if (cp[0] ==
']') {
623 square_bracket_level--;
631 else if (cp[0] ==
' ' && (square_bracket_level > 0)) {
637 else if (cp[0] ==
' ' && cp[1] ==
' ') {
640 else if (cp[-1] ==
'*' && cp[0] ==
' ') {
652 skip_until_closing_brace =
true;
654 else if (skip_until_closing_brace) {
656 skip_until_closing_brace =
false;
662 if (end_ptr ==
nullptr) {
663 fprintf(stderr,
"Error: '%s' block must end with '%s'\n", cpp_block_start, cpp_block_end);
666 const int skip_offset = end_ptr - cp + strlen(cpp_block_end);
688 FILE *fp = fopen(filepath,
"rb");
690 FILE *fp = fopen(filepath,
"r");
699 fseek(fp, 0
L, SEEK_END);
701 fseek(fp, 0
L, SEEK_SET);
715 if (fread(
data, *r_len, 1, fp) != 1) {
733 char *maindata =
static_cast<char *
>(
read_file_data(filepath, &maindata_len));
735 if (maindata_len == -1) {
736 fprintf(stderr,
"Can't read file %s\n", filepath);
741 char *mainend = maindata + maindata_len - 1;
745 bool skip_struct =
false;
746 while (
count < maindata_len) {
749 if (md[0] ==
'#' && md[1] ==
' ' && md[2] ==
'#') {
772 const int struct_type_index =
add_type(md1, 0);
773 if (struct_type_index == -1) {
774 fprintf(stderr,
"File '%s' contains struct we can't parse \"%s\"\n", filepath, md1);
778 short *structpoin =
add_struct(struct_type_index);
779 short *sp = structpoin + 2;
785 while (*md1 !=
'}') {
790 if (
ELEM(*md1,
',',
' ')) {
798 while (*md1 !=
'}') {
805 const char *md1_prev = md1;
813 "File '%s' contains non white space character "
814 "\"%c\" after identifier \"%s\"\n",
825 if (
STR_ELEM(md1,
"long",
"ulong")) {
828 "File '%s' contains use of \"%s\" in DNA struct which is not allowed\n",
833 const int member_type_index =
add_type(md1, 0);
834 if (member_type_index == -1) {
836 stderr,
"File '%s' contains struct we can't parse \"%s\"\n", filepath, md1);
845 while (*md1 !=
';') {
854 int slen = int(strlen(md1));
855 if (md1[slen - 1] ==
';') {
862 "File '%s' contains struct with name that can't be added \"%s\"\n",
868 sp[0] = member_type_index;
886 "File '%s' contains struct with name that can't be added \"%s\"\n",
893 sp[0] = member_type_index;
924 int struct_type_index,
933 "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n",
935 types[struct_type_index],
942 "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n",
944 types[struct_type_index],
951 "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n",
953 types[struct_type_index],
963 bool dna_error =
false;
966 fprintf(file_verify,
"/* Verify struct sizes and member offsets are as expected by DNA. */\n");
967 fprintf(file_verify,
"#include \"BLI_assert.h\"\n\n");
969 fprintf(file_verify,
"#define DNA_DEPRECATED_ALLOW\n");
972 fprintf(file_verify,
"#define assert_line_ assert_line_DNA_\n");
974 fprintf(file_verify,
"#include \"%s%s\"\n", base_directory,
includefiles[
i]);
976 fprintf(file_verify,
"#undef assert_line_\n");
977 fprintf(file_verify,
"\n");
983 const int lastunknown = unknown;
989 const short *structpoin =
structs[a];
990 const int struct_type_index = structpoin[0];
996 const short *sp = structpoin + 2;
1001 int max_align_32 = 0;
1002 int max_align_64 = 0;
1005 for (
int b = 0;
b < structpoin[1];
b++, sp += 2) {
1007 const char *cp =
members[sp[1]];
1008 int namelen = int(strlen(cp));
1014 char name_static[1024];
1018 const char *str_pair[2] = {
types[struct_type_index], name_static};
1019 const char *name_alias =
static_cast<const char *
>(
1021 fprintf(file_verify,
1022 "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset "
1025 name_alias ? name_alias : name_static,
1030 if (cp[0] ==
'*' || cp[1] ==
'*') {
1033 if (cp[namelen - 1] ==
']') {
1039 "Zero array size found or could not parse %s: '%.*s'\n",
1040 types[struct_type_index],
1047 if (
sizeof(
void *) == 4) {
1048 if (size_native % 4) {
1050 "Align pointer error in struct (size_native 4): %s %s\n",
1051 types[struct_type_index],
1057 if (size_native % 8) {
1059 "Align pointer error in struct (size_native 8): %s %s\n",
1060 types[struct_type_index],
1068 "Align pointer error in struct (size_64 8): %s %s\n",
1069 types[struct_type_index],
1074 size_native +=
sizeof(
void *) *
mul;
1077 max_align_32 = std::max(max_align_32, 4);
1078 max_align_64 = std::max(max_align_64, 8);
1080 else if (cp[0] ==
'[') {
1084 "Parse error in struct, invalid member name: %s %s\n",
1085 types[struct_type_index],
1092 if (cp[namelen - 1] ==
']') {
1098 "Zero array size found or could not parse %s: '%.*s'\n",
1099 types[struct_type_index],
1106 if (type >= firststruct) {
1107 if (
sizeof(
void *) == 8 && (size_native % 8)) {
1109 "Align struct error: %s::%s (starts at %d on the native platform; "
1110 "%d %% %zu = %d bytes)\n",
1111 types[struct_type_index],
1123 firststruct, struct_type_index, type, size_32, cp,
"32 bit"))
1128 firststruct, struct_type_index, type, size_64, cp,
"64 bit"))
1136 max_align_32 = std::max<int>(max_align_32,
types_align_32[type]);
1137 max_align_64 = std::max<int>(max_align_64,
types_align_64[type]);
1147 if (size_native == 0) {
1166 if (size_32 % max_align_32) {
1170 if ((size_64 % max_align_64 == 0) && (size_32 % max_align_32 == 4)) {
1172 "Sizeerror in 32 bit struct: %s (add padding pointer)\n",
1173 types[struct_type_index]);
1177 "Sizeerror in 32 bit struct: %s (add %d bytes)\n",
1178 types[struct_type_index],
1179 max_align_32 - (size_32 % max_align_32));
1184 if (size_64 % max_align_64) {
1186 "Sizeerror in 64 bit struct: %s (add %d bytes)\n",
1187 types[struct_type_index],
1188 max_align_64 - (size_64 % max_align_64));
1192 if (size_native % 4 && !
ELEM(size_native, 1, 2)) {
1194 "Sizeerror 4 in struct: %s (add %d bytes)\n",
1195 types[struct_type_index],
1201 fprintf(file_verify,
1202 "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n",
1209 if (unknown == lastunknown) {
1215 fprintf(stderr,
"ERROR: still %d structs unknown\n", unknown);
1218 fprintf(stderr,
"*** Known structs :\n");
1221 const short *structpoin =
structs[a];
1222 const int structtype = structpoin[0];
1226 fprintf(stderr,
" %s\n",
types[structtype]);
1231 fprintf(stderr,
"*** Unknown structs :\n");
1234 const short *structpoin =
structs[a];
1235 const int structtype = structpoin[0];
1239 fprintf(stderr,
" %s\n",
types[structtype]);
1249#define MAX_DNA_LINE_LENGTH 20
1253 static int linelength = 0;
1254 const char *
data = (
const char *)pntr;
1256 for (
int i = 0;
i <
size;
i++) {
1257 fprintf(file,
"%d, ",
data[
i]);
1260 fprintf(file,
"\n");
1269 printf(
"\n\n*** All detected structs:\n");
1276 const short *structpoin =
structs[a];
1277 const int structtype = structpoin[0];
1282 printf(
"*** End of list\n");
1286 const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify, FILE *file_ids)
1351 const int raw_data_type_index =
add_type(
"raw_data", 0);
1352 short *raw_data_struct_info =
add_struct(raw_data_type_index);
1354 raw_data_struct_info[1] = 0;
1366 int header_count = 0;
1379 DEBUG_PRINTF(0,
"\tFinished scanning %d headers.\n", header_count);
1390 short struct_members_num;
1407 struct_members_num = sp[1];
1409 for (
b = 0;
b < struct_members_num;
b++, sp += 2) {
1410 printf(
" %s %s allign32:%d, allign64:%d\n",
1427 const char nil_bytes[4] = {0};
1437 for (
int member_index = 0; member_index <
members_num; member_index++) {
1438 int member_len = strlen(
members[member_index]) + 1;
1442 int len_align = (
len + 3) & ~3;
1443 if (
len != len_align) {
1453 for (
int type_index = 0; type_index <
types_num; type_index++) {
1454 int type_len = strlen(
types[type_index]) + 1;
1458 len_align = (
len + 3) & ~3;
1459 if (
len != len_align) {
1479 sp += 2 + 2 * (sp[1]);
1480 len = intptr_t((
char *)sp - (
char *)
structs[0]);
1489 fprintf(file_offsets,
"#pragma once\n");
1490 fprintf(file_offsets,
"#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n");
1491 fprintf(file_offsets,
"enum {\n");
1493 const short *structpoin =
structs[
i];
1494 const int struct_type_index = structpoin[0];
1495 fprintf(file_offsets,
1496 "\t_SDNA_TYPE_%s = %d,\n",
1500 fprintf(file_offsets,
"\tSDNA_TYPE_MAX = %d,\n",
structs_num);
1501 fprintf(file_offsets,
"};\n\n");
1505 fprintf(file_ids,
"\n\nnamespace blender::dna {\n\n");
1506 fprintf(file_ids,
"template<typename T> int sdna_struct_id_get();\n\n");
1507 fprintf(file_ids,
"int sdna_struct_id_get_max();\n");
1508 fprintf(file_ids,
"int sdna_struct_id_get_max() { return %d; }\n",
structs_num - 1);
1509 fprintf(file_ids,
"\n}\n");
1513 const short *structpoin =
structs[
i];
1514 const int struct_type_index = structpoin[0];
1516 fprintf(file_ids,
"struct %s;\n",
name);
1518 "template<> int blender::dna::sdna_struct_id_get<%s>() { return %d; }\n",
1528 for (
int struct_index = 0; struct_index <
structs_num; struct_index++) {
1529 const short *sp =
structs[struct_index];
1530 const char *type =
types[sp[0]];
1531 const int len = sp[1];
1533 for (
int a = 0; a <
len; a++, sp += 2) {
1534 char *member =
members[sp[1]];
1538 "Error: duplicate name found '%s.%s', "
1539 "likely cause is 'dna_rename_defs.h'\n",
1582 FILE *fp = fopen(file,
"w");
1584 "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n",
1591# define BASE_HEADER "../"
1596 int return_status = 0;
1598 if (!
ELEM(argc, 5, 6)) {
1599 printf(
"Usage: %s dna.c dna_struct_offsets.h dna_struct_ids.cc [base directory]\n", argv[0]);
1603 FILE *file_dna = fopen(argv[1],
"w");
1604 FILE *file_dna_offsets = fopen(argv[2],
"w");
1605 FILE *file_dna_verify = fopen(argv[3],
"w");
1606 FILE *file_dna_ids = fopen(argv[4],
"w");
1608 printf(
"Unable to open file: %s\n", argv[1]);
1611 else if (!file_dna_offsets) {
1612 printf(
"Unable to open file: %s\n", argv[2]);
1615 else if (!file_dna_verify) {
1616 printf(
"Unable to open file: %s\n", argv[3]);
1619 else if (!file_dna_ids) {
1620 printf(
"Unable to open file: %s\n", argv[4]);
1624 const char *base_directory;
1627 base_directory = argv[5];
1637# define FORCE_ALIGN_4 " __attribute__((aligned(4))) "
1639# define FORCE_ALIGN_4 " "
1641 fprintf(file_dna,
"extern const unsigned char DNAstr[];\n");
1642 fprintf(file_dna,
"const unsigned char" FORCE_ALIGN_4 "DNAstr[] = {\n");
1646 base_directory, file_dna, file_dna_offsets, file_dna_verify, file_dna_ids))
1655 fprintf(file_dna,
"};\n");
1656 fprintf(file_dna,
"extern const int DNAlen;\n");
1657 fprintf(file_dna,
"const int DNAlen = sizeof(DNAstr);\n");
1664 if (file_dna_offsets) {
1665 fclose(file_dna_offsets);
1667 if (file_dna_verify) {
1668 fclose(file_dna_verify);
1671 fclose(file_dna_ids);
1675 return return_status;
1686# pragma GCC diagnostic error "-Wpadded"
1693#include "dna_includes_all.h"
1709#define DNA_STRUCT_RENAME(old, new) (void)sizeof(new);
1710#define DNA_STRUCT_RENAME_MEMBER(struct_name, old, new) (void)offsetof(struct_name, new);
1712#undef DNA_STRUCT_RENAME
1713#undef DNA_STRUCT_RENAME_MEMBER
#define BLI_STATIC_ASSERT(a, msg)
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
GSet * BLI_gset_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_gset_add(GSet *gs, void *key)
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
#define SNPRINTF(dst, format,...)
#define UNUSED_FUNCTION(x)
#define SDNA_RAW_DATA_STRUCT_INDEX
Read Guarded memory(de)allocation.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static void mul(btAlignedObjectArray< T > &items, const Q &value)
int DNA_member_array_num(const char *str)
uint DNA_member_id_offset_start(const char *member_full)
uint DNA_member_id_strip(char *member)
uint DNA_member_id_strip_copy(char *member_id_dst, const char *member_full_src)
char * DNA_member_id_rename(MemArena *mem_arena, const char *member_id_src, const int member_id_src_len, const char *member_id_dst, const int member_id_dst_len, const char *member_full_src, const int member_full_src_len, const uint member_full_src_offset_len)
@ DNA_RENAME_ALIAS_FROM_STATIC
@ DNA_RENAME_STATIC_FROM_ALIAS
void DNA_alias_maps(enum eDNA_RenameDir version_dir, struct GHash **r_type_map, struct GHash **r_member_map)
static int additional_slen_offset
static bool match_identifier(const char *str, const char *identifier)
#define MAX_DNA_LINE_LENGTH
static short * types_size_native
static short * types_align_32
static int preprocess_include(char *maindata, const int maindata_len)
static short * types_size_32
void print_struct_sizes()
static char * match_preproc_strstr(char *__restrict str, const char *__restrict start)
static bool str_startswith(const char *__restrict str, const char *__restrict start)
static short * structdata
GHash * type_map_alias_from_static
static int add_type(const char *type_name, int size)
static const char * version_member_static_from_alias(const int type_index, const char *member_alias_full)
static short * types_size_64
static bool match_identifier_and_advance(char **str_ptr, const char *identifier)
static int add_member(const char *member_name)
static void * read_file_data(const char *filepath, int *r_len)
GHash * member_map_alias_from_static
void BLI_system_backtrace(FILE *fp)
static int make_structDNA(const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify, FILE *file_ids)
static struct @262302365306145015147135362170176324152201236327 g_version_data
static void dna_write(FILE *file, const void *pntr, const int size)
static bool check_field_alignment(int firststruct, int struct_type_index, int type, int len, const char *name, const char *detail)
#define DEBUG_PRINTF(debug_level,...)
static short * add_struct(int type_index)
static int convert_include(const char *filepath)
GHash * type_map_static_from_alias
static const char * version_struct_alias_from_static(const char *type_static)
static short * types_align_64
static bool match_identifier_with_len(const char *str, const char *identifier, const size_t identifier_len)
#define SDNA_MAX_FILENAME_LENGTH
static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory)
static const char * version_struct_static_from_alias(const char *type_alias)
GHash * member_map_static_from_alias
static const char * includefiles[]
static MemArena * mem_arena
static bool is_name_legal(const char *name)
static bool match_preproc_prefix(const char *__restrict str, const char *__restrict start)
static void make_bad_file(const char *file, int line)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)