apiGen.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  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. int main(int argc, char **argv)
  178. {
  179. using namespace bParse;
  180. dump = fopen("dump.py", "w");
  181. if (!dump) return 0;
  182. fprintf(dump, "%s\n", data);
  183. #if 0
  184. char* filename = "../../../../data/r2d2_multibody.bullet";
  185. if (argc==2)
  186. filename = argv[1];
  187. bString fileStr(filename);
  188. bString extension(".bullet");
  189. int index2 = fileStr.find(extension);
  190. if (index2>=0)
  191. isBulletFile=true;
  192. FILE* fp = fopen (filename,"rb");
  193. if (!fp)
  194. {
  195. printf("error: file not found %s\n",filename);
  196. exit(0);
  197. }
  198. char* memBuf = 0;
  199. int len = 0;
  200. long currentpos = ftell(fp); /* save current cursor position */
  201. long newpos;
  202. int bytesRead;
  203. fseek(fp, 0, SEEK_END); /* seek to end */
  204. newpos = ftell(fp); /* find position of end -- this is the length */
  205. fseek(fp, currentpos, SEEK_SET); /* restore previous cursor position */
  206. len = newpos;
  207. memBuf = (char*)malloc(len);
  208. bytesRead = fread(memBuf,len,1,fp);
  209. bool swap = false;
  210. if (isBulletFile)
  211. {
  212. btBulletFile f(memBuf,len);
  213. swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
  214. } else
  215. {
  216. bBlenderFile f(memBuf,len);
  217. swap = (f.getFlags() & FD_ENDIAN_SWAP)!=0;
  218. }
  219. #else
  220. isBulletFile = true;
  221. bool swap = false;
  222. char *memBuf = sBulletDNAstr;
  223. int len = sBulletDNAlen;
  224. #endif
  225. char *blenderData = memBuf;
  226. int sdnaPos = 0;
  227. int mDataStart = 12;
  228. char *tempBuffer = blenderData;
  229. for (int i = 0; i < len; i++)
  230. {
  231. // looking for the data's starting position
  232. // and the start of SDNA decls
  233. if (!mDataStart && strncmp(tempBuffer, "REND", 4) == 0)
  234. mDataStart = i;
  235. if (!sdnaPos && strncmp(tempBuffer, "SDNA", 4) == 0)
  236. sdnaPos = i;
  237. if (mDataStart && sdnaPos) break;
  238. tempBuffer++;
  239. }
  240. FILE *fpdna = fopen("dnaString.txt", "w");
  241. char buf[1024];
  242. for (int i = 0; i < len - sdnaPos; i++)
  243. {
  244. int dnaval = (memBuf + sdnaPos)[i];
  245. if ((i % 32) == 0)
  246. {
  247. sprintf(buf, "%d,\n", dnaval);
  248. }
  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