apiGen.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /* Copyright (C) 2006 Charlie C
  2. *
  3. * This software is provided 'as-is', without any express or implied
  4. * warranty. In no event will the authors be held liable for any damages
  5. * arising from the use of this software.
  6. *
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. *
  11. * 1. The origin of this software must not be misrepresented; you must not
  12. * claim that you wrote the original software. If you use this software
  13. * in a product, an acknowledgment in the product documentation would be
  14. * appreciated but is not required.
  15. * 2. Altered source versions must be plainly marked as such, and must not be
  16. * misrepresented as being the original software.
  17. * 3. This notice may not be removed or altered from any source distribution.
  18. */
  19. #include <sstream>
  20. #include "bDNA.h"
  21. #include "bBlenderFile.h"
  22. #include "btBulletFile.h"
  23. #include "LinearMath/btSerializer.h"
  24. #include "bCommon.h"
  25. #include <map>
  26. #include <vector>
  27. #include <string.h>
  28. bool isBulletFile = true;
  29. using namespace bParse;
  30. typedef std::string bString;
  31. ///////////////////////////////////////////////////////////////////////////////
  32. typedef std::map<bString, bString> bStringMap;
  33. typedef std::vector<class bVariable> bVariableList;
  34. typedef std::vector<bString> bStringList;
  35. ///////////////////////////////////////////////////////////////////////////////
  36. static FILE *dump = 0;
  37. static bDNA *mDNA =0;
  38. static bStringMap mStructs;
  39. ///////////////////////////////////////////////////////////////////////////////
  40. class bVariable
  41. {
  42. public:
  43. bVariable();
  44. ~bVariable();
  45. bString dataType;
  46. bString variableName;
  47. bString functionName;
  48. bString classCtor;
  49. bString memberVariable;
  50. bString memberDataType;
  51. bString functionArgs;
  52. void initialize(bString dataType, bString variable, bStringMap refDataTable);
  53. bool isPtr;
  54. bool isFunctionPtr;
  55. bool isPtrToPtr;
  56. bool isArray;
  57. bool isCharArray;
  58. bool isListBase;
  59. bool isPadding;
  60. bool isCommentedOut;
  61. bool isGeneratedType;
  62. bool isbString;
  63. };
  64. ///////////////////////////////////////////////////////////////////////////////
  65. bool dataTypeStandard(bString dataType)
  66. {
  67. if (dataType == "char")
  68. return true;
  69. if (dataType == "short")
  70. return true;
  71. if (dataType == "int")
  72. return true;
  73. if (dataType == "long")
  74. return true;
  75. if (dataType == "float")
  76. return true;
  77. if (dataType == "double")
  78. return true;
  79. if (dataType == "void")
  80. return true;
  81. if (dataType == "btScalar")
  82. return true;
  83. return false;
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////
  86. void writeTemplate(short *structData)
  87. {
  88. bString type = mDNA->getType(structData[0]);
  89. bString className=type;
  90. bString prefix = isBulletFile? "bullet_" : "blender_";
  91. int thisLen = structData[1];
  92. structData+=2;
  93. bString fileName = prefix+type;
  94. bVariableList dataTypes;
  95. bStringMap includeFiles;
  96. for (int dataVal =0; dataVal<thisLen; dataVal++, structData+=2)
  97. {
  98. bString dataType = mDNA->getType(structData[0]);
  99. bString dataName = mDNA->getName(structData[1]);
  100. {
  101. bString newDataType = "";
  102. bString newDataName = "";
  103. bStringMap::iterator addB = mStructs.find(dataType);
  104. if (addB != mStructs.end())
  105. {
  106. newDataType = addB->second;
  107. newDataName = dataName;
  108. }
  109. else
  110. {
  111. if (dataTypeStandard(dataType))
  112. {
  113. newDataType = dataType;
  114. newDataName = dataName;
  115. }
  116. else
  117. {
  118. // Unresolved
  119. // set it to an empty struct
  120. // if it's not a ptr generate an error
  121. newDataType = "bInvalidHandle";
  122. newDataName = dataName;
  123. if (dataName[0] != '*')
  124. {
  125. }
  126. }
  127. }
  128. if (!newDataType.empty() && !newDataName.empty())
  129. {
  130. bVariable var = bVariable();
  131. var.initialize(newDataType, newDataName, mStructs);
  132. dataTypes.push_back(var);
  133. }
  134. }
  135. bStringMap::iterator include = mStructs.find(dataType);
  136. if (include != mStructs.end())
  137. {
  138. if (dataName[0] != '*')
  139. {
  140. if (includeFiles.find(dataType)== includeFiles.end())
  141. {
  142. includeFiles[dataType]=prefix+dataType;
  143. }
  144. }
  145. }
  146. }
  147. fprintf(dump, "###############################################################\n");
  148. fprintf(dump, "%s = bStructClass()\n", fileName.c_str());
  149. fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str());
  150. fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str());
  151. bVariableList::iterator vars = dataTypes.begin();
  152. while (vars!= dataTypes.end())
  153. {
  154. fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str());
  155. vars++;
  156. }
  157. bStringMap::iterator inc = includeFiles.begin();
  158. while (inc != includeFiles.end())
  159. {
  160. fprintf(dump, "%s.includes.append('%s.h')\n", fileName.c_str(), inc->second.c_str());
  161. inc++;
  162. }
  163. fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str());
  164. }
  165. ///////////////////////////////////////////////////////////////////////////////
  166. char data[]={
  167. "\n"
  168. "class bStructClass:\n"
  169. " def __init__(self):\n"
  170. " self.name = \"\";\n"
  171. " self.filename = \"\";\n"
  172. " self.includes = []\n"
  173. " self.dataTypes = []\n"
  174. "\n\n"
  175. "DataTypeList = []\n"
  176. };
  177. ///////////////////////////////////////////////////////////////////////////////
  178. int main(int argc,char** argv)
  179. {
  180. using namespace bParse;
  181. dump = fopen("dump.py", "w");
  182. if (!dump) return 0;
  183. fprintf(dump, "%s\n", data);
  184. #if 0
  185. char* filename = "../../../../data/r2d2_multibody.bullet";
  186. if (argc==2)
  187. filename = argv[1];
  188. bString fileStr(filename);
  189. bString extension(".bullet");
  190. int index2 = fileStr.find(extension);
  191. if (index2>=0)
  192. isBulletFile=true;
  193. FILE* fp = fopen (filename,"rb");
  194. if (!fp)
  195. {
  196. printf("error: file not found %s\n",filename);
  197. exit(0);
  198. }
  199. char* memBuf = 0;
  200. int len = 0;
  201. long currentpos = ftell(fp); /* save current cursor position */
  202. long newpos;
  203. int bytesRead;
  204. fseek(fp, 0, SEEK_END); /* seek to end */
  205. newpos = ftell(fp); /* find position of end -- this is the length */
  206. fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */
  207. len = newpos;
  208. memBuf = (char*)malloc(len);
  209. bytesRead = fread(memBuf,len,1,fp);
  210. bool swap = false;
  211. if (isBulletFile)
  212. {
  213. btBulletFile f(memBuf,len);
  214. swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
  215. } else
  216. {
  217. bBlenderFile f(memBuf,len);
  218. swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
  219. }
  220. #else
  221. isBulletFile = true;
  222. bool swap = false;
  223. char* memBuf = sBulletDNAstr;
  224. int len = sBulletDNAlen;
  225. #endif
  226. char *blenderData = memBuf;
  227. int sdnaPos=0;
  228. int mDataStart = 12;
  229. char *tempBuffer = blenderData;
  230. for (int i=0; i<len; i++)
  231. {
  232. // looking for the data's starting position
  233. // and the start of SDNA decls
  234. if (!mDataStart && strncmp(tempBuffer, "REND", 4)==0)
  235. mDataStart = i;
  236. if (!sdnaPos && strncmp(tempBuffer, "SDNA", 4)==0)
  237. sdnaPos = i;
  238. if (mDataStart && sdnaPos) break;
  239. tempBuffer++;
  240. }
  241. FILE* fpdna = fopen("dnaString.txt","w");
  242. char buf[1024];
  243. for (int i=0;i<len-sdnaPos;i++)
  244. {
  245. int dnaval = (memBuf+sdnaPos)[i];
  246. if ((i%32)==0)
  247. {
  248. sprintf(buf,"%d,\n",dnaval);
  249. } else
  250. {
  251. sprintf(buf,"%d,",dnaval);
  252. }
  253. fwrite(buf,strlen(buf),1,fpdna);
  254. }
  255. fclose(fpdna);
  256. mDNA = new bDNA();
  257. //mDNA->initMemory();
  258. mDNA->init(memBuf+sdnaPos, len-sdnaPos, swap);
  259. for (int i=0; i<mDNA->getNumStructs(); i++)
  260. {
  261. short *structData = mDNA->getStruct(i);
  262. bString type = mDNA->getType(structData[0]);
  263. bString className = type;
  264. mStructs[type]=className;
  265. }
  266. for (int i=0; i<mDNA->getNumStructs(); i++)
  267. {
  268. short *structData = mDNA->getStruct(i);
  269. writeTemplate(structData);
  270. }
  271. delete mDNA;
  272. fclose(dump);
  273. return 0;
  274. }
  275. ///////////////////////////////////////////////////////////////////////////////
  276. ///////////////////////////////////////////////////////////////////////////////
  277. int _getArraySize(char* str)
  278. {
  279. int a, mul=1;
  280. char stri[100], *cp=0;
  281. int len = (int)strlen(str);
  282. memcpy(stri, str, len+1);
  283. for (a=0; a<len; a++)
  284. {
  285. if (str[a]== '[')
  286. cp= &(stri[a+1]);
  287. else if ( str[a]==']' && cp)
  288. {
  289. stri[a]= 0;
  290. mul*= atoi(cp);
  291. }
  292. }
  293. return mul;
  294. }
  295. ///////////////////////////////////////////////////////////////////////////////
  296. bVariable::bVariable()
  297. : dataType("invalid"),
  298. variableName("invalid"),
  299. functionName(""),
  300. classCtor(""),
  301. memberVariable(""),
  302. memberDataType(""),
  303. functionArgs(""),
  304. isPtr(false),
  305. isFunctionPtr(false),
  306. isPtrToPtr(false),
  307. isArray(false),
  308. isCharArray(false),
  309. isListBase(false),
  310. isPadding(false),
  311. isCommentedOut(false),
  312. isGeneratedType(false),
  313. isbString(false)
  314. {
  315. }
  316. ///////////////////////////////////////////////////////////////////////////////
  317. bVariable::~bVariable()
  318. {
  319. dataType.clear();
  320. variableName.clear();
  321. }
  322. ///////////////////////////////////////////////////////////////////////////////
  323. void bVariable::initialize(bString type, bString variable, bStringMap refDataTable)
  324. {
  325. dataType = type;
  326. variableName = variable;
  327. if (variableName[0] == '*')
  328. {
  329. isPtr = true;
  330. if (variableName[1] == '*')
  331. isPtrToPtr = true;
  332. }
  333. if (variableName[0] == '(')
  334. if (variableName[1] == '*')
  335. isFunctionPtr = true;
  336. if (variableName[variableName.size()-1] == ']')
  337. {
  338. isArray = true;
  339. if (type == "char")
  340. isCharArray = true;
  341. }
  342. if (type == "ListBase")
  343. isListBase = true;
  344. if (variableName[0] == 'p')
  345. {
  346. bString sub = variableName.substr(0,3);
  347. if (sub == "pad")
  348. isPadding = true;
  349. }
  350. if (dataType[0] == '/' && dataType[1] == '/')
  351. isCommentedOut = true;
  352. if (refDataTable.find(dataType) != refDataTable.end())
  353. isGeneratedType = true;
  354. if (!isBulletFile)
  355. {
  356. // replace valid float arrays
  357. if (dataType == "float" && isArray)
  358. {
  359. int size = _getArraySize((char*)variableName.c_str());
  360. if (size==3)
  361. {
  362. dataType = "vec3f";
  363. variableName = variableName.substr(0, variableName.find_first_of("["));
  364. }
  365. if (size==4)
  366. {
  367. dataType = "vec4f";
  368. variableName = variableName.substr(0, variableName.find_first_of("["));
  369. }
  370. }
  371. }
  372. memberDataType = dataType;
  373. functionArgs = variableName;
  374. }
  375. // eof