style cleanup
[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
137         /* empty string to indicate end of includefiles */
138         ""
139 };
140
141 static int maxdata = 500000, maxnr = 50000;
142 static int nr_names = 0;
143 static int nr_types = 0;
144 static int nr_structs = 0;
145 static char **names, *namedata;      /* at address names[a] is string a */
146 static char **types, *typedata;      /* at address types[a] is string a */
147 static short *typelens_native;       /* at typelens[a] is the length of type 'a' on this systems bitness (32 or 64) */
148 static short *typelens_64;           /* contains sizes as they are calculated on 64 bit systems */
149 static short **structs, *structdata; /* at sp = structs[a] is the first address of a struct definition
150                                       * sp[0] is type number
151                                       * sp[1] is amount of elements
152                                       * sp[2] sp[3] is typenr,  namenr (etc) */
153 /**
154  * Variable to control debug output of makesdna.
155  * debugSDNA:
156  *  - 0 = no output, except errors
157  *  - 1 = detail actions
158  *  - 2 = full trace, tell which names and types were found
159  *  - 4 = full trace, plus all gritty details
160  */
161 static int debugSDNA = 0;
162 static int additional_slen_offset;
163
164 /* ************************************************************************** */
165 /* Functions                                                                  */
166 /* ************************************************************************** */
167
168 /**
169  * Add type \c str to struct indexed by \c len, if it was not yet found.
170  * \param str char
171  * \param len int
172  */
173 static int add_type(const char *str, int len);
174
175 /**
176  * Add variable \c str to 
177  * \param str
178  */
179 static int add_name(const char *str);
180
181 /**
182  * Search whether this structure type was already found, and if not,
183  * add it.
184  */
185 static short *add_struct(int namecode);
186
187 /**
188  * Remove comments from this buffer. Assumes that the buffer refers to
189  * ascii-code text.
190  */
191 static int preprocess_include(char *maindata, int len);
192
193 /**
194  * Scan this file for serializable types.
195  */ 
196 static int convert_include(char *filename);
197
198 /**
199  * Determine how many bytes are needed for an array.
200  */ 
201 static int arraysize(char *astr, int len);
202
203 /**
204  * Determine how many bytes are needed for each struct.
205  */ 
206 static int calculate_structlens(int);
207
208 /**
209  * Construct the DNA.c file
210  */ 
211 void dna_write(FILE *file, void *pntr, int size);
212
213 /**
214  * Report all structures found so far, and print their lengths.
215  */
216 void printStructLengths(void);
217
218
219
220 /* ************************************************************************** */
221 /* Implementation                                                             */
222 /* ************************************************************************** */
223
224 /* ************************* MAKEN DNA ********************** */
225
226 static int add_type(const char *str, int len)
227 {
228         int nr;
229         char *cp;
230         
231         /* first do validity check */
232         if (str[0] == 0) {
233                 return -1;
234         }
235         else if (strchr(str, '*')) {
236                 /* note: this is valid C syntax but we can't parse, complain!
237                  * 'struct SomeStruct* somevar;' <-- correct but we cant handle right now. */
238                 return -1;
239         }
240         
241         /* search through type array */
242         for (nr = 0; nr < nr_types; nr++) {
243                 if (strcmp(str, types[nr]) == 0) {
244                         if (len) {
245                                 typelens_native[nr] = len;
246                                 typelens_64[nr] = len;
247                         }
248                         return nr;
249                 }
250         }
251         
252         /* append new type */
253         if (nr_types == 0) cp = typedata;
254         else {
255                 cp = types[nr_types - 1] + strlen(types[nr_types - 1]) + 1;
256         }
257         strcpy(cp, str);
258         types[nr_types] = cp;
259         typelens_native[nr_types] = len;
260         typelens_64[nr_types] = len;
261         
262         if (nr_types >= maxnr) {
263                 printf("too many types\n");
264                 return nr_types - 1;
265         }
266         nr_types++;
267         
268         return nr_types - 1;
269 }
270
271
272 /**
273  *
274  * Because of the weird way of tokenizing, we have to 'cast' function
275  * pointers to ... (*f)(), whatever the original signature. In fact,
276  * we add name and type at the same time... There are two special
277  * cases, unfortunately. These are explicitly checked.
278  *
279  * */
280 static int add_name(const char *str)
281 {
282         int nr, i, j, k;
283         char *cp;
284         char buf[255]; /* stupid limit, change it :) */
285         const char *name;
286
287         additional_slen_offset = 0;
288         
289         if (str[0] == 0 /*  || (str[1] == 0) */) return -1;
290
291         if (str[0] == '(' && str[1] == '*') {
292                 /* we handle function pointer and special array cases here, e.g.
293                  * void (*function)(...) and float (*array)[..]. the array case
294                  * name is still converted to (array *)() though because it is that
295                  * way in old dna too, and works correct with elementsize() */
296                 int isfuncptr = (strchr(str + 1, '(')) != NULL;
297
298                 if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer or multidim array pointer found\n");
299                 /* functionpointer: transform the type (sometimes) */
300                 i = 0;
301
302                 while (str[i] != ')') {
303                         buf[i] = str[i];
304                         i++;
305                 }
306                 
307                 /* Another number we need is the extra slen offset. This extra
308                  * offset is the overshoot after a space. If there is no
309                  * space, no overshoot should be calculated. */
310                 j = i; /* j at first closing brace */
311
312                 if (debugSDNA > 3) printf("first brace after offset %d\n", i);
313
314                 j++; /* j beyond closing brace ? */
315                 while ((str[j] != 0) && (str[j] != ')')) {
316                         if (debugSDNA > 3) printf("seen %c ( %d)\n", str[j], str[j]);
317                         j++;
318                 }
319                 if (debugSDNA > 3) printf("seen %c ( %d)\n"
320                                               "special after offset%d\n",
321                                               str[j], str[j], j);
322                                 
323                 if (!isfuncptr) {
324                         /* multidimensional array pointer case */
325                         if (str[j] == 0) {
326                                 if (debugSDNA > 3) printf("offsetting for multidim array pointer\n");
327                         }
328                         else
329                                 printf("Error during tokening multidim array pointer\n");
330                 }
331                 else if (str[j] == 0) {
332                         if (debugSDNA > 3) printf("offsetting for space\n"); 
333                         /* get additional offset */
334                         k = 0;
335                         while (str[j] != ')') {
336                                 j++;
337                                 k++;
338                         }
339                         if (debugSDNA > 3) printf("extra offset %d\n", k);
340                         additional_slen_offset = k;
341                 }
342                 else if (str[j] == ')') {
343                         if (debugSDNA > 3) printf("offsetting for brace\n");
344                         ; /* don't get extra offset */
345                 }
346                 else {
347                         printf("Error during tokening function pointer argument list\n");
348                 }
349                                 
350                 /*
351                  * Put )(void) at the end? Maybe )(). Should check this with
352                  * old sdna. Actually, sometimes )(), sometimes )(void...)
353                  * Alas.. such is the nature of braindamage :(
354                  *
355                  * Sorted it out: always do )(), except for headdraw and
356                  * windraw, part of ScrArea. This is important, because some
357                  * linkers will treat different fp's differently when called
358                  * !!! This has to do with interference in byte-alignment and
359                  * the way args are pushed on the stack.
360                  *
361                  * */
362                 buf[i] = 0;
363                 if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); 
364                 if ((strncmp(buf, "(*headdraw", 10) == 0) ||
365                     (strncmp(buf, "(*windraw", 9) == 0) )
366                 {
367                         buf[i] = ')';
368                         buf[i + 1] = '(';
369                         buf[i + 2] = 'v';
370                         buf[i + 3] = 'o';
371                         buf[i + 4] = 'i';
372                         buf[i + 5] = 'd';
373                         buf[i + 6] = ')';
374                         buf[i + 7] = 0;
375                 }
376                 else {
377                         buf[i] = ')';
378                         buf[i + 1] = '(';
379                         buf[i + 2] = ')';
380                         buf[i + 3] = 0;
381                 }
382                 /* now precede with buf*/
383                 if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf);
384                 name = buf;
385         }
386         else {
387                 /* normal field: old code */
388                 name = str;
389         }
390         
391         /* search name array */
392         for (nr = 0; nr < nr_names; nr++) {
393                 if (strcmp(name, names[nr]) == 0) {
394                         return nr;
395                 }
396         }
397         
398         /* append new type */
399         if (nr_names == 0) cp = namedata;
400         else {
401                 cp = names[nr_names - 1] + strlen(names[nr_names - 1]) + 1;
402         }
403         strcpy(cp, name);
404         names[nr_names] = cp;
405         
406         if (nr_names >= maxnr) {
407                 printf("too many names\n");
408                 return nr_names - 1;
409         }
410         nr_names++;
411         
412         return nr_names - 1;
413 }
414
415 static short *add_struct(int namecode)
416 {
417         int len;
418         short *sp;
419
420         if (nr_structs == 0) {
421                 structs[0] = structdata;
422         }
423         else {
424                 sp = structs[nr_structs - 1];
425                 len = sp[1];
426                 structs[nr_structs] = sp + 2 * len + 2;
427         }
428         
429         sp = structs[nr_structs];
430         sp[0] = namecode;
431         
432         if (nr_structs >= maxnr) {
433                 printf("too many structs\n");
434                 return sp;
435         }
436         nr_structs++;
437         
438         return sp;
439 }
440
441 static int preprocess_include(char *maindata, int len)
442 {
443         int a, newlen, comment = 0;
444         char *cp, *temp, *md;
445         
446         /* note: len + 1, last character is a dummy to prevent
447          * comparisons using uninitialized memory */
448         temp = MEM_mallocN(len + 1, "preprocess_include");
449         temp[len] = ' ';
450
451         memcpy(temp, maindata, len);
452         
453         /* remove all c++ comments */
454         /* replace all enters/tabs/etc with spaces */
455         cp = temp;
456         a = len;
457         comment = 0;
458         while (a--) {
459                 if (cp[0] == '/' && cp[1] == '/') {
460                         comment = 1;
461                 }
462                 else if (*cp < 32) {
463                         comment = 0;
464                 }
465                 if (comment || *cp < 32 || *cp > 128) *cp = 32;
466                 cp++;
467         }
468         
469
470         /* data from temp copy to maindata, remove comments and double spaces */
471         cp = temp;
472         md = maindata;
473         newlen = 0;
474         comment = 0;
475         a = len;
476         while (a--) {
477                 
478                 if (cp[0] == '/' && cp[1] == '*') {
479                         comment = 1;
480                         cp[0] = cp[1] = 32;
481                 }
482                 if (cp[0] == '*' && cp[1] == '/') {
483                         comment = 0;
484                         cp[0] = cp[1] = 32;
485                 }
486
487                 /* do not copy when: */
488                 if (comment) {
489                         /* pass */
490                 }
491                 else if (cp[0] == ' ' && cp[1] == ' ') {
492                         /* pass */
493                 }
494                 else if (cp[-1] == '*' && cp[0] == ' ') {
495                         /* pointers with a space */
496                 }       /* skip special keywords */
497                 else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
498                         /* single values are skipped already, so decrement 1 less */
499                         a -= 13;
500                         cp += 13;
501                 }
502                 else {
503                         md[0] = cp[0];
504                         md++;
505                         newlen++;
506                 }
507                 cp++;
508         }
509         
510         MEM_freeN(temp);
511         return newlen;
512 }
513
514 static void *read_file_data(char *filename, int *len_r)
515 {
516 #ifdef WIN32
517         FILE *fp = fopen(filename, "rb");
518 #else
519         FILE *fp = fopen(filename, "r");
520 #endif
521         void *data;
522
523         if (!fp) {
524                 *len_r = -1;
525                 return NULL;
526         }
527
528         fseek(fp, 0L, SEEK_END);
529         *len_r = ftell(fp);
530         fseek(fp, 0L, SEEK_SET);
531
532         data = MEM_mallocN(*len_r, "read_file_data");
533         if (!data) {
534                 *len_r = -1;
535                 fclose(fp);
536                 return NULL;
537         }
538
539         if (fread(data, *len_r, 1, fp) != 1) {
540                 *len_r = -1;
541                 MEM_freeN(data);
542                 fclose(fp);
543                 return NULL;
544         }
545         
546         fclose(fp);
547         return data;
548 }
549
550 static int convert_include(char *filename)
551 {
552         /* read include file, skip structs with a '#' before it.
553          * store all data in temporal arrays.
554          */
555         int filelen, count, overslaan, slen, type, name, strct;
556         short *structpoin, *sp;
557         char *maindata, *mainend, *md, *md1;
558         
559         md = maindata = read_file_data(filename, &filelen);
560         if (filelen == -1) {
561                 printf("Can't read file %s\n", filename);
562                 return 1;
563         }
564
565         filelen = preprocess_include(maindata, filelen);
566         mainend = maindata + filelen - 1;
567
568         /* we look for '{' and then back to 'struct' */
569         count = 0;
570         overslaan = 0;
571         while (count < filelen) {
572                 
573                 /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
574                 if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
575                         overslaan = 1;
576                 }
577                 
578                 if (md[0] == '{') {
579                         md[0] = 0;
580                         if (overslaan) {
581                                 overslaan = 0;
582                         }
583                         else {
584                                 if (md[-1] == ' ') md[-1] = 0;
585                                 md1 = md - 2;
586                                 while (*md1 != 32) md1--;       /* to beginning of word */
587                                 md1++;
588                                 
589                                 /* we've got a struct name when... */
590                                 if (strncmp(md1 - 7, "struct", 6) == 0) {
591
592                                         strct = add_type(md1, 0);
593                                         if (strct == -1) {
594                                                 printf("File '%s' contains struct we cant parse \"%s\"\n", filename, md1);
595                                                 return 1;
596                                         }
597
598                                         structpoin = add_struct(strct);
599                                         sp = structpoin + 2;
600
601                                         if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]);
602
603                                         /* first lets make it all nice strings */
604                                         md1 = md + 1;
605                                         while (*md1 != '}') {
606                                                 if (md1 > mainend) break;
607                                                 
608                                                 if (*md1 == ',' || *md1 == ' ') *md1 = 0;
609                                                 md1++;
610                                         }
611                                         
612                                         /* read types and names until first character that is not '}' */
613                                         md1 = md + 1;
614                                         while (*md1 != '}') {
615                                                 if (md1 > mainend) break;
616                                                 
617                                                 /* skip when it says 'struct' or 'unsigned' or 'const' */
618                                                 if (*md1) {
619                                                         if (strncmp(md1, "struct", 6) == 0) md1 += 7;
620                                                         if (strncmp(md1, "unsigned", 8) == 0) md1 += 9;
621                                                         if (strncmp(md1, "const", 5) == 0) md1 += 6;
622                                                         
623                                                         /* we've got a type! */
624                                                         type = add_type(md1, 0);
625                                                         if (type == -1) {
626                                                                 printf("File '%s' contains struct we can't parse \"%s\"\n", filename, md1);
627                                                                 return 1;
628                                                         }
629
630                                                         if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1);
631
632                                                         md1 += strlen(md1);
633
634                                                         
635                                                         /* read until ';' */
636                                                         while (*md1 != ';') {
637                                                                 if (md1 > mainend) break;
638                                                                 
639                                                                 if (*md1) {
640                                                                         /* We've got a name. slen needs
641                                                                          * correction for function
642                                                                          * pointers! */
643                                                                         slen = (int) strlen(md1);
644                                                                         if (md1[slen - 1] == ';') {
645                                                                                 md1[slen - 1] = 0;
646
647
648                                                                                 name = add_name(md1);
649                                                                                 slen += additional_slen_offset;
650                                                                                 sp[0] = type;
651                                                                                 sp[1] = name;
652
653                                                                                 if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s |", names[name]);
654
655                                                                                 structpoin[1]++;
656                                                                                 sp += 2;
657                                                                                                                                                                         
658                                                                                 md1 += slen;
659                                                                                 break;
660                                                                         }
661                                                                         
662
663                                                                         name = add_name(md1);
664                                                                         slen += additional_slen_offset;
665
666                                                                         sp[0] = type;
667                                                                         sp[1] = name;
668                                                                         if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s ||", names[name]);
669
670                                                                         structpoin[1]++;
671                                                                         sp += 2;
672                                                                         
673                                                                         md1 += slen;
674                                                                 }
675                                                                 md1++;
676                                                         }
677
678                                                         if (debugSDNA > 1) printf(")\n");
679
680                                                 }
681                                                 md1++;
682                                         }
683                                 }
684                         }
685                 }
686                 count++;
687                 md++;
688         }
689         
690         MEM_freeN(maindata);
691
692         return 0;
693 }
694
695 static int arraysize(char *astr, int len)
696 {
697         int a, mul = 1;
698         char str[100], *cp = NULL;
699
700         memcpy(str, astr, len + 1);
701         
702         for (a = 0; a < len; a++) {
703                 if (str[a] == '[') {
704                         cp = &(str[a + 1]);
705                 }
706                 else if (str[a] == ']' && cp) {
707                         str[a] = 0;
708                         /* if 'cp' is a preprocessor definition, it will evaluate to 0,
709                          * the caller needs to check for this case and throw an error */
710                         mul *= atoi(cp);
711                 }
712         }
713         
714         return mul;
715 }
716
717 static int calculate_structlens(int firststruct)
718 {
719         int a, b, len_native, len_64, unknown = nr_structs, lastunknown, structtype, type, mul, namelen;
720         short *sp, *structpoin;
721         char *cp;
722         int has_pointer, dna_error = 0;
723                 
724         while (unknown) {
725                 lastunknown = unknown;
726                 unknown = 0;
727                 
728                 /* check all structs... */
729                 for (a = 0; a < nr_structs; a++) {
730                         structpoin = structs[a];
731                         structtype = structpoin[0];
732
733                         /* when length is not known... */
734                         if (typelens_native[structtype] == 0) {
735                                 
736                                 sp = structpoin + 2;
737                                 len_native = 0;
738                                 len_64 = 0;
739                                 has_pointer = 0;
740                                 
741                                 /* check all elements in struct */
742                                 for (b = 0; b < structpoin[1]; b++, sp += 2) {
743                                         type = sp[0];
744                                         cp = names[sp[1]];
745
746                                         namelen = (int) strlen(cp);
747                                         /* is it a pointer or function pointer? */
748                                         if (cp[0] == '*' || cp[1] == '*') {
749                                                 has_pointer = 1;
750                                                 /* has the name an extra length? (array) */
751                                                 mul = 1;
752                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
753
754                                                 if (mul == 0) {
755                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
756                                                         dna_error = 1;
757                                                 }
758
759                                                 /* 4-8 aligned/ */
760                                                 if (sizeof(void *) == 4) {
761                                                         if (len_native % 4) {
762                                                                 printf("Align pointer error in struct (len_native 4): %s %s\n", types[structtype], cp);
763                                                                 dna_error = 1;
764                                                         }
765                                                 }
766                                                 else {
767                                                         if (len_native % 8) {
768                                                                 printf("Align pointer error in struct (len_native 8): %s %s\n", types[structtype], cp);
769                                                                 dna_error = 1;
770                                                         }
771                                                 }
772
773                                                 if (len_64 % 8) {
774                                                         printf("Align pointer error in struct (len_64 8): %s %s\n", types[structtype], cp);
775                                                         dna_error = 1;
776                                                 }
777
778                                                 len_native += sizeof(void *) * mul;
779                                                 len_64 += 8 * mul;
780
781                                         }
782                                         else if (cp[0] == '[') {
783                                                 /* parsing can cause names "var" and "[3]" to be found for "float var [3]" ... */
784                                                 printf("Parse error in struct, invalid member name: %s %s\n", types[structtype], cp);
785                                                 dna_error = 1;
786                                         }
787                                         else if (typelens_native[type]) {
788                                                 /* has the name an extra length? (array) */
789                                                 mul = 1;
790                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
791
792                                                 if (mul == 0) {
793                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
794                                                         dna_error = 1;
795                                                 }
796
797                                                 /* struct alignment */
798                                                 if (type >= firststruct) {
799                                                         if (sizeof(void *) == 8 && (len_native % 8) ) {
800                                                                 printf("Align struct error: %s %s\n", types[structtype], cp);
801                                                                 dna_error = 1;
802                                                         }
803                                                 }
804                                                 
805                                                 /* 2-4-8 aligned/ */
806                                                 if (type < firststruct && typelens_native[type] > 4 && (len_native % 8)) {
807                                                         printf("Align 8 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 8);
808                                                         dna_error = 1;
809                                                 }
810                                                 if (typelens_native[type] > 3 && (len_native % 4) ) {
811                                                         printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 4);
812                                                         dna_error = 1;
813                                                 }
814                                                 else if (typelens_native[type] == 2 && (len_native % 2) ) {
815                                                         printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len_native % 2);
816                                                         dna_error = 1;
817                                                 }
818
819                                                 len_native += mul * typelens_native[type];
820                                                 len_64 += mul * typelens_64[type];
821                                                 
822                                         }
823                                         else {
824                                                 len_native = 0;
825                                                 len_64 = 0;
826                                                 break;
827                                         }
828                                 }
829                                 
830                                 if (len_native == 0) {
831                                         unknown++;
832                                 }
833                                 else {
834                                         typelens_native[structtype] = len_native;
835                                         typelens_64[structtype] = len_64;
836                                         /* two ways to detect if a struct contains a pointer:
837                                          * has_pointer is set or len_64 != len_native */
838                                         if (has_pointer || len_64 != len_native) {
839                                                 if (len_64 % 8) {
840                                                         printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], len_64 % 8);
841                                                         dna_error = 1;
842                                                 }
843                                         }
844                                         
845                                         if (len_native % 4) {
846                                                 printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len_native % 4);
847                                                 dna_error = 1;
848                                         }
849                                         
850                                 }
851                         }
852                 }
853                 
854                 if (unknown == lastunknown) break;
855         }
856         
857         if (unknown) {
858                 printf("ERROR: still %d structs unknown\n", unknown);
859
860                 if (debugSDNA) {
861                         printf("*** Known structs :\n");
862                         
863                         for (a = 0; a < nr_structs; a++) {
864                                 structpoin = structs[a];
865                                 structtype = structpoin[0];
866                                 
867                                 /* length unknown */
868                                 if (typelens_native[structtype] != 0) {
869                                         printf("  %s\n", types[structtype]);
870                                 }
871                         }
872                 }
873
874                         
875                 printf("*** Unknown structs :\n");
876                         
877                 for (a = 0; a < nr_structs; a++) {
878                         structpoin = structs[a];
879                         structtype = structpoin[0];
880
881                         /* length unknown yet */
882                         if (typelens_native[structtype] == 0) {
883                                 printf("  %s\n", types[structtype]);
884                         }
885                 }
886
887                 dna_error = 1;
888         }
889
890         return(dna_error);
891 }
892
893 #define MAX_DNA_LINE_LENGTH 20
894
895 void dna_write(FILE *file, void *pntr, int size)
896 {
897         static int linelength = 0;
898         int i;
899         char *data;
900
901         data = (char *) pntr;
902         
903         for (i = 0; i < size; i++) {
904                 fprintf(file, "%d, ", data[i]);
905                 linelength++;
906                 if (linelength >= MAX_DNA_LINE_LENGTH) {
907                         fprintf(file, "\n");
908                         linelength = 0;
909                 }
910         }
911 }
912
913 void printStructLengths(void)
914 {
915         int a, unknown = nr_structs, structtype;
916         /*int lastunknown;*/ /*UNUSED*/
917         short *structpoin;
918         printf("\n\n*** All detected structs:\n");
919
920         while (unknown) {
921                 /*lastunknown = unknown;*/ /*UNUSED*/
922                 unknown = 0;
923                 
924                 /* check all structs... */
925                 for (a = 0; a < nr_structs; a++) {
926                         structpoin = structs[a];
927                         structtype = structpoin[0];
928                         printf("\t%s\t:%d\n", types[structtype], typelens_native[structtype]);
929                 }
930         }
931
932         printf("*** End of list\n");
933
934 }
935
936
937 static int make_structDNA(char *baseDirectory, FILE *file)
938 {
939         int len, i;
940         short *sp;
941         /* str contains filenames. Since we now include paths, I stretched       */
942         /* it a bit. Hope this is enough :) -nzc-                                */
943         char str[SDNA_MAX_FILENAME_LENGTH], *cp;
944         int firststruct;
945         
946         if (debugSDNA > -1) {
947                 fflush(stdout);
948                 printf("Running makesdna at debug level %d\n", debugSDNA);
949         }
950                 
951         /* the longest known struct is 50k, so we assume 100k is sufficent! */
952         namedata = MEM_callocN(maxdata, "namedata");
953         typedata = MEM_callocN(maxdata, "typedata");
954         structdata = MEM_callocN(maxdata, "structdata");
955         
956         /* a maximum of 5000 variables, must be sufficient? */
957         names = MEM_callocN(sizeof(char *) * maxnr, "names");
958         types = MEM_callocN(sizeof(char *) * maxnr, "types");
959         typelens_native = MEM_callocN(sizeof(short) * maxnr, "typelens_native");
960         typelens_64 = MEM_callocN(sizeof(short) * maxnr, "typelens_64");
961         structs = MEM_callocN(sizeof(short) * maxnr, "structs");
962
963         /* insertion of all known types */
964         /* watch it: uint is not allowed! use in structs an unsigned int */
965         /* watch it: sizes must match DNA_elem_type_size() */
966         add_type("char", 1);     /* SDNA_TYPE_CHAR */
967         add_type("uchar", 1);    /* SDNA_TYPE_UCHAR */
968         add_type("short", 2);    /* SDNA_TYPE_SHORT */
969         add_type("ushort", 2);   /* SDNA_TYPE_USHORT */
970         add_type("int", 4);      /* SDNA_TYPE_INT */
971         add_type("long", 4);     /* SDNA_TYPE_LONG */           /* should it be 8 on 64 bits? */
972         add_type("ulong", 4);    /* SDNA_TYPE_ULONG */
973         add_type("float", 4);    /* SDNA_TYPE_FLOAT */
974         add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
975         add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
976         add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
977         add_type("void", 0);     /* SDNA_TYPE_VOID */
978
979         /* the defines above shouldn't be output in the padding file... */
980         firststruct = nr_types;
981         
982         /* add all include files defined in the global array                     */
983         /* Since the internal file+path name buffer has limited length, I do a   */
984         /* little test first...                                                  */
985         /* Mind the breaking condition here!                                     */
986         if (debugSDNA) printf("\tStart of header scan:\n"); 
987         for (i = 0; strlen(includefiles[i]); i++) {
988                 sprintf(str, "%s%s", baseDirectory, includefiles[i]);
989                 if (debugSDNA) printf("\t|-- Converting %s\n", str);
990                 if (convert_include(str)) {
991                         return (1);
992                 }
993         }
994         if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 
995
996         if (calculate_structlens(firststruct)) {
997                 /* error */
998                 return(1);
999         }
1000
1001         /* FOR DEBUG */
1002         if (debugSDNA > 1) {
1003                 int a, b;
1004 /*          short *elem; */
1005                 short num_types;
1006
1007                 printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
1008                 for (a = 0; a < nr_names; a++) {
1009                         printf(" %s\n", names[a]);
1010                 }
1011                 printf("\n");
1012                 
1013                 sp = typelens_native;
1014                 for (a = 0; a < nr_types; a++, sp++) {
1015                         printf(" %s %d\n", types[a], *sp);
1016                 }
1017                 printf("\n");
1018                 
1019                 for (a = 0; a < nr_structs; a++) {
1020                         sp = structs[a];
1021                         printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], typelens_native[sp[0]]);
1022                         num_types  = sp[1];
1023                         sp += 2;
1024                         /* ? num_types was elem? */
1025                         for (b = 0; b < num_types; b++, sp += 2) {
1026                                 printf("   %s %s\n", types[sp[0]], names[sp[1]]);
1027                         }
1028                 }
1029         }
1030
1031         /* file writing */
1032
1033         if (debugSDNA > -1) printf("Writing file ... ");
1034                 
1035         if (nr_names == 0 || nr_structs == 0) {
1036                 /* pass */
1037         }
1038         else {
1039                 strcpy(str, "SDNA");
1040                 dna_write(file, str, 4);
1041                 
1042                 /* write names */
1043                 strcpy(str, "NAME");
1044                 dna_write(file, str, 4);
1045                 len = nr_names;
1046                 dna_write(file, &len, 4);
1047                 
1048                 /* calculate size of datablock with strings */
1049                 cp = names[nr_names - 1];
1050                 cp += strlen(names[nr_names - 1]) + 1;         /* +1: null-terminator */
1051                 len = (intptr_t) (cp - (char *) names[0]);
1052                 len = (len + 3) & ~3;
1053                 dna_write(file, names[0], len);
1054                 
1055                 /* write TYPES */
1056                 strcpy(str, "TYPE");
1057                 dna_write(file, str, 4);
1058                 len = nr_types;
1059                 dna_write(file, &len, 4);
1060         
1061                 /* calculate datablock size */
1062                 cp = types[nr_types - 1];
1063                 cp += strlen(types[nr_types - 1]) + 1;     /* +1: null-terminator */
1064                 len = (intptr_t) (cp - (char *) types[0]);
1065                 len = (len + 3) & ~3;
1066                 
1067                 dna_write(file, types[0], len);
1068                 
1069                 /* WRITE TYPELENGTHS */
1070                 strcpy(str, "TLEN");
1071                 dna_write(file, str, 4);
1072                 
1073                 len = 2 * nr_types;
1074                 if (nr_types & 1) len += 2;
1075                 dna_write(file, typelens_native, len);
1076                 
1077                 /* WRITE STRUCTS */
1078                 strcpy(str, "STRC");
1079                 dna_write(file, str, 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; strlen(includefiles[i]); 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                         char baseDirectory[256];
1169
1170                         if (argc == 3) {
1171                                 strcpy(baseDirectory, argv[2]);
1172                         }
1173                         else {
1174                                 strcpy(baseDirectory, BASE_HEADER);
1175                         }
1176
1177                         fprintf(file, "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, "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  * unless structs are nested */
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 /* end of list */