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__); \
137static int add_type(
const char *type_name,
int size);
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);
304static int add_type(
const char *type_name,
int size)
307 if (type_name[0] == 0) {
310 if (strchr(type_name,
'*')) {
319 for (
int type_index = 0; type_index <
types_num; type_index++) {
320 if (
STREQ(type_name, types[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 ==
' ') {
570 char *temp =
static_cast<char *
>(
MEM_mallocN(maindata_len + 1,
"preprocess_include"));
571 temp[maindata_len] =
' ';
573 memcpy(temp, maindata, maindata_len);
578 int a = maindata_len;
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 bool skip_until_closing_brace =
false;
606 if (cp[0] ==
'/' && cp[1] ==
'*') {
610 if (cp[0] ==
'*' && cp[1] ==
'/') {
619 else if (cp[0] ==
' ' && cp[1] ==
' ') {
622 else if (cp[-1] ==
'*' && cp[0] ==
' ') {
634 skip_until_closing_brace =
true;
636 else if (skip_until_closing_brace) {
638 skip_until_closing_brace =
false;
644 if (end_ptr ==
nullptr) {
645 fprintf(stderr,
"Error: '%s' block must end with '%s'\n", cpp_block_start, cpp_block_end);
648 const int skip_offset = end_ptr - cp + strlen(cpp_block_end);
668 FILE *fp = fopen(filepath,
"rb");
670 FILE *fp = fopen(filepath,
"r");
679 fseek(fp, 0
L, SEEK_END);
681 fseek(fp, 0
L, SEEK_SET);
695 if (fread(data, *r_len, 1, fp) != 1) {
713 char *maindata =
static_cast<char *
>(
read_file_data(filepath, &maindata_len));
715 if (maindata_len == -1) {
716 fprintf(stderr,
"Can't read file %s\n", filepath);
721 char *mainend = maindata + maindata_len - 1;
725 bool skip_struct =
false;
726 while (
count < maindata_len) {
729 if (md[0] ==
'#' && md[1] ==
' ' && md[2] ==
'#') {
752 const int struct_type_index =
add_type(md1, 0);
753 if (struct_type_index == -1) {
754 fprintf(stderr,
"File '%s' contains struct we can't parse \"%s\"\n", filepath, md1);
758 short *structpoin =
add_struct(struct_type_index);
759 short *sp = structpoin + 2;
761 DEBUG_PRINTF(1,
"\t|\t|-- detected struct %s\n", types[struct_type_index]);
765 while (*md1 !=
'}') {
770 if (
ELEM(*md1,
',',
' ')) {
778 while (*md1 !=
'}') {
785 const char *md1_prev = md1;
793 "File '%s' contains non white space character "
794 "\"%c\" after identifier \"%s\"\n",
805 if (
STR_ELEM(md1,
"long",
"ulong")) {
808 "File '%s' contains use of \"%s\" in DNA struct which is not allowed\n",
813 const int member_type_index =
add_type(md1, 0);
814 if (member_type_index == -1) {
816 stderr,
"File '%s' contains struct we can't parse \"%s\"\n", filepath, md1);
825 while (*md1 !=
';') {
834 int slen =
int(strlen(md1));
835 if (md1[slen - 1] ==
';') {
842 "File '%s' contains struct with name that can't be added \"%s\"\n",
848 sp[0] = member_type_index;
851 if (
members[name] !=
nullptr) {
866 "File '%s' contains struct with name that can't be added \"%s\"\n",
873 sp[0] = member_type_index;
875 if (
members[name] !=
nullptr) {
904 int struct_type_index,
913 "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n",
915 types[struct_type_index],
922 "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n",
924 types[struct_type_index],
931 "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n",
933 types[struct_type_index],
943 bool dna_error =
false;
946 fprintf(file_verify,
"/* Verify struct sizes and member offsets are as expected by DNA. */\n");
947 fprintf(file_verify,
"#include \"BLI_assert.h\"\n\n");
949 fprintf(file_verify,
"#define DNA_DEPRECATED_ALLOW\n");
952 fprintf(file_verify,
"#define assert_line_ assert_line_DNA_\n");
954 fprintf(file_verify,
"#include \"%s%s\"\n", base_directory,
includefiles[i]);
956 fprintf(file_verify,
"#undef assert_line_\n");
957 fprintf(file_verify,
"\n");
963 const int lastunknown = unknown;
969 const short *structpoin =
structs[a];
970 const int struct_type_index = structpoin[0];
976 const short *sp = structpoin + 2;
981 int max_align_32 = 0;
982 int max_align_64 = 0;
985 for (
int b = 0;
b < structpoin[1];
b++, sp += 2) {
987 const char *cp =
members[sp[1]];
988 int namelen =
int(strlen(cp));
994 char name_static[1024];
998 const char *str_pair[2] = {types[struct_type_index], name_static};
999 const char *name_alias =
static_cast<const char *
>(
1001 fprintf(file_verify,
1002 "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset "
1005 name_alias ? name_alias : name_static,
1010 if (cp[0] ==
'*' || cp[1] ==
'*') {
1013 if (cp[namelen - 1] ==
']') {
1019 "Zero array size found or could not parse %s: '%.*s'\n",
1020 types[struct_type_index],
1027 if (
sizeof(
void *) == 4) {
1028 if (size_native % 4) {
1030 "Align pointer error in struct (size_native 4): %s %s\n",
1031 types[struct_type_index],
1037 if (size_native % 8) {
1039 "Align pointer error in struct (size_native 8): %s %s\n",
1040 types[struct_type_index],
1048 "Align pointer error in struct (size_64 8): %s %s\n",
1049 types[struct_type_index],
1054 size_native +=
sizeof(
void *) *
mul;
1057 max_align_32 = std::max(max_align_32, 4);
1058 max_align_64 = std::max(max_align_64, 8);
1060 else if (cp[0] ==
'[') {
1064 "Parse error in struct, invalid member name: %s %s\n",
1065 types[struct_type_index],
1072 if (cp[namelen - 1] ==
']') {
1078 "Zero array size found or could not parse %s: '%.*s'\n",
1079 types[struct_type_index],
1086 if (type >= firststruct) {
1087 if (
sizeof(
void *) == 8 && (size_native % 8)) {
1089 "Align struct error: %s::%s (starts at %d on the native platform; "
1090 "%d %% %zu = %d bytes)\n",
1091 types[struct_type_index],
1103 firststruct, struct_type_index, type, size_32, cp,
"32 bit"))
1108 firststruct, struct_type_index, type, size_64, cp,
"64 bit"))
1116 max_align_32 = std::max<int>(max_align_32,
types_align_32[type]);
1117 max_align_64 = std::max<int>(max_align_64,
types_align_64[type]);
1127 if (size_native == 0) {
1146 if (size_32 % max_align_32) {
1150 if ((size_64 % max_align_64 == 0) && (size_32 % max_align_32 == 4)) {
1152 "Sizeerror in 32 bit struct: %s (add padding pointer)\n",
1153 types[struct_type_index]);
1157 "Sizeerror in 32 bit struct: %s (add %d bytes)\n",
1158 types[struct_type_index],
1159 max_align_32 - (size_32 % max_align_32));
1164 if (size_64 % max_align_64) {
1166 "Sizeerror in 64 bit struct: %s (add %d bytes)\n",
1167 types[struct_type_index],
1168 max_align_64 - (size_64 % max_align_64));
1172 if (size_native % 4 && !
ELEM(size_native, 1, 2)) {
1174 "Sizeerror 4 in struct: %s (add %d bytes)\n",
1175 types[struct_type_index],
1181 fprintf(file_verify,
1182 "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n",
1189 if (unknown == lastunknown) {
1195 fprintf(stderr,
"ERROR: still %d structs unknown\n", unknown);
1198 fprintf(stderr,
"*** Known structs :\n");
1201 const short *structpoin =
structs[a];
1202 const int structtype = structpoin[0];
1206 fprintf(stderr,
" %s\n", types[structtype]);
1211 fprintf(stderr,
"*** Unknown structs :\n");
1214 const short *structpoin =
structs[a];
1215 const int structtype = structpoin[0];
1219 fprintf(stderr,
" %s\n", types[structtype]);
1229#define MAX_DNA_LINE_LENGTH 20
1231static void dna_write(FILE *file,
const void *pntr,
const int size)
1233 static int linelength = 0;
1234 const char *data = (
const char *)pntr;
1236 for (
int i = 0; i <
size; i++) {
1237 fprintf(file,
"%d, ", data[i]);
1240 fprintf(file,
"\n");
1249 printf(
"\n\n*** All detected structs:\n");
1256 const short *structpoin =
structs[a];
1257 const int structtype = structpoin[0];
1262 printf(
"*** End of list\n");
1338 const int raw_data_type_index =
add_type(
"raw_data", 0);
1339 short *raw_data_struct_info =
add_struct(raw_data_type_index);
1341 raw_data_struct_info[1] = 0;
1353 int header_count = 0;
1366 DEBUG_PRINTF(0,
"\tFinished scanning %d headers.\n", header_count);
1377 short struct_members_num;
1387 printf(
" %s %d\n", types[a], *sp);
1394 struct_members_num = sp[1];
1396 for (
b = 0;
b < struct_members_num;
b++, sp += 2) {
1397 printf(
" %s %s allign32:%d, allign64:%d\n",
1414 const char nil_bytes[4] = {0};
1424 for (
int member_index = 0; member_index <
members_num; member_index++) {
1425 int member_len = strlen(
members[member_index]) + 1;
1429 int len_align = (
len + 3) & ~3;
1430 if (
len != len_align) {
1440 for (
int type_index = 0; type_index <
types_num; type_index++) {
1441 int type_len = strlen(types[type_index]) + 1;
1442 dna_write(file, types[type_index], type_len);
1445 len_align = (
len + 3) & ~3;
1446 if (
len != len_align) {
1466 sp += 2 + 2 * (sp[1]);
1476 fprintf(file_offsets,
"#pragma once\n");
1477 fprintf(file_offsets,
"#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n");
1478 fprintf(file_offsets,
"enum {\n");
1480 const short *structpoin =
structs[i];
1481 const int struct_type_index = structpoin[0];
1482 fprintf(file_offsets,
1483 "\t_SDNA_TYPE_%s = %d,\n",
1487 fprintf(file_offsets,
"\tSDNA_TYPE_MAX = %d,\n",
structs_num);
1488 fprintf(file_offsets,
"};\n\n");
1495 for (
int struct_index = 0; struct_index <
structs_num; struct_index++) {
1496 const short *sp =
structs[struct_index];
1497 const char *type = types[sp[0]];
1498 const int len = sp[1];
1500 for (
int a = 0; a <
len; a++, sp += 2) {
1501 char *member =
members[sp[1]];
1505 "Error: duplicate name found '%s.%s', "
1506 "likely cause is 'dna_rename_defs.h'\n",
1549 FILE *fp = fopen(file,
"w");
1551 "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n",
1558# define BASE_HEADER "../"
1563 int return_status = 0;
1565 if (!
ELEM(argc, 4, 5)) {
1566 printf(
"Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]);
1570 FILE *file_dna = fopen(argv[1],
"w");
1571 FILE *file_dna_offsets = fopen(argv[2],
"w");
1572 FILE *file_dna_verify = fopen(argv[3],
"w");
1574 printf(
"Unable to open file: %s\n", argv[1]);
1577 else if (!file_dna_offsets) {
1578 printf(
"Unable to open file: %s\n", argv[2]);
1581 else if (!file_dna_verify) {
1582 printf(
"Unable to open file: %s\n", argv[3]);
1586 const char *base_directory;
1589 base_directory = argv[4];
1599# define FORCE_ALIGN_4 " __attribute__((aligned(4))) "
1601# define FORCE_ALIGN_4 " "
1603 fprintf(file_dna,
"extern const unsigned char DNAstr[];\n");
1604 fprintf(file_dna,
"const unsigned char" FORCE_ALIGN_4 "DNAstr[] = {\n");
1607 if (
make_structDNA(base_directory, file_dna, file_dna_offsets, file_dna_verify)) {
1615 fprintf(file_dna,
"};\n");
1616 fprintf(file_dna,
"extern const int DNAlen;\n");
1617 fprintf(file_dna,
"const int DNAlen = sizeof(DNAstr);\n");
1624 if (file_dna_offsets) {
1625 fclose(file_dna_offsets);
1627 if (file_dna_verify) {
1628 fclose(file_dna_verify);
1632 return return_status;
1643# pragma GCC diagnostic error "-Wpadded"
1650#include "dna_includes_all.h"
1666#define DNA_STRUCT_RENAME(old, new) (void)sizeof(new);
1667#define DNA_STRUCT_RENAME_MEMBER(struct_name, old, new) (void)offsetof(struct_name, new);
1669#undef DNA_STRUCT_RENAME
1670#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)
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
#define SNPRINTF(dst, format,...)
#define UNUSED_FUNCTION(x)
#define SDNA_RAW_DATA_STRUCT_INDEX
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static void mul(btAlignedObjectArray< T > &items, const Q &value)
local_group_size(16, 16) .push_constant(Type b
int DNA_member_array_num(const char *str)
void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_type_map, GHash **r_member_map)
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
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
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 int make_structDNA(const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify)
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 UNUSED_FUNCTION dna_rename_defs_ensure()
static void * read_file_data(const char *filepath, int *r_len)
GHash * member_map_alias_from_static
static struct @1325 g_version_data
void BLI_system_backtrace(FILE *fp)
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_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)