code cleanup: favor braces when blocks have mixed brace use.
[blender.git] / source / blender / makesdna / intern / makesdna.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /**  \file makesdna.c
29  *   \brief Struct muncher for making SDNA.
30  *   \ingroup DNA
31  *
32  * \section aboutmakesdnac About makesdna tool
33  * Originally by Ton, some mods by Frank, and some cleaning and
34  * extension by Nzc.
35  *
36  * Makesdna creates a .c file with a long string of numbers that
37  * encode the Blender file format. It is fast, because it is basically
38  * a binary dump. There are some details to mind when reconstructing
39  * the file (endianness and byte-alignment).
40  *
41  * This little program scans all structs that need to be serialized,
42  * and determined the names and types of all members. It calculates
43  * how much memory (on disk or in ram) is needed to store that struct,
44  * and the offsets for reaching a particular one.
45  *
46  * There is a facility to get verbose output from sdna. Search for
47  * \ref debugSDNA. This int can be set to 0 (no output) to some int. Higher
48  * numbers give more output.
49  */
50
51 #include <string.h>
52 #include <stdlib.h>
53 #include <stdio.h>
54
55 #include "MEM_guardedalloc.h"
56 #include "DNA_sdna_types.h"
57
58 #include "BLO_sys_types.h" // for intptr_t support
59
60 #define SDNA_MAX_FILENAME_LENGTH 255
61
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
67         /* if you add files here, please add them at the end
68          * of makesdna.c (this file) as well */
69
70         "DNA_listBase.h",
71         "DNA_vec_types.h",
72         "DNA_ID.h",
73         "DNA_ipo_types.h",
74         "DNA_key_types.h",
75         "DNA_text_types.h",
76         "DNA_packedFile_types.h",
77         "DNA_camera_types.h",
78         "DNA_image_types.h",
79         "DNA_texture_types.h",
80         "DNA_lamp_types.h",
81         "DNA_material_types.h",
82         "DNA_vfont_types.h",
83         /* if you add files here, please add them at the end
84          * of makesdna.c (this file) as well */
85         "DNA_meta_types.h",
86         "DNA_curve_types.h",
87         "DNA_mesh_types.h",
88         "DNA_meshdata_types.h",
89         "DNA_modifier_types.h",
90         "DNA_lattice_types.h",
91         "DNA_object_types.h",
92         "DNA_object_force.h",
93         "DNA_object_fluidsim.h",
94         "DNA_world_types.h",
95         "DNA_scene_types.h",
96         "DNA_view3d_types.h",
97         "DNA_view2d_types.h",
98         "DNA_space_types.h",
99         "DNA_userdef_types.h",
100         "DNA_screen_types.h",
101         "DNA_sdna_types.h",
102         // if you add files here, please add them at the end
103         // of makesdna.c (this file) as well
104         "DNA_fileglobal_types.h",
105         "DNA_sequence_types.h",
106         "DNA_effect_types.h",
107         "DNA_outliner_types.h",
108         "DNA_property_types.h",
109         "DNA_sensor_types.h",
110         "DNA_controller_types.h",
111         "DNA_actuator_types.h",
112         "DNA_sound_types.h",
113         "DNA_group_types.h",
114         "DNA_armature_types.h",
115         "DNA_action_types.h",
116         "DNA_constraint_types.h",
117         "DNA_nla_types.h",
118         "DNA_node_types.h",
119         "DNA_color_types.h",
120         "DNA_brush_types.h",
121         "DNA_customdata_types.h",
122         "DNA_particle_types.h",
123         "DNA_cloth_types.h",
124         "DNA_gpencil_types.h",
125         /* if you add files here, please add them at the end
126          * of makesdna.c (this file) as well */
127         "DNA_windowmanager_types.h",
128         "DNA_anim_types.h",
129         "DNA_boid_types.h",
130         "DNA_smoke_types.h",
131         "DNA_speaker_types.h",
132         "DNA_movieclip_types.h",
133         "DNA_tracking_types.h",
134         "DNA_dynamicpaint_types.h",
135         "DNA_mask_types.h",
136         "DNA_rigidbody_types.h",
137
138         /* empty string to indicate end of includefiles */
139         ""
140 };
141
142 static int maxdata = 500000, maxnr = 50000;
143 static int nr_names = 0;
144 static int nr_types = 0;
145 static int nr_structs = 0;
146 static char **names, *namedata;      /* at address names[a] is string a */
147 static char **types, *typedata;      /* at address types[a] is string a */
148 static short *typelens_native;       /* at typelens[a] is the length of type 'a' on this systems bitness (32 or 64) */
149 static short *typelens_64;           /* contains sizes as they are calculated on 64 bit systems */
150 static short **structs, *structdata; /* at sp = structs[a] is the first address of a struct definition
151                                       * sp[0] is type number
152                                       * sp[1] is amount of elements
153                                       * sp[2] sp[3] is typenr,  namenr (etc) */
154 /**
155  * Variable to control debug output of makesdna.
156  * debugSDNA:
157  *  - 0 = no output, except errors
158  *  - 1 = detail actions
159  *  - 2 = full trace, tell which names and types were found
160  *  - 4 = full trace, plus all gritty details
161  */
162 static int debugSDNA = 0;
163 static int additional_slen_offset;
164
165 /* ************************************************************************** */
166 /* Functions                                                                  */
167 /* ************************************************************************** */
168
169 /**
170  * Add type \c str to struct indexed by \c len, if it was not yet found.
171  * \param str char
172  * \param len int
173  */
174 static int add_type(const char *str, int len);
175
176 /**
177  * Add variable \c str to 
178  * \param str
179  */
180 static int add_name(const char *str);
181
182 /**
183  * Search whether this structure type was already found, and if not,
184  * add it.
185  */
186 static short *add_struct(int namecode);
187
188 /**
189  * Remove comments from this buffer. Assumes that the buffer refers to
190  * ascii-code text.
191  */
192 static int preprocess_include(char *maindata, int len);
193
194 /**
195  * Scan this file for serializable types.
196  */ 
197 static int convert_include(char *filename);
198
199 /**
200  * Determine how many bytes are needed for an array.
201  */ 
202 static int arraysize(char *astr, int len);
203
204 /**
205  * Determine how many bytes are needed for each struct.
206  */ 
207 static int calculate_structlens(int);
208
209 /**
210  * Construct the DNA.c file
211  */ 
212 static void dna_write(FILE *file, const void *pntr, const int size);
213
214 /**
215  * Report all structures found so far, and print their lengths.
216  */
217 void printStructLengths(void);
218
219
220
221 /* ************************************************************************** */
222 /* Implementation                                                             */
223 /* ************************************************************************** */
224
225 /* ************************* MAKEN DNA ********************** */
226
227 static int add_type(const char *str, int len)
228 {
229         int nr;
230         char *cp;
231         
232         /* first do validity check */
233         if (str[0] == 0) {
234                 return -1;
235         }
236         else if (strchr(str, '*')) {
237                 /* note: this is valid C syntax but we can't parse, complain!
238                  * 'struct SomeStruct* somevar;' <-- correct but we cant handle right now. */
239                 return -1;
240         }
241         
242         /* search through type array */
243         for (nr = 0; nr < nr_types; nr++) {
244                 if (strcmp(str, types[nr]) == 0) {
245                         if (len) {
246                                 typelens_native[nr] = len;
247                                 typelens_64[nr] = len;
248                         }
249                         return nr;
250                 }
251         }
252         
253         /* append new type */
254         if (nr_types == 0) {
255                 cp = typedata;
256         }
257         else {
258                 cp = types[nr_types - 1] + strlen(types[nr_types - 1]) + 1;
259         }
260         strcpy(cp, str);
261         types[nr_types] = cp;
262         typelens_native[nr_types] = len;
263         typelens_64[nr_types] = len;
264         
265         if (nr_types >= maxnr) {
266                 printf("too many types\n");
267                 return nr_types - 1;
268         }
269         nr_types++;
270         
271         return nr_types - 1;
272 }
273
274
275 /**
276  *
277  * Because of the weird way of tokenizing, we have to 'cast' function
278  * pointers to ... (*f)(), whatever the original signature. In fact,
279  * we add name and type at the same time... There are two special
280  * cases, unfortunately. These are explicitly checked.
281  *
282  * */
283 static int add_name(const char *str)
284 {
285         int nr, i, j, k;
286         char *cp;
287         char buf[255]; /* stupid limit, change it :) */
288         const char *name;
289
290         additional_slen_offset = 0;
291         
292         if (str[0] == 0 /*  || (str[1] == 0) */) return -1;
293
294         if (str[0] == '(' && str[1] == '*') {
295                 /* we handle function pointer and special array cases here, e.g.
296                  * void (*function)(...) and float (*array)[..]. the array case
297                  * name is still converted to (array *)() though because it is that
298                  * way in old dna too, and works correct with elementsize() */
299                 int isfuncptr = (strchr(str + 1, '(')) != NULL;
300
301                 if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer or multidim array pointer found\n");
302                 /* functionpointer: transform the type (sometimes) */
303                 i = 0;
304
305                 while (str[i] != ')') {
306                         buf[i] = str[i];
307                         i++;
308                 }
309                 
310                 /* Another number we need is the extra slen offset. This extra
311                  * offset is the overshoot after a space. If there is no
312                  * space, no overshoot should be calculated. */
313                 j = i; /* j at first closing brace */
314
315                 if (debugSDNA > 3) printf("first brace after offset %d\n", i);
316
317                 j++; /* j beyond closing brace ? */
318                 while ((str[j] != 0) && (str[j] != ')')) {
319                         if (debugSDNA > 3) printf("seen %c ( %d)\n", str[j], str[j]);
320                         j++;
321                 }
322                 if (debugSDNA > 3) printf("seen %c ( %d)\n"
323                                               "special after offset%d\n",
324                                               str[j], str[j], j);
325                                 
326                 if (!isfuncptr) {
327                         /* multidimensional array pointer case */
328                         if (str[j] == 0) {
329                                 if (debugSDNA > 3) printf("offsetting for multidim array pointer\n");
330                         }
331                         else
332                                 printf("Error during tokening multidim array pointer\n");
333                 }
334                 else if (str[j] == 0) {
335                         if (debugSDNA > 3) printf("offsetting for space\n"); 
336                         /* get additional offset */
337                         k = 0;
338                         while (str[j] != ')') {
339                                 j++;
340                                 k++;
341                         }
342                         if (debugSDNA > 3) printf("extra offset %d\n", k);
343                         additional_slen_offset = k;
344                 }
345                 else if (str[j] == ')') {
346                         if (debugSDNA > 3) printf("offsetting for brace\n");
347                         ; /* don't get extra offset */
348                 }
349                 else {
350                         printf("Error during tokening function pointer argument list\n");
351                 }
352                                 
353                 /*
354                  * Put )(void) at the end? Maybe )(). Should check this with
355                  * old sdna. Actually, sometimes )(), sometimes )(void...)
356                  * Alas.. such is the nature of braindamage :(
357                  *
358                  * Sorted it out: always do )(), except for headdraw and
359                  * windraw, part of ScrArea. This is important, because some
360                  * linkers will treat different fp's differently when called
361                  * !!! This has to do with interference in byte-alignment and
362                  * the way args are pushed on the stack.
363                  *
364                  * */
365                 buf[i] = 0;
366                 if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); 
367                 if ((strncmp(buf, "(*headdraw", 10) == 0) ||
368                     (strncmp(buf, "(*windraw", 9) == 0) )
369                 {
370                         buf[i] = ')';
371                         buf[i + 1] = '(';
372                         buf[i + 2] = 'v';
373                         buf[i + 3] = 'o';
374                         buf[i + 4] = 'i';
375                         buf[i + 5] = 'd';
376                         buf[i + 6] = ')';
377                         buf[i + 7] = 0;
378                 }
379                 else {
380                         buf[i] = ')';
381                         buf[i + 1] = '(';
382                         buf[i + 2] = ')';
383                         buf[i + 3] = 0;
384                 }
385                 /* now precede with buf*/
386                 if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf);
387                 name = buf;
388         }
389         else {
390                 /* normal field: old code */
391                 name = str;
392         }
393         
394         /* search name array */
395         for (nr = 0; nr < nr_names; nr++) {
396                 if (strcmp(name, names[nr]) == 0) {
397                         return nr;
398                 }
399         }
400         
401         /* append new type */
402         if (nr_names == 0) {
403                 cp = namedata;
404         }
405         else {
406                 cp = names[nr_names - 1] + strlen(names[nr_names - 1]) + 1;
407         }
408         strcpy(cp, name);
409         names[nr_names] = cp;
410         
411         if (nr_names >= maxnr) {
412                 printf("too many names\n");
413                 return nr_names - 1;
414         }
415         nr_names++;
416         
417         return nr_names - 1;
418 }
419
420 static short *add_struct(int namecode)
421 {
422         int len;
423         short *sp;
424
425         if (nr_structs == 0) {
426                 structs[0] = structdata;
427         }
428         else {
429                 sp = structs[nr_structs - 1];
430                 len = sp[1];
431                 structs[nr_structs] = sp + 2 * len + 2;
432         }
433         
434         sp = structs[nr_structs];
435         sp[0] = namecode;
436         
437         if (nr_structs >= maxnr) {
438                 printf("too many structs\n");
439                 return sp;
440         }
441         nr_structs++;
442         
443         return sp;
444 }
445
446 static int preprocess_include(char *maindata, int len)
447 {
448         int a, newlen, comment = 0;
449         char *cp, *temp, *md;
450         
451         /* note: len + 1, last character is a dummy to prevent
452          * comparisons using uninitialized memory */
453         temp = MEM_mallocN(len + 1, "preprocess_include");
454         temp[len] = ' ';
455
456         memcpy(temp, maindata, len);
457         
458         /* remove all c++ comments */
459         /* replace all enters/tabs/etc with spaces */
460         cp = temp;
461         a = len;
462         comment = 0;
463         while (a--) {
464                 if (cp[0] == '/' && cp[1] == '/') {
465                         comment = 1;
466                 }
467                 else if (*cp < 32) {
468                         comment = 0;
469                 }
470                 if (comment || *cp < 32 || *cp > 128) *cp = 32;
471                 cp++;
472         }
473         
474
475         /* data from temp copy to maindata, remove comments and double spaces */
476         cp = temp;
477         md = maindata;
478         newlen = 0;
479         comment = 0;
480         a = len;
481         while (a--) {
482                 
483                 if (cp[0] == '/' && cp[1] == '*') {
484                         comment = 1;
485                         cp[0] = cp[1] = 32;
486                 }
487                 if (cp[0] == '*' && cp[1] == '/') {
488                         comment = 0;
489                         cp[0] = cp[1] = 32;
490                 }
491
492                 /* do not copy when: */
493                 if (comment) {
494                         /* pass */
495                 }
496                 else if (cp[0] == ' ' && cp[1] == ' ') {
497                         /* pass */
498                 }
499                 else if (cp[-1] == '*' && cp[0] == ' ') {
500                         /* pointers with a space */
501                 }       /* skip special keywords */
502                 else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
503                         /* single values are skipped already, so decrement 1 less */
504                         a -= 13;
505                         cp += 13;
506                 }
507                 else {
508                         md[0] = cp[0];
509                         md++;
510                         newlen++;
511                 }
512                 cp++;
513         }
514         
515         MEM_freeN(temp);
516         return newlen;
517 }
518
519 static void *read_file_data(char *filename, int *len_r)
520 {
521 #ifdef WIN32
522         FILE *fp = fopen(filename, "rb");
523 #else
524         FILE *fp = fopen(filename, "r");
525 #endif
526         void *data;
527
528         if (!fp) {
529                 *len_r = -1;
530                 return NULL;
531         }
532
533         fseek(fp, 0L, SEEK_END);
534         *len_r = ftell(fp);
535         fseek(fp, 0L, SEEK_SET);
536
537         data = MEM_mallocN(*len_r, "read_file_data");
538         if (!data) {
539                 *len_r = -1;
540                 fclose(fp);
541                 return NULL;
542         }
543
544         if (fread(data, *len_r, 1, fp) != 1) {
545                 *len_r = -1;
546                 MEM_freeN(data);
547                 fclose(fp);
548                 return NULL;
549         }
550         
551         fclose(fp);
552         return data;
553 }
554
555 static int convert_include(char *filename)
556 {
557         /* read include file, skip structs with a '#' before it.
558          * store all data in temporal arrays.
559          */
560         int filelen, count, overslaan, slen, type, name, strct;
561         short *structpoin, *sp;
562         char *maindata, *mainend, *md, *md1;
563         
564         md = maindata = read_file_data(filename, &filelen);
565         if (filelen == -1) {
566                 printf("Can't read file %s\n", filename);
567                 return 1;
568         }
569
570         filelen = preprocess_include(maindata, filelen);
571         mainend = maindata + filelen - 1;
572
573         /* we look for '{' and then back to 'struct' */
574         count = 0;
575         overslaan = 0;
576         while (count < filelen) {
577                 
578                 /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
579                 if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
580                         overslaan = 1;
581                 }
582                 
583                 if (md[0] == '{') {
584                         md[0] = 0;
585                         if (overslaan) {
586                                 overslaan = 0;
587                         }
588                         else {
589                                 if (md[-1] == ' ') md[-1] = 0;
590                                 md1 = md - 2;
591                                 while (*md1 != 32) md1--;       /* to beginning of word */
592                                 md1++;
593                                 
594                                 /* we've got a struct name when... */
595                                 if (strncmp(md1 - 7, "struct", 6) == 0) {
596
597                                         strct = add_type(md1, 0);
598                                         if (strct == -1) {
599                                                 printf("File '%s' contains struct we cant parse \"%s\"\n", filename, md1);
600                                                 return 1;
601                                         }
602
603                                         structpoin = add_struct(strct);
604                                         sp = structpoin + 2;
605
606                                         if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]);
607
608                                         /* first lets make it all nice strings */
609                                         md1 = md + 1;
610                                         while (*md1 != '}') {
611                                                 if (md1 > mainend) break;
612                                                 
613                                                 if (*md1 == ',' || *md1 == ' ') *md1 = 0;
614                                                 md1++;
615                                         }
616                                         
617                                         /* read types and names until first character that is not '}' */
618                                         md1 = md + 1;
619                                         while (*md1 != '}') {
620                                                 if (md1 > mainend) break;
621                                                 
622                                                 /* skip when it says 'struct' or 'unsigned' or 'const' */
623                                                 if (*md1) {
624                                                         if (strncmp(md1, "struct", 6) == 0) md1 += 7;
625                                                         if (strncmp(md1, "unsigned", 8) == 0) md1 += 9;
626                                                         if (strncmp(md1, "const", 5) == 0) md1 += 6;
627                                                         
628                                                         /* we've got a type! */
629                                                         type = add_type(md1, 0);
630                                                         if (type == -1) {
631                                                                 printf("File '%s' contains struct we can't parse \"%s\"\n", filename, md1);
632                                                                 return 1;
633                                                         }
634
635                                                         if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1);
636
637                                                         md1 += strlen(md1);
638
639                                                         
640                                                         /* read until ';' */
641                                                         while (*md1 != ';') {
642                                                                 if (md1 > mainend) break;
643                                                                 
644                                                                 if (*md1) {
645                                                                         /* We've got a name. slen needs
646                                                                          * correction for function
647                                                                          * pointers! */
648                                                                         slen = (int) strlen(md1);
649                                                                         if (md1[slen - 1] == ';') {
650                                                                                 md1[slen - 1] = 0;
651
652
653                                                                                 name = add_name(md1);
654                                                                                 slen += additional_slen_offset;
655                                                                                 sp[0] = type;
656                                                                                 sp[1] = name;
657
658                                                                                 if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s |", names[name]);
659
660                                                                                 structpoin[1]++;
661                                                                                 sp += 2;
662                                                                                                                                                                         
663                                                                                 md1 += slen;
664                                                                                 break;
665                                                                         }
666                                                                         
667
668                                                                         name = add_name(md1);
669                                                                         slen += additional_slen_offset;
670
671                                                                         sp[0] = type;
672                                                                         sp[1] = name;
673                                                                         if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s ||", names[name]);
674
675                                                                         structpoin[1]++;
676                                                                         sp += 2;
677                                                                         
678                                                                         md1 += slen;
679                                                                 }
680                                                                 md1++;
681                                                         }
682
683                                                         if (debugSDNA > 1) printf(")\n");
684
685                                                 }
686                                                 md1++;
687                                         }
688                                 }
689                         }
690                 }
691                 count++;
692                 md++;
693         }
694         
695         MEM_freeN(maindata);
696
697         return 0;
698 }
699
700 static int arraysize(char *astr, int len)
701 {
702         int a, mul = 1;
703         char str[100], *cp = NULL;
704
705         memcpy(str, astr, len + 1);
706         
707         for (a = 0; a < len; a++) {
708                 if (str[a] == '[') {
709                         cp = &(str[a + 1]);
710                 }
711                 else if (str[a] == ']' && cp) {
712                         str[a] = 0;
713                         /* if 'cp' is a preprocessor definition, it will evaluate to 0,
714                          * the caller needs to check for this case and throw an error */
715                         mul *= atoi(cp);
716                 }
717         }
718         
719         return mul;
720 }
721
722 static int calculate_structlens(int firststruct)
723 {
724         int a, b, len_native, len_64, unknown = nr_structs, lastunknown, structtype, type, mul, namelen;
725         short *sp, *structpoin;
726         char *cp;
727         int has_pointer, dna_error = 0;
728                 
729         while (unknown) {
730                 lastunknown = unknown;
731                 unknown = 0;
732                 
733                 /* check all structs... */
734                 for (a = 0; a < nr_structs; a++) {
735                         structpoin = structs[a];
736                         structtype = structpoin[0];
737
738                         /* when length is not known... */
739                         if (typelens_native[structtype] == 0) {
740                                 
741                                 sp = structpoin + 2;
742                                 len_native = 0;
743                                 len_64 = 0;
744                                 has_pointer = 0;
745                                 
746                                 /* check all elements in struct */
747                                 for (b = 0; b < structpoin[1]; b++, sp += 2) {
748                                         type = sp[0];
749                                         cp = names[sp[1]];
750
751                                         namelen = (int) strlen(cp);
752                                         /* is it a pointer or function pointer? */
753                                         if (cp[0] == '*' || cp[1] == '*') {
754                                                 has_pointer = 1;
755                                                 /* has the name an extra length? (array) */
756                                                 mul = 1;
757                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
758
759                                                 if (mul == 0) {
760                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
761                                                         dna_error = 1;
762                                                 }
763
764                                                 /* 4-8 aligned/ */
765                                                 if (sizeof(void *) == 4) {
766                                                         if (len_native % 4) {
767                                                                 printf("Align pointer error in struct (len_native 4): %s %s\n", types[structtype], cp);
768                                                                 dna_error = 1;
769                                                         }
770                                                 }
771                                                 else {
772                                                         if (len_native % 8) {
773                                                                 printf("Align pointer error in struct (len_native 8): %s %s\n", types[structtype], cp);
774                                                                 dna_error = 1;
775                                                         }
776                                                 }
777
778                                                 if (len_64 % 8) {
779                                                         printf("Align pointer error in struct (len_64 8): %s %s\n", types[structtype], cp);
780                                                         dna_error = 1;
781                                                 }
782
783                                                 len_native += sizeof(void *) * mul;
784                                                 len_64 += 8 * mul;
785
786                                         }
787                                         else if (cp[0] == '[') {
788                                                 /* parsing can cause names "var" and "[3]" to be found for "float var [3]" ... */
789                                                 printf("Parse error in struct, invalid member name: %s %s\n", types[structtype], cp);
790                                                 dna_error = 1;
791                                         }
792                                         else if (typelens_native[type]) {
793                                                 /* has the name an extra length? (array) */
794                                                 mul = 1;
795                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
796
797                                                 if (mul == 0) {
798                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
799                                                         dna_error = 1;
800                                                 }
801
802                                                 /* struct alignment */
803                                                 if (type >= firststruct) {
804                                                         if (sizeof(void *) == 8 && (len_native % 8) ) {
805                                                                 printf("Align struct error: %s %s\n", types[structtype], cp);
806                                                                 dna_error = 1;
807                                                         }
808                                                 }
809                                                 
810                                                 /* 2-4-8 aligned/ */
811                                                 if (type < firststruct && typelens_native[type] > 4 && (len_native % 8)) {
812                                                         printf("Align 8 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 8);
813                                                         dna_error = 1;
814                                                 }
815                                                 if (typelens_native[type] > 3 && (len_native % 4) ) {
816                                                         printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 4);
817                                                         dna_error = 1;
818                                                 }
819                                                 else if (typelens_native[type] == 2 && (len_native % 2) ) {
820                                                         printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 2);
821                                                         dna_error = 1;
822                                                 }
823
824                                                 len_native += mul * typelens_native[type];
825                                                 len_64 += mul * typelens_64[type];
826                                                 
827                                         }
828                                         else {
829                                                 len_native = 0;
830                                                 len_64 = 0;
831                                                 break;
832                                         }
833                                 }
834                                 
835                                 if (len_native == 0) {
836                                         unknown++;
837                                 }
838                                 else {
839                                         typelens_native[structtype] = len_native;
840                                         typelens_64[structtype] = len_64;
841                                         /* two ways to detect if a struct contains a pointer:
842                                          * has_pointer is set or len_64 != len_native */
843                                         if (has_pointer || len_64 != len_native) {
844                                                 if (len_64 % 8) {
845                                                         printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], len_64 % 8);
846                                                         dna_error = 1;
847                                                 }
848                                         }
849                                         
850                                         if (len_native % 4) {
851                                                 printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len_native % 4);
852                                                 dna_error = 1;
853                                         }
854                                         
855                                 }
856                         }
857                 }
858                 
859                 if (unknown == lastunknown) break;
860         }
861         
862         if (unknown) {
863                 printf("ERROR: still %d structs unknown\n", unknown);
864
865                 if (debugSDNA) {
866                         printf("*** Known structs :\n");
867                         
868                         for (a = 0; a < nr_structs; a++) {
869                                 structpoin = structs[a];
870                                 structtype = structpoin[0];
871                                 
872                                 /* length unknown */
873                                 if (typelens_native[structtype] != 0) {
874                                         printf("  %s\n", types[structtype]);
875                                 }
876                         }
877                 }
878
879                         
880                 printf("*** Unknown structs :\n");
881                         
882                 for (a = 0; a < nr_structs; a++) {
883                         structpoin = structs[a];
884                         structtype = structpoin[0];
885
886                         /* length unknown yet */
887                         if (typelens_native[structtype] == 0) {
888                                 printf("  %s\n", types[structtype]);
889                         }
890                 }
891
892                 dna_error = 1;
893         }
894
895         return(dna_error);
896 }
897
898 #define MAX_DNA_LINE_LENGTH 20
899
900 static void dna_write(FILE *file, const void *pntr, const int size)
901 {
902         static int linelength = 0;
903         int i;
904         char *data;
905
906         data = (char *) pntr;
907         
908         for (i = 0; i < size; i++) {
909                 fprintf(file, "%d, ", data[i]);
910                 linelength++;
911                 if (linelength >= MAX_DNA_LINE_LENGTH) {
912                         fprintf(file, "\n");
913                         linelength = 0;
914                 }
915         }
916 }
917
918 void printStructLengths(void)
919 {
920         int a, unknown = nr_structs, structtype;
921         /*int lastunknown;*/ /*UNUSED*/
922         short *structpoin;
923         printf("\n\n*** All detected structs:\n");
924
925         while (unknown) {
926                 /*lastunknown = unknown;*/ /*UNUSED*/
927                 unknown = 0;
928                 
929                 /* check all structs... */
930                 for (a = 0; a < nr_structs; a++) {
931                         structpoin = structs[a];
932                         structtype = structpoin[0];
933                         printf("\t%s\t:%d\n", types[structtype], typelens_native[structtype]);
934                 }
935         }
936
937         printf("*** End of list\n");
938
939 }
940
941
942 static int make_structDNA(const char *baseDirectory, FILE *file)
943 {
944         int len, i;
945         short *sp;
946         /* str contains filenames. Since we now include paths, I stretched       */
947         /* it a bit. Hope this is enough :) -nzc-                                */
948         char str[SDNA_MAX_FILENAME_LENGTH], *cp;
949         int firststruct;
950         
951         if (debugSDNA > -1) {
952                 fflush(stdout);
953                 printf("Running makesdna at debug level %d\n", debugSDNA);
954         }
955                 
956         /* the longest known struct is 50k, so we assume 100k is sufficent! */
957         namedata = MEM_callocN(maxdata, "namedata");
958         typedata = MEM_callocN(maxdata, "typedata");
959         structdata = MEM_callocN(maxdata, "structdata");
960         
961         /* a maximum of 5000 variables, must be sufficient? */
962         names = MEM_callocN(sizeof(char *) * maxnr, "names");
963         types = MEM_callocN(sizeof(char *) * maxnr, "types");
964         typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native");
965         typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64");
966         structs = MEM_callocN(sizeof(short) * maxnr, "structs");
967
968         /* insertion of all known types */
969         /* watch it: uint is not allowed! use in structs an unsigned int */
970         /* watch it: sizes must match DNA_elem_type_size() */
971         add_type("char", 1);     /* SDNA_TYPE_CHAR */
972         add_type("uchar", 1);    /* SDNA_TYPE_UCHAR */
973         add_type("short", 2);    /* SDNA_TYPE_SHORT */
974         add_type("ushort", 2);   /* SDNA_TYPE_USHORT */
975         add_type("int", 4);      /* SDNA_TYPE_INT */
976         add_type("long", 4);     /* SDNA_TYPE_LONG */           /* should it be 8 on 64 bits? */
977         add_type("ulong", 4);    /* SDNA_TYPE_ULONG */
978         add_type("float", 4);    /* SDNA_TYPE_FLOAT */
979         add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
980         add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
981         add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
982         add_type("void", 0);     /* SDNA_TYPE_VOID */
983
984         /* the defines above shouldn't be output in the padding file... */
985         firststruct = nr_types;
986         
987         /* add all include files defined in the global array                     */
988         /* Since the internal file+path name buffer has limited length, I do a   */
989         /* little test first...                                                  */
990         /* Mind the breaking condition here!                                     */
991         if (debugSDNA) printf("\tStart of header scan:\n"); 
992         for (i = 0; *(includefiles[i]) != '\0'; i++) {
993                 sprintf(str, "%s%s", baseDirectory, includefiles[i]);
994                 if (debugSDNA) printf("\t|-- Converting %s\n", str);
995                 if (convert_include(str)) {
996                         return (1);
997                 }
998         }
999         if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 
1000
1001         if (calculate_structlens(firststruct)) {
1002                 /* error */
1003                 return(1);
1004         }
1005
1006         /* FOR DEBUG */
1007         if (debugSDNA > 1) {
1008                 int a, b;
1009                 /* short *elem; */
1010                 short num_types;
1011
1012                 printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
1013                 for (a = 0; a < nr_names; a++) {
1014                         printf(" %s\n", names[a]);
1015                 }
1016                 printf("\n");
1017                 
1018                 sp = typelens_native;
1019                 for (a = 0; a < nr_types; a++, sp++) {
1020                         printf(" %s %d\n", types[a], *sp);
1021                 }
1022                 printf("\n");
1023                 
1024                 for (a = 0; a < nr_structs; a++) {
1025                         sp = structs[a];
1026                         printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], typelens_native[sp[0]]);
1027                         num_types  = sp[1];
1028                         sp += 2;
1029                         /* ? num_types was elem? */
1030                         for (b = 0; b < num_types; b++, sp += 2) {
1031                                 printf("   %s %s\n", types[sp[0]], names[sp[1]]);
1032                         }
1033                 }
1034         }
1035
1036         /* file writing */
1037
1038         if (debugSDNA > -1) printf("Writing file ... ");
1039                 
1040         if (nr_names == 0 || nr_structs == 0) {
1041                 /* pass */
1042         }
1043         else {
1044                 dna_write(file, "SDNA", 4);
1045                 
1046                 /* write names */
1047                 dna_write(file, "NAME", 4);
1048                 len = nr_names;
1049                 dna_write(file, &len, 4);
1050                 
1051                 /* calculate size of datablock with strings */
1052                 cp = names[nr_names - 1];
1053                 cp += strlen(names[nr_names - 1]) + 1;         /* +1: null-terminator */
1054                 len = (intptr_t) (cp - (char *) names[0]);
1055                 len = (len + 3) & ~3;
1056                 dna_write(file, names[0], len);
1057                 
1058                 /* write TYPES */
1059                 dna_write(file, "TYPE", 4);
1060                 len = nr_types;
1061                 dna_write(file, &len, 4);
1062         
1063                 /* calculate datablock size */
1064                 cp = types[nr_types - 1];
1065                 cp += strlen(types[nr_types - 1]) + 1;     /* +1: null-terminator */
1066                 len = (intptr_t) (cp - (char *) types[0]);
1067                 len = (len + 3) & ~3;
1068                 
1069                 dna_write(file, types[0], len);
1070                 
1071                 /* WRITE TYPELENGTHS */
1072                 dna_write(file, "TLEN", 4);
1073                 
1074                 len = 2 * nr_types;
1075                 if (nr_types & 1) len += 2;
1076                 dna_write(file, typelens_native, len);
1077                 
1078                 /* WRITE STRUCTS */
1079                 dna_write(file, "STRC", 4);
1080                 len = nr_structs;
1081                 dna_write(file, &len, 4);
1082         
1083                 /* calc datablock size */
1084                 sp = structs[nr_structs - 1];
1085                 sp += 2 + 2 * (sp[1]);
1086                 len = (intptr_t) ((char *) sp - (char *) structs[0]);
1087                 len = (len + 3) & ~3;
1088                 
1089                 dna_write(file, structs[0], len);
1090         
1091                 /* a simple dna padding test */
1092                 if (0) {
1093                         FILE *fp;
1094                         int a;
1095                         
1096                         fp = fopen("padding.c", "w");
1097                         if (fp == NULL) {
1098                                 /* pass */
1099                         }
1100                         else {
1101
1102                                 /* add all include files defined in the global array */
1103                                 for (i = 0; *(includefiles[i]) != '\0'; i++) {
1104                                         fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
1105                                 }
1106
1107                                 fprintf(fp, "main() {\n");
1108                                 sp = typelens_native;
1109                                 sp += firststruct;
1110                                 for (a = firststruct; a < nr_types; a++, sp++) {
1111                                         if (*sp) {
1112                                                 fprintf(fp, "\tif (sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
1113                                                 fprintf(fp, "%%d %s %d ", types[a], *sp);
1114                                                 fprintf(fp, "\\n\",  sizeof(struct %s) - %d);\n", types[a], *sp);
1115                                         }
1116                                 }
1117                                 fprintf(fp, "}\n");
1118                                 fclose(fp);
1119                         }
1120                 }
1121                 /*      end end padding test */
1122         }
1123         
1124         
1125         MEM_freeN(namedata);
1126         MEM_freeN(typedata);
1127         MEM_freeN(structdata);
1128         MEM_freeN(names);
1129         MEM_freeN(types);
1130         MEM_freeN(typelens_native);
1131         MEM_freeN(typelens_64);
1132         MEM_freeN(structs);
1133
1134         if (debugSDNA > -1) printf("done.\n");
1135         
1136         return(0);
1137 }
1138
1139 /* ************************* END MAKE DNA ********************** */
1140
1141 static void make_bad_file(const char *file, int line)
1142 {
1143         FILE *fp = fopen(file, "w");
1144         fprintf(fp, "#error \"Error! can't make correct DNA.c file from %s:%d, STUPID!\"\n", __FILE__, line);
1145         fclose(fp);
1146 }
1147
1148 #ifndef BASE_HEADER
1149 #define BASE_HEADER "../"
1150 #endif
1151
1152 int main(int argc, char **argv)
1153 {
1154         FILE *file;
1155         int return_status = 0;
1156
1157         if (argc != 2 && argc != 3) {
1158                 printf("Usage: %s outfile.c [base directory]\n", argv[0]);
1159                 return_status = 1;
1160         }
1161         else {
1162                 file = fopen(argv[1], "w");
1163                 if (!file) {
1164                         printf("Unable to open file: %s\n", argv[1]);
1165                         return_status = 1;
1166                 }
1167                 else {
1168                         const char *baseDirectory;
1169
1170                         if (argc == 3) {
1171                                 baseDirectory = argv[2];
1172                         }
1173                         else {
1174                                 baseDirectory = BASE_HEADER;
1175                         }
1176
1177                         fprintf(file, "const unsigned char DNAstr[] = {\n");
1178                         if (make_structDNA(baseDirectory, file)) {
1179                                 /* error */
1180                                 fclose(file);
1181                                 make_bad_file(argv[1], __LINE__);
1182                                 return_status = 1;
1183                         }
1184                         else {
1185                                 fprintf(file, "};\n");
1186                                 fprintf(file, "const int DNAlen = sizeof(DNAstr);\n");
1187         
1188                                 fclose(file);
1189                         }
1190                 }
1191         }
1192
1193                 
1194         return(return_status);
1195 }
1196
1197 /* handy but fails on struct bounds which makesdna doesnt care about
1198  * with quite the same strictness as GCC does */
1199 #if 0
1200 /* include files for automatic dependencies */
1201
1202 /* extra safety check that we are aligned,
1203  * warnings here are easier to fix the makesdna's */
1204 #ifdef __GNUC__
1205 #  pragma GCC diagnostic error "-Wpadded"
1206 #endif
1207
1208 #endif /* if 0 */
1209
1210 #include "DNA_listBase.h"
1211 #include "DNA_vec_types.h"
1212 #include "DNA_ID.h"
1213 #include "DNA_ipo_types.h"
1214 #include "DNA_key_types.h"
1215 #include "DNA_text_types.h"
1216 #include "DNA_packedFile_types.h"
1217 #include "DNA_camera_types.h"
1218 #include "DNA_image_types.h"
1219 #include "DNA_texture_types.h"
1220 #include "DNA_lamp_types.h"
1221 #include "DNA_material_types.h"
1222 #include "DNA_vfont_types.h"
1223 #include "DNA_meta_types.h"
1224 #include "DNA_curve_types.h"
1225 #include "DNA_mesh_types.h"
1226 #include "DNA_meshdata_types.h"
1227 #include "DNA_modifier_types.h"
1228 #include "DNA_lattice_types.h"  
1229 #include "DNA_object_types.h"
1230 #include "DNA_object_force.h"
1231 #include "DNA_object_fluidsim.h"
1232 #include "DNA_world_types.h"
1233 #include "DNA_scene_types.h"
1234 #include "DNA_view3d_types.h"
1235 #include "DNA_view2d_types.h"   
1236 #include "DNA_space_types.h"
1237 #include "DNA_userdef_types.h"
1238 #include "DNA_screen_types.h"
1239 #include "DNA_sdna_types.h"
1240 #include "DNA_fileglobal_types.h"
1241 #include "DNA_sequence_types.h"
1242 #include "DNA_effect_types.h"
1243 #include "DNA_outliner_types.h"
1244 #include "DNA_property_types.h"
1245 #include "DNA_sensor_types.h"
1246 #include "DNA_controller_types.h"
1247 #include "DNA_actuator_types.h"
1248 #include "DNA_sound_types.h"
1249 #include "DNA_group_types.h"
1250 #include "DNA_armature_types.h"
1251 #include "DNA_action_types.h"
1252 #include "DNA_constraint_types.h"
1253 #include "DNA_nla_types.h"
1254 #include "DNA_node_types.h"
1255 #include "DNA_color_types.h"
1256 #include "DNA_brush_types.h"
1257 #include "DNA_customdata_types.h"
1258 #include "DNA_particle_types.h"
1259 #include "DNA_cloth_types.h"
1260 #include "DNA_gpencil_types.h"
1261 #include "DNA_windowmanager_types.h"
1262 #include "DNA_anim_types.h"
1263 #include "DNA_boid_types.h"
1264 #include "DNA_smoke_types.h"
1265 #include "DNA_speaker_types.h"
1266 #include "DNA_movieclip_types.h"
1267 #include "DNA_tracking_types.h"
1268 #include "DNA_dynamicpaint_types.h"
1269 #include "DNA_mask_types.h"
1270 #include "DNA_rigidbody_types.h"
1271 /* end of list */