Blender V5.0
makesdna.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
26
27#define DNA_DEPRECATED_ALLOW
28
29#include <algorithm>
30#include <cctype>
31#include <cstdio>
32#include <cstdlib>
33#include <cstring>
34
35#include "MEM_guardedalloc.h"
36
37#include "BLI_alloca.h"
38#include "BLI_ghash.h"
39#include "BLI_memarena.h"
40#include "BLI_string.h"
41#include "BLI_sys_types.h" /* For `intptr_t` support. */
42#include "BLI_system.h" /* For #BLI_system_backtrace stub. */
43#include "BLI_utildefines.h"
44
45#include "DNA_sdna_types.h"
46#include "dna_utils.h"
47
48#define SDNA_MAX_FILENAME_LENGTH 255
49
50/* The include file below is automatically generated from the `SRC_DNA_INC`
51 * variable in `source/blender/CMakeLists.txt`. */
52static const char *includefiles[] = {
53#include "dna_includes_as_strings.h"
54 /* Empty string to indicate end of include files. */
55 "",
56};
57
58/* -------------------------------------------------------------------- */
61
62static MemArena *mem_arena = nullptr;
63
64static int max_data_size = 500000, max_array_len = 50000;
65static int members_num = 0;
66static int types_num = 0;
67static int structs_num = 0;
69static char **members;
71static char **types;
73static short *types_size_native;
75static short *types_align_32;
77static short *types_align_64;
79static short *types_size_32;
81static short *types_size_64;
88static short **structs, *structdata;
89
91static struct {
96} g_version_data = {nullptr};
97
106static int debugSDNA = 0;
108
109#define DEBUG_PRINTF(debug_level, ...) \
110 { \
111 if (debugSDNA > debug_level) { \
112 printf(__VA_ARGS__); \
113 } \
114 } \
115 ((void)0)
116
117/* stub for BLI_abort() */
118#ifndef NDEBUG
120{
121 (void)fp;
122}
123#endif
124
126
127/* -------------------------------------------------------------------- */
130
137static int add_type(const char *type_name, int size);
138
144static int add_member(const char *member_name);
145
151static short *add_struct(int type_index);
152
157static int preprocess_include(char *maindata, const int maindata_len);
158
162static int convert_include(const char *filepath);
163
167static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory);
168
172static void dna_write(FILE *file, const void *pntr, const int size);
173
177void print_struct_sizes();
178
180
181/* -------------------------------------------------------------------- */
186
187static bool match_identifier_with_len(const char *str,
188 const char *identifier,
189 const size_t identifier_len)
190{
191 if (strncmp(str, identifier, identifier_len) == 0) {
192 /* Check `str` isn't a prefix to a longer identifier. */
193 if (isdigit(str[identifier_len]) || isalpha(str[identifier_len]) ||
194 (str[identifier_len] == '_'))
195 {
196 return false;
197 }
198 return true;
199 }
200 return false;
201}
202
203static bool match_identifier(const char *str, const char *identifier)
204{
205 const size_t identifier_len = strlen(identifier);
206 return match_identifier_with_len(str, identifier, identifier_len);
207}
208
209static bool match_identifier_and_advance(char **str_ptr, const char *identifier)
210{
211 const size_t identifier_len = strlen(identifier);
212 if (match_identifier_with_len(*str_ptr, identifier, identifier_len)) {
213 (*str_ptr) += identifier_len;
214 return true;
215 }
216 return false;
217}
218
219static const char *version_struct_static_from_alias(const char *type_alias)
220{
221 const char *type_static = static_cast<const char *>(
222 BLI_ghash_lookup(g_version_data.type_map_static_from_alias, type_alias));
223 if (type_static != nullptr) {
224 return type_static;
225 }
226 return type_alias;
227}
228
229static const char *version_struct_alias_from_static(const char *type_static)
230{
231 const char *type_alias = static_cast<const char *>(
232 BLI_ghash_lookup(g_version_data.type_map_alias_from_static, type_static));
233 if (type_alias != nullptr) {
234 return type_alias;
235 }
236 return type_static;
237}
238
239static const char *version_member_static_from_alias(const int type_index,
240 const char *member_alias_full)
241{
242 const uint member_alias_full_len = strlen(member_alias_full);
243 char *member_alias = static_cast<char *>(alloca(member_alias_full_len + 1));
244 const int member_alias_len = DNA_member_id_strip_copy(member_alias, member_alias_full);
245 const char *str_pair[2] = {types[type_index], member_alias};
246 const char *member_static = static_cast<const char *>(
247 BLI_ghash_lookup(g_version_data.member_map_static_from_alias, str_pair));
248 if (member_static != nullptr) {
250 member_alias,
251 member_alias_len,
252 member_static,
253 strlen(member_static),
254 member_alias_full,
255 member_alias_full_len,
256 DNA_member_id_offset_start(member_alias_full));
257 }
258 return member_alias_full;
259}
260
265static bool is_name_legal(const char *name)
266{
267 const int name_size = strlen(name) + 1;
268 char *name_strip = static_cast<char *>(alloca(name_size));
269 DNA_member_id_strip_copy(name_strip, name);
270
271 const char prefix[] = {'p', 'a', 'd'};
272
273 if (name[0] == '_') {
274 if (strncmp(&name_strip[1], prefix, sizeof(prefix)) != 0) {
275 fprintf(
276 stderr, "Error: only '_pad' variables can start with an underscore, found '%s'\n", name);
277 return false;
278 }
279 }
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') {
283 /* may be part of a word, allow that. */
284 return true;
285 }
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;
291 break;
292 }
293 }
294 if (has_only_digit_or_none) {
295 /* found 'pad' or 'pad123'. */
296 fprintf(
297 stderr, "Error: padding variables must be formatted '_pad[number]', found '%s'\n", name);
298 return false;
299 }
300 }
301 return true;
302}
303
304static int add_type(const char *type_name, int size)
305{
306 /* first do validity check */
307 if (type_name[0] == 0) {
308 return -1;
309 }
310 if (strchr(type_name, '*')) {
311 /* NOTE: this is valid C syntax but we can't parse, complain!
312 * `struct SomeStruct* some_var;` <-- correct but we can't handle right now. */
313 return -1;
314 }
315
316 type_name = version_struct_static_from_alias(type_name);
317
318 /* search through type array */
319 for (int type_index = 0; type_index < types_num; type_index++) {
320 if (STREQ(type_name, types[type_index])) {
321 if (size) {
322 types_size_native[type_index] = size;
323 types_size_32[type_index] = size;
324 types_size_64[type_index] = size;
325 types_align_32[type_index] = size;
326 types_align_64[type_index] = size;
327 }
328 return type_index;
329 }
330 }
331
332 /* append new type */
333 const int type_name_len = strlen(type_name) + 1;
334 char *cp = static_cast<char *>(BLI_memarena_alloc(mem_arena, type_name_len));
335 memcpy(cp, type_name, type_name_len);
336 types[types_num] = cp;
342 if (types_num >= max_array_len) {
343 printf("too many types\n");
344 return types_num - 1;
345 }
346 types_num++;
347
348 return types_num - 1;
349}
350
357static int add_member(const char *member_name)
358{
359 char buf[255]; /* stupid limit, change it :) */
360 const char *name;
361
363
364 if (member_name[0] == 0 /* `|| (member_name[1] == 0)` */) {
365 return -1;
366 }
367
368 if (member_name[0] == '(' && member_name[1] == '*') {
369 /* We handle function pointer and special array cases here, e.g.
370 * `void (*function)(...)` and `float (*array)[..]`. the array case
371 * name is still converted to (array *)() though because it is that
372 * way in old DNA too, and works correct with #DNA_struct_member_size. */
373 int isfuncptr = (strchr(member_name + 1, '(')) != nullptr;
374
375 DEBUG_PRINTF(3, "\t\t\t\t*** Function pointer or multidim array pointer found\n");
376 /* function-pointer: transform the type (sometimes). */
377 int i = 0;
378
379 while (member_name[i] != ')') {
380 buf[i] = member_name[i];
381 i++;
382 }
383
384 /* Another number we need is the extra slen offset. This extra
385 * offset is the overshoot after a space. If there is no
386 * space, no overshoot should be calculated. */
387 int j = i; /* j at first closing brace */
388
389 DEBUG_PRINTF(3, "first brace after offset %d\n", i);
390
391 j++; /* j beyond closing brace ? */
392 while ((member_name[j] != 0) && (member_name[j] != ')')) {
393 DEBUG_PRINTF(3, "seen %c (%d)\n", member_name[j], member_name[j]);
394 j++;
395 }
396 DEBUG_PRINTF(3,
397 "seen %c (%d)\n"
398 "special after offset%d\n",
399 member_name[j],
400 member_name[j],
401 j);
402
403 if (!isfuncptr) {
404 /* multidimensional array pointer case */
405 if (member_name[j] == 0) {
406 DEBUG_PRINTF(3, "offsetting for multi-dimensional array pointer\n");
407 }
408 else {
409 printf("Error during tokenizing multi-dimensional array pointer\n");
410 }
411 }
412 else if (member_name[j] == 0) {
413 DEBUG_PRINTF(3, "offsetting for space\n");
414 /* get additional offset */
415 int k = 0;
416 while (member_name[j] != ')') {
417 j++;
418 k++;
419 }
420 DEBUG_PRINTF(3, "extra offset %d\n", k);
422 }
423 else if (member_name[j] == ')') {
424 DEBUG_PRINTF(3, "offsetting for brace\n");
425 /* don't get extra offset */
426 }
427 else {
428 printf("Error during tokening function pointer argument list\n");
429 }
430
431 /*
432 * Put `)(void)` at the end? Maybe `)()`. Should check this with
433 * old `sdna`. Actually, sometimes `)()`, sometimes `)(void...)`
434 * Alas.. such is the nature of brain-damage :(
435 *
436 * Sorted it out: always do )(), except for `headdraw` and
437 * `windraw`, part of #ScrArea. This is important, because some
438 * linkers will treat different fp's differently when called
439 * !!! This has to do with interference in byte-alignment and
440 * the way arguments are pushed on the stack.
441 */
442 buf[i] = 0;
443 DEBUG_PRINTF(3, "Name before chomping: %s\n", buf);
444 if ((strncmp(buf, "(*headdraw", 10) == 0) || strncmp(buf, "(*windraw", 9) == 0) {
445 buf[i] = ')';
446 buf[i + 1] = '(';
447 buf[i + 2] = 'v';
448 buf[i + 3] = 'o';
449 buf[i + 4] = 'i';
450 buf[i + 5] = 'd';
451 buf[i + 6] = ')';
452 buf[i + 7] = 0;
453 }
454 else {
455 buf[i] = ')';
456 buf[i + 1] = '(';
457 buf[i + 2] = ')';
458 buf[i + 3] = 0;
459 }
460 /* Now proceed with buf. */
461 DEBUG_PRINTF(3, "\t\t\t\t\tProposing fp name %s\n", buf);
462 name = buf;
463 }
464 else {
465 /* normal field: old code */
466 name = member_name;
467 }
468
469 /* search name array */
470 for (int member_index = 0; member_index < members_num; member_index++) {
471 if (STREQ(name, members[member_index])) {
472 return member_index;
473 }
474 }
475
476 /* Sanity check the name. */
477 if (!is_name_legal(name)) {
478 return -1;
479 }
480
481 /* Append new name. */
482 const int name_len = strlen(name) + 1;
483 char *cp = static_cast<char *>(BLI_memarena_alloc(mem_arena, name_len));
484 memcpy(cp, name, name_len);
485 members[members_num] = cp;
486
487 if (members_num >= max_array_len) {
488 printf("too many names\n");
489 return members_num - 1;
490 }
491 members_num++;
492
493 return members_num - 1;
494}
495
496static short *add_struct(int type_index)
497{
498 if (structs_num == 0) {
499 structs[0] = structdata;
500 }
501 else {
502 short *sp = structs[structs_num - 1];
503 const int len = sp[1];
504 structs[structs_num] = sp + 2 * len + 2;
505 }
506
507 short *sp = structs[structs_num];
508 sp[0] = type_index;
509
510 if (structs_num >= max_array_len) {
511 printf("too many structs\n");
512 return sp;
513 }
514 structs_num++;
515
516 return sp;
517}
518
519/* Copied from `BLI_str_startswith` string.c
520 * to avoid complicating the compilation process of makesdna. */
521static bool str_startswith(const char *__restrict str, const char *__restrict start)
522{
523 for (; *str && *start; str++, start++) {
524 if (*str != *start) {
525 return false;
526 }
527 }
528
529 return (*start == '\0');
530}
531
537static bool match_preproc_prefix(const char *__restrict str, const char *__restrict start)
538{
539 if (*str != '#') {
540 return false;
541 }
542 str++;
543 while (*str == ' ') {
544 str++;
545 }
546 return str_startswith(str, start);
547}
548
552static char *match_preproc_strstr(char *__restrict str, const char *__restrict start)
553{
554 while ((str = strchr(str, '#'))) {
555 str++;
556 while (*str == ' ') {
557 str++;
558 }
559 if (str_startswith(str, start)) {
560 return str;
561 }
562 }
563 return nullptr;
564}
565
566static int preprocess_include(char *maindata, const int maindata_len)
567{
568 /* NOTE: len + 1, last character is a dummy to prevent
569 * comparisons using uninitialized memory */
570 char *temp = MEM_malloc_arrayN<char>(size_t(maindata_len) + 1, "preprocess_include");
571 temp[maindata_len] = ' ';
572
573 memcpy(temp, maindata, maindata_len);
574
575 /* remove all c++ comments */
576 /* replace all enters/tabs/etc with spaces */
577 char *cp = temp;
578 int a = maindata_len;
579 bool comment = false;
580 while (a--) {
581 if (cp[0] == '/' && cp[1] == '/') {
582 comment = true;
583 }
584 else if (*cp == '\n') {
585 comment = false;
586 }
587 if (comment || *cp < 32 || *cp > 128) {
588 *cp = 32;
589 }
590 cp++;
591 }
592
593 /* No need for leading '#' character. */
594 const char *cpp_block_start = "ifdef __cplusplus";
595 const char *cpp_block_end = "endif";
596
597 /* data from temp copy to maindata, remove comments and double spaces */
598 cp = temp;
599 char *md = maindata;
600 int newlen = 0;
601 comment = false;
602 a = maindata_len;
603 int square_bracket_level = 0;
604 bool skip_until_closing_brace = false;
605 while (a--) {
606
607 if (cp[0] == '/' && cp[1] == '*') {
608 BLI_assert(comment == false);
609 comment = true;
610 cp[0] = cp[1] = 32;
611 }
612 if (cp[0] == '*' && cp[1] == '/') {
613 BLI_assert(comment == true);
614 comment = false;
615 cp[0] = cp[1] = 32;
616 }
617
618 if (comment == false) {
619 if (cp[0] == '[') {
620 square_bracket_level++;
621 }
622 else if (cp[0] == ']') {
623 square_bracket_level--;
624 }
625 }
626
627 /* do not copy when: */
628 if (comment) {
629 /* pass */
630 }
631 else if (cp[0] == ' ' && (square_bracket_level > 0)) {
632 /* NOTE(@ideasman42): This is done to allow `member[C_STYLE_COMMENT 1024]`,
633 * which is then read as `member[1024]`.
634 * It's important to skip the spaces here,
635 * otherwise the literal would be read as: `member[` and `1024]`. */
636 }
637 else if (cp[0] == ' ' && cp[1] == ' ') {
638 /* pass */
639 }
640 else if (cp[-1] == '*' && cp[0] == ' ') {
641 /* pointers with a space */
642 } /* skip special keywords */
643 else if (match_identifier(cp, "DNA_DEPRECATED")) {
644 /* single values are skipped already, so decrement 1 less */
645 a -= 13;
646 cp += 13;
647 }
648 else if (match_identifier(cp, "DNA_DEFINE_CXX_METHODS")) {
649 /* single values are skipped already, so decrement 1 less */
650 a -= 21;
651 cp += 21;
652 skip_until_closing_brace = true;
653 }
654 else if (skip_until_closing_brace) {
655 if (cp[0] == ')') {
656 skip_until_closing_brace = false;
657 }
658 }
659 else if (match_preproc_prefix(cp, cpp_block_start)) {
660 char *end_ptr = match_preproc_strstr(cp, cpp_block_end);
661
662 if (end_ptr == nullptr) {
663 fprintf(stderr, "Error: '%s' block must end with '%s'\n", cpp_block_start, cpp_block_end);
664 }
665 else {
666 const int skip_offset = end_ptr - cp + strlen(cpp_block_end);
667 a -= skip_offset;
668 cp += skip_offset;
669 }
670 }
671 else {
672 md[0] = cp[0];
673 md++;
674 newlen++;
675 }
676 cp++;
677 }
678
679 BLI_assert(square_bracket_level == 0);
680
681 MEM_freeN(temp);
682 return newlen;
683}
684
685static void *read_file_data(const char *filepath, int *r_len)
686{
687#ifdef WIN32
688 FILE *fp = fopen(filepath, "rb");
689#else
690 FILE *fp = fopen(filepath, "r");
691#endif
692 void *data;
693
694 if (!fp) {
695 *r_len = -1;
696 return nullptr;
697 }
698
699 fseek(fp, 0L, SEEK_END);
700 *r_len = ftell(fp);
701 fseek(fp, 0L, SEEK_SET);
702
703 if (*r_len == -1) {
704 fclose(fp);
705 return nullptr;
706 }
707
708 data = MEM_mallocN(*r_len, "read_file_data");
709 if (!data) {
710 *r_len = -1;
711 fclose(fp);
712 return nullptr;
713 }
714
715 if (fread(data, *r_len, 1, fp) != 1) {
716 *r_len = -1;
718 fclose(fp);
719 return nullptr;
720 }
721
722 fclose(fp);
723 return data;
724}
725
726static int convert_include(const char *filepath)
727{
728 /* read include file, skip structs with a '#' before it.
729 * store all data in temporal arrays.
730 */
731
732 int maindata_len;
733 char *maindata = static_cast<char *>(read_file_data(filepath, &maindata_len));
734 char *md = maindata;
735 if (maindata_len == -1) {
736 fprintf(stderr, "Can't read file %s\n", filepath);
737 return 1;
738 }
739
740 maindata_len = preprocess_include(maindata, maindata_len);
741 char *mainend = maindata + maindata_len - 1;
742
743 /* we look for '{' and then back to 'struct' */
744 int count = 0;
745 bool skip_struct = false;
746 while (count < maindata_len) {
747
748 /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
749 if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
750 skip_struct = true;
751 }
752
753 if (md[0] == '{') {
754 md[0] = 0;
755 if (skip_struct) {
756 skip_struct = false;
757 }
758 else {
759 if (md[-1] == ' ') {
760 md[-1] = 0;
761 }
762 char *md1 = md - 2;
763 while (*md1 != 32) {
764 /* to beginning of word */
765 md1--;
766 }
767 md1++;
768
769 /* we've got a struct name when... */
770 if (match_identifier(md1 - 7, "struct")) {
771
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);
775 return 1;
776 }
777
778 short *structpoin = add_struct(struct_type_index);
779 short *sp = structpoin + 2;
780
781 DEBUG_PRINTF(1, "\t|\t|-- detected struct %s\n", types[struct_type_index]);
782
783 /* first lets make it all nice strings */
784 md1 = md + 1;
785 while (*md1 != '}') {
786 if (md1 > mainend) {
787 break;
788 }
789
790 if (ELEM(*md1, ',', ' ')) {
791 *md1 = 0;
792 }
793 md1++;
794 }
795
796 /* read types and names until first character that is not '}' */
797 md1 = md + 1;
798 while (*md1 != '}') {
799 if (md1 > mainend) {
800 break;
801 }
802
803 /* skip when it says 'struct' or 'unsigned' or 'const' */
804 if (*md1) {
805 const char *md1_prev = md1;
806 while (match_identifier_and_advance(&md1, "struct") ||
807 match_identifier_and_advance(&md1, "unsigned") ||
808 match_identifier_and_advance(&md1, "const"))
809 {
810 if (UNLIKELY(!ELEM(*md1, '\0', ' '))) {
811 /* This will happen with: `unsigned(*value)[3]` which isn't supported. */
812 fprintf(stderr,
813 "File '%s' contains non white space character "
814 "\"%c\" after identifier \"%s\"\n",
815 filepath,
816 *md1,
817 md1_prev);
818 return 1;
819 }
820 /* Skip ' ' or '\0'. */
821 md1++;
822 }
823
824 /* we've got a type! */
825 if (STR_ELEM(md1, "long", "ulong")) {
826 /* Forbid using long/ulong because those can be either 32 or 64 bit. */
827 fprintf(stderr,
828 "File '%s' contains use of \"%s\" in DNA struct which is not allowed\n",
829 filepath,
830 md1);
831 return -1;
832 }
833 const int member_type_index = add_type(md1, 0);
834 if (member_type_index == -1) {
835 fprintf(
836 stderr, "File '%s' contains struct we can't parse \"%s\"\n", filepath, md1);
837 return 1;
838 }
839
840 DEBUG_PRINTF(1, "\t|\t|\tfound type %s (", md1);
841
842 md1 += strlen(md1);
843
844 /* read until ';' */
845 while (*md1 != ';') {
846 if (md1 > mainend) {
847 break;
848 }
849
850 if (*md1) {
851 /* We've got a name. slen needs
852 * correction for function
853 * pointers! */
854 int slen = int(strlen(md1));
855 if (md1[slen - 1] == ';') {
856 md1[slen - 1] = 0;
857
858 const int name = add_member(
859 version_member_static_from_alias(struct_type_index, md1));
860 if (name == -1) {
861 fprintf(stderr,
862 "File '%s' contains struct with name that can't be added \"%s\"\n",
863 filepath,
864 md1);
865 return 1;
866 }
868 sp[0] = member_type_index;
869 sp[1] = name;
870
871 if (members[name] != nullptr) {
872 DEBUG_PRINTF(1, "%s |", members[name]);
873 }
874
875 structpoin[1]++;
876 sp += 2;
877
878 md1 += slen;
879 break;
880 }
881
882 const int name = add_member(
883 version_member_static_from_alias(struct_type_index, md1));
884 if (name == -1) {
885 fprintf(stderr,
886 "File '%s' contains struct with name that can't be added \"%s\"\n",
887 filepath,
888 md1);
889 return 1;
890 }
892
893 sp[0] = member_type_index;
894 sp[1] = name;
895 if (members[name] != nullptr) {
896 DEBUG_PRINTF(1, "%s ||", members[name]);
897 }
898
899 structpoin[1]++;
900 sp += 2;
901
902 md1 += slen;
903 }
904 md1++;
905 }
906
907 DEBUG_PRINTF(1, ")\n");
908 }
909 md1++;
910 }
911 }
912 }
913 }
914 count++;
915 md++;
916 }
917
918 MEM_freeN(maindata);
919
920 return 0;
921}
922
923static bool check_field_alignment(int firststruct,
924 int struct_type_index,
925 int type,
926 int len,
927 const char *name,
928 const char *detail)
929{
930 bool result = true;
931 if (type < firststruct && types_size_native[type] > 4 && (len % 8)) {
932 fprintf(stderr,
933 "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n",
934 detail,
935 types[struct_type_index],
936 name,
937 len % 8);
938 result = false;
939 }
940 if (types_size_native[type] > 3 && (len % 4)) {
941 fprintf(stderr,
942 "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n",
943 detail,
944 types[struct_type_index],
945 name,
946 len % 4);
947 result = false;
948 }
949 if (types_size_native[type] == 2 && (len % 2)) {
950 fprintf(stderr,
951 "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n",
952 detail,
953 types[struct_type_index],
954 name,
955 len % 2);
956 result = false;
957 }
958 return result;
959}
960
961static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory)
962{
963 bool dna_error = false;
964
965 /* Write test to verify sizes are accurate. */
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");
968 /* Needed so we can find offsets of deprecated structs. */
969 fprintf(file_verify, "#define DNA_DEPRECATED_ALLOW\n");
970 /* Workaround enum naming collision in static asserts
971 * (ideally this included a unique name/id per file). */
972 fprintf(file_verify, "#define assert_line_ assert_line_DNA_\n");
973 for (int i = 0; *(includefiles[i]) != '\0'; i++) {
974 fprintf(file_verify, "#include \"%s%s\"\n", base_directory, includefiles[i]);
975 }
976 fprintf(file_verify, "#undef assert_line_\n");
977 fprintf(file_verify, "\n");
978
979 /* Multiple iterations to handle nested structs. */
980 /* 'raw data' SDNA_RAW_DATA_STRUCT_INDEX fake struct should be ignored here. */
981 int unknown = structs_num - 1;
982 while (unknown) {
983 const int lastunknown = unknown;
984 unknown = 0;
985
986 /* check all structs... */
987 BLI_STATIC_ASSERT(SDNA_RAW_DATA_STRUCT_INDEX == 0, "'raw data' SDNA struct index should be 0")
988 for (int a = SDNA_RAW_DATA_STRUCT_INDEX + 1; a < structs_num; a++) {
989 const short *structpoin = structs[a];
990 const int struct_type_index = structpoin[0];
991 const char *struct_type_name = version_struct_alias_from_static(types[struct_type_index]);
992
993 /* when length is not known... */
994 if (types_size_native[struct_type_index] == 0) {
995
996 const short *sp = structpoin + 2;
997 int size_native = 0;
998 int size_32 = 0;
999 int size_64 = 0;
1000 /* Sizes of the largest field in a struct. */
1001 int max_align_32 = 0;
1002 int max_align_64 = 0;
1003
1004 /* check all members in struct */
1005 for (int b = 0; b < structpoin[1]; b++, sp += 2) {
1006 int type = sp[0];
1007 const char *cp = members[sp[1]];
1008 int namelen = int(strlen(cp));
1009
1010 /* Write size verification to file. */
1011 {
1012 /* Normally 'alloca' would be used here, however we can't in a loop.
1013 * Use an over-sized buffer instead. */
1014 char name_static[1024];
1015 BLI_assert(sizeof(name_static) > namelen);
1016
1017 DNA_member_id_strip_copy(name_static, cp);
1018 const char *str_pair[2] = {types[struct_type_index], name_static};
1019 const char *name_alias = static_cast<const char *>(
1020 BLI_ghash_lookup(g_version_data.member_map_alias_from_static, str_pair));
1021 fprintf(file_verify,
1022 "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset "
1023 "verify\");\n",
1024 struct_type_name,
1025 name_alias ? name_alias : name_static,
1026 size_native);
1027 }
1028
1029 /* is it a pointer or function pointer? */
1030 if (cp[0] == '*' || cp[1] == '*') {
1031 /* has the name an extra length? (array) */
1032 int mul = 1;
1033 if (cp[namelen - 1] == ']') {
1035 }
1036
1037 if (mul == 0) {
1038 fprintf(stderr,
1039 "Zero array size found or could not parse %s: '%.*s'\n",
1040 types[struct_type_index],
1041 namelen + 1,
1042 cp);
1043 dna_error = true;
1044 }
1045
1046 /* 4-8 aligned/ */
1047 if (sizeof(void *) == 4) {
1048 if (size_native % 4) {
1049 fprintf(stderr,
1050 "Align pointer error in struct (size_native 4): %s %s\n",
1051 types[struct_type_index],
1052 cp);
1053 dna_error = true;
1054 }
1055 }
1056 else {
1057 if (size_native % 8) {
1058 fprintf(stderr,
1059 "Align pointer error in struct (size_native 8): %s %s\n",
1060 types[struct_type_index],
1061 cp);
1062 dna_error = true;
1063 }
1064 }
1065
1066 if (size_64 % 8) {
1067 fprintf(stderr,
1068 "Align pointer error in struct (size_64 8): %s %s\n",
1069 types[struct_type_index],
1070 cp);
1071 dna_error = true;
1072 }
1073
1074 size_native += sizeof(void *) * mul;
1075 size_32 += 4 * mul;
1076 size_64 += 8 * mul;
1077 max_align_32 = std::max(max_align_32, 4);
1078 max_align_64 = std::max(max_align_64, 8);
1079 }
1080 else if (cp[0] == '[') {
1081 /* parsing can cause names "var" and "[3]"
1082 * to be found for "float var [3]" */
1083 fprintf(stderr,
1084 "Parse error in struct, invalid member name: %s %s\n",
1085 types[struct_type_index],
1086 cp);
1087 dna_error = true;
1088 }
1089 else if (types_size_native[type]) {
1090 /* has the name an extra length? (array) */
1091 int mul = 1;
1092 if (cp[namelen - 1] == ']') {
1094 }
1095
1096 if (mul == 0) {
1097 fprintf(stderr,
1098 "Zero array size found or could not parse %s: '%.*s'\n",
1099 types[struct_type_index],
1100 namelen + 1,
1101 cp);
1102 dna_error = true;
1103 }
1104
1105 /* struct alignment */
1106 if (type >= firststruct) {
1107 if (sizeof(void *) == 8 && (size_native % 8)) {
1108 fprintf(stderr,
1109 "Align struct error: %s::%s (starts at %d on the native platform; "
1110 "%d %% %zu = %d bytes)\n",
1111 types[struct_type_index],
1112 cp,
1113 size_native,
1114 size_native,
1115 sizeof(void *),
1116 size_native % 8);
1117 dna_error = true;
1118 }
1119 }
1120
1121 /* Check 2-4-8 aligned. */
1123 firststruct, struct_type_index, type, size_32, cp, "32 bit"))
1124 {
1125 dna_error = true;
1126 }
1128 firststruct, struct_type_index, type, size_64, cp, "64 bit"))
1129 {
1130 dna_error = true;
1131 }
1132
1133 size_native += mul * types_size_native[type];
1134 size_32 += mul * types_size_32[type];
1135 size_64 += mul * types_size_64[type];
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]);
1138 }
1139 else {
1140 size_native = 0;
1141 size_32 = 0;
1142 size_64 = 0;
1143 break;
1144 }
1145 }
1146
1147 if (size_native == 0) {
1148 unknown++;
1149 }
1150 else {
1151 types_size_native[struct_type_index] = size_native;
1152 types_size_32[struct_type_index] = size_32;
1153 types_size_64[struct_type_index] = size_64;
1154 types_align_32[struct_type_index] = max_align_32;
1155 types_align_64[struct_type_index] = max_align_64;
1156
1157 /* Sanity check 1: alignment should never be 0. */
1158 BLI_assert(max_align_32);
1159 BLI_assert(max_align_64);
1160
1161 /* Sanity check 2: alignment should always be equal or smaller than the maximum
1162 * size of a build in type which is 8 bytes (i.e. `int64_t` or double). */
1163 BLI_assert(max_align_32 <= 8);
1164 BLI_assert(max_align_64 <= 8);
1165
1166 if (size_32 % max_align_32) {
1167 /* There is an one odd case where only the 32 bit struct has alignment issues
1168 * and the 64 bit does not, that can only be fixed by adding a padding pointer
1169 * to the struct to resolve the problem. */
1170 if ((size_64 % max_align_64 == 0) && (size_32 % max_align_32 == 4)) {
1171 fprintf(stderr,
1172 "Sizeerror in 32 bit struct: %s (add padding pointer)\n",
1173 types[struct_type_index]);
1174 }
1175 else {
1176 fprintf(stderr,
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));
1180 }
1181 dna_error = true;
1182 }
1183
1184 if (size_64 % max_align_64) {
1185 fprintf(stderr,
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));
1189 dna_error = true;
1190 }
1191
1192 if (size_native % 4 && !ELEM(size_native, 1, 2)) {
1193 fprintf(stderr,
1194 "Sizeerror 4 in struct: %s (add %d bytes)\n",
1195 types[struct_type_index],
1196 size_native % 4);
1197 dna_error = true;
1198 }
1199
1200 /* Write size verification to file. */
1201 fprintf(file_verify,
1202 "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n",
1203 struct_type_name,
1204 size_native);
1205 }
1206 }
1207 }
1208
1209 if (unknown == lastunknown) {
1210 break;
1211 }
1212 }
1213
1214 if (unknown) {
1215 fprintf(stderr, "ERROR: still %d structs unknown\n", unknown);
1216
1217 if (debugSDNA) {
1218 fprintf(stderr, "*** Known structs :\n");
1219
1220 for (int a = 0; a < structs_num; a++) {
1221 const short *structpoin = structs[a];
1222 const int structtype = structpoin[0];
1223
1224 /* length unknown */
1225 if (types_size_native[structtype] != 0) {
1226 fprintf(stderr, " %s\n", types[structtype]);
1227 }
1228 }
1229 }
1230
1231 fprintf(stderr, "*** Unknown structs :\n");
1232
1233 for (int a = 0; a < structs_num; a++) {
1234 const short *structpoin = structs[a];
1235 const int structtype = structpoin[0];
1236
1237 /* length unknown yet */
1238 if (types_size_native[structtype] == 0) {
1239 fprintf(stderr, " %s\n", types[structtype]);
1240 }
1241 }
1242
1243 dna_error = true;
1244 }
1245
1246 return dna_error;
1247}
1248
1249#define MAX_DNA_LINE_LENGTH 20
1250
1251static void dna_write(FILE *file, const void *pntr, const int size)
1252{
1253 static int linelength = 0;
1254 const char *data = (const char *)pntr;
1255
1256 for (int i = 0; i < size; i++) {
1257 fprintf(file, "%d, ", data[i]);
1258 linelength++;
1259 if (linelength >= MAX_DNA_LINE_LENGTH) {
1260 fprintf(file, "\n");
1261 linelength = 0;
1262 }
1263 }
1264}
1265
1267{
1268 int unknown = structs_num;
1269 printf("\n\n*** All detected structs:\n");
1270
1271 while (unknown) {
1272 unknown = 0;
1273
1274 /* check all structs... */
1275 for (int a = 0; a < structs_num; a++) {
1276 const short *structpoin = structs[a];
1277 const int structtype = structpoin[0];
1278 printf("\t%s\t:%d\n", types[structtype], types_size_native[structtype]);
1279 }
1280 }
1281
1282 printf("*** End of list\n");
1283}
1284
1286 const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify, FILE *file_ids)
1287{
1288 if (debugSDNA > 0) {
1289 fflush(stdout);
1290 printf("Running makesdna at debug level %d\n", debugSDNA);
1291 }
1292
1294
1295 /* the longest known struct is 50k, so we assume 100k is sufficient! */
1297
1298 /* a maximum of 5000 variables, must be sufficient? */
1306
1308
1309 /* Build versioning data */
1311 &g_version_data.type_map_alias_from_static,
1312 &g_version_data.member_map_alias_from_static);
1314 &g_version_data.type_map_static_from_alias,
1315 &g_version_data.member_map_static_from_alias);
1316
1324 add_type("char", 1); /* SDNA_TYPE_CHAR */
1325 add_type("uchar", 1); /* SDNA_TYPE_UCHAR */
1326 add_type("short", 2); /* SDNA_TYPE_SHORT */
1327 add_type("ushort", 2); /* SDNA_TYPE_USHORT */
1328 add_type("int", 4); /* SDNA_TYPE_INT */
1329
1330 /* NOTE: long isn't supported,
1331 * these are place-holders to maintain alignment with #eSDNA_Type. */
1332 add_type("long", 4); /* SDNA_TYPE_LONG */
1333 add_type("ulong", 4); /* SDNA_TYPE_ULONG */
1334
1335 add_type("float", 4); /* SDNA_TYPE_FLOAT */
1336 add_type("double", 8); /* SDNA_TYPE_DOUBLE */
1337 add_type("int64_t", 8); /* SDNA_TYPE_INT64 */
1338 add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
1339 add_type("void", 0); /* SDNA_TYPE_VOID */
1340 add_type("int8_t", 1); /* SDNA_TYPE_INT8 */
1341
1342 /* Fake place-holder struct definition used to get an identifier for raw, untyped bytes buffers
1343 * in blend-files.
1344 *
1345 * It will be written into the blend-files SDNA, but it must never be used in the source code.
1346 * Trying to declare `struct raw_data` in DNA headers will cause a build error.
1347 *
1348 * NOTE: While not critical, since all blend-files before introduction of this 'raw_data'
1349 * type/struct have been using the `0` value for raw data #BHead.SDNAnr, it's best to reserve
1350 * that first struct index to this raw data explicitly. */
1351 const int raw_data_type_index = add_type("raw_data", 0); /* SDNA_TYPE_RAW_DATA */
1352 short *raw_data_struct_info = add_struct(raw_data_type_index);
1353 /* There are no members in this struct. */
1354 raw_data_struct_info[1] = 0;
1355 BLI_STATIC_ASSERT(SDNA_RAW_DATA_STRUCT_INDEX == 0, "'raw data' SDNA struct index should be 0")
1356 BLI_assert(raw_data_struct_info == structs[SDNA_RAW_DATA_STRUCT_INDEX]);
1357
1358 /* the defines above shouldn't be output in the padding file... */
1359 const int firststruct = types_num;
1360
1361 /* Add all include files defined in the global array.
1362 * Since the internal file+path name buffer has limited length,
1363 * I do a little test first...
1364 * Mind the breaking condition here! */
1365 DEBUG_PRINTF(0, "\tStart of header scan:\n");
1366 int header_count = 0;
1367 for (int i = 0; *(includefiles[i]) != '\0'; i++) {
1368 header_count++;
1369
1370 /* NOTE(nzc): `str` contains filenames.
1371 * Since we now include paths, I stretched it a bit. Hope this is enough :). */
1373 SNPRINTF(str, "%s%s", base_directory, includefiles[i]);
1374 DEBUG_PRINTF(0, "\t|-- Converting %s\n", str);
1375 if (convert_include(str)) {
1376 return 1;
1377 }
1378 }
1379 DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", header_count);
1380
1381 if (calculate_struct_sizes(firststruct, file_verify, base_directory)) {
1382 /* error */
1383 return 1;
1384 }
1385
1386 /* FOR DEBUG */
1387 if (debugSDNA > 1) {
1388 int a, b;
1389 // short *elem;
1390 short struct_members_num;
1391
1392 printf("names_len %d types_len %d structs_len %d\n", members_num, types_num, structs_num);
1393 for (a = 0; a < members_num; a++) {
1394 printf(" %s\n", members[a]);
1395 }
1396 printf("\n");
1397
1398 const short *sp = types_size_native;
1399 for (a = 0; a < types_num; a++, sp++) {
1400 printf(" %s %d\n", types[a], *sp);
1401 }
1402 printf("\n");
1403
1404 for (a = 0; a < structs_num; a++) {
1405 sp = structs[a];
1406 printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]);
1407 struct_members_num = sp[1];
1408 sp += 2;
1409 for (b = 0; b < struct_members_num; b++, sp += 2) {
1410 printf(" %s %s allign32:%d, allign64:%d\n",
1411 types[sp[0]],
1412 members[sp[1]],
1413 types_align_32[sp[0]],
1414 types_align_64[sp[0]]);
1415 }
1416 }
1417 }
1418
1419 /* file writing */
1420
1421 DEBUG_PRINTF(0, "Writing file ... ");
1422
1423 if (members_num == 0 || structs_num == 0) {
1424 /* pass */
1425 }
1426 else {
1427 const char nil_bytes[4] = {0};
1428
1429 dna_write(file, "SDNA", 4);
1430
1431 /* write names */
1432 dna_write(file, "NAME", 4);
1433 int len = members_num;
1434 dna_write(file, &len, 4);
1435 /* write array */
1436 len = 0;
1437 for (int member_index = 0; member_index < members_num; member_index++) {
1438 int member_len = strlen(members[member_index]) + 1;
1439 dna_write(file, members[member_index], member_len);
1440 len += member_len;
1441 }
1442 int len_align = (len + 3) & ~3;
1443 if (len != len_align) {
1444 dna_write(file, nil_bytes, len_align - len);
1445 }
1446
1447 /* write TYPES */
1448 dna_write(file, "TYPE", 4);
1449 len = types_num;
1450 dna_write(file, &len, 4);
1451 /* write array */
1452 len = 0;
1453 for (int type_index = 0; type_index < types_num; type_index++) {
1454 int type_len = strlen(types[type_index]) + 1;
1455 dna_write(file, types[type_index], type_len);
1456 len += type_len;
1457 }
1458 len_align = (len + 3) & ~3;
1459 if (len != len_align) {
1460 dna_write(file, nil_bytes, len_align - len);
1461 }
1462
1463 /* WRITE TYPELENGTHS */
1464 dna_write(file, "TLEN", 4);
1465
1466 len = 2 * types_num;
1467 if (types_num & 1) {
1468 len += 2;
1469 }
1471
1472 /* WRITE STRUCTS */
1473 dna_write(file, "STRC", 4);
1474 len = structs_num;
1475 dna_write(file, &len, 4);
1476
1477 /* calc datablock size */
1478 const short *sp = structs[structs_num - 1];
1479 sp += 2 + 2 * (sp[1]);
1480 len = intptr_t((char *)sp - (char *)structs[0]);
1481 len = (len + 3) & ~3;
1482
1483 dna_write(file, structs[0], len);
1484 }
1485
1486 /* write a simple enum with all structs offsets,
1487 * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */
1488 {
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");
1492 for (int i = 0; i < structs_num; i++) {
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",
1497 version_struct_alias_from_static(types[struct_type_index]),
1498 i);
1499 }
1500 fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", structs_num);
1501 fprintf(file_offsets, "};\n\n");
1502 }
1503
1504 {
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");
1510
1511 /* Starting at 1, because 0 is "raw data". */
1512 for (int i = 1; i < structs_num; i++) {
1513 const short *structpoin = structs[i];
1514 const int struct_type_index = structpoin[0];
1515 const char *name = version_struct_alias_from_static(types[struct_type_index]);
1516 fprintf(file_ids, "struct %s;\n", name);
1517 fprintf(file_ids,
1518 "template<> int blender::dna::sdna_struct_id_get<%s>() { return %d; }\n",
1519 name,
1520 i);
1521 }
1522 }
1523
1524 /* Check versioning errors which could cause duplicate names,
1525 * do last because names are stripped. */
1526 {
1527 GSet *members_unique = BLI_gset_str_new_ex(__func__, 512);
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];
1532 sp += 2;
1533 for (int a = 0; a < len; a++, sp += 2) {
1534 char *member = members[sp[1]];
1535 DNA_member_id_strip(member);
1536 if (!BLI_gset_add(members_unique, member)) {
1537 fprintf(stderr,
1538 "Error: duplicate name found '%s.%s', "
1539 "likely cause is 'dna_rename_defs.h'\n",
1540 type,
1541 member);
1542 return 1;
1543 }
1544 }
1545 BLI_gset_clear(members_unique, nullptr);
1546 }
1547 BLI_gset_free(members_unique, nullptr);
1548 }
1549
1559
1561
1562 BLI_ghash_free(g_version_data.type_map_alias_from_static, nullptr, nullptr);
1563 BLI_ghash_free(g_version_data.type_map_static_from_alias, nullptr, nullptr);
1564 BLI_ghash_free(g_version_data.member_map_static_from_alias, MEM_freeN, nullptr);
1565 BLI_ghash_free(g_version_data.member_map_alias_from_static, MEM_freeN, nullptr);
1566
1567 DEBUG_PRINTF(0, "done.\n");
1568
1569 return 0;
1570}
1571
1573
1574/* end make DNA. */
1575
1576/* -------------------------------------------------------------------- */
1579
1580static void make_bad_file(const char *file, int line)
1581{
1582 FILE *fp = fopen(file, "w");
1583 fprintf(fp,
1584 "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n",
1585 __FILE__,
1586 line);
1587 fclose(fp);
1588}
1589
1590#ifndef BASE_HEADER
1591# define BASE_HEADER "../"
1592#endif
1593
1594int main(int argc, char **argv)
1595{
1596 int return_status = 0;
1597
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]);
1600 return_status = 1;
1601 }
1602 else {
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");
1607 if (!file_dna) {
1608 printf("Unable to open file: %s\n", argv[1]);
1609 return_status = 1;
1610 }
1611 else if (!file_dna_offsets) {
1612 printf("Unable to open file: %s\n", argv[2]);
1613 return_status = 1;
1614 }
1615 else if (!file_dna_verify) {
1616 printf("Unable to open file: %s\n", argv[3]);
1617 return_status = 1;
1618 }
1619 else if (!file_dna_ids) {
1620 printf("Unable to open file: %s\n", argv[4]);
1621 return_status = 1;
1622 }
1623 else {
1624 const char *base_directory;
1625
1626 if (argc == 6) {
1627 base_directory = argv[5];
1628 }
1629 else {
1630 base_directory = BASE_HEADER;
1631 }
1632
1633 /* NOTE: #init_structDNA() in dna_genfile.cc expects `sdna->data` is 4-bytes aligned.
1634 * `DNAstr[]` buffer written by `makesdna` is used for this data, so make `DNAstr` forcefully
1635 * 4-bytes aligned. */
1636#ifdef __GNUC__
1637# define FORCE_ALIGN_4 " __attribute__((aligned(4))) "
1638#else
1639# define FORCE_ALIGN_4 " "
1640#endif
1641 fprintf(file_dna, "extern const unsigned char DNAstr[];\n");
1642 fprintf(file_dna, "const unsigned char" FORCE_ALIGN_4 "DNAstr[] = {\n");
1643#undef FORCE_ALIGN_4
1644
1645 if (make_structDNA(
1646 base_directory, file_dna, file_dna_offsets, file_dna_verify, file_dna_ids))
1647 {
1648 /* error */
1649 fclose(file_dna);
1650 file_dna = nullptr;
1651 make_bad_file(argv[1], __LINE__);
1652 return_status = 1;
1653 }
1654 else {
1655 fprintf(file_dna, "};\n");
1656 fprintf(file_dna, "extern const int DNAlen;\n");
1657 fprintf(file_dna, "const int DNAlen = sizeof(DNAstr);\n");
1658 }
1659 }
1660
1661 if (file_dna) {
1662 fclose(file_dna);
1663 }
1664 if (file_dna_offsets) {
1665 fclose(file_dna_offsets);
1666 }
1667 if (file_dna_verify) {
1668 fclose(file_dna_verify);
1669 }
1670 if (file_dna_ids) {
1671 fclose(file_dna_ids);
1672 }
1673 }
1674
1675 return return_status;
1676}
1677
1678/* handy but fails on struct bounds which makesdna doesn't care about
1679 * with quite the same strictness as GCC does */
1680#if 0
1681/* include files for automatic dependencies */
1682
1683/* extra safety check that we are aligned,
1684 * warnings here are easier to fix the makesdna's */
1685# ifdef __GNUC__
1686# pragma GCC diagnostic error "-Wpadded"
1687# endif
1688
1689#endif /* if 0 */
1690
1691/* The include file below is automatically generated from the `SRC_DNA_INC`
1692 * variable in 'source/blender/CMakeLists.txt'. */
1693#include "dna_includes_all.h"
1694
1695/* end of list */
1696
1698
1699/* -------------------------------------------------------------------- */
1706
1707static void UNUSED_FUNCTION(dna_rename_defs_ensure)()
1708{
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);
1711#include "dna_rename_defs.h"
1712#undef DNA_STRUCT_RENAME
1713#undef DNA_STRUCT_RENAME_MEMBER
1714}
1715
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:83
#define BLI_assert(a)
Definition BLI_assert.h:46
struct GSet GSet
Definition BLI_ghash.h:337
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:731
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)
Definition BLI_ghash.cc:860
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.cc:966
#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 STR_ELEM(...)
Definition BLI_string.h:661
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:604
unsigned int uint
#define UNUSED_FUNCTION(x)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define SDNA_RAW_DATA_STRUCT_INDEX
Read Guarded memory(de)allocation.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static void mul(btAlignedObjectArray< T > &items, const Q &value)
int DNA_member_array_num(const char *str)
Definition dna_utils.cc:29
uint DNA_member_id_offset_start(const char *member_full)
Definition dna_utils.cc:74
uint DNA_member_id_strip(char *member)
Definition dna_utils.cc:106
uint DNA_member_id_strip_copy(char *member_id_dst, const char *member_full_src)
Definition dna_utils.cc:96
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)
Definition dna_utils.cc:134
@ DNA_RENAME_ALIAS_FROM_STATIC
Definition dna_utils.h:91
@ DNA_RENAME_STATIC_FROM_ALIAS
Definition dna_utils.h:90
void DNA_alias_maps(enum eDNA_RenameDir version_dir, struct GHash **r_type_map, struct GHash **r_member_map)
#define str(s)
#define main()
#define printf(...)
int count
static int additional_slen_offset
Definition makesdna.cc:107
static bool match_identifier(const char *str, const char *identifier)
Definition makesdna.cc:203
#define MAX_DNA_LINE_LENGTH
Definition makesdna.cc:1249
static short * types_size_native
Definition makesdna.cc:73
static short * types_align_32
Definition makesdna.cc:75
static int preprocess_include(char *maindata, const int maindata_len)
Definition makesdna.cc:566
static short * types_size_32
Definition makesdna.cc:79
void print_struct_sizes()
Definition makesdna.cc:1266
#define BASE_HEADER
Definition makesdna.cc:1591
static int types_num
Definition makesdna.cc:66
static char * match_preproc_strstr(char *__restrict str, const char *__restrict start)
Definition makesdna.cc:552
static bool str_startswith(const char *__restrict str, const char *__restrict start)
Definition makesdna.cc:521
static short * structdata
Definition makesdna.cc:88
GHash * type_map_alias_from_static
Definition makesdna.cc:92
static int add_type(const char *type_name, int size)
Definition makesdna.cc:304
static const char * version_member_static_from_alias(const int type_index, const char *member_alias_full)
Definition makesdna.cc:239
static short * types_size_64
Definition makesdna.cc:81
static bool match_identifier_and_advance(char **str_ptr, const char *identifier)
Definition makesdna.cc:209
static int add_member(const char *member_name)
Definition makesdna.cc:357
static void * read_file_data(const char *filepath, int *r_len)
Definition makesdna.cc:685
GHash * member_map_alias_from_static
Definition makesdna.cc:94
static int max_data_size
Definition makesdna.cc:64
void BLI_system_backtrace(FILE *fp)
Definition makesdna.cc:119
static char ** types
Definition makesdna.cc:71
static int make_structDNA(const char *base_directory, FILE *file, FILE *file_offsets, FILE *file_verify, FILE *file_ids)
Definition makesdna.cc:1285
static struct @262302365306145015147135362170176324152201236327 g_version_data
static void dna_write(FILE *file, const void *pntr, const int size)
Definition makesdna.cc:1251
static bool check_field_alignment(int firststruct, int struct_type_index, int type, int len, const char *name, const char *detail)
Definition makesdna.cc:923
#define DEBUG_PRINTF(debug_level,...)
Definition makesdna.cc:109
static short * add_struct(int type_index)
Definition makesdna.cc:496
static short ** structs
Definition makesdna.cc:88
static int debugSDNA
Definition makesdna.cc:106
static int convert_include(const char *filepath)
Definition makesdna.cc:726
GHash * type_map_static_from_alias
Definition makesdna.cc:93
static const char * version_struct_alias_from_static(const char *type_static)
Definition makesdna.cc:229
static short * types_align_64
Definition makesdna.cc:77
static bool match_identifier_with_len(const char *str, const char *identifier, const size_t identifier_len)
Definition makesdna.cc:187
#define SDNA_MAX_FILENAME_LENGTH
Definition makesdna.cc:48
static int members_num
Definition makesdna.cc:65
static int max_array_len
Definition makesdna.cc:64
static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory)
Definition makesdna.cc:961
#define FORCE_ALIGN_4
static int structs_num
Definition makesdna.cc:67
static const char * version_struct_static_from_alias(const char *type_alias)
Definition makesdna.cc:219
GHash * member_map_static_from_alias
Definition makesdna.cc:95
static const char * includefiles[]
Definition makesdna.cc:52
static MemArena * mem_arena
Definition makesdna.cc:62
static char ** members
Definition makesdna.cc:69
static bool is_name_legal(const char *name)
Definition makesdna.cc:265
static bool match_preproc_prefix(const char *__restrict str, const char *__restrict start)
Definition makesdna.cc:537
static void make_bad_file(const char *file, int line)
Definition makesdna.cc:1580
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define L
const char * name
i
Definition text_draw.cc:230
uint len