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