makesdna.cpp 32 KB

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