makesdna.cpp 31 KB

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