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