|
Blender
V2.59
|
00001 /* 00002 * $Id: makesdna.c 37613 2011-06-18 03:14:24Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00053 #define DNA_VERSION_DATE "$Id: makesdna.c 37613 2011-06-18 03:14:24Z campbellbarton $" 00054 00055 #include <string.h> 00056 #include <stdlib.h> 00057 #include <stdio.h> 00058 00059 #include "MEM_guardedalloc.h" 00060 #include "DNA_sdna_types.h" 00061 00062 #include "BLO_sys_types.h" // for intptr_t support 00063 00064 #define SDNA_MAX_FILENAME_LENGTH 255 00065 00066 00067 /* Included the path relative from /source/blender/ here, so we can move */ 00068 /* headers around with more freedom. */ 00069 const char *includefiles[] = { 00070 00071 // if you add files here, please add them at the end 00072 // of makesdna.c (this file) as well 00073 00074 "DNA_listBase.h", 00075 "DNA_vec_types.h", 00076 "DNA_ID.h", 00077 "DNA_ipo_types.h", 00078 "DNA_key_types.h", 00079 "DNA_text_types.h", 00080 "DNA_packedFile_types.h", 00081 "DNA_camera_types.h", 00082 "DNA_image_types.h", 00083 "DNA_texture_types.h", 00084 "DNA_lamp_types.h", 00085 "DNA_material_types.h", 00086 "DNA_vfont_types.h", 00087 // if you add files here, please add them at the end 00088 // of makesdna.c (this file) as well 00089 "DNA_meta_types.h", 00090 "DNA_curve_types.h", 00091 "DNA_mesh_types.h", 00092 "DNA_meshdata_types.h", 00093 "DNA_modifier_types.h", 00094 "DNA_lattice_types.h", 00095 "DNA_object_types.h", 00096 "DNA_object_force.h", 00097 "DNA_object_fluidsim.h", 00098 "DNA_world_types.h", 00099 "DNA_scene_types.h", 00100 "DNA_view3d_types.h", 00101 "DNA_view2d_types.h", 00102 "DNA_space_types.h", 00103 "DNA_userdef_types.h", 00104 "DNA_screen_types.h", 00105 "DNA_sdna_types.h", 00106 // if you add files here, please add them at the end 00107 // of makesdna.c (this file) as well 00108 "DNA_fileglobal_types.h", 00109 "DNA_sequence_types.h", 00110 "DNA_effect_types.h", 00111 "DNA_outliner_types.h", 00112 "DNA_property_types.h", 00113 "DNA_sensor_types.h", 00114 "DNA_controller_types.h", 00115 "DNA_actuator_types.h", 00116 "DNA_sound_types.h", 00117 "DNA_group_types.h", 00118 "DNA_armature_types.h", 00119 "DNA_action_types.h", 00120 "DNA_constraint_types.h", 00121 "DNA_nla_types.h", 00122 "DNA_node_types.h", 00123 "DNA_color_types.h", 00124 "DNA_brush_types.h", 00125 "DNA_customdata_types.h", 00126 "DNA_particle_types.h", 00127 "DNA_cloth_types.h", 00128 "DNA_gpencil_types.h", 00129 // if you add files here, please add them at the end 00130 // of makesdna.c (this file) as well 00131 "DNA_windowmanager_types.h", 00132 "DNA_anim_types.h", 00133 "DNA_boid_types.h", 00134 "DNA_smoke_types.h", 00135 00136 // empty string to indicate end of includefiles 00137 "" 00138 }; 00139 00140 int maxdata= 500000, maxnr= 50000; 00141 int nr_names=0; 00142 int nr_types=0; 00143 int nr_structs=0; 00144 char **names, *namedata; /* at address names[a] is string a */ 00145 char **types, *typedata; /* at address types[a] is string a */ 00146 short *typelens; /* at typelens[a] is de length of type a */ 00147 short *alphalens; /* contains sizes as they are calculated on the DEC Alpha (64 bits) */ 00148 short **structs, *structdata; /* at sp= structs[a] is the first address of a struct definition 00149 sp[0] is type number 00150 sp[1] is amount of elements 00151 sp[2] sp[3] is typenr, namenr (etc) */ 00160 int debugSDNA = 0; 00161 int additional_slen_offset; 00162 00163 /* ************************************************************************** */ 00164 /* Functions */ 00165 /* ************************************************************************** */ 00166 00172 int add_type(const char *str, int len); 00173 00178 int add_name(char *str); 00179 00184 short *add_struct(int namecode); 00185 00190 int preprocess_include(char *maindata, int len); 00191 00195 int convert_include(char *filename); 00196 00200 int arraysize(char *astr, int len); 00201 00205 static int calculate_structlens(int); 00206 00210 void dna_write(FILE *file, void *pntr, int size); 00211 00215 void printStructLenghts(void); 00216 00217 00218 00219 /* ************************************************************************** */ 00220 /* Implementation */ 00221 /* ************************************************************************** */ 00222 00223 /* ************************* MAKEN DNA ********************** */ 00224 00225 int add_type(const char *str, int len) 00226 { 00227 int nr; 00228 char *cp; 00229 00230 if(str[0]==0) return -1; 00231 00232 /* search through type array */ 00233 for(nr=0; nr<nr_types; nr++) { 00234 if(strcmp(str, types[nr])==0) { 00235 if (len) { 00236 typelens[nr]= len; 00237 alphalens[nr] = len; 00238 } 00239 return nr; 00240 } 00241 } 00242 00243 /* append new type */ 00244 if(nr_types==0) cp= typedata; 00245 else { 00246 cp= types[nr_types-1]+strlen(types[nr_types-1])+1; 00247 } 00248 strcpy(cp, str); 00249 types[nr_types]= cp; 00250 typelens[nr_types]= len; 00251 alphalens[nr_types]= len; 00252 00253 if(nr_types>=maxnr) { 00254 printf("too many types\n"); 00255 return nr_types-1; 00256 } 00257 nr_types++; 00258 00259 return nr_types-1; 00260 } 00261 00262 00271 int add_name(char *str) 00272 { 00273 int nr, i, j, k; 00274 char *cp; 00275 char buf[255]; /* stupid limit, change it :) */ 00276 char *name; 00277 00278 additional_slen_offset = 0; 00279 00280 if(str[0]==0 /* || (str[1]==0) */) return -1; 00281 00282 if (str[0] == '(' && str[1] == '*') { 00283 /* we handle function pointer and special array cases here, e.g. 00284 void (*function)(...) and float (*array)[..]. the array case 00285 name is still converted to (array*)() though because it is that 00286 way in old dna too, and works correct with elementsize() */ 00287 int isfuncptr = (strchr(str+1, '(')) != NULL; 00288 00289 if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer or multidim array pointer found\n"); 00290 /* functionpointer: transform the type (sometimes) */ 00291 i = 0; 00292 00293 while (str[i] != ')') { 00294 buf[i] = str[i]; 00295 i++; 00296 } 00297 00298 /* Another number we need is the extra slen offset. This extra 00299 * offset is the overshoot after a space. If there is no 00300 * space, no overshoot should be calculated. */ 00301 j = i; /* j at first closing brace */ 00302 00303 if (debugSDNA > 3) printf("first brace after offset %d\n", i); 00304 00305 j++; /* j beyond closing brace ? */ 00306 while ((str[j] != 0) && (str[j] != ')' )) { 00307 if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); 00308 j++; 00309 } 00310 if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); 00311 if (debugSDNA > 3) printf("special after offset %d\n", j); 00312 00313 if (!isfuncptr) { 00314 /* multidimensional array pointer case */ 00315 if(str[j] == 0) { 00316 if (debugSDNA > 3) printf("offsetting for multidim array pointer\n"); 00317 } 00318 else 00319 printf("Error during tokening multidim array pointer\n"); 00320 } 00321 else if (str[j] == 0 ) { 00322 if (debugSDNA > 3) printf("offsetting for space\n"); 00323 /* get additional offset */ 00324 k = 0; 00325 while (str[j] != ')') { 00326 j++; 00327 k++; 00328 } 00329 if (debugSDNA > 3) printf("extra offset %d\n", k); 00330 additional_slen_offset = k; 00331 } else if (str[j] == ')' ) { 00332 if (debugSDNA > 3) printf("offsetting for brace\n"); 00333 ; /* don't get extra offset */ 00334 } else { 00335 printf("Error during tokening function pointer argument list\n"); 00336 } 00337 00338 /* 00339 * Put )(void) at the end? Maybe )(). Should check this with 00340 * old sdna. Actually, sometimes )(), sometimes )(void...) 00341 * Alas.. such is the nature of braindamage :( 00342 * 00343 * Sorted it out: always do )(), except for headdraw and 00344 * windraw, part of ScrArea. This is important, because some 00345 * linkers will treat different fp's differently when called 00346 * !!! This has to do with interference in byte-alignment and 00347 * the way args are pushed on the stack. 00348 * 00349 * */ 00350 buf[i] = 0; 00351 if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); 00352 if ( (strncmp(buf,"(*headdraw", 10) == 0) 00353 || (strncmp(buf,"(*windraw", 9) == 0) ) { 00354 buf[i] = ')'; 00355 buf[i+1] = '('; 00356 buf[i+2] = 'v'; 00357 buf[i+3] = 'o'; 00358 buf[i+4] = 'i'; 00359 buf[i+5] = 'd'; 00360 buf[i+6] = ')'; 00361 buf[i+7] = 0; 00362 } else { 00363 buf[i] = ')'; 00364 buf[i+1] = '('; 00365 buf[i+2] = ')'; 00366 buf[i+3] = 0; 00367 } 00368 /* now precede with buf*/ 00369 if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf); 00370 name = buf; 00371 } else { 00372 /* normal field: old code */ 00373 name = str; 00374 } 00375 00376 /* search name array */ 00377 for(nr=0; nr<nr_names; nr++) { 00378 if(strcmp(name, names[nr])==0) { 00379 return nr; 00380 } 00381 } 00382 00383 /* append new type */ 00384 if(nr_names==0) cp= namedata; 00385 else { 00386 cp= names[nr_names-1]+strlen(names[nr_names-1])+1; 00387 } 00388 strcpy(cp, name); 00389 names[nr_names]= cp; 00390 00391 if(nr_names>=maxnr) { 00392 printf("too many names\n"); 00393 return nr_names-1; 00394 } 00395 nr_names++; 00396 00397 return nr_names-1; 00398 } 00399 00400 short *add_struct(int namecode) 00401 { 00402 int len; 00403 short *sp; 00404 00405 if(nr_structs==0) { 00406 structs[0]= structdata; 00407 } 00408 else { 00409 sp= structs[nr_structs-1]; 00410 len= sp[1]; 00411 structs[nr_structs]= sp+ 2*len+2; 00412 } 00413 00414 sp= structs[nr_structs]; 00415 sp[0]= namecode; 00416 00417 if(nr_structs>=maxnr) { 00418 printf("too many structs\n"); 00419 return sp; 00420 } 00421 nr_structs++; 00422 00423 return sp; 00424 } 00425 00426 int preprocess_include(char *maindata, int len) 00427 { 00428 int a, newlen, comment = 0; 00429 char *cp, *temp, *md; 00430 00431 /* note: len + 1, last character is a dummy to prevent 00432 * comparisons using uninitialized memory */ 00433 temp= MEM_mallocN(len + 1, "preprocess_include"); 00434 temp[len]= ' '; 00435 00436 memcpy(temp, maindata, len); 00437 00438 // remove all c++ comments 00439 /* replace all enters/tabs/etc with spaces */ 00440 cp= temp; 00441 a= len; 00442 comment = 0; 00443 while(a--) { 00444 if(cp[0]=='/' && cp[1]=='/') { 00445 comment = 1; 00446 } else if (*cp<32) { 00447 comment = 0; 00448 } 00449 if (comment || *cp<32 || *cp>128 ) *cp= 32; 00450 cp++; 00451 } 00452 00453 00454 /* data from temp copy to maindata, remove comments and double spaces */ 00455 cp= temp; 00456 md= maindata; 00457 newlen= 0; 00458 comment= 0; 00459 a= len; 00460 while(a--) { 00461 00462 if(cp[0]=='/' && cp[1]=='*') { 00463 comment= 1; 00464 cp[0]=cp[1]= 32; 00465 } 00466 if(cp[0]=='*' && cp[1]=='/') { 00467 comment= 0; 00468 cp[0]=cp[1]= 32; 00469 } 00470 00471 /* do not copy when: */ 00472 if(comment); 00473 else if( cp[0]==' ' && cp[1]==' ' ); 00474 else if( cp[-1]=='*' && cp[0]==' ' ); /* pointers with a space */ 00475 else { 00476 md[0]= cp[0]; 00477 md++; 00478 newlen++; 00479 } 00480 cp++; 00481 } 00482 00483 MEM_freeN(temp); 00484 return newlen; 00485 } 00486 00487 static void *read_file_data(char *filename, int *len_r) 00488 { 00489 #ifdef WIN32 00490 FILE *fp= fopen(filename, "rb"); 00491 #else 00492 FILE *fp= fopen(filename, "r"); 00493 #endif 00494 void *data; 00495 00496 if (!fp) { 00497 *len_r= -1; 00498 return NULL; 00499 } 00500 00501 fseek(fp, 0L, SEEK_END); 00502 *len_r= ftell(fp); 00503 fseek(fp, 0L, SEEK_SET); 00504 00505 data= MEM_mallocN(*len_r, "read_file_data"); 00506 if (!data) { 00507 *len_r= -1; 00508 fclose(fp); 00509 return NULL; 00510 } 00511 00512 if (fread(data, *len_r, 1, fp)!=1) { 00513 *len_r= -1; 00514 MEM_freeN(data); 00515 fclose(fp); 00516 return NULL; 00517 } 00518 00519 fclose(fp); 00520 return data; 00521 } 00522 00523 int convert_include(char *filename) 00524 { 00525 /* read include file, skip structs with a '#' before it. 00526 store all data in temporal arrays. 00527 */ 00528 int filelen, count, overslaan, slen, type, name, strct; 00529 short *structpoin, *sp; 00530 char *maindata, *mainend, *md, *md1; 00531 00532 md= maindata= read_file_data(filename, &filelen); 00533 if (filelen==-1) { 00534 printf("Can't read file %s\n", filename); 00535 return 1; 00536 } 00537 00538 filelen= preprocess_include(maindata, filelen); 00539 mainend= maindata+filelen-1; 00540 00541 /* we look for '{' and then back to 'struct' */ 00542 count= 0; 00543 overslaan= 0; 00544 while(count<filelen) { 00545 00546 /* code for skipping a struct: two hashes on 2 lines. (preprocess added a space) */ 00547 if(md[0]=='#' && md[1]==' ' && md[2]=='#') { 00548 overslaan= 1; 00549 } 00550 00551 if(md[0]=='{') { 00552 md[0]= 0; 00553 if(overslaan) { 00554 overslaan= 0; 00555 } 00556 else { 00557 if(md[-1]==' ') md[-1]= 0; 00558 md1= md-2; 00559 while( *md1!=32) md1--; /* to beginning of word */ 00560 md1++; 00561 00562 /* we've got a struct name when... */ 00563 if( strncmp(md1-7, "struct", 6)==0 ) { 00564 00565 00566 strct= add_type(md1, 0); 00567 structpoin= add_struct(strct); 00568 sp= structpoin+2; 00569 00570 if (debugSDNA > 1) printf("\t|\t|-- detected struct %s\n", types[strct]); 00571 00572 /* first lets make it all nice strings */ 00573 md1= md+1; 00574 while(*md1 != '}') { 00575 if(md1>mainend) break; 00576 00577 if(*md1==',' || *md1==' ') *md1= 0; 00578 md1++; 00579 } 00580 00581 /* read types and names until first character that is not '}' */ 00582 md1= md+1; 00583 while( *md1 != '}' ) { 00584 if(md1>mainend) break; 00585 00586 /* skip when it says 'struct' or 'unsigned' or 'const' */ 00587 if(*md1) { 00588 if( strncmp(md1, "struct", 6)==0 ) md1+= 7; 00589 if( strncmp(md1, "unsigned", 8)==0 ) md1+= 9; 00590 if( strncmp(md1, "const", 5)==0 ) md1+= 6; 00591 00592 /* we've got a type! */ 00593 type= add_type(md1, 0); 00594 00595 if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1); 00596 00597 md1+= strlen(md1); 00598 00599 00600 /* read until ';' */ 00601 while( *md1 != ';' ) { 00602 if(md1>mainend) break; 00603 00604 if(*md1) { 00605 /* We've got a name. slen needs 00606 * correction for function 00607 * pointers! */ 00608 slen= (int) strlen(md1); 00609 if( md1[slen-1]==';' ) { 00610 md1[slen-1]= 0; 00611 00612 00613 name= add_name(md1); 00614 slen += additional_slen_offset; 00615 sp[0]= type; 00616 sp[1]= name; 00617 00618 if ((debugSDNA>1) && (names[name] != NULL)) printf("%s |", names[name]); 00619 00620 structpoin[1]++; 00621 sp+= 2; 00622 00623 md1+= slen; 00624 break; 00625 } 00626 00627 00628 name= add_name(md1); 00629 slen += additional_slen_offset; 00630 00631 sp[0]= type; 00632 sp[1]= name; 00633 if ((debugSDNA > 1) && (names[name] != NULL)) printf("%s ||", names[name]); 00634 00635 structpoin[1]++; 00636 sp+= 2; 00637 00638 md1+= slen; 00639 } 00640 md1++; 00641 } 00642 00643 if (debugSDNA > 1) printf(")\n"); 00644 00645 } 00646 md1++; 00647 } 00648 } 00649 } 00650 } 00651 count++; 00652 md++; 00653 } 00654 00655 MEM_freeN(maindata); 00656 00657 return 0; 00658 } 00659 00660 int arraysize(char *astr, int len) 00661 { 00662 int a, mul=1; 00663 char str[100], *cp=NULL; 00664 00665 memcpy(str, astr, len+1); 00666 00667 for(a=0; a<len; a++) { 00668 if( str[a]== '[' ) { 00669 cp= &(str[a+1]); 00670 } 00671 else if( str[a]==']' && cp) { 00672 str[a]= 0; 00673 /* if 'cp' is a preprocessor definition, it will evaluate to 0, 00674 * the caller needs to check for this case and throw an error */ 00675 mul*= atoi(cp); 00676 } 00677 } 00678 00679 return mul; 00680 } 00681 00682 static int calculate_structlens(int firststruct) 00683 { 00684 int a, b, len, alphalen, unknown= nr_structs, lastunknown, structtype, type, mul, namelen; 00685 short *sp, *structpoin; 00686 char *cp; 00687 int has_pointer, dna_error = 0; 00688 00689 while(unknown) { 00690 lastunknown= unknown; 00691 unknown= 0; 00692 00693 /* check all structs... */ 00694 for(a=0; a<nr_structs; a++) { 00695 structpoin= structs[a]; 00696 structtype= structpoin[0]; 00697 00698 /* when length is not known... */ 00699 if(typelens[structtype]==0) { 00700 00701 sp= structpoin+2; 00702 len= 0; 00703 alphalen = 0; 00704 has_pointer = 0; 00705 00706 /* check all elements in struct */ 00707 for(b=0; b<structpoin[1]; b++, sp+=2) { 00708 type= sp[0]; 00709 cp= names[sp[1]]; 00710 00711 namelen= (int) strlen(cp); 00712 /* is it a pointer or function pointer? */ 00713 if(cp[0]=='*' || cp[1]=='*') { 00714 has_pointer = 1; 00715 /* has the name an extra length? (array) */ 00716 mul= 1; 00717 if( cp[namelen-1]==']') mul= arraysize(cp, namelen); 00718 00719 if (mul == 0) { 00720 printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp); 00721 dna_error = 1; 00722 } 00723 00724 /* 4-8 aligned/ */ 00725 if(sizeof(void *) == 4) { 00726 if (len % 4) { 00727 printf("Align pointer error in struct (len4): %s %s\n", types[structtype], cp); 00728 dna_error = 1; 00729 } 00730 } else { 00731 if (len % 8) { 00732 printf("Align pointer error in struct (len8): %s %s\n", types[structtype], cp); 00733 dna_error = 1; 00734 } 00735 } 00736 00737 if (alphalen % 8) { 00738 printf("Align pointer error in struct (alphalen8): %s %s\n", types[structtype],cp); 00739 dna_error = 1; 00740 } 00741 00742 len += sizeof(void *) * mul; 00743 alphalen += 8 * mul; 00744 00745 } else if(cp[0]=='[') { 00746 /* parsing can cause names "var" and "[3]" to be found for "float var [3]" ... */ 00747 printf("Parse error in struct, invalid member name: %s %s\n", types[structtype], cp); 00748 dna_error = 1; 00749 } else if( typelens[type] ) { 00750 /* has the name an extra length? (array) */ 00751 mul= 1; 00752 if( cp[namelen-1]==']') mul= arraysize(cp, namelen); 00753 00754 if (mul == 0) { 00755 printf("Zero array size found or could not parse %s: '%.*s'\n", types[structtype], namelen + 1, cp); 00756 dna_error = 1; 00757 } 00758 00759 /* struct alignment */ 00760 if(type >= firststruct) { 00761 if(sizeof(void *)==8 && (len % 8) ) { 00762 printf("Align struct error: %s %s\n", types[structtype],cp); 00763 dna_error = 1; 00764 } 00765 } 00766 00767 /* 2-4 aligned/ */ 00768 if(typelens[type]>3 && (len % 4) ) { 00769 printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%4); 00770 dna_error = 1; 00771 } 00772 else if(typelens[type]==2 && (len % 2) ) { 00773 printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%2); 00774 dna_error = 1; 00775 } 00776 00777 len += mul*typelens[type]; 00778 alphalen += mul * alphalens[type]; 00779 00780 } else { 00781 len= 0; 00782 alphalen = 0; 00783 break; 00784 } 00785 } 00786 00787 if (len==0) { 00788 unknown++; 00789 } else { 00790 typelens[structtype]= len; 00791 alphalens[structtype]= alphalen; 00792 // two ways to detect if a struct contains a pointer: 00793 // has_pointer is set or alphalen != len 00794 if (has_pointer || alphalen != len) { 00795 if (alphalen % 8) { 00796 printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); 00797 dna_error = 1; 00798 } 00799 } 00800 00801 if(len % 4) { 00802 printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4); 00803 dna_error = 1; 00804 } 00805 00806 } 00807 } 00808 } 00809 00810 if(unknown==lastunknown) break; 00811 } 00812 00813 if(unknown) { 00814 printf("ERROR: still %d structs unknown\n", unknown); 00815 00816 if (debugSDNA) { 00817 printf("*** Known structs : \n"); 00818 00819 for(a=0; a<nr_structs; a++) { 00820 structpoin= structs[a]; 00821 structtype= structpoin[0]; 00822 00823 /* length unknown */ 00824 if(typelens[structtype]!=0) { 00825 printf(" %s\n", types[structtype]); 00826 } 00827 } 00828 } 00829 00830 00831 printf("*** Unknown structs : \n"); 00832 00833 for(a=0; a<nr_structs; a++) { 00834 structpoin= structs[a]; 00835 structtype= structpoin[0]; 00836 00837 /* length unkown yet */ 00838 if(typelens[structtype]==0) { 00839 printf(" %s\n", types[structtype]); 00840 } 00841 } 00842 } 00843 00844 return(dna_error); 00845 } 00846 00847 #define MAX_DNA_LINE_LENGTH 20 00848 00849 void dna_write(FILE *file, void *pntr, int size) 00850 { 00851 static int linelength = 0; 00852 int i; 00853 char *data; 00854 00855 data = (char *) pntr; 00856 00857 for (i = 0 ; i < size ; i++) 00858 { 00859 fprintf(file, "%d,", data[i]); 00860 linelength++; 00861 if (linelength >= MAX_DNA_LINE_LENGTH) { 00862 fprintf(file, "\n"); 00863 linelength = 0; 00864 } 00865 } 00866 } 00867 00868 void printStructLenghts(void) 00869 { 00870 int a, unknown= nr_structs, structtype; 00871 /*int lastunknown;*/ /*UNUSED*/ 00872 short *structpoin; 00873 printf("\n\n*** All detected structs:\n"); 00874 00875 while(unknown) { 00876 /*lastunknown= unknown;*/ /*UNUSED*/ 00877 unknown= 0; 00878 00879 /* check all structs... */ 00880 for(a=0; a<nr_structs; a++) { 00881 structpoin= structs[a]; 00882 structtype= structpoin[0]; 00883 printf("\t%s\t:%d\n", types[structtype], typelens[structtype]); 00884 } 00885 } 00886 00887 printf("*** End of list\n"); 00888 00889 } 00890 00891 00892 int make_structDNA(char *baseDirectory, FILE *file) 00893 { 00894 int len, i; 00895 short *sp; 00896 /* str contains filenames. Since we now include paths, I stretched */ 00897 /* it a bit. Hope this is enough :) -nzc- */ 00898 char str[SDNA_MAX_FILENAME_LENGTH], *cp; 00899 int firststruct; 00900 00901 if (debugSDNA > -1) { 00902 fflush(stdout); 00903 printf("Running makesdna at debug level %d\n", debugSDNA); 00904 printf("\tProgram version: %s\n", DNA_VERSION_DATE); 00905 } 00906 00907 /* the longest known struct is 50k, so we assume 100k is sufficent! */ 00908 namedata= MEM_callocN(maxdata, "namedata"); 00909 typedata= MEM_callocN(maxdata, "typedata"); 00910 structdata= MEM_callocN(maxdata, "structdata"); 00911 00912 /* a maximum of 5000 variables, must be sufficient? */ 00913 names= MEM_callocN(sizeof(char *)*maxnr, "names"); 00914 types= MEM_callocN(sizeof(char *)*maxnr, "types"); 00915 typelens= MEM_callocN(sizeof(short)*maxnr, "typelens"); 00916 alphalens= MEM_callocN(sizeof(short)*maxnr, "alphalens"); 00917 structs= MEM_callocN(sizeof(short)*maxnr, "structs"); 00918 00919 /* insertion of all known types */ 00920 /* watch it: uint is not allowed! use in structs an unsigned int */ 00921 add_type("char", 1); /* 0 */ 00922 add_type("uchar", 1); /* 1 */ 00923 add_type("short", 2); /* 2 */ 00924 add_type("ushort", 2); /* 3 */ 00925 add_type("int", 4); /* 4 */ 00926 add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */ 00927 add_type("ulong", 4); /* 6 */ 00928 add_type("float", 4); /* 7 */ 00929 add_type("double", 8); /* 8 */ 00930 add_type("void", 0); /* 9 */ 00931 00932 // the defines above shouldn't be output in the padding file... 00933 firststruct = nr_types; 00934 00935 /* add all include files defined in the global array */ 00936 /* Since the internal file+path name buffer has limited length, I do a */ 00937 /* little test first... */ 00938 /* Mind the breaking condition here! */ 00939 if (debugSDNA) printf("\tStart of header scan:\n"); 00940 for (i = 0; strlen(includefiles[i]); i++) { 00941 sprintf(str, "%s%s", baseDirectory, includefiles[i]); 00942 if (debugSDNA) printf("\t|-- Converting %s\n", str); 00943 if (convert_include(str)) { 00944 return (1); 00945 } 00946 } 00947 if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); 00948 00949 if (calculate_structlens(firststruct)) { 00950 // error 00951 return(1); 00952 } 00953 00954 /* FOR DEBUG */ 00955 if (debugSDNA > 1) 00956 { 00957 int a,b; 00958 /* short *elem; */ 00959 short num_types; 00960 00961 printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs); 00962 for(a=0; a<nr_names; a++) { 00963 printf(" %s \n", names[a]); 00964 } 00965 printf("\n"); 00966 00967 sp= typelens; 00968 for(a=0; a<nr_types; a++, sp++) { 00969 printf(" %s %d\n", types[a], *sp); 00970 } 00971 printf("\n"); 00972 00973 for(a=0; a<nr_structs; a++) { 00974 sp= structs[a]; 00975 printf(" struct %s elems: %d size: %d\n", types[sp[0]], sp[1],typelens[sp[0]]); 00976 num_types = sp[1]; 00977 sp+= 2; 00978 /* ? num_types was elem? */ 00979 for(b=0; b< num_types; b++, sp+= 2) { 00980 printf(" %s %s\n", types[sp[0]], names[sp[1]]); 00981 } 00982 } 00983 } 00984 00985 /* file writing */ 00986 00987 if (debugSDNA > -1) printf("Writing file ... "); 00988 00989 if(nr_names==0 || nr_structs==0); 00990 else { 00991 strcpy(str, "SDNA"); 00992 dna_write(file, str, 4); 00993 00994 /* write names */ 00995 strcpy(str, "NAME"); 00996 dna_write(file, str, 4); 00997 len= nr_names; 00998 dna_write(file, &len, 4); 00999 01000 /* calculate size of datablock with strings */ 01001 cp= names[nr_names-1]; 01002 cp+= strlen(names[nr_names-1]) + 1; /* +1: null-terminator */ 01003 len= (intptr_t) (cp - (char*) names[0]); 01004 len= (len+3) & ~3; 01005 dna_write(file, names[0], len); 01006 01007 /* write TYPES */ 01008 strcpy(str, "TYPE"); 01009 dna_write(file, str, 4); 01010 len= nr_types; 01011 dna_write(file, &len, 4); 01012 01013 /* calculate datablock size */ 01014 cp= types[nr_types-1]; 01015 cp+= strlen(types[nr_types-1]) + 1; /* +1: null-terminator */ 01016 len= (intptr_t) (cp - (char*) types[0]); 01017 len= (len+3) & ~3; 01018 01019 dna_write(file, types[0], len); 01020 01021 /* WRITE TYPELENGTHS */ 01022 strcpy(str, "TLEN"); 01023 dna_write(file, str, 4); 01024 01025 len= 2*nr_types; 01026 if(nr_types & 1) len+= 2; 01027 dna_write(file, typelens, len); 01028 01029 /* WRITE STRUCTS */ 01030 strcpy(str, "STRC"); 01031 dna_write(file, str, 4); 01032 len= nr_structs; 01033 dna_write(file, &len, 4); 01034 01035 /* calc datablock size */ 01036 sp= structs[nr_structs-1]; 01037 sp+= 2+ 2*( sp[1] ); 01038 len= (intptr_t) ((char*) sp - (char*) structs[0]); 01039 len= (len+3) & ~3; 01040 01041 dna_write(file, structs[0], len); 01042 01043 /* a simple dna padding test */ 01044 if (0) { 01045 FILE *fp; 01046 int a; 01047 01048 fp= fopen("padding.c", "w"); 01049 if(fp==NULL); 01050 else { 01051 01052 // add all include files defined in the global array 01053 for (i = 0; strlen(includefiles[i]); i++) { 01054 fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]); 01055 } 01056 01057 fprintf(fp, "main(){\n"); 01058 sp = typelens; 01059 sp += firststruct; 01060 for(a=firststruct; a<nr_types; a++, sp++) { 01061 if(*sp) { 01062 fprintf(fp, "\tif(sizeof(struct %s) - %d) printf(\"ALIGN ERROR:", types[a], *sp); 01063 fprintf(fp, "%%d %s %d ", types[a], *sp); 01064 fprintf(fp, "\\n\", sizeof(struct %s) - %d);\n", types[a], *sp); 01065 } 01066 } 01067 fprintf(fp, "}\n"); 01068 fclose(fp); 01069 } 01070 } 01071 /* end end padding test */ 01072 } 01073 01074 01075 MEM_freeN(namedata); 01076 MEM_freeN(typedata); 01077 MEM_freeN(structdata); 01078 MEM_freeN(names); 01079 MEM_freeN(types); 01080 MEM_freeN(typelens); 01081 MEM_freeN(alphalens); 01082 MEM_freeN(structs); 01083 01084 if (debugSDNA > -1) printf("done.\n"); 01085 01086 return(0); 01087 } 01088 01089 /* ************************* END MAKE DNA ********************** */ 01090 01091 static void make_bad_file(char *file, int line) 01092 { 01093 FILE *fp= fopen(file, "w"); 01094 fprintf(fp, "#error \"Error! can't make correct DNA.c file from %s:%d, STUPID!\"\n", __FILE__, line); 01095 fclose(fp); 01096 } 01097 01098 #ifndef BASE_HEADER 01099 #define BASE_HEADER "../" 01100 #endif 01101 01102 int main(int argc, char ** argv) 01103 { 01104 FILE *file; 01105 int return_status = 0; 01106 01107 if (argc!=2 && argc!=3) { 01108 printf("Usage: %s outfile.c [base directory]\n", argv[0]); 01109 return_status = 1; 01110 } else { 01111 file = fopen(argv[1], "w"); 01112 if (!file) { 01113 printf ("Unable to open file: %s\n", argv[1]); 01114 return_status = 1; 01115 } else { 01116 char baseDirectory[256]; 01117 01118 if (argc==3) { 01119 strcpy(baseDirectory, argv[2]); 01120 } else { 01121 strcpy(baseDirectory, BASE_HEADER); 01122 } 01123 01124 fprintf (file, "unsigned char DNAstr[]= {\n"); 01125 if (make_structDNA(baseDirectory, file)) { 01126 // error 01127 fclose(file); 01128 make_bad_file(argv[1], __LINE__); 01129 return_status = 1; 01130 } else { 01131 fprintf(file, "};\n"); 01132 fprintf(file, "int DNAlen= sizeof(DNAstr);\n"); 01133 01134 fclose(file); 01135 } 01136 } 01137 } 01138 01139 01140 return(return_status); 01141 } 01142 01143 // include files for automatic dependancies 01144 #include "DNA_listBase.h" 01145 #include "DNA_vec_types.h" 01146 #include "DNA_ID.h" 01147 #include "DNA_ipo_types.h" 01148 #include "DNA_key_types.h" 01149 #include "DNA_text_types.h" 01150 #include "DNA_packedFile_types.h" 01151 #include "DNA_camera_types.h" 01152 #include "DNA_image_types.h" 01153 #include "DNA_texture_types.h" 01154 #include "DNA_lamp_types.h" 01155 #include "DNA_material_types.h" 01156 #include "DNA_vfont_types.h" 01157 #include "DNA_meta_types.h" 01158 #include "DNA_curve_types.h" 01159 #include "DNA_mesh_types.h" 01160 #include "DNA_meshdata_types.h" 01161 #include "DNA_modifier_types.h" 01162 #include "DNA_lattice_types.h" 01163 #include "DNA_object_types.h" 01164 #include "DNA_object_force.h" 01165 #include "DNA_object_fluidsim.h" 01166 #include "DNA_world_types.h" 01167 #include "DNA_scene_types.h" 01168 #include "DNA_view3d_types.h" 01169 #include "DNA_view2d_types.h" 01170 #include "DNA_space_types.h" 01171 #include "DNA_userdef_types.h" 01172 #include "DNA_screen_types.h" 01173 #include "DNA_sdna_types.h" 01174 #include "DNA_fileglobal_types.h" 01175 #include "DNA_sequence_types.h" 01176 #include "DNA_effect_types.h" 01177 #include "DNA_outliner_types.h" 01178 #include "DNA_property_types.h" 01179 #include "DNA_sensor_types.h" 01180 #include "DNA_controller_types.h" 01181 #include "DNA_actuator_types.h" 01182 #include "DNA_sound_types.h" 01183 #include "DNA_group_types.h" 01184 #include "DNA_armature_types.h" 01185 #include "DNA_action_types.h" 01186 #include "DNA_constraint_types.h" 01187 #include "DNA_nla_types.h" 01188 #include "DNA_node_types.h" 01189 #include "DNA_color_types.h" 01190 #include "DNA_brush_types.h" 01191 #include "DNA_customdata_types.h" 01192 #include "DNA_particle_types.h" 01193 #include "DNA_cloth_types.h" 01194 #include "DNA_gpencil_types.h" 01195 #include "DNA_windowmanager_types.h" 01196 #include "DNA_anim_types.h" 01197 #include "DNA_boid_types.h" 01198 #include "DNA_smoke_types.h" 01199 /* end of list */