1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup DNA
22  *
23  * \brief Struct muncher for making SDNA.
24  *
25  * \section aboutmakesdnac About makesdna tool
26  * Originally by Ton, some mods by Frank, and some cleaning and
27  * extension by Nzc.
28  *
29  * Makesdna creates a .c file with a long string of numbers that
30  * encode the Blender file format. It is fast, because it is basically
31  * a binary dump. There are some details to mind when reconstructing
32  * the file (endianness and byte-alignment).
33  *
34  * This little program scans all structs that need to be serialized,
35  * and determined the names and types of all members. It calculates
36  * how much memory (on disk or in ram) is needed to store that struct,
37  * and the offsets for reaching a particular one.
38  *
39  * There is a facility to get verbose output from sdna. Search for
40  * \ref debugSDNA. This int can be set to 0 (no output) to some int. Higher
41  * numbers give more output.
42  */
43 
44 #define DNA_DEPRECATED_ALLOW
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include "MEM_guardedalloc.h"
51 
52 #include "BLI_alloca.h"
53 #include "BLI_ghash.h"
54 #include "BLI_memarena.h"
55 #include "BLI_sys_types.h" /* for intptr_t support */
56 #include "BLI_system.h"    /* for 'BLI_system_backtrace' stub. */
57 #include "BLI_utildefines.h"
58 
59 #include "dna_utils.h"
60 
61 #define SDNA_MAX_FILENAME_LENGTH 255
62 
63 /* Included the path relative from /source/blender/ here, so we can move     */
64 /* headers around with more freedom.                                         */
65 static const char *includefiles[] = {
66     /* if you add files here, please add them at the end
67      * of makesdna.c (this file) as well */
68     "DNA_listBase.h",
69     "DNA_vec_types.h",
70     "DNA_ID.h",
71     "DNA_ipo_types.h",
72     "DNA_key_types.h",
73     "DNA_text_types.h",
74     "DNA_packedFile_types.h",
75     "DNA_gpu_types.h",
76     "DNA_camera_types.h",
77     "DNA_image_types.h",
78     "DNA_texture_types.h",
79     "DNA_light_types.h",
80     "DNA_material_types.h",
81     "DNA_vfont_types.h",
82     "DNA_meta_types.h",
83     "DNA_curve_types.h",
84     "DNA_mesh_types.h",
85     "DNA_meshdata_types.h",
86     "DNA_modifier_types.h",
87     "DNA_lattice_types.h",
88     "DNA_object_types.h",
89     "DNA_object_force_types.h",
90     "DNA_object_fluidsim_types.h",
91     "DNA_world_types.h",
92     "DNA_scene_types.h",
93     "DNA_view3d_types.h",
94     "DNA_view2d_types.h",
95     "DNA_space_types.h",
96     "DNA_userdef_types.h",
97     "DNA_screen_types.h",
98     "DNA_sdna_types.h",
99     "DNA_fileglobal_types.h",
100     "DNA_sequence_types.h",
101     "DNA_session_uuid_types.h",
102     "DNA_effect_types.h",
103     "DNA_outliner_types.h",
104     "DNA_sound_types.h",
105     "DNA_collection_types.h",
106     "DNA_armature_types.h",
107     "DNA_action_types.h",
108     "DNA_constraint_types.h",
109     "DNA_nla_types.h",
110     "DNA_node_types.h",
111     "DNA_color_types.h",
112     "DNA_brush_types.h",
113     "DNA_customdata_types.h",
114     "DNA_particle_types.h",
115     "DNA_cloth_types.h",
116     "DNA_gpencil_types.h",
117     "DNA_gpencil_modifier_types.h",
118     "DNA_shader_fx_types.h",
119     "DNA_windowmanager_types.h",
120     "DNA_anim_types.h",
121     "DNA_boid_types.h",
122     "DNA_fluid_types.h",
123     "DNA_speaker_types.h",
124     "DNA_movieclip_types.h",
125     "DNA_tracking_types.h",
126     "DNA_dynamicpaint_types.h",
127     "DNA_mask_types.h",
128     "DNA_rigidbody_types.h",
129     "DNA_freestyle_types.h",
130     "DNA_linestyle_types.h",
131     "DNA_cachefile_types.h",
132     "DNA_layer_types.h",
133     "DNA_workspace_types.h",
134     "DNA_lightprobe_types.h",
135     "DNA_curveprofile_types.h",
136     "DNA_xr_types.h",
137     "DNA_hair_types.h",
138     "DNA_pointcloud_types.h",
139     "DNA_volume_types.h",
140     "DNA_simulation_types.h",
141     "DNA_pointcache_types.h",
142 
143     /* see comment above before editing! */
144 
145     /* empty string to indicate end of includefiles */
146     "",
147 };
148 
149 /* -------------------------------------------------------------------- */
150 /** \name Variables
151  * \{ */
152 
153 static MemArena *mem_arena = NULL;
154 
155 static int max_data_size = 500000, max_array_len = 50000;
156 static int names_len = 0;
157 static int types_len = 0;
158 static int structs_len = 0;
159 /** At address `names[a]` is string `a`. */
160 static char **names;
161 /** At address `types[a]` is string `a`. */
162 static char **types;
163 /** At `types_size[a]` is the size of type `a` on this systems bitness (32 or 64). */
164 static short *types_size_native;
165 /** Contains sizes as they are calculated on 32 bit systems. */
166 static short *types_size_32;
167 /** Contains sizes as they are calculated on 64 bit systems. */
168 static short *types_size_64;
169 /**
170  * At `sp = structs[a]` is the first address of a struct definition:
171  * - `sp[0]` is type number.
172  * - `sp[1]` is the length of the element array (next).
173  * - `sp[2]` sp[3] is [(type_index, name_index), ..] (number of pairs is defined by `sp[1]`),
174  */
175 static short **structs, *structdata;
176 
177 /** Versioning data */
178 static struct {
179   GHash *struct_map_alias_from_static;
180   GHash *struct_map_static_from_alias;
181   GHash *elem_map_alias_from_static;
182   GHash *elem_map_static_from_alias;
183 } g_version_data = {NULL};
184 
185 /**
186  * Variable to control debug output of makesdna.
187  * debugSDNA:
188  * - 0 = no output, except errors
189  * - 1 = detail actions
190  * - 2 = full trace, tell which names and types were found
191  * - 4 = full trace, plus all gritty details
192  */
193 static int debugSDNA = 0;
194 static int additional_slen_offset;
195 
196 #define DEBUG_PRINTF(debug_level, ...) \
197   { \
198     if (debugSDNA > debug_level) { \
199       printf(__VA_ARGS__); \
200     } \
201   } \
202   ((void)0)
203 
204 /* stub for BLI_abort() */
205 #ifndef NDEBUG
BLI_system_backtrace(FILE * fp)206 void BLI_system_backtrace(FILE *fp)
207 {
208   (void)fp;
209 }
210 #endif
211 
212 /** \} */
213 
214 /* -------------------------------------------------------------------- */
215 /** \name Function Declarations
216  * \{ */
217 
218 /**
219  * Ensure type \c str to is in the #types array.
220  * \param str: Struct name without any qualifiers.
221  * \param size: The struct size in bytes.
222  * \return Index in the #types array.
223  */
224 static int add_type(const char *str, int size);
225 
226 /**
227  * Ensure \c str is int the #names array.
228  * \param str: Struct member name which may include pointer prefix & array size.
229  * \return Index in the #names array.
230  */
231 static int add_name(const char *str);
232 
233 /**
234  * Search whether this structure type was already found, and if not,
235  * add it.
236  */
237 static short *add_struct(int namecode);
238 
239 /**
240  * Remove comments from this buffer. Assumes that the buffer refers to
241  * ascii-code text.
242  */
243 static int preprocess_include(char *maindata, const int maindata_len);
244 
245 /**
246  * Scan this file for serializable types.
247  */
248 static int convert_include(const char *filename);
249 
250 /**
251  * Determine how many bytes are needed for each struct.
252  */
253 static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory);
254 
255 /**
256  * Construct the DNA.c file
257  */
258 static void dna_write(FILE *file, const void *pntr, const int size);
259 
260 /**
261  * Report all structures found so far, and print their lengths.
262  */
263 void print_struct_sizes(void);
264 
265 /** \} */
266 
267 /* -------------------------------------------------------------------- */
268 /** \name Implementation
269  *
270  * Make DNA string (write to file).
271  * \{ */
272 
version_struct_static_from_alias(const char * str)273 static const char *version_struct_static_from_alias(const char *str)
274 {
275   const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_static_from_alias, str);
276   if (str_test != NULL) {
277     return str_test;
278   }
279   return str;
280 }
281 
version_struct_alias_from_static(const char * str)282 static const char *version_struct_alias_from_static(const char *str)
283 {
284   const char *str_test = BLI_ghash_lookup(g_version_data.struct_map_alias_from_static, str);
285   if (str_test != NULL) {
286     return str_test;
287   }
288   return str;
289 }
290 
version_elem_static_from_alias(const int strct,const char * elem_alias_full)291 static const char *version_elem_static_from_alias(const int strct, const char *elem_alias_full)
292 {
293   const uint elem_alias_full_len = strlen(elem_alias_full);
294   char *elem_alias = alloca(elem_alias_full_len + 1);
295   const int elem_alias_len = DNA_elem_id_strip_copy(elem_alias, elem_alias_full);
296   const char *str_pair[2] = {types[strct], elem_alias};
297   const char *elem_static = BLI_ghash_lookup(g_version_data.elem_map_static_from_alias, str_pair);
298   if (elem_static != NULL) {
299     return DNA_elem_id_rename(mem_arena,
300                               elem_alias,
301                               elem_alias_len,
302                               elem_static,
303                               strlen(elem_static),
304                               elem_alias_full,
305                               elem_alias_full_len,
306                               DNA_elem_id_offset_start(elem_alias_full));
307   }
308   return elem_alias_full;
309 }
310 
311 /**
312  * Enforce '_pad123' naming convention, disallow 'pad123' or 'pad_123',
313  * special exception for [a-z] after since there is a 'pad_rot_angle' preference.
314  */
is_name_legal(const char * name)315 static bool is_name_legal(const char *name)
316 {
317   const int name_size = strlen(name) + 1;
318   char *name_strip = alloca(name_size);
319   DNA_elem_id_strip_copy(name_strip, name);
320 
321   const char prefix[] = {'p', 'a', 'd'};
322 
323   if (name[0] == '_') {
324     if (strncmp(&name_strip[1], prefix, sizeof(prefix)) != 0) {
325       fprintf(
326           stderr, "Error: only '_pad' variables can start with an underscore, found '%s'\n", name);
327       return false;
328     }
329   }
330   else if (strncmp(name_strip, prefix, sizeof(prefix)) == 0) {
331     int i = sizeof(prefix);
332     if (name_strip[i] >= 'a' && name_strip[i] <= 'z') {
333       /* may be part of a word, allow that. */
334       return true;
335     }
336     bool has_only_digit_or_none = true;
337     for (; name_strip[i]; i++) {
338       const char c = name_strip[i];
339       if (!((c >= '0' && c <= '9') || c == '_')) {
340         has_only_digit_or_none = false;
341         break;
342       }
343     }
344     if (has_only_digit_or_none) {
345       /* found 'pad' or 'pad123'. */
346       fprintf(
347           stderr, "Error: padding variables must be formatted '_pad[number]', found '%s'\n", name);
348       return false;
349     }
350   }
351   return true;
352 }
353 
add_type(const char * str,int size)354 static int add_type(const char *str, int size)
355 {
356   /* first do validity check */
357   if (str[0] == 0) {
358     return -1;
359   }
360   if (strchr(str, '*')) {
361     /* note: this is valid C syntax but we can't parse, complain!
362      * `struct SomeStruct* some_var;` <-- correct but we cant handle right now. */
363     return -1;
364   }
365 
366   str = version_struct_static_from_alias(str);
367 
368   /* search through type array */
369   for (int index = 0; index < types_len; index++) {
370     if (STREQ(str, types[index])) {
371       if (size) {
372         types_size_native[index] = size;
373         types_size_32[index] = size;
374         types_size_64[index] = size;
375       }
376       return index;
377     }
378   }
379 
380   /* append new type */
381   const int str_size = strlen(str) + 1;
382   char *cp = BLI_memarena_alloc(mem_arena, str_size);
383   memcpy(cp, str, str_size);
384   types[types_len] = cp;
385   types_size_native[types_len] = size;
386   types_size_32[types_len] = size;
387   types_size_64[types_len] = size;
388 
389   if (types_len >= max_array_len) {
390     printf("too many types\n");
391     return types_len - 1;
392   }
393   types_len++;
394 
395   return types_len - 1;
396 }
397 
398 /**
399  *
400  * Because of the weird way of tokenizing, we have to 'cast' function
401  * pointers to ... (*f)(), whatever the original signature. In fact,
402  * we add name and type at the same time... There are two special
403  * cases, unfortunately. These are explicitly checked.
404  *
405  * */
add_name(const char * str)406 static int add_name(const char *str)
407 {
408   char buf[255]; /* stupid limit, change it :) */
409   const char *name;
410 
411   additional_slen_offset = 0;
412 
413   if (str[0] == 0 /*  || (str[1] == 0) */) {
414     return -1;
415   }
416 
417   if (str[0] == '(' && str[1] == '*') {
418     /* We handle function pointer and special array cases here, e.g.
419      * `void (*function)(...)` and `float (*array)[..]`. the array case
420      * name is still converted to (array *)() though because it is that
421      * way in old DNA too, and works correct with #DNA_elem_size_nr. */
422     int isfuncptr = (strchr(str + 1, '(')) != NULL;
423 
424     DEBUG_PRINTF(3, "\t\t\t\t*** Function pointer or multidim array pointer found\n");
425     /* functionpointer: transform the type (sometimes) */
426     int i = 0;
427 
428     while (str[i] != ')') {
429       buf[i] = str[i];
430       i++;
431     }
432 
433     /* Another number we need is the extra slen offset. This extra
434      * offset is the overshoot after a space. If there is no
435      * space, no overshoot should be calculated. */
436     int j = i; /* j at first closing brace */
437 
438     DEBUG_PRINTF(3, "first brace after offset %d\n", i);
439 
440     j++; /* j beyond closing brace ? */
441     while ((str[j] != 0) && (str[j] != ')')) {
442       DEBUG_PRINTF(3, "seen %c (%d)\n", str[j], str[j]);
443       j++;
444     }
445     DEBUG_PRINTF(3,
446                  "seen %c (%d)\n"
447                  "special after offset%d\n",
448                  str[j],
449                  str[j],
450                  j);
451 
452     if (!isfuncptr) {
453       /* multidimensional array pointer case */
454       if (str[j] == 0) {
455         DEBUG_PRINTF(3, "offsetting for multidim array pointer\n");
456       }
457       else {
458         printf("Error during tokening multidim array pointer\n");
459       }
460     }
461     else if (str[j] == 0) {
462       DEBUG_PRINTF(3, "offsetting for space\n");
463       /* get additional offset */
464       int k = 0;
465       while (str[j] != ')') {
466         j++;
467         k++;
468       }
469       DEBUG_PRINTF(3, "extra offset %d\n", k);
470       additional_slen_offset = k;
471     }
472     else if (str[j] == ')') {
473       DEBUG_PRINTF(3, "offsetting for brace\n");
474       /* don't get extra offset */
475     }
476     else {
477       printf("Error during tokening function pointer argument list\n");
478     }
479 
480     /*
481      * Put )(void) at the end? Maybe )(). Should check this with
482      * old sdna. Actually, sometimes )(), sometimes )(void...)
483      * Alas.. such is the nature of brain-damage :(
484      *
485      * Sorted it out: always do )(), except for headdraw and
486      * windraw, part of ScrArea. This is important, because some
487      * linkers will treat different fp's differently when called
488      * !!! This has to do with interference in byte-alignment and
489      * the way args are pushed on the stack.
490      *
491      * */
492     buf[i] = 0;
493     DEBUG_PRINTF(3, "Name before chomping: %s\n", buf);
494     if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) {
495       buf[i] = ')';
496       buf[i + 1] = '(';
497       buf[i + 2] = 'v';
498       buf[i + 3] = 'o';
499       buf[i + 4] = 'i';
500       buf[i + 5] = 'd';
501       buf[i + 6] = ')';
502       buf[i + 7] = 0;
503     }
504     else {
505       buf[i] = ')';
506       buf[i + 1] = '(';
507       buf[i + 2] = ')';
508       buf[i + 3] = 0;
509     }
510     /* now proceed with buf*/
511     DEBUG_PRINTF(3, "\t\t\t\t\tProposing fp name %s\n", buf);
512     name = buf;
513   }
514   else {
515     /* normal field: old code */
516     name = str;
517   }
518 
519   /* search name array */
520   for (int nr = 0; nr < names_len; nr++) {
521     if (STREQ(name, names[nr])) {
522       return nr;
523     }
524   }
525 
526   /* Sanity check the name. */
527   if (!is_name_legal(name)) {
528     return -1;
529   }
530 
531   /* Append new name. */
532   const int name_size = strlen(name) + 1;
533   char *cp = BLI_memarena_alloc(mem_arena, name_size);
534   memcpy(cp, name, name_size);
535   names[names_len] = cp;
536 
537   if (names_len >= max_array_len) {
538     printf("too many names\n");
539     return names_len - 1;
540   }
541   names_len++;
542 
543   return names_len - 1;
544 }
545 
add_struct(int namecode)546 static short *add_struct(int namecode)
547 {
548   if (structs_len == 0) {
549     structs[0] = structdata;
550   }
551   else {
552     short *sp = structs[structs_len - 1];
553     const int len = sp[1];
554     structs[structs_len] = sp + 2 * len + 2;
555   }
556 
557   short *sp = structs[structs_len];
558   sp[0] = namecode;
559 
560   if (structs_len >= max_array_len) {
561     printf("too many structs\n");
562     return sp;
563   }
564   structs_len++;
565 
566   return sp;
567 }
568 
preprocess_include(char * maindata,const int maindata_len)569 static int preprocess_include(char *maindata, const int maindata_len)
570 {
571   /* note: len + 1, last character is a dummy to prevent
572    * comparisons using uninitialized memory */
573   char *temp = MEM_mallocN(maindata_len + 1, "preprocess_include");
574   temp[maindata_len] = ' ';
575 
576   memcpy(temp, maindata, maindata_len);
577 
578   /* remove all c++ comments */
579   /* replace all enters/tabs/etc with spaces */
580   char *cp = temp;
581   int a = maindata_len;
582   int comment = 0;
583   while (a--) {
584     if (cp[0] == '/' && cp[1] == '/') {
585       comment = 1;
586     }
587     else if (*cp == '\n') {
588       comment = 0;
589     }
590     if (comment || *cp < 32 || *cp > 128) {
591       *cp = 32;
592     }
593     cp++;
594   }
595 
596   /* data from temp copy to maindata, remove comments and double spaces */
597   cp = temp;
598   char *md = maindata;
599   int newlen = 0;
600   comment = 0;
601   a = maindata_len;
602   while (a--) {
603 
604     if (cp[0] == '/' && cp[1] == '*') {
605       comment = 1;
606       cp[0] = cp[1] = 32;
607     }
608     if (cp[0] == '*' && cp[1] == '/') {
609       comment = 0;
610       cp[0] = cp[1] = 32;
611     }
612 
613     /* do not copy when: */
614     if (comment) {
615       /* pass */
616     }
617     else if (cp[0] == ' ' && cp[1] == ' ') {
618       /* pass */
619     }
620     else if (cp[-1] == '*' && cp[0] == ' ') {
621       /* pointers with a space */
622     } /* skip special keywords */
623     else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
624       /* single values are skipped already, so decrement 1 less */
625       a -= 13;
626       cp += 13;
627     }
628     else {
629       md[0] = cp[0];
630       md++;
631       newlen++;
632     }
633     cp++;
634   }
635 
636   MEM_freeN(temp);
637   return newlen;
638 }
639 
read_file_data(const char * filename,int * r_len)640 static void *read_file_data(const char *filename, int *r_len)
641 {
642 #ifdef WIN32
643   FILE *fp = fopen(filename, "rb");
644 #else
645   FILE *fp = fopen(filename, "r");
646 #endif
647   void *data;
648 
649   if (!fp) {
650     *r_len = -1;
651     return NULL;
652   }
653 
654   fseek(fp, 0L, SEEK_END);
655   *r_len = ftell(fp);
656   fseek(fp, 0L, SEEK_SET);
657 
658   if (*r_len == -1) {
659     fclose(fp);
660     return NULL;
661   }
662 
663   data = MEM_mallocN(*r_len, "read_file_data");
664   if (!data) {
665     *r_len = -1;
666     fclose(fp);
667     return NULL;
668   }
669 
670   if (fread(data, *r_len, 1, fp) != 1) {
671     *r_len = -1;
672     MEM_freeN(data);
673     fclose(fp);
674     return NULL;
675   }
676 
677   fclose(fp);
678   return data;
679 }
680 
convert_include(const char * filename)681 static int convert_include(const char *filename)
682 {
683   /* read include file, skip structs with a '#' before it.
684    * store all data in temporal arrays.
685    */
686 
687   int maindata_len;
688   char *maindata = read_file_data(filename, &maindata_len);
689   char *md = maindata;
690   if (maindata_len == -1) {
691     fprintf(stderr, "Can't read file %s\n", filename);
692     return 1;
693   }
694 
695   maindata_len = preprocess_include(maindata, maindata_len);
696   char *mainend = maindata + maindata_len - 1;
697 
698   /* we look for '{' and then back to 'struct' */
699   int count = 0;
700   bool skip_struct = false;
701   while (count < maindata_len) {
702 
703     /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
704     if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
705       skip_struct = true;
706     }
707 
708     if (md[0] == '{') {
709       md[0] = 0;
710       if (skip_struct) {
711         skip_struct = false;
712       }
713       else {
714         if (md[-1] == ' ') {
715           md[-1] = 0;
716         }
717         char *md1 = md - 2;
718         while (*md1 != 32) {
719           /* to beginning of word */
720           md1--;
721         }
722         md1++;
723 
724         /* we've got a struct name when... */
725         if (strncmp(md1 - 7, "struct", 6) == 0) {
726 
727           const int strct = add_type(md1, 0);
728           if (strct == -1) {
729             fprintf(stderr, "File '%s' contains struct we cant parse \"%s\"\n", filename, md1);
730             return 1;
731           }
732 
733           short *structpoin = add_struct(strct);
734           short *sp = structpoin + 2;
735 
736           DEBUG_PRINTF(1, "\t|\t|-- detected struct %s\n", types[strct]);
737 
738           /* first lets make it all nice strings */
739           md1 = md + 1;
740           while (*md1 != '}') {
741             if (md1 > mainend) {
742               break;
743             }
744 
745             if (*md1 == ',' || *md1 == ' ') {
746               *md1 = 0;
747             }
748             md1++;
749           }
750 
751           /* read types and names until first character that is not '}' */
752           md1 = md + 1;
753           while (*md1 != '}') {
754             if (md1 > mainend) {
755               break;
756             }
757 
758             /* skip when it says 'struct' or 'unsigned' or 'const' */
759             if (*md1) {
760               if (strncmp(md1, "struct", 6) == 0) {
761                 md1 += 7;
762               }
763               if (strncmp(md1, "unsigned", 8) == 0) {
764                 md1 += 9;
765               }
766               if (strncmp(md1, "const", 5) == 0) {
767                 md1 += 6;
768               }
769 
770               /* we've got a type! */
771               const int type = add_type(md1, 0);
772               if (type == -1) {
773                 fprintf(
774                     stderr, "File '%s' contains struct we can't parse \"%s\"\n", filename, md1);
775                 return 1;
776               }
777 
778               DEBUG_PRINTF(1, "\t|\t|\tfound type %s (", md1);
779 
780               md1 += strlen(md1);
781 
782               /* read until ';' */
783               while (*md1 != ';') {
784                 if (md1 > mainend) {
785                   break;
786                 }
787 
788                 if (*md1) {
789                   /* We've got a name. slen needs
790                    * correction for function
791                    * pointers! */
792                   int slen = (int)strlen(md1);
793                   if (md1[slen - 1] == ';') {
794                     md1[slen - 1] = 0;
795 
796                     const int name = add_name(version_elem_static_from_alias(strct, md1));
797                     if (name == -1) {
798                       fprintf(stderr,
799                               "File '%s' contains struct with name that can't be added \"%s\"\n",
800                               filename,
801                               md1);
802                       return 1;
803                     }
804                     slen += additional_slen_offset;
805                     sp[0] = type;
806                     sp[1] = name;
807 
808                     if (names[name] != NULL) {
809                       DEBUG_PRINTF(1, "%s |", names[name]);
810                     }
811 
812                     structpoin[1]++;
813                     sp += 2;
814 
815                     md1 += slen;
816                     break;
817                   }
818 
819                   const int name = add_name(version_elem_static_from_alias(strct, md1));
820                   if (name == -1) {
821                     fprintf(stderr,
822                             "File '%s' contains struct with name that can't be added \"%s\"\n",
823                             filename,
824                             md1);
825                     return 1;
826                   }
827                   slen += additional_slen_offset;
828 
829                   sp[0] = type;
830                   sp[1] = name;
831                   if (names[name] != NULL) {
832                     DEBUG_PRINTF(1, "%s ||", names[name]);
833                   }
834 
835                   structpoin[1]++;
836                   sp += 2;
837 
838                   md1 += slen;
839                 }
840                 md1++;
841               }
842 
843               DEBUG_PRINTF(1, ")\n");
844             }
845             md1++;
846           }
847         }
848       }
849     }
850     count++;
851     md++;
852   }
853 
854   MEM_freeN(maindata);
855 
856   return 0;
857 }
858 
check_field_alignment(int firststruct,int structtype,int type,int len,const char * name,const char * detail)859 static bool check_field_alignment(
860     int firststruct, int structtype, int type, int len, const char *name, const char *detail)
861 {
862   bool result = true;
863   if (type < firststruct && types_size_native[type] > 4 && (len % 8)) {
864     fprintf(stderr,
865             "Align 8 error (%s) in struct: %s %s (add %d padding bytes)\n",
866             detail,
867             types[structtype],
868             name,
869             len % 8);
870     result = false;
871   }
872   if (types_size_native[type] > 3 && (len % 4)) {
873     fprintf(stderr,
874             "Align 4 error (%s) in struct: %s %s (add %d padding bytes)\n",
875             detail,
876             types[structtype],
877             name,
878             len % 4);
879     result = false;
880   }
881   if (types_size_native[type] == 2 && (len % 2)) {
882     fprintf(stderr,
883             "Align 2 error (%s) in struct: %s %s (add %d padding bytes)\n",
884             detail,
885             types[structtype],
886             name,
887             len % 2);
888     result = false;
889   }
890   return result;
891 }
892 
calculate_struct_sizes(int firststruct,FILE * file_verify,const char * base_directory)893 static int calculate_struct_sizes(int firststruct, FILE *file_verify, const char *base_directory)
894 {
895   bool dna_error = false;
896 
897   /* Write test to verify sizes are accurate. */
898   fprintf(file_verify, "/* Verify struct sizes and member offsets are as expected by DNA. */\n");
899   fprintf(file_verify, "#include \"BLI_assert.h\"\n\n");
900   /* Needed so we can find offsets of deprecated structs. */
901   fprintf(file_verify, "#define DNA_DEPRECATED_ALLOW\n");
902   /* Workaround enum naming collision in static asserts
903    * (ideally this included a unique name/id per file). */
904   fprintf(file_verify, "#define assert_line_ assert_line_DNA_\n");
905   for (int i = 0; *(includefiles[i]) != '\0'; i++) {
906     fprintf(file_verify, "#include \"%s%s\"\n", base_directory, includefiles[i]);
907   }
908   fprintf(file_verify, "#undef assert_line_\n");
909   fprintf(file_verify, "\n");
910 
911   /* Multiple iterations to handle nested structs. */
912   int unknown = structs_len;
913   while (unknown) {
914     const int lastunknown = unknown;
915     unknown = 0;
916 
917     /* check all structs... */
918     for (int a = 0; a < structs_len; a++) {
919       const short *structpoin = structs[a];
920       const int structtype = structpoin[0];
921       const char *structname = version_struct_alias_from_static(types[structtype]);
922 
923       /* when length is not known... */
924       if (types_size_native[structtype] == 0) {
925 
926         const short *sp = structpoin + 2;
927         int size_native = 0;
928         int size_32 = 0;
929         int size_64 = 0;
930         bool has_pointer = false;
931 
932         /* check all elements in struct */
933         for (int b = 0; b < structpoin[1]; b++, sp += 2) {
934           int type = sp[0];
935           const char *cp = names[sp[1]];
936           int namelen = (int)strlen(cp);
937 
938           /* Write size verification to file. */
939           {
940             /* Normally 'alloca' would be used here, however we can't in a loop.
941              * Use an over-sized buffer instead. */
942             char name_static[1024];
943             BLI_assert(sizeof(name_static) > namelen);
944 
945             DNA_elem_id_strip_copy(name_static, cp);
946             const char *str_pair[2] = {types[structtype], name_static};
947             const char *name_alias = BLI_ghash_lookup(g_version_data.elem_map_alias_from_static,
948                                                       str_pair);
949             fprintf(file_verify,
950                     "BLI_STATIC_ASSERT(offsetof(struct %s, %s) == %d, \"DNA member offset "
951                     "verify\");\n",
952                     structname,
953                     name_alias ? name_alias : name_static,
954                     size_native);
955           }
956 
957           /* is it a pointer or function pointer? */
958           if (cp[0] == '*' || cp[1] == '*') {
959             has_pointer = 1;
960             /* has the name an extra length? (array) */
961             int mul = 1;
962             if (cp[namelen - 1] == ']') {
963               mul = DNA_elem_array_size(cp);
964             }
965 
966             if (mul == 0) {
967               fprintf(stderr,
968                       "Zero array size found or could not parse %s: '%.*s'\n",
969                       types[structtype],
970                       namelen + 1,
971                       cp);
972               dna_error = 1;
973             }
974 
975             /* 4-8 aligned/ */
976             if (sizeof(void *) == 4) {
977               if (size_native % 4) {
978                 fprintf(stderr,
979                         "Align pointer error in struct (size_native 4): %s %s\n",
980                         types[structtype],
981                         cp);
982                 dna_error = 1;
983               }
984             }
985             else {
986               if (size_native % 8) {
987                 fprintf(stderr,
988                         "Align pointer error in struct (size_native 8): %s %s\n",
989                         types[structtype],
990                         cp);
991                 dna_error = 1;
992               }
993             }
994 
995             if (size_64 % 8) {
996               fprintf(stderr,
997                       "Align pointer error in struct (size_64 8): %s %s\n",
998                       types[structtype],
999                       cp);
1000               dna_error = 1;
1001             }
1002 
1003             size_native += sizeof(void *) * mul;
1004             size_32 += 4 * mul;
1005             size_64 += 8 * mul;
1006           }
1007           else if (cp[0] == '[') {
1008             /* parsing can cause names "var" and "[3]"
1009              * to be found for "float var [3]" */
1010             fprintf(stderr,
1011                     "Parse error in struct, invalid member name: %s %s\n",
1012                     types[structtype],
1013                     cp);
1014             dna_error = 1;
1015           }
1016           else if (types_size_native[type]) {
1017             /* has the name an extra length? (array) */
1018             int mul = 1;
1019             if (cp[namelen - 1] == ']') {
1020               mul = DNA_elem_array_size(cp);
1021             }
1022 
1023             if (mul == 0) {
1024               fprintf(stderr,
1025                       "Zero array size found or could not parse %s: '%.*s'\n",
1026                       types[structtype],
1027                       namelen + 1,
1028                       cp);
1029               dna_error = 1;
1030             }
1031 
1032             /* struct alignment */
1033             if (type >= firststruct) {
1034               if (sizeof(void *) == 8 && (size_native % 8)) {
1035                 fprintf(stderr, "Align struct error: %s %s\n", types[structtype], cp);
1036                 dna_error = 1;
1037               }
1038             }
1039 
1040             /* Check 2-4-8 aligned. */
1041             if (!check_field_alignment(firststruct, structtype, type, size_32, cp, "32 bit")) {
1042               dna_error = 1;
1043             }
1044             if (!check_field_alignment(firststruct, structtype, type, size_64, cp, "64 bit")) {
1045               dna_error = 1;
1046             }
1047 
1048             size_native += mul * types_size_native[type];
1049             size_32 += mul * types_size_32[type];
1050             size_64 += mul * types_size_64[type];
1051           }
1052           else {
1053             size_native = 0;
1054             size_32 = 0;
1055             size_64 = 0;
1056             break;
1057           }
1058         }
1059 
1060         if (size_native == 0) {
1061           unknown++;
1062         }
1063         else {
1064           types_size_native[structtype] = size_native;
1065           types_size_32[structtype] = size_32;
1066           types_size_64[structtype] = size_64;
1067           /* Two ways to detect if a struct contains a pointer:
1068            * has_pointer is set or size_native doesn't match any of 32/64bit lengths. */
1069           if (has_pointer || size_64 != size_native || size_32 != size_native) {
1070             if (size_64 % 8) {
1071               fprintf(stderr,
1072                       "Sizeerror 8 in struct: %s (add %d bytes)\n",
1073                       types[structtype],
1074                       size_64 % 8);
1075               dna_error = 1;
1076             }
1077           }
1078 
1079           if (size_native % 4) {
1080             fprintf(stderr,
1081                     "Sizeerror 4 in struct: %s (add %d bytes)\n",
1082                     types[structtype],
1083                     size_native % 4);
1084             dna_error = 1;
1085           }
1086 
1087           /* Write size verification to file. */
1088           fprintf(file_verify,
1089                   "BLI_STATIC_ASSERT(sizeof(struct %s) == %d, \"DNA struct size verify\");\n\n",
1090                   structname,
1091                   size_native);
1092         }
1093       }
1094     }
1095 
1096     if (unknown == lastunknown) {
1097       break;
1098     }
1099   }
1100 
1101   if (unknown) {
1102     fprintf(stderr, "ERROR: still %d structs unknown\n", unknown);
1103 
1104     if (debugSDNA) {
1105       fprintf(stderr, "*** Known structs :\n");
1106 
1107       for (int a = 0; a < structs_len; a++) {
1108         const short *structpoin = structs[a];
1109         const int structtype = structpoin[0];
1110 
1111         /* length unknown */
1112         if (types_size_native[structtype] != 0) {
1113           fprintf(stderr, "  %s\n", types[structtype]);
1114         }
1115       }
1116     }
1117 
1118     fprintf(stderr, "*** Unknown structs :\n");
1119 
1120     for (int a = 0; a < structs_len; a++) {
1121       const short *structpoin = structs[a];
1122       const int structtype = structpoin[0];
1123 
1124       /* length unknown yet */
1125       if (types_size_native[structtype] == 0) {
1126         fprintf(stderr, "  %s\n", types[structtype]);
1127       }
1128     }
1129 
1130     dna_error = 1;
1131   }
1132 
1133   return dna_error;
1134 }
1135 
1136 #define MAX_DNA_LINE_LENGTH 20
1137 
dna_write(FILE * file,const void * pntr,const int size)1138 static void dna_write(FILE *file, const void *pntr, const int size)
1139 {
1140   static int linelength = 0;
1141   const char *data = (const char *)pntr;
1142 
1143   for (int i = 0; i < size; i++) {
1144     fprintf(file, "%d, ", data[i]);
1145     linelength++;
1146     if (linelength >= MAX_DNA_LINE_LENGTH) {
1147       fprintf(file, "\n");
1148       linelength = 0;
1149     }
1150   }
1151 }
1152 
print_struct_sizes(void)1153 void print_struct_sizes(void)
1154 {
1155   int unknown = structs_len;
1156   printf("\n\n*** All detected structs:\n");
1157 
1158   while (unknown) {
1159     unknown = 0;
1160 
1161     /* check all structs... */
1162     for (int a = 0; a < structs_len; a++) {
1163       const short *structpoin = structs[a];
1164       const int structtype = structpoin[0];
1165       printf("\t%s\t:%d\n", types[structtype], types_size_native[structtype]);
1166     }
1167   }
1168 
1169   printf("*** End of list\n");
1170 }
1171 
make_structDNA(const char * base_directory,FILE * file,FILE * file_offsets,FILE * file_verify)1172 static int make_structDNA(const char *base_directory,
1173                           FILE *file,
1174                           FILE *file_offsets,
1175                           FILE *file_verify)
1176 {
1177   if (debugSDNA > 0) {
1178     fflush(stdout);
1179     printf("Running makesdna at debug level %d\n", debugSDNA);
1180   }
1181 
1182   mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
1183 
1184   /* the longest known struct is 50k, so we assume 100k is sufficient! */
1185   structdata = MEM_callocN(max_data_size, "structdata");
1186 
1187   /* a maximum of 5000 variables, must be sufficient? */
1188   names = MEM_callocN(sizeof(char *) * max_array_len, "names");
1189   types = MEM_callocN(sizeof(char *) * max_array_len, "types");
1190   types_size_native = MEM_callocN(sizeof(short) * max_array_len, "types_size_native");
1191   types_size_32 = MEM_callocN(sizeof(short) * max_array_len, "types_size_32");
1192   types_size_64 = MEM_callocN(sizeof(short) * max_array_len, "types_size_64");
1193   structs = MEM_callocN(sizeof(short *) * max_array_len, "structs");
1194 
1195   /* Build versioning data */
1196   DNA_alias_maps(DNA_RENAME_ALIAS_FROM_STATIC,
1197                  &g_version_data.struct_map_alias_from_static,
1198                  &g_version_data.elem_map_alias_from_static);
1199   DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS,
1200                  &g_version_data.struct_map_static_from_alias,
1201                  &g_version_data.elem_map_static_from_alias);
1202 
1203   /**
1204    * Insertion of all known types.
1205    *
1206    * \warning Order of function calls here must be aligned with #eSDNA_Type.
1207    * \warning uint is not allowed! use in structs an unsigned int.
1208    * \warning sizes must match #DNA_elem_type_size().
1209    */
1210   add_type("char", 1);   /* SDNA_TYPE_CHAR */
1211   add_type("uchar", 1);  /* SDNA_TYPE_UCHAR */
1212   add_type("short", 2);  /* SDNA_TYPE_SHORT */
1213   add_type("ushort", 2); /* SDNA_TYPE_USHORT */
1214   add_type("int", 4);    /* SDNA_TYPE_INT */
1215 
1216   /* note, long isn't supported,
1217    * these are place-holders to maintain alignment with eSDNA_Type*/
1218   add_type("long", 4);  /* SDNA_TYPE_LONG */
1219   add_type("ulong", 4); /* SDNA_TYPE_ULONG */
1220 
1221   add_type("float", 4);    /* SDNA_TYPE_FLOAT */
1222   add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
1223   add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
1224   add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
1225   add_type("void", 0);     /* SDNA_TYPE_VOID */
1226 
1227   /* the defines above shouldn't be output in the padding file... */
1228   const int firststruct = types_len;
1229 
1230   /* add all include files defined in the global array                     */
1231   /* Since the internal file+path name buffer has limited length, I do a   */
1232   /* little test first...                                                  */
1233   /* Mind the breaking condition here!                                     */
1234   DEBUG_PRINTF(0, "\tStart of header scan:\n");
1235   int header_count = 0;
1236   for (int i = 0; *(includefiles[i]) != '\0'; i++) {
1237     header_count++;
1238 
1239     /* str contains filenames. Since we now include paths, I stretched       */
1240     /* it a bit. Hope this is enough :) -nzc-                                */
1241     char str[SDNA_MAX_FILENAME_LENGTH];
1242     sprintf(str, "%s%s", base_directory, includefiles[i]);
1243     DEBUG_PRINTF(0, "\t|-- Converting %s\n", str);
1244     if (convert_include(str)) {
1245       return 1;
1246     }
1247   }
1248   DEBUG_PRINTF(0, "\tFinished scanning %d headers.\n", header_count);
1249 
1250   if (calculate_struct_sizes(firststruct, file_verify, base_directory)) {
1251     /* error */
1252     return 1;
1253   }
1254 
1255   /* FOR DEBUG */
1256   if (debugSDNA > 1) {
1257     int a, b;
1258     /* short *elem; */
1259     short num_types;
1260 
1261     printf("names_len %d types_len %d structs_len %d\n", names_len, types_len, structs_len);
1262     for (a = 0; a < names_len; a++) {
1263       printf(" %s\n", names[a]);
1264     }
1265     printf("\n");
1266 
1267     const short *sp = types_size_native;
1268     for (a = 0; a < types_len; a++, sp++) {
1269       printf(" %s %d\n", types[a], *sp);
1270     }
1271     printf("\n");
1272 
1273     for (a = 0; a < structs_len; a++) {
1274       sp = structs[a];
1275       printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], types_size_native[sp[0]]);
1276       num_types = sp[1];
1277       sp += 2;
1278       /* ? num_types was elem? */
1279       for (b = 0; b < num_types; b++, sp += 2) {
1280         printf("   %s %s\n", types[sp[0]], names[sp[1]]);
1281       }
1282     }
1283   }
1284 
1285   /* file writing */
1286 
1287   DEBUG_PRINTF(0, "Writing file ... ");
1288 
1289   if (names_len == 0 || structs_len == 0) {
1290     /* pass */
1291   }
1292   else {
1293     const char nil_bytes[4] = {0};
1294 
1295     dna_write(file, "SDNA", 4);
1296 
1297     /* write names */
1298     dna_write(file, "NAME", 4);
1299     int len = names_len;
1300     dna_write(file, &len, 4);
1301     /* write array */
1302     len = 0;
1303     for (int nr = 0; nr < names_len; nr++) {
1304       int name_size = strlen(names[nr]) + 1;
1305       dna_write(file, names[nr], name_size);
1306       len += name_size;
1307     }
1308     int len_align = (len + 3) & ~3;
1309     if (len != len_align) {
1310       dna_write(file, nil_bytes, len_align - len);
1311     }
1312 
1313     /* write TYPES */
1314     dna_write(file, "TYPE", 4);
1315     len = types_len;
1316     dna_write(file, &len, 4);
1317     /* write array */
1318     len = 0;
1319     for (int nr = 0; nr < types_len; nr++) {
1320       int type_size = strlen(types[nr]) + 1;
1321       dna_write(file, types[nr], type_size);
1322       len += type_size;
1323     }
1324     len_align = (len + 3) & ~3;
1325     if (len != len_align) {
1326       dna_write(file, nil_bytes, len_align - len);
1327     }
1328 
1329     /* WRITE TYPELENGTHS */
1330     dna_write(file, "TLEN", 4);
1331 
1332     len = 2 * types_len;
1333     if (types_len & 1) {
1334       len += 2;
1335     }
1336     dna_write(file, types_size_native, len);
1337 
1338     /* WRITE STRUCTS */
1339     dna_write(file, "STRC", 4);
1340     len = structs_len;
1341     dna_write(file, &len, 4);
1342 
1343     /* calc datablock size */
1344     const short *sp = structs[structs_len - 1];
1345     sp += 2 + 2 * (sp[1]);
1346     len = (intptr_t)((char *)sp - (char *)structs[0]);
1347     len = (len + 3) & ~3;
1348 
1349     dna_write(file, structs[0], len);
1350   }
1351 
1352   /* write a simple enum with all structs offsets,
1353    * should only be accessed via SDNA_TYPE_FROM_STRUCT macro */
1354   {
1355     fprintf(file_offsets, "#pragma once\n");
1356     fprintf(file_offsets, "#define SDNA_TYPE_FROM_STRUCT(id) _SDNA_TYPE_##id\n");
1357     fprintf(file_offsets, "enum {\n");
1358     for (int i = 0; i < structs_len; i++) {
1359       const short *structpoin = structs[i];
1360       const int structtype = structpoin[0];
1361       fprintf(file_offsets,
1362               "\t_SDNA_TYPE_%s = %d,\n",
1363               version_struct_alias_from_static(types[structtype]),
1364               i);
1365     }
1366     fprintf(file_offsets, "\tSDNA_TYPE_MAX = %d,\n", structs_len);
1367     fprintf(file_offsets, "};\n\n");
1368   }
1369 
1370   /* Check versioning errors which could cause duplicate names,
1371    * do last because names are stripped. */
1372   {
1373     GSet *names_unique = BLI_gset_str_new_ex(__func__, 512);
1374     for (int struct_nr = 0; struct_nr < structs_len; struct_nr++) {
1375       const short *sp = structs[struct_nr];
1376       const char *struct_name = types[sp[0]];
1377       const int len = sp[1];
1378       sp += 2;
1379       for (int a = 0; a < len; a++, sp += 2) {
1380         char *name = names[sp[1]];
1381         DNA_elem_id_strip(name);
1382         if (!BLI_gset_add(names_unique, name)) {
1383           fprintf(stderr,
1384                   "Error: duplicate name found '%s.%s', "
1385                   "likely cause is 'dna_rename_defs.h'\n",
1386                   struct_name,
1387                   name);
1388           return 1;
1389         }
1390       }
1391       BLI_gset_clear(names_unique, NULL);
1392     }
1393     BLI_gset_free(names_unique, NULL);
1394   }
1395 
1396   MEM_freeN(structdata);
1397   MEM_freeN(names);
1398   MEM_freeN(types);
1399   MEM_freeN(types_size_native);
1400   MEM_freeN(types_size_32);
1401   MEM_freeN(types_size_64);
1402   MEM_freeN(structs);
1403 
1404   BLI_memarena_free(mem_arena);
1405 
1406   BLI_ghash_free(g_version_data.struct_map_alias_from_static, NULL, NULL);
1407   BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL);
1408   BLI_ghash_free(g_version_data.elem_map_static_from_alias, MEM_freeN, NULL);
1409   BLI_ghash_free(g_version_data.elem_map_alias_from_static, MEM_freeN, NULL);
1410 
1411   DEBUG_PRINTF(0, "done.\n");
1412 
1413   return 0;
1414 }
1415 
1416 /** \} */
1417 
1418 /* end make DNA. */
1419 
1420 /* -------------------------------------------------------------------- */
1421 /** \name Main Function
1422  * \{ */
1423 
make_bad_file(const char * file,int line)1424 static void make_bad_file(const char *file, int line)
1425 {
1426   FILE *fp = fopen(file, "w");
1427   fprintf(fp,
1428           "#error \"Error! can't make correct DNA.c file from %s:%d, check alignment.\"\n",
1429           __FILE__,
1430           line);
1431   fclose(fp);
1432 }
1433 
1434 #ifndef BASE_HEADER
1435 #  define BASE_HEADER "../"
1436 #endif
1437 
main(int argc,char ** argv)1438 int main(int argc, char **argv)
1439 {
1440   int return_status = 0;
1441 
1442   if (argc != 4 && argc != 5) {
1443     printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]);
1444     return_status = 1;
1445   }
1446   else {
1447     FILE *file_dna = fopen(argv[1], "w");
1448     FILE *file_dna_offsets = fopen(argv[2], "w");
1449     FILE *file_dna_verify = fopen(argv[3], "w");
1450     if (!file_dna) {
1451       printf("Unable to open file: %s\n", argv[1]);
1452       return_status = 1;
1453     }
1454     else if (!file_dna_offsets) {
1455       printf("Unable to open file: %s\n", argv[2]);
1456       return_status = 1;
1457     }
1458     else if (!file_dna_verify) {
1459       printf("Unable to open file: %s\n", argv[3]);
1460       return_status = 1;
1461     }
1462     else {
1463       const char *base_directory;
1464 
1465       if (argc == 5) {
1466         base_directory = argv[4];
1467       }
1468       else {
1469         base_directory = BASE_HEADER;
1470       }
1471 
1472       fprintf(file_dna, "extern const unsigned char DNAstr[];\n");
1473       fprintf(file_dna, "const unsigned char DNAstr[] = {\n");
1474       if (make_structDNA(base_directory, file_dna, file_dna_offsets, file_dna_verify)) {
1475         /* error */
1476         fclose(file_dna);
1477         file_dna = NULL;
1478         make_bad_file(argv[1], __LINE__);
1479         return_status = 1;
1480       }
1481       else {
1482         fprintf(file_dna, "};\n");
1483         fprintf(file_dna, "extern const int DNAlen;\n");
1484         fprintf(file_dna, "const int DNAlen = sizeof(DNAstr);\n");
1485       }
1486     }
1487 
1488     if (file_dna) {
1489       fclose(file_dna);
1490     }
1491     if (file_dna_offsets) {
1492       fclose(file_dna_offsets);
1493     }
1494     if (file_dna_verify) {
1495       fclose(file_dna_verify);
1496     }
1497   }
1498 
1499   return return_status;
1500 }
1501 
1502 /* handy but fails on struct bounds which makesdna doesn't care about
1503  * with quite the same strictness as GCC does */
1504 #if 0
1505 /* include files for automatic dependencies */
1506 
1507 /* extra safety check that we are aligned,
1508  * warnings here are easier to fix the makesdna's */
1509 #  ifdef __GNUC__
1510 #    pragma GCC diagnostic error "-Wpadded"
1511 #  endif
1512 
1513 #endif /* if 0 */
1514 
1515 /**
1516  * Disable types:
1517  *
1518  * - 'long': even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit,
1519  *   use int, int32_t or int64_t instead.
1520  * - 'int8_t': as DNA doesn't yet support 'signed char' types,
1521  *   all char types are assumed to be unsigned.
1522  *   We should be able to support this, it's just not something which has been added yet.
1523  *
1524  * Only valid use would be as a runtime variable if an API expected a long,
1525  * but so far we don't have this happening.
1526  */
1527 #ifdef __GNUC__
1528 #  pragma GCC poison long
1529 #  pragma GCC poison int8_t
1530 #endif
1531 
1532 #include "DNA_ID.h"
1533 #include "DNA_action_types.h"
1534 #include "DNA_anim_types.h"
1535 #include "DNA_armature_types.h"
1536 #include "DNA_boid_types.h"
1537 #include "DNA_brush_types.h"
1538 #include "DNA_cachefile_types.h"
1539 #include "DNA_camera_types.h"
1540 #include "DNA_cloth_types.h"
1541 #include "DNA_collection_types.h"
1542 #include "DNA_color_types.h"
1543 #include "DNA_constraint_types.h"
1544 #include "DNA_curve_types.h"
1545 #include "DNA_curveprofile_types.h"
1546 #include "DNA_customdata_types.h"
1547 #include "DNA_dynamicpaint_types.h"
1548 #include "DNA_effect_types.h"
1549 #include "DNA_fileglobal_types.h"
1550 #include "DNA_fluid_types.h"
1551 #include "DNA_freestyle_types.h"
1552 #include "DNA_gpencil_modifier_types.h"
1553 #include "DNA_gpencil_types.h"
1554 #include "DNA_hair_types.h"
1555 #include "DNA_image_types.h"
1556 #include "DNA_ipo_types.h"
1557 #include "DNA_key_types.h"
1558 #include "DNA_lattice_types.h"
1559 #include "DNA_layer_types.h"
1560 #include "DNA_light_types.h"
1561 #include "DNA_lightprobe_types.h"
1562 #include "DNA_linestyle_types.h"
1563 #include "DNA_listBase.h"
1564 #include "DNA_mask_types.h"
1565 #include "DNA_material_types.h"
1566 #include "DNA_mesh_types.h"
1567 #include "DNA_meshdata_types.h"
1568 #include "DNA_meta_types.h"
1569 #include "DNA_modifier_types.h"
1570 #include "DNA_movieclip_types.h"
1571 #include "DNA_nla_types.h"
1572 #include "DNA_node_types.h"
1573 #include "DNA_object_fluidsim_types.h"
1574 #include "DNA_object_force_types.h"
1575 #include "DNA_object_types.h"
1576 #include "DNA_outliner_types.h"
1577 #include "DNA_packedFile_types.h"
1578 #include "DNA_particle_types.h"
1579 #include "DNA_pointcache_types.h"
1580 #include "DNA_pointcloud_types.h"
1581 #include "DNA_rigidbody_types.h"
1582 #include "DNA_scene_types.h"
1583 #include "DNA_screen_types.h"
1584 #include "DNA_sdna_types.h"
1585 #include "DNA_sequence_types.h"
1586 #include "DNA_session_uuid_types.h"
1587 #include "DNA_shader_fx_types.h"
1588 #include "DNA_simulation_types.h"
1589 #include "DNA_sound_types.h"
1590 #include "DNA_space_types.h"
1591 #include "DNA_speaker_types.h"
1592 #include "DNA_text_types.h"
1593 #include "DNA_texture_types.h"
1594 #include "DNA_tracking_types.h"
1595 #include "DNA_userdef_types.h"
1596 #include "DNA_vec_types.h"
1597 #include "DNA_vfont_types.h"
1598 #include "DNA_view2d_types.h"
1599 #include "DNA_view3d_types.h"
1600 #include "DNA_volume_types.h"
1601 #include "DNA_windowmanager_types.h"
1602 #include "DNA_workspace_types.h"
1603 #include "DNA_world_types.h"
1604 #include "DNA_xr_types.h"
1605 
1606 /* end of list */
1607 
1608 /** \} */
1609 
1610 /* -------------------------------------------------------------------- */
1611 /** \name DNA Renaming Sanity Check
1612  *
1613  * Without this it's possible to reference struct members that don't exist,
1614  * breaking backward & forward compatibility.
1615  *
1616  * \{ */
1617 
UNUSED_FUNCTION(dna_rename_defs_ensure)1618 static void UNUSED_FUNCTION(dna_rename_defs_ensure)(void)
1619 {
1620 #define DNA_STRUCT_RENAME(old, new) (void)sizeof(new);
1621 #define DNA_STRUCT_RENAME_ELEM(struct_name, old, new) (void)offsetof(struct_name, new);
1622 #include "dna_rename_defs.h"
1623 #undef DNA_STRUCT_RENAME
1624 #undef DNA_STRUCT_RENAME_ELEM
1625 }
1626 
1627 /** \} */
1628