svn merge ^/trunk/blender -r46699:46714
[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;              /* at typelens[a] is de length of type a */
148 static short *alphalens;             /* contains sizes as they are calculated on the DEC Alpha (64 bits), infact any 64bit system */
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[nr] = len;
246                                 alphalens[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[nr_types] = len;
260         alphalens[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                 else if (cp[0] == ' ' && cp[1] == ' ') ;
490                 else if (cp[-1] == '*' && cp[0] == ' ') ;  /* pointers with a space */
491
492                 /* skip special keywords */
493                 else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) {
494                         /* single values are skipped already, so decrement 1 less */
495                         a -= 13;
496                         cp += 13;
497                 }
498                 else {
499                         md[0] = cp[0];
500                         md++;
501                         newlen++;
502                 }
503                 cp++;
504         }
505         
506         MEM_freeN(temp);
507         return newlen;
508 }
509
510 static void *read_file_data(char *filename, int *len_r)
511 {
512 #ifdef WIN32
513         FILE *fp = fopen(filename, "rb");
514 #else
515         FILE *fp = fopen(filename, "r");
516 #endif
517         void *data;
518
519         if (!fp) {
520                 *len_r = -1;
521                 return NULL;
522         }
523
524         fseek(fp, 0L, SEEK_END);
525         *len_r = ftell(fp);
526         fseek(fp, 0L, SEEK_SET);
527
528         data = MEM_mallocN(*len_r, "read_file_data");
529         if (!data) {
530                 *len_r = -1;
531                 fclose(fp);
532                 return NULL;
533         }
534
535         if (fread(data, *len_r, 1, fp) != 1) {
536                 *len_r = -1;
537                 MEM_freeN(data);
538                 fclose(fp);
539                 return NULL;
540         }
541         
542         fclose(fp);
543         return data;
544 }
545
546 static int convert_include(char *filename)
547 {
548         /* read include file, skip structs with a '#' before it.
549          * store all data in temporal arrays.
550          */
551         int filelen, count, overslaan, slen, type, name, strct;
552         short *structpoin, *sp;
553         char *maindata, *mainend, *md, *md1;
554         
555         md = maindata = read_file_data(filename, &filelen);
556         if (filelen == -1) {
557                 printf("Can't read file %s\n", filename);
558                 return 1;
559         }
560
561         filelen = preprocess_include(maindata, filelen);
562         mainend = maindata + filelen - 1;
563
564         /* we look for '{' and then back to 'struct' */
565         count = 0;
566         overslaan = 0;
567         while (count < filelen) {
568                 
569                 /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */
570                 if (md[0] == '#' && md[1] == ' ' && md[2] == '#') {
571                         overslaan = 1;
572                 }
573                 
574                 if (md[0] == '{') {
575                         md[0] = 0;
576                         if (overslaan) {
577                                 overslaan = 0;
578                         }
579                         else {
580                                 if (md[-1] == ' ') md[-1] = 0;
581                                 md1 = md - 2;
582                                 while (*md1 != 32) md1--;       /* to beginning of word */
583                                 md1++;
584                                 
585                                 /* we've got a struct name when... */
586                                 if (strncmp(md1 - 7, "struct", 6) == 0) {
587
588                                         strct = add_type(md1, 0);
589                                         if (strct == -1) {
590                                                 printf("File '%s' contains struct we cant parse \"%s\"\n", filename, md1);
591                                                 return 1;
592                                         }
593
594                                         structpoin = add_struct(strct);
595                                         sp = structpoin + 2;
596
597                                         if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]);
598
599                                         /* first lets make it all nice strings */
600                                         md1 = md + 1;
601                                         while (*md1 != '}') {
602                                                 if (md1 > mainend) break;
603                                                 
604                                                 if (*md1 == ',' || *md1 == ' ') *md1 = 0;
605                                                 md1++;
606                                         }
607                                         
608                                         /* read types and names until first character that is not '}' */
609                                         md1 = md + 1;
610                                         while (*md1 != '}') {
611                                                 if (md1 > mainend) break;
612                                                 
613                                                 /* skip when it says 'struct' or 'unsigned' or 'const' */
614                                                 if (*md1) {
615                                                         if (strncmp(md1, "struct", 6) == 0) md1 += 7;
616                                                         if (strncmp(md1, "unsigned", 8) == 0) md1 += 9;
617                                                         if (strncmp(md1, "const", 5) == 0) md1 += 6;
618                                                         
619                                                         /* we've got a type! */
620                                                         type = add_type(md1, 0);
621                                                         if (type == -1) {
622                                                                 printf("File '%s' contains struct we can't parse \"%s\"\n", filename, md1);
623                                                                 return 1;
624                                                         }
625
626                                                         if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1);
627
628                                                         md1 += strlen(md1);
629
630                                                         
631                                                         /* read until ';' */
632                                                         while (*md1 != ';') {
633                                                                 if (md1 > mainend) break;
634                                                                 
635                                                                 if (*md1) {
636                                                                         /* We've got a name. slen needs
637                                                                          * correction for function
638                                                                          * pointers! */
639                                                                         slen = (int) strlen(md1);
640                                                                         if (md1[slen - 1] == ';') {
641                                                                                 md1[slen - 1] = 0;
642
643
644                                                                                 name = add_name(md1);
645                                                                                 slen += additional_slen_offset;
646                                                                                 sp[0] = type;
647                                                                                 sp[1] = name;
648
649                                                                                 if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s |", names[name]);
650
651                                                                                 structpoin[1]++;
652                                                                                 sp += 2;
653                                                                                                                                                                         
654                                                                                 md1 += slen;
655                                                                                 break;
656                                                                         }
657                                                                         
658
659                                                                         name = add_name(md1);
660                                                                         slen += additional_slen_offset;
661
662                                                                         sp[0] = type;
663                                                                         sp[1] = name;
664                                                                         if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s ||", names[name]);
665
666                                                                         structpoin[1]++;
667                                                                         sp += 2;
668                                                                         
669                                                                         md1 += slen;
670                                                                 }
671                                                                 md1++;
672                                                         }
673
674                                                         if (debugSDNA > 1) printf(")\n");
675
676                                                 }
677                                                 md1++;
678                                         }
679                                 }
680                         }
681                 }
682                 count++;
683                 md++;
684         }
685         
686         MEM_freeN(maindata);
687
688         return 0;
689 }
690
691 static int arraysize(char *astr, int len)
692 {
693         int a, mul = 1;
694         char str[100], *cp = NULL;
695
696         memcpy(str, astr, len + 1);
697         
698         for (a = 0; a < len; a++) {
699                 if (str[a] == '[') {
700                         cp = &(str[a + 1]);
701                 }
702                 else if (str[a] == ']' && cp) {
703                         str[a] = 0;
704                         /* if 'cp' is a preprocessor definition, it will evaluate to 0,
705                          * the caller needs to check for this case and throw an error */
706                         mul *= atoi(cp);
707                 }
708         }
709         
710         return mul;
711 }
712
713 static int calculate_structlens(int firststruct)
714 {
715         int a, b, len, alphalen, unknown = nr_structs, lastunknown, structtype, type, mul, namelen;
716         short *sp, *structpoin;
717         char *cp;
718         int has_pointer, dna_error = 0;
719                 
720         while (unknown) {
721                 lastunknown = unknown;
722                 unknown = 0;
723                 
724                 /* check all structs... */
725                 for (a = 0; a < nr_structs; a++) {
726                         structpoin = structs[a];
727                         structtype = structpoin[0];
728
729                         /* when length is not known... */
730                         if (typelens[structtype] == 0) {
731                                 
732                                 sp = structpoin + 2;
733                                 len = 0;
734                                 alphalen = 0;
735                                 has_pointer = 0;
736                                 
737                                 /* check all elements in struct */
738                                 for (b = 0; b < structpoin[1]; b++, sp += 2) {
739                                         type = sp[0];
740                                         cp = names[sp[1]];
741
742                                         namelen = (int) strlen(cp);
743                                         /* is it a pointer or function pointer? */
744                                         if (cp[0] == '*' || cp[1] == '*') {
745                                                 has_pointer = 1;
746                                                 /* has the name an extra length? (array) */
747                                                 mul = 1;
748                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
749
750                                                 if (mul == 0) {
751                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
752                                                         dna_error = 1;
753                                                 }
754
755                                                 /* 4-8 aligned/ */
756                                                 if (sizeof(void *) == 4) {
757                                                         if (len % 4) {
758                                                                 printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp);
759                                                                 dna_error = 1;
760                                                         }
761                                                 }
762                                                 else {
763                                                         if (len % 8) {
764                                                                 printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp);
765                                                                 dna_error = 1;
766                                                         }
767                                                 }
768
769                                                 if (alphalen % 8) {
770                                                         printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype], cp);
771                                                         dna_error = 1;
772                                                 }
773
774                                                 len += sizeof(void *) * mul;
775                                                 alphalen += 8 * mul;
776
777                                         }
778                                         else if (cp[0] == '[') {
779                                                 /* parsing can cause names "var" and "[3]" to be found for "float var [3]" ... */
780                                                 printf("Parse error in struct, invalid member name: %s %s\n", types[structtype], cp);
781                                                 dna_error = 1;
782                                         }
783                                         else if (typelens[type]) {
784                                                 /* has the name an extra length? (array) */
785                                                 mul = 1;
786                                                 if (cp[namelen - 1] == ']') mul = arraysize(cp, namelen);
787
788                                                 if (mul == 0) {
789                                                         printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp);
790                                                         dna_error = 1;
791                                                 }
792
793                                                 /* struct alignment */
794                                                 if (type >= firststruct) {
795                                                         if (sizeof(void *) == 8 && (len % 8) ) {
796                                                                 printf("Align struct error: %s %s\n", types[structtype], cp);
797                                                                 dna_error = 1;
798                                                         }
799                                                 }
800                                                 
801                                                 /* 2-4 aligned/ */
802                                                 if (typelens[type] > 3 && (len % 4) ) {
803                                                         printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len % 4);
804                                                         dna_error = 1;
805                                                 }
806                                                 else if (typelens[type] == 2 && (len % 2) ) {
807                                                         printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len % 2);
808                                                         dna_error = 1;
809                                                 }
810
811                                                 len += mul * typelens[type];
812                                                 alphalen += mul * alphalens[type];
813                                                 
814                                         }
815                                         else {
816                                                 len = 0;
817                                                 alphalen = 0;
818                                                 break;
819                                         }
820                                 }
821                                 
822                                 if (len == 0) {
823                                         unknown++;
824                                 }
825                                 else {
826                                         typelens[structtype] = len;
827                                         alphalens[structtype] = alphalen;
828                                         // two ways to detect if a struct contains a pointer:
829                                         // has_pointer is set or alphalen != len
830                                         if (has_pointer || alphalen != len) {
831                                                 if (alphalen % 8) {
832                                                         printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen % 8);
833                                                         dna_error = 1;
834                                                 }
835                                         }
836                                         
837                                         if (len % 4) {
838                                                 printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len % 4);
839                                                 dna_error = 1;
840                                         }
841                                         
842                                 }
843                         }
844                 }
845                 
846                 if (unknown == lastunknown) break;
847         }
848         
849         if (unknown) {
850                 printf("ERROR: still %d structs unknown\n", unknown);
851
852                 if (debugSDNA) {
853                         printf("*** Known structs :\n");
854                         
855                         for (a = 0; a < nr_structs; a++) {
856                                 structpoin = structs[a];
857                                 structtype = structpoin[0];
858                                 
859                                 /* length unknown */
860                                 if (typelens[structtype] != 0) {
861                                         printf("  %s\n", types[structtype]);
862                                 }
863                         }
864                 }
865
866                         
867                 printf("*** Unknown structs :\n");
868                         
869                 for (a = 0; a < nr_structs; a++) {
870                         structpoin = structs[a];
871                         structtype = structpoin[0];
872
873                         /* length unknown yet */
874                         if (typelens[structtype] == 0) {
875                                 printf("  %s\n", types[structtype]);
876                         }
877                 }
878
879                 dna_error = 1;
880         }
881
882         return(dna_error);
883 }
884
885 #define MAX_DNA_LINE_LENGTH 20
886
887 void dna_write(FILE *file, void *pntr, int size)
888 {
889         static int linelength = 0;
890         int i;
891         char *data;
892
893         data = (char *) pntr;
894         
895         for (i = 0; i < size; i++) {
896                 fprintf(file, "%d, ", data[i]);
897                 linelength++;
898                 if (linelength >= MAX_DNA_LINE_LENGTH) {
899                         fprintf(file, "\n");
900                         linelength = 0;
901                 }
902         }
903 }
904
905 void printStructLengths(void)
906 {
907         int a, unknown = nr_structs, structtype;
908         /*int lastunknown;*/ /*UNUSED*/
909         short *structpoin;
910         printf("\n\n*** All detected structs:\n");
911
912         while (unknown) {
913                 /*lastunknown= unknown;*/ /*UNUSED*/
914                 unknown = 0;
915                 
916                 /* check all structs... */
917                 for (a = 0; a < nr_structs; a++) {
918                         structpoin = structs[a];
919                         structtype = structpoin[0];
920                         printf("\t%s\t:%d\n", types[structtype], typelens[structtype]);
921                 }
922         }
923
924         printf("*** End of list\n");
925
926 }
927
928
929 static int make_structDNA(char *baseDirectory, FILE *file)
930 {
931         int len, i;
932         short *sp;
933         /* str contains filenames. Since we now include paths, I stretched       */
934         /* it a bit. Hope this is enough :) -nzc-                                */
935         char str[SDNA_MAX_FILENAME_LENGTH], *cp;
936         int firststruct;
937         
938         if (debugSDNA > -1) {
939                 fflush(stdout);
940                 printf("Running makesdna at debug level %d\n", debugSDNA);
941         }
942                 
943         /* the longest known struct is 50k, so we assume 100k is sufficent! */
944         namedata = MEM_callocN(maxdata, "namedata");
945         typedata = MEM_callocN(maxdata, "typedata");
946         structdata = MEM_callocN(maxdata, "structdata");
947         
948         /* a maximum of 5000 variables, must be sufficient? */
949         names = MEM_callocN(sizeof(char *) * maxnr, "names");
950         types = MEM_callocN(sizeof(char *) * maxnr, "types");
951         typelens = MEM_callocN(sizeof(short) * maxnr, "typelens");
952         alphalens = MEM_callocN(sizeof(short) * maxnr, "alphalens");
953         structs = MEM_callocN(sizeof(short) * maxnr, "structs");
954
955         /* insertion of all known types */
956         /* watch it: uint is not allowed! use in structs an unsigned int */
957         /* watch it: sizes must match DNA_elem_type_size() */
958         add_type("char", 1);     /* SDNA_TYPE_CHAR */
959         add_type("uchar", 1);    /* SDNA_TYPE_UCHAR */
960         add_type("short", 2);    /* SDNA_TYPE_SHORT */
961         add_type("ushort", 2);   /* SDNA_TYPE_USHORT */
962         add_type("int", 4);      /* SDNA_TYPE_INT */
963         add_type("long", 4);     /* SDNA_TYPE_LONG */           /* should it be 8 on 64 bits? */
964         add_type("ulong", 4);    /* SDNA_TYPE_ULONG */
965         add_type("float", 4);    /* SDNA_TYPE_FLOAT */
966         add_type("double", 8);   /* SDNA_TYPE_DOUBLE */
967         add_type("int64_t", 8);  /* SDNA_TYPE_INT64 */
968         add_type("uint64_t", 8); /* SDNA_TYPE_UINT64 */
969         add_type("void", 0);     /* SDNA_TYPE_VOID */
970
971         // the defines above shouldn't be output in the padding file...
972         firststruct = nr_types;
973         
974         /* add all include files defined in the global array                     */
975         /* Since the internal file+path name buffer has limited length, I do a   */
976         /* little test first...                                                  */
977         /* Mind the breaking condition here!                                     */
978         if (debugSDNA) printf("\tStart of header scan:\n"); 
979         for (i = 0; strlen(includefiles[i]); i++) {
980                 sprintf(str, "%s%s", baseDirectory, includefiles[i]);
981                 if (debugSDNA) printf("\t|-- Converting %s\n", str);
982                 if (convert_include(str)) {
983                         return (1);
984                 }
985         }
986         if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 
987
988         if (calculate_structlens(firststruct)) {
989                 // error
990                 return(1);
991         }
992
993         /* FOR DEBUG */
994         if (debugSDNA > 1) {
995                 int a, b;
996 /*          short *elem; */
997                 short num_types;
998
999                 printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs);
1000                 for (a = 0; a < nr_names; a++) {
1001                         printf(" %s\n", names[a]);
1002                 }
1003                 printf("\n");
1004                 
1005                 sp = typelens;
1006                 for (a = 0; a < nr_types; a++, sp++) {
1007                         printf(" %s %d\n", types[a], *sp);
1008                 }
1009                 printf("\n");
1010                 
1011                 for (a = 0; a < nr_structs; a++) {
1012                         sp = structs[a];
1013                         printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1], typelens[sp[0]]);
1014                         num_types  = sp[1];
1015                         sp += 2;
1016                         /* ? num_types was elem? */
1017                         for (b = 0; b < num_types; b++, sp += 2) {
1018                                 printf("   %s %s\n", types[sp[0]], names[sp[1]]);
1019                         }
1020                 }
1021         }
1022
1023         /* file writing */
1024
1025         if (debugSDNA > -1) printf("Writing file ... ");
1026                 
1027         if (nr_names == 0 || nr_structs == 0) ;
1028         else {
1029                 strcpy(str, "SDNA");
1030                 dna_write(file, str, 4);
1031                 
1032                 /* write names */
1033                 strcpy(str, "NAME");
1034                 dna_write(file, str, 4);
1035                 len = nr_names;
1036                 dna_write(file, &len, 4);
1037                 
1038                 /* calculate size of datablock with strings */
1039                 cp = names[nr_names - 1];
1040                 cp += strlen(names[nr_names - 1]) + 1;         /* +1: null-terminator */
1041                 len = (intptr_t) (cp - (char *) names[0]);
1042                 len = (len + 3) & ~3;
1043                 dna_write(file, names[0], len);
1044                 
1045                 /* write TYPES */
1046                 strcpy(str, "TYPE");
1047                 dna_write(file, str, 4);
1048                 len = nr_types;
1049                 dna_write(file, &len, 4);
1050         
1051                 /* calculate datablock size */
1052                 cp = types[nr_types - 1];
1053                 cp += strlen(types[nr_types - 1]) + 1;     /* +1: null-terminator */
1054                 len = (intptr_t) (cp - (char *) types[0]);
1055                 len = (len + 3) & ~3;
1056                 
1057                 dna_write(file, types[0], len);
1058                 
1059                 /* WRITE TYPELENGTHS */
1060                 strcpy(str, "TLEN");
1061                 dna_write(file, str, 4);
1062                 
1063                 len = 2 * nr_types;
1064                 if (nr_types & 1) len += 2;
1065                 dna_write(file, typelens, len);
1066                 
1067                 /* WRITE STRUCTS */
1068                 strcpy(str, "STRC");
1069                 dna_write(file, str, 4);
1070                 len = nr_structs;
1071                 dna_write(file, &len, 4);
1072         
1073                 /* calc datablock size */
1074                 sp = structs[nr_structs - 1];
1075                 sp += 2 + 2 * (sp[1]);
1076                 len = (intptr_t) ((char *) sp - (char *) structs[0]);
1077                 len = (len + 3) & ~3;
1078                 
1079                 dna_write(file, structs[0], len);
1080         
1081                 /* a simple dna padding test */
1082                 if (0) {
1083                         FILE *fp;
1084                         int a;
1085                         
1086                         fp = fopen("padding.c", "w");
1087                         if (fp == NULL) ;
1088                         else {
1089
1090                                 // add all include files defined in the global array
1091                                 for (i = 0; strlen(includefiles[i]); i++) {
1092                                         fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]);
1093                                 }
1094
1095                                 fprintf(fp, "main() {\n");
1096                                 sp = typelens;
1097                                 sp += firststruct;
1098                                 for (a = firststruct; a < nr_types; a++, sp++) {
1099                                         if (*sp) {
1100                                                 fprintf(fp, "\tif (sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp);
1101                                                 fprintf(fp, "%%d %s %d ", types[a], *sp);
1102                                                 fprintf(fp, "\\n\",  sizeof(struct %s) - %d);\n", types[a], *sp);
1103                                         }
1104                                 }
1105                                 fprintf(fp, "}\n");
1106                                 fclose(fp);
1107                         }
1108                 }
1109                 /*      end end padding test */
1110         }
1111         
1112         
1113         MEM_freeN(namedata);
1114         MEM_freeN(typedata);
1115         MEM_freeN(structdata);
1116         MEM_freeN(names);
1117         MEM_freeN(types);
1118         MEM_freeN(typelens);
1119         MEM_freeN(alphalens);
1120         MEM_freeN(structs);
1121
1122         if (debugSDNA > -1) printf("done.\n");
1123         
1124         return(0);
1125 }
1126
1127 /* ************************* END MAKE DNA ********************** */
1128
1129 static void make_bad_file(const char *file, int line)
1130 {
1131         FILE *fp = fopen(file, "w");
1132         fprintf(fp, "#error \"Error! can't make correct DNA.c file from %s:%d, STUPID!\"\n", __FILE__, line);
1133         fclose(fp);
1134 }
1135
1136 #ifndef BASE_HEADER
1137 #define BASE_HEADER "../"
1138 #endif
1139
1140 int main(int argc, char **argv)
1141 {
1142         FILE *file;
1143         int return_status = 0;
1144
1145         if (argc != 2 && argc != 3) {
1146                 printf("Usage: %s outfile.c [base directory]\n", argv[0]);
1147                 return_status = 1;
1148         }
1149         else {
1150                 file = fopen(argv[1], "w");
1151                 if (!file) {
1152                         printf("Unable to open file: %s\n", argv[1]);
1153                         return_status = 1;
1154                 }
1155                 else {
1156                         char baseDirectory[256];
1157
1158                         if (argc == 3) {
1159                                 strcpy(baseDirectory, argv[2]);
1160                         }
1161                         else {
1162                                 strcpy(baseDirectory, BASE_HEADER);
1163                         }
1164
1165                         fprintf(file, "unsigned char DNAstr[]= {\n");
1166                         if (make_structDNA(baseDirectory, file)) {
1167                                 // error
1168                                 fclose(file);
1169                                 make_bad_file(argv[1], __LINE__);
1170                                 return_status = 1;
1171                         }
1172                         else {
1173                                 fprintf(file, "};\n");
1174                                 fprintf(file, "int DNAlen= sizeof(DNAstr);\n");
1175         
1176                                 fclose(file);
1177                         }
1178                 }
1179         }
1180
1181                 
1182         return(return_status);
1183 }
1184
1185 /* include files for automatic dependencies */
1186 #include "DNA_listBase.h"
1187 #include "DNA_vec_types.h"
1188 #include "DNA_ID.h"
1189 #include "DNA_ipo_types.h"
1190 #include "DNA_key_types.h"
1191 #include "DNA_text_types.h"
1192 #include "DNA_packedFile_types.h"
1193 #include "DNA_camera_types.h"
1194 #include "DNA_image_types.h"
1195 #include "DNA_texture_types.h"
1196 #include "DNA_lamp_types.h"
1197 #include "DNA_material_types.h"
1198 #include "DNA_vfont_types.h"
1199 #include "DNA_meta_types.h"
1200 #include "DNA_curve_types.h"
1201 #include "DNA_mesh_types.h"
1202 #include "DNA_meshdata_types.h"
1203 #include "DNA_modifier_types.h"
1204 #include "DNA_lattice_types.h"  
1205 #include "DNA_object_types.h"
1206 #include "DNA_object_force.h"
1207 #include "DNA_object_fluidsim.h"
1208 #include "DNA_world_types.h"
1209 #include "DNA_scene_types.h"
1210 #include "DNA_view3d_types.h"
1211 #include "DNA_view2d_types.h"   
1212 #include "DNA_space_types.h"
1213 #include "DNA_userdef_types.h"
1214 #include "DNA_screen_types.h"
1215 #include "DNA_sdna_types.h"
1216 #include "DNA_fileglobal_types.h"
1217 #include "DNA_sequence_types.h"
1218 #include "DNA_effect_types.h"
1219 #include "DNA_outliner_types.h"
1220 #include "DNA_property_types.h"
1221 #include "DNA_sensor_types.h"
1222 #include "DNA_controller_types.h"
1223 #include "DNA_actuator_types.h"
1224 #include "DNA_sound_types.h"
1225 #include "DNA_group_types.h"
1226 #include "DNA_armature_types.h"
1227 #include "DNA_action_types.h"
1228 #include "DNA_constraint_types.h"
1229 #include "DNA_nla_types.h"
1230 #include "DNA_node_types.h"
1231 #include "DNA_color_types.h"
1232 #include "DNA_brush_types.h"
1233 #include "DNA_customdata_types.h"
1234 #include "DNA_particle_types.h"
1235 #include "DNA_cloth_types.h"
1236 #include "DNA_gpencil_types.h"
1237 #include "DNA_windowmanager_types.h"
1238 #include "DNA_anim_types.h"
1239 #include "DNA_boid_types.h"
1240 #include "DNA_smoke_types.h"
1241 #include "DNA_speaker_types.h"
1242 #include "DNA_movieclip_types.h"
1243 #include "DNA_tracking_types.h"
1244 #include "DNA_dynamicpaint_types.h"
1245 #include "DNA_mask_types.h"
1246 /* end of list */