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