apiGen.cpp 9.7 KB

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