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