EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
HeaderGenerator.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24 */
25 
26 #include "eve-xmlpktgen.h"
27 
28 #include "HeaderGenerator.h"
29 
30 
32 : Generator( outputFile )
33 {
35 }
36 
37 bool ClassHeaderGenerator::RegisterName( const char* name, uint32 row )
38 {
39  if (mNamesUsed.find( name ) != mNamesUsed.end() )
40  {
41  std::cout << std::endl << "ClassHeaderGenerator::RegisterName: Field at line " << row << ": The name '" << name << "' is already used.";
42 
43  return false;
44  }
45 
46  mNamesUsed.insert( name );
47  return true;
48 }
49 
51 {
52  mNamesUsed.clear();
53 }
54 
56 {
58 
60 }
61 
62 bool ClassHeaderGenerator::ProcessElementDef( const TiXmlElement* field )
63 {
64  const char* name = field->Attribute("name");
65  if (name == nullptr) {
66  std::cout << std::endl << "ClassHeaderGenerator::ProcessElementDef: <element> at line " << field->Row() << " contains more than one root element, skipping.";
67  return false;
68  }
69 
70  const TiXmlElement* main = field->FirstChildElement();
71  if (main->NextSiblingElement() != nullptr) {
72  std::cout << std::endl << "ClassHeaderGenerator::ProcessElementDef: <element> at line " << field->Row() << " contains more than one root element, skipping.";
73  return false;
74  }
75 
76  const char* encode_type = GetEncodeType( main );
77  fprintf( mOutputFile,
78  "class %s\n"
79  "{\n"
80  "public:\n"
81  " %s();\n"
82  " %s(const %s& oth);\n"
83  " ~%s();\n"
84  "\n"
85  " void Dump(LogType type, const char* pfx = \" \") const;\n"
86  "\n"
87  " bool Decode(PyRep* packet);\n"
88  " bool Decode(PyRep** packet);\n"
89  " bool Decode(%s** packet);\n"
90  " %s* Encode() const;\n"
91  "\n"
92  " %s& operator=(const %s& oth);\n"
93  "\n",
94  name,
95 
96  name,
97  name, name,
98  name,
99 
100  encode_type,
101  encode_type,
102 
103  name, name
104  );
105 
106  if (!ParseElement( main ) )
107  return false;
108 
109  fprintf( mOutputFile,
110  "};\n"
111  "\n"
112  );
113 
114  ClearNames();
115 
116  return true;
117 }
118 
119 bool ClassHeaderGenerator::ProcessElement( const TiXmlElement* field )
120 {
121  const char* name = field->Attribute( "name" );
122  if (name == nullptr) {
123  std::cout << std::endl << "ClassHeaderGenerator::ProcessElement: field at line " << field->Row() << " is missing the name attribute, skipping.";
124  return false;
125  }
126  const char* type = field->Attribute( "type" );
127  if (type == nullptr) {
128  std::cout << std::endl << "ClassHeaderGenerator::ProcessElement: field at line " << field->Row() << " is missing the type attribute, skipping.";
129  return false;
130  }
131 
132  if (!RegisterName( name, field->Row() ))
133  return false;
134 
135  fprintf( mOutputFile,
136  " %s\t%s;\n",
137  type, name
138  );
139 
140  return true;
141 }
142 
143 bool ClassHeaderGenerator::ProcessElementPtr( const TiXmlElement* field )
144 {
145  const char* name = field->Attribute( "name" );
146  if (name == nullptr) {
147  std::cout << std::endl << "ClassHeaderGenerator::ProcessElementPtr: field at line " << field->Row() << " is missing the name attribute, skipping.";
148  return false;
149  }
150  const char* type = field->Attribute( "type" );
151  if (type == nullptr) {
152  std::cout << std::endl << "ClassHeaderGenerator::ProcessElementPtr: field at line " << field->Row() << " is missing the type attribute, skipping.";
153  return false;
154  }
155 
156  if (!RegisterName( name, field->Row()))
157  return false;
158 
159  fprintf( mOutputFile,
160  " %s*\t%s;\n",
161  type, name
162  );
163 
164  return true;
165 }
166 
167 bool ClassHeaderGenerator::ProcessRaw( const TiXmlElement* field )
168 {
169  const char* name = field->Attribute( "name" );
170  if (name == nullptr) {
171  std::cout << std::endl << "ClassHeaderGenerator::ProcessRaw: field at line " << field->Row() << " is missing the name attribute, skipping.";
172  return false;
173  }
174 
175  if (!RegisterName( name, field->Row()))
176  return false;
177 
178  fprintf( mOutputFile,
179  " PyRep*\t\t%s;\n",
180  name
181  );
182 
183  return true;
184 }
185 
186 bool ClassHeaderGenerator::ProcessInt( const TiXmlElement* field )
187 {
188  const char* name = field->Attribute( "name" );
189  if (name == nullptr) {
190  std::cout << std::endl << "ClassHeaderGenerator::ProcessInt: field at line " << field->Row() << " is missing the name attribute, skipping.";
191  return false;
192  }
193 
194  if (!RegisterName(name, field->Row()))
195  return false;
196 
197  fprintf( mOutputFile,
198  " int32\t\t%s;\n",
199  name
200  );
201 
202  return true;
203 }
204 
205 bool ClassHeaderGenerator::ProcessLong( const TiXmlElement* field )
206 {
207  const char* name = field->Attribute( "name" );
208  if (name == nullptr) {
209  std::cout << std::endl << "ClassHeaderGenerator::ProcessLong: field at line " << field->Row() << " is missing the name attribute, skipping.";
210  return false;
211  }
212 
213  if (!RegisterName(name, field->Row()))
214  return false;
215 
216  fprintf( mOutputFile,
217  " int64\t\t%s;\n",
218  name
219  );
220 
221  return true;
222 }
223 
224 bool ClassHeaderGenerator::ProcessReal( const TiXmlElement* field )
225 {
226  const char* name = field->Attribute( "name" );
227  if (name == nullptr) {
228  std::cout << std::endl << "ClassHeaderGenerator::ProcessReal: field at line " << field->Row() << " is missing the name attribute, skipping.";
229  return false;
230  }
231 
232  if (!RegisterName(name, field->Row()))
233  return false;
234 
235  fprintf( mOutputFile,
236  " double\t\t%s;\n",
237  name
238  );
239 
240  return true;
241 }
242 
243 bool ClassHeaderGenerator::ProcessBool( const TiXmlElement* field )
244 {
245  const char* name = field->Attribute( "name" );
246  if (name == nullptr) {
247  std::cout << std::endl << "ClassHeaderGenerator::ProcessBool: field at line " << field->Row() << " is missing the name attribute, skipping.";
248  return false;
249  }
250 
251  if (!RegisterName(name, field->Row()))
252  return false;
253 
254  fprintf( mOutputFile,
255  " bool\t\t%s;\n",
256  name
257  );
258 
259  return true;
260 }
261 
262 bool ClassHeaderGenerator::ProcessNone( const TiXmlElement* field )
263 {
264  return true;
265 }
266 
267 bool ClassHeaderGenerator::ProcessBuffer( const TiXmlElement* field )
268 {
269  const char* name = field->Attribute( "name" );
270  if (name == nullptr) {
271  std::cout << std::endl << "ClassHeaderGenerator::ProcessBuffer: field at line " << field->Row() << " is missing the name attribute, skipping.";
272  return false;
273  }
274 
275  if (!RegisterName(name, field->Row()))
276  return false;
277 
278  fprintf( mOutputFile,
279  " PyBuffer*\t%s;\n",
280  name
281  );
282 
283  return true;
284 }
285 
286 bool ClassHeaderGenerator::ProcessString( const TiXmlElement* field )
287 {
288  const char* name = field->Attribute( "name" );
289  if (name == nullptr) {
290  std::cout << std::endl << "ClassHeaderGenerator::ProcessString: field at line " << field->Row() << " is missing the name attribute, skipping.";
291  return false;
292  }
293 
294  if (!RegisterName(name, field->Row()))
295  return false;
296 
297  fprintf( mOutputFile,
298  " std::string\t\t%s;\n",
299  name
300  );
301 
302  return true;
303 }
304 
305 bool ClassHeaderGenerator::ProcessStringInline( const TiXmlElement* field )
306 {
307  return true;
308 }
309 
310 bool ClassHeaderGenerator::ProcessWString( const TiXmlElement* field )
311 {
312  const char* name = field->Attribute( "name" );
313  if (name == nullptr) {
314  std::cout << std::endl << "ClassHeaderGenerator::ProcessWString: field at line " << field->Row() << " is missing the name attribute, skipping.";
315  return false;
316  }
317 
318  if (!RegisterName(name, field->Row()))
319  return false;
320 
321  fprintf( mOutputFile,
322  " std::string\t\t%s;\n",
323  name
324  );
325 
326  return true;
327 }
328 
329 bool ClassHeaderGenerator::ProcessWStringInline( const TiXmlElement* field )
330 {
331  return true;
332 }
333 
334 bool ClassHeaderGenerator::ProcessToken( const TiXmlElement* field )
335 {
336  const char* name = field->Attribute( "name" );
337  if (name == nullptr) {
338  std::cout << std::endl << "ClassHeaderGenerator::ProcessToken: field at line " << field->Row() << " is missing the name attribute, skipping.";
339  return false;
340  }
341 
342  if (!RegisterName(name, field->Row()))
343  return false;
344 
345  fprintf( mOutputFile,
346  " PyToken*\t\t%s;\n",
347  name
348  );
349 
350  return true;
351 }
352 
353 bool ClassHeaderGenerator::ProcessTokenInline( const TiXmlElement* field )
354 {
355  return true;
356 }
357 
358 bool ClassHeaderGenerator::ProcessObject( const TiXmlElement* field )
359 {
360  const char* name = field->Attribute( "name" );
361  if (name == nullptr) {
362  std::cout << std::endl << "ClassHeaderGenerator::ProcessObject: field at line " << field->Row() << " is missing the name attribute, skipping.";
363  return false;
364  }
365 
366  fprintf( mOutputFile,
367  " PyObject*\t%s;\n",
368  name
369  );
370 
371  return true;
372 }
373 
374 bool ClassHeaderGenerator::ProcessObjectInline( const TiXmlElement* field )
375 {
376  return ParseElementChildren( field, 2 );
377 }
378 
379 bool ClassHeaderGenerator::ProcessObjectEx( const TiXmlElement* field )
380 {
381  const char* name = field->Attribute( "name" );
382  if (name == nullptr) {
383  std::cout << std::endl << "ClassHeaderGenerator::ProcessObjectEx: field at line " << field->Row() << " is missing the name attribute, skipping.";
384  return false;
385  }
386  const char* type = field->Attribute( "type" );
387  if (type == nullptr) {
388  std::cout << std::endl << "ClassHeaderGenerator::ProcessObjectEx: field at line " << field->Row() << " is missing the type attribute, skipping.";
389  return false;
390  }
391 
392  if (!RegisterName(name, field->Row()))
393  return false;
394 
395  fprintf( mOutputFile,
396  " %s*\t%s;\n",
397  type, name
398  );
399 
400  return true;
401 }
402 
403 bool ClassHeaderGenerator::ProcessTuple( const TiXmlElement* field )
404 {
405  const char* name = field->Attribute( "name" );
406  if (name == nullptr) {
407  std::cout << std::endl << "ClassHeaderGenerator::ProcessTuple: field at line " << field->Row() << " is missing the name attribute, skipping.";
408  return false;
409  }
410 
411  if (!RegisterName(name, field->Row()))
412  return false;
413 
414  fprintf( mOutputFile,
415  " PyTuple*\t\t%s;\n",
416  name
417  );
418 
419  return true;
420 }
421 
422 bool ClassHeaderGenerator::ProcessTupleInline( const TiXmlElement* field )
423 {
424  return ParseElementChildren( field );
425 }
426 
427 bool ClassHeaderGenerator::ProcessList( const TiXmlElement* field )
428 {
429  const char* name = field->Attribute( "name" );
430  if (name == nullptr) {
431  std::cout << std::endl << "ClassHeaderGenerator::ProcessList: field at line " << field->Row() << " is missing the name attribute, skipping.";
432  return false;
433  }
434 
435  if (!RegisterName(name, field->Row()))
436  return false;
437 
438  fprintf( mOutputFile,
439  " PyList*\t\t%s;\n",
440  name
441  );
442 
443  return true;
444 }
445 
446 bool ClassHeaderGenerator::ProcessListInline( const TiXmlElement* field )
447 {
448  return ParseElementChildren( field );
449 }
450 
451 bool ClassHeaderGenerator::ProcessListInt( const TiXmlElement* field )
452 {
453  const char* name = field->Attribute( "name" );
454  if (name == nullptr) {
455  std::cout << std::endl << "ClassHeaderGenerator::ProcessListInt: field at line " << field->Row() << " is missing the name attribute, skipping.";
456  return false;
457  }
458 
459  if (!RegisterName(name, field->Row()))
460  return false;
461 
462  fprintf( mOutputFile,
463  " std::vector<int32>\t%s;\n",
464  name
465  );
466 
467  return true;
468 }
469 
470 bool ClassHeaderGenerator::ProcessListLong( const TiXmlElement* field )
471 {
472  const char* name = field->Attribute( "name" );
473  if (name == nullptr) {
474  std::cout << std::endl << "ClassHeaderGenerator::ProcessListLong: field at line " << field->Row() << " is missing the name attribute, skipping.";
475  return false;
476  }
477 
478  if (!RegisterName(name, field->Row()))
479  return false;
480 
481  fprintf( mOutputFile,
482  " std::vector<int64>\t%s;\n",
483  name
484  );
485 
486  return true;
487 }
488 
489 bool ClassHeaderGenerator::ProcessListStr( const TiXmlElement* field )
490 {
491  const char* name = field->Attribute( "name" );
492  if (name == nullptr) {
493  std::cout << std::endl << "ClassHeaderGenerator::ProcessListStr: field at line " << field->Row() << " is missing the name attribute, skipping.";
494  return false;
495  }
496 
497  if (!RegisterName(name, field->Row()))
498  return false;
499 
500  fprintf( mOutputFile,
501  " std::vector<std::string>\t%s;\n",
502  name
503  );
504 
505  return true;
506 }
507 
508 bool ClassHeaderGenerator::ProcessDict( const TiXmlElement* field )
509 {
510  const char* name = field->Attribute( "name" );
511  if (name == nullptr) {
512  std::cout << std::endl << "ClassHeaderGenerator::ProcessDict: field at line " << field->Row() << " is missing the name attribute, skipping.";
513  return false;
514  }
515 
516  if (!RegisterName(name, field->Row()))
517  return false;
518 
519  fprintf( mOutputFile,
520  " PyDict*\t\t%s;\n",
521  name
522  );
523 
524  return true;
525 }
526 
527 bool ClassHeaderGenerator::ProcessDictInline( const TiXmlElement* field )
528 {
529  return ParseElementChildren( field );
530 }
531 
532 bool ClassHeaderGenerator::ProcessDictInlineEntry( const TiXmlElement* field )
533 {
534  //we dont really even care about this...
535  const char* key = field->Attribute( "key" );
536  if (!key) {
537  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictInlineEntry: field at line " << field->Row() << " is missing the key attribute, skipping.";
538  return false;
539  }
540 
541  return ParseElementChildren( field, 1 );
542 }
543 
544 bool ClassHeaderGenerator::ProcessDictRaw( const TiXmlElement* field )
545 {
546  const char* name = field->Attribute( "name" );
547  if (name == nullptr) {
548  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictRaw: field at line " << field->Row() << " is missing the name attribute, skipping.";
549  return false;
550  }
551 
552  const char* key = field->Attribute( "key" );
553  if (key == nullptr) {
554  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictRaw: field at line " << field->Row() << " is missing the key attribute, skipping.";
555  return false;
556  }
557  const char* pykey = field->Attribute( "pykey" );
558  if (pykey == nullptr) {
559  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictRaw: field at line " << field->Row() << " is missing the pykey attribute, skipping.";
560  return false;
561  }
562  const char* value = field->Attribute( "value" );
563  if (value == nullptr) {
564  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictRaw: field at line " << field->Row() << " is missing the value attribute, skipping.";
565  return false;
566  }
567  const char* pyvalue = field->Attribute( "pyvalue" );
568  if (pyvalue == nullptr) {
569  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictRaw: field at line " << field->Row() << " is missing the pyvalue attribute, skipping.";
570  return false;
571  }
572 
573  if (!RegisterName(name, field->Row()))
574  return false;
575 
576  fprintf( mOutputFile,
577  " std::map<%s, %s>\t%s;\n",
578  key, value, name
579  );
580 
581  return true;
582 }
583 
584 bool ClassHeaderGenerator::ProcessDictInt( const TiXmlElement* field )
585 {
586  const char* name = field->Attribute( "name" );
587  if (name == nullptr) {
588  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictInt: field at line " << field->Row() << " is missing the name attribute, skipping.";
589  return false;
590  }
591 
592  if (!RegisterName(name, field->Row()))
593  return false;
594 
595  fprintf( mOutputFile,
596  " std::map<int32, PyRep*>\t%s;\n",
597  name
598  );
599 
600  return true;
601 }
602 
603 bool ClassHeaderGenerator::ProcessDictStr( const TiXmlElement* field )
604 {
605  const char* name = field->Attribute( "name" );
606  if (name == nullptr) {
607  std::cout << std::endl << "ClassHeaderGenerator::ProcessDictStr: field at line " << field->Row() << " is missing the name attribute, skipping.";
608  return false;
609  }
610 
611  if (!RegisterName(name, field->Row()))
612  return false;
613 
614  fprintf( mOutputFile,
615  " std::map<std::string, PyRep*>\t%s;\n",
616  name
617  );
618 
619  return true;
620 }
621 
622 bool ClassHeaderGenerator::ProcessSubStreamInline( const TiXmlElement* field )
623 {
624  return ParseElementChildren( field, 1 );
625 }
626 
627 bool ClassHeaderGenerator::ProcessSubStructInline( const TiXmlElement* field )
628 {
629  return ParseElementChildren( field, 1 );
630 }
631 
bool ProcessObject(const TiXmlElement *field)
bool ProcessToken(const TiXmlElement *field)
bool ProcessString(const TiXmlElement *field)
bool ProcessDictRaw(const TiXmlElement *field)
bool ParseElement(const TiXmlElement *element) const
Parses element using registered parsers.
Definition: XMLParser.cpp:61
std::set< std::string > mNamesUsed
bool ProcessListStr(const TiXmlElement *field)
bool ProcessBuffer(const TiXmlElement *field)
void RegisterProcessors()
Definition: Generator.cpp:44
bool ProcessList(const TiXmlElement *field)
ClassHeaderGenerator(FILE *outputFile=NULL)
bool ProcessWStringInline(const TiXmlElement *field)
bool ProcessStringInline(const TiXmlElement *field)
bool ProcessWString(const TiXmlElement *field)
bool ProcessTokenInline(const TiXmlElement *field)
bool ProcessDict(const TiXmlElement *field)
bool ProcessListInline(const TiXmlElement *field)
bool ProcessReal(const TiXmlElement *field)
bool ProcessDictInlineEntry(const TiXmlElement *field)
bool ProcessNone(const TiXmlElement *field)
bool ProcessObjectInline(const TiXmlElement *field)
bool ProcessListLong(const TiXmlElement *field)
FILE * mOutputFile
Definition: Generator.h:108
bool ProcessDictInline(const TiXmlElement *field)
bool ProcessBool(const TiXmlElement *field)
bool ProcessElementPtr(const TiXmlElement *field)
bool ProcessInt(const TiXmlElement *field)
bool ProcessDictInt(const TiXmlElement *field)
unsigned __int32 uint32
Definition: eve-compat.h:50
static const char * GetEncodeType(const TiXmlElement *element)
Obtains encode type of given element.
Definition: Generator.cpp:86
bool ProcessTuple(const TiXmlElement *field)
bool ProcessRaw(const TiXmlElement *field)
bool ProcessDictStr(const TiXmlElement *field)
int main(int argc, char *argv[])
bool RegisterName(const char *name, uint32 row)
bool ProcessElementDef(const TiXmlElement *field)
Generic class for eve-xmlpktgen's generators.
Definition: Generator.h:37
bool ProcessSubStructInline(const TiXmlElement *field)
bool ParseElementChildren(const TiXmlElement *element, size_t max=0) const
Parses element's children using registered parsers.
Definition: XMLParser.cpp:72
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type() key(value)-Send an OnRemoteMessage" ) COMMAND( setbpattr
bool ProcessElement(const TiXmlElement *field)
bool ProcessListInt(const TiXmlElement *field)
bool ProcessLong(const TiXmlElement *field)
bool ProcessSubStreamInline(const TiXmlElement *field)
bool ProcessObjectEx(const TiXmlElement *field)
void AddMemberParser(const char *name, T &instance, bool(T::*method)(const TiXmlElement *))
Adds a member parser.
Definition: XMLParserEx.h:55
bool ProcessTupleInline(const TiXmlElement *field)