doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TypeInfoGen.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 #include "TypeInfoGen.h"
32 
33 #define TYPE_INFO_GEN_VERSION "1.0"
34 
35 /*
36 ================
37 idTypeInfoGen::idTypeInfoGen
38 ================
39 */
41 }
42 
43 /*
44 ================
45 idTypeInfoGen::~idTypeInfoGen
46 ================
47 */
49  constants.DeleteContents( true );
50  enums.DeleteContents( true );
51  classes.DeleteContents( true );
52 }
53 
54 /*
55 ================
56 idTypeInfoGen::GetInheritance
57 ================
58 */
59 int idTypeInfoGen::GetInheritance( const char *typeName ) const {
60  int i;
61 
62  for ( i = 0; i < classes.Num(); i++ ) {
63  if ( classes[i]->typeName.Cmp( typeName ) == 0 ) {
64  if ( classes[i]->superType[0] != '\0' ) {
65  return 1 + GetInheritance( classes[i]->superType );
66  }
67  break;
68  }
69  }
70  return 0;
71 }
72 
73 /*
74 ================
75 idTypeInfoGen::EvaluateIntegerString
76 ================
77 */
79  idParser src;
80  idStr evalString;
81 
82  if ( string.Find( "::" ) != -1 ) {
83  return 0;
84  }
85  evalString = "$evalint(" + string + ")";
86  src.LoadMemory( evalString, evalString.Length(), "eval integer" );
87  return src.ParseInt();
88 }
89 
90 /*
91 ================
92 idTypeInfoGen::EvaluateFloatString
93 ================
94 */
95 float idTypeInfoGen::EvaluateFloatString( const idStr &string ) {
96  idParser src;
97  idStr evalString;
98 
99  if ( string.Find( "::" ) != -1 ) {
100  return 0.0f;
101  }
102  evalString = "$evalfloat(" + string + ")";
103  src.LoadMemory( evalString, evalString.Length(), "eval float" );
104  return src.ParseFloat();
105 }
106 
107 /*
108 ================
109 idTypeInfoGen::FindConstant
110 ================
111 */
113  int i;
114 
115  for ( i = 0; i < constants.Num(); i++ ) {
116  if ( constants[i]->name.Cmp( name ) == 0 ) {
117  return constants[i];
118  }
119  }
120  return NULL;
121 }
122 
123 /*
124 ================
125 idTypeInfoGen::GetIntegerConstant
126 ================
127 */
128 int idTypeInfoGen::GetIntegerConstant( const char *scope, const char *name, idParser &src ) {
129  idConstantInfo *constant = FindConstant( idStr( scope ) + name );
130  if ( constant == NULL ) {
131  constant = FindConstant( name );
132  }
133  if ( constant ) {
134  return EvaluateIntegerString( constant->value );
135  }
136  src.Warning( "unknown value '%s' in constant expression", name );
137  return 0;
138 }
139 
140 /*
141 ================
142 idTypeInfoGen::GetFloatConstant
143 ================
144 */
145 float idTypeInfoGen::GetFloatConstant( const char *scope, const char *name, idParser &src ) {
146  idConstantInfo *constant = FindConstant( idStr( scope ) + name );
147  if ( constant == NULL ) {
148  constant = FindConstant( name );
149  }
150  if ( constant ) {
151  return EvaluateFloatString( constant->value );
152  }
153  src.Warning( "unknown value '%s' in constant expression", name );
154  return 0;
155 }
156 
157 /*
158 ================
159 idTypeInfoGen::ParseArraySize
160 ================
161 */
162 int idTypeInfoGen::ParseArraySize( const char *scope, idParser &src ) {
163  idToken token;
164  idStr sizeString, constantString;
165  int size, totalSize;
166 
167  if ( !src.CheckTokenString( "[" ) ) {
168  return 0;
169  }
170 
171  totalSize = 1;
172  sizeString = "";
173  while( src.ReadToken( &token ) ) {
174  if ( token == "]" ) {
175  if ( sizeString.Length() ) {
176  size = EvaluateIntegerString( sizeString );
177  if ( size ) {
178  totalSize *= size;
179  }
180  sizeString = "";
181  }
182  if ( !src.CheckTokenString( "[" ) ) {
183  break;
184  }
185  } else if ( token.type == TT_NAME ) {
186  constantString = token;
187  while( src.CheckTokenString( "::" ) ) {
188  src.ExpectTokenType( TT_NAME, 0, &token );
189  constantString += "::" + token;
190  }
191  sizeString += va( "%d", GetIntegerConstant( scope, constantString, src ) );
192  } else {
193  sizeString += token;
194  }
195  }
196 
197  return totalSize;
198 }
199 
200 /*
201 ================
202 idTypeInfoGen::ParseConstantValue
203 ================
204 */
206  idToken token;
207  idStr constantString;
208 
209  int indent = 0;
210  while( src.ReadToken( &token ) ) {
211  if ( token == "(" ) {
212  indent++;
213  } else if ( token == ")" ) {
214  indent--;
215  } else if ( indent == 0 && ( token == ";" || token == "," || token == "}" ) ) {
216  src.UnreadToken( &token );
217  break;
218  } else if ( token.type == TT_NAME ) {
219  constantString = token;
220  while( src.CheckTokenString( "::" ) ) {
221  src.ExpectTokenType( TT_NAME, 0, &token );
222  constantString += "::" + token;
223  }
224  value += va( "%d", GetIntegerConstant( scope, constantString, src ) );
225  continue;
226  }
227  value += token;
228  }
229 }
230 
231 /*
232 ================
233 idTypeInfoGen::ParseEnumType
234 ================
235 */
236 idEnumTypeInfo *idTypeInfoGen::ParseEnumType( const char *scope, bool isTemplate, bool typeDef, idParser &src ) {
237  int value;
238  idToken token;
239  idEnumTypeInfo *typeInfo;
240  idEnumValueInfo enumValue;
241  idStr valueString;
242 
243  typeInfo = new idEnumTypeInfo;
244  typeInfo->scope = scope;
245  typeInfo->isTemplate = isTemplate;
246 
247  if ( src.CheckTokenType( TT_NAME, 0, &token ) ) {
248  typeInfo->typeName = token;
249  typeInfo->unnamed = false;
250  } else {
251  sprintf( typeInfo->typeName, "enum_%d", enums.Num() );
252  typeInfo->unnamed = true;
253  }
254 
255  if ( !src.CheckTokenString( "{" ) ) {
256  src.UnreadToken( &token );
257  delete typeInfo;
258  return NULL;
259  }
260 
261  value = -1;
262  while( src.ExpectTokenType( TT_NAME, 0, &token ) ) {
263 
264  enumValue.name = token;
265 
266  if ( src.CheckTokenString( "=" ) ) {
267  idStr valueString;
268  ParseConstantValue( scope, src, valueString );
269  if ( valueString.Length() ) {
270  value = EvaluateIntegerString( valueString );
271  }
272  } else {
273  value++;
274  }
275 
276  enumValue.value = value;
277  typeInfo->values.Append( enumValue );
278 
279  // add a constant for the enum value
280  idConstantInfo *constantInfo = new idConstantInfo;
281  constantInfo->name = scope + enumValue.name;
282  constantInfo->type = "int";
283  constantInfo->value = va( "%d", value );
284  constants.Append( constantInfo );
285 
286  src.CheckTokenString( "," );
287 
288  if ( src.CheckTokenString( "}" ) ) {
289  break;
290  }
291  }
292 
293  if ( typeDef ) {
294  if ( src.CheckTokenType( TT_NAME, 0, &token ) ) {
295  typeInfo->typeName = token;
296  typeInfo->unnamed = false;
297  }
298  src.ExpectTokenString( ";" );
299  }
300 
301  //common->Printf( "enum %s%s\n", typeInfo->scope.c_str(), typeInfo->typeName.c_str() );
302 
303  return typeInfo;
304 }
305 
306 /*
307 ================
308 idTypeInfoGen::ParseClassType
309 ================
310 */
311 idClassTypeInfo *idTypeInfoGen::ParseClassType( const char *scope, const char *templateArgs, bool isTemplate, bool typeDef, idParser &src ) {
312  idToken token;
313  idClassTypeInfo *typeInfo;
314 
315  typeInfo = new idClassTypeInfo;
316  typeInfo->scope = scope;
317  typeInfo->isTemplate = isTemplate;
318 
319  if ( src.CheckTokenType( TT_NAME, 0, &token ) ) {
320  typeInfo->typeName = token + templateArgs;
321  typeInfo->unnamed = false;
322  } else {
323  sprintf( typeInfo->typeName, "class_%d%s", classes.Num(), templateArgs );
324  typeInfo->unnamed = true;
325  }
326 
327  if ( src.CheckTokenString( ":" ) ) {
328  if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
329  delete typeInfo;
330  return NULL;
331  }
332  while( token == "public" ||
333  token == "protected" ||
334  token == "private" ) {
335 
336  if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
337  delete typeInfo;
338  return NULL;
339  }
340 
341  typeInfo->superType = token;
342 
343  // read template arguments
344  if ( src.CheckTokenString( "<" ) ) {
345 
346  int indent = 1;
347  typeInfo->superType += "< ";
348  while( src.ReadToken( &token ) ) {
349  if ( token == "<" ) {
350  indent++;
351  } else if ( token == ">" ) {
352  indent--;
353  if ( indent == 0 ) {
354  break;
355  }
356  }
357  typeInfo->superType += token + " ";
358  }
359  typeInfo->superType += ">";
360  }
361 
362  // check for multiple inheritance
363  if ( !src.CheckTokenString( "," ) ) {
364  break;
365  }
366 
367  if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
368  delete typeInfo;
369  return NULL;
370  }
371 
372  src.Warning( "multiple inheritance not supported for '%s%s'", typeInfo->scope.c_str(), typeInfo->typeName.c_str() );
373  }
374  }
375 
376  if ( !src.CheckTokenString( "{" ) ) {
377  src.UnreadToken( &token );
378  delete typeInfo;
379  return NULL;
380  }
381 
382  ParseScope( typeInfo->scope + typeInfo->typeName + "::", typeInfo->isTemplate, src, typeInfo );
383 
384  if ( typeDef ) {
385  if ( src.CheckTokenType( TT_NAME, 0, &token ) ) {
386  typeInfo->typeName = token + templateArgs;
387  typeInfo->unnamed = false;
388  }
389  src.ExpectTokenString( ";" );
390  }
391 
392  //common->Printf( "class %s%s : %s\n", typeInfo->scope.c_str(), typeInfo->typeName.c_str(), typeInfo->superType.c_str() );
393 
394  return typeInfo;
395 }
396 
397 /*
398 ================
399 idTypeInfoGen::ParseScope
400 ================
401 */
402 void idTypeInfoGen::ParseScope( const char *scope, bool isTemplate, idParser &src, idClassTypeInfo *typeInfo ) {
403  int indent;
404  idToken token;
405  idClassTypeInfo *classInfo;
406  idEnumTypeInfo *enumInfo;
407  idStr varType;
408  bool isConst = false;
409  bool isStatic = false;
410 
411  indent = 1;
412  while( indent ) {
413  if ( !src.ReadToken( &token ) ) {
414  break;
415  }
416 
417  if ( token == "{" ) {
418 
419  do {
420  if ( token == "{" ) {
421  indent++;
422  } else if ( token == "}" ) {
423  indent--;
424  }
425  varType += token + " ";
426  } while( indent > 1 && src.ReadToken( &token ) );
427 
428  } else if ( token == "}" ) {
429 
430  assert( indent == 1 );
431  indent--;
432 
433  } else if ( token == "<" ) {
434 
435  do {
436  if ( token == "<" ) {
437  indent++;
438  } else if ( token == ">" ) {
439  indent--;
440  }
441  varType += token + " ";
442  } while( indent > 1 && src.ReadToken( &token ) );
443 
444  } else if ( token == ";" ) {
445 
446  varType = "";
447  isConst = false;
448  isStatic = false;
449 
450  } else if ( token == "public" || token == "protected" || token == "private" ) {
451 
452  if ( !src.ExpectTokenString( ":" ) ) {
453  break;
454  }
455  varType = "";
456  isConst = false;
457  isStatic = false;
458 
459  } else if ( token == "friend" ) {
460 
461  // skip friend classes/methods
462  while( src.ReadToken( &token ) ) {
463  if ( token == "{" ) {
464  indent++;
465  } else if ( token == "}" ) {
466  indent--;
467  if ( indent == 1 ) {
468  break;
469  }
470  } else if ( token == ";" && indent == 1 ) {
471  break;
472  }
473  }
474 
475  varType = "";
476  isConst = false;
477  isStatic = false;
478 
479  } else if ( token == "template" ) {
480 
481  varType = "";
482 
483  if ( src.CheckTokenString( "<" ) ) {
484 
485  int indent = 1;
486  varType += "< ";
487  while( src.ReadToken( &token ) ) {
488  if ( token == "<" ) {
489  indent++;
490  } else if ( token == ">" ) {
491  indent--;
492  if ( indent == 0 ) {
493  break;
494  }
495  }
496  varType += token + " ";
497  }
498  varType += ">";
499  }
500 
501  if ( src.CheckTokenString( "class" ) ) {
502 
503  // parse template class
504  classInfo = ParseClassType( scope, varType, true, false, src );
505  if ( classInfo ) {
506  classes.Append( classInfo );
507  }
508 
509  } else {
510 
511  // skip template methods
512  while( src.ReadToken( &token ) ) {
513  if ( token == "{" ) {
514  indent++;
515  } else if ( token == "}" ) {
516  indent--;
517  if ( indent == 1 ) {
518  break;
519  }
520  } else if ( token == ";" && indent == 1 ) {
521  break;
522  }
523  }
524  }
525 
526  varType = "";
527  isConst = false;
528  isStatic = false;
529 
530  } else if ( token == "namespace" ) {
531 
532  // parse namespace
533  classInfo = ParseClassType( scope, "", isTemplate, false, src );
534  delete classInfo;
535 
536  } else if ( token == "class" ) {
537 
538  // parse class
539  classInfo = ParseClassType( scope, "", isTemplate, false, src );
540  if ( classInfo ) {
541  classes.Append( classInfo );
542  }
543 
544  } else if ( token == "struct" ) {
545 
546  // parse struct
547  classInfo = ParseClassType( scope, "", isTemplate, false, src );
548  if ( classInfo ) {
549  classes.Append( classInfo );
550  varType = classInfo->scope + classInfo->typeName;
551  }
552 
553  } else if ( token == "union" ) {
554 
555  // parse union
556  classInfo = ParseClassType( scope, "", isTemplate, false, src );
557  if ( classInfo ) {
558  classes.Append( classInfo );
559  }
560 
561  } else if ( token == "enum" ) {
562 
563  // parse enum
564  enumInfo = ParseEnumType( scope, isTemplate, false, src );
565  if ( enumInfo ) {
566  enums.Append( enumInfo );
567  varType = enumInfo->scope + enumInfo->typeName;
568  }
569 
570  } else if ( token == "typedef" ) {
571 
572  if ( token == "class" ) {
573 
574  // parse typedef class
575  classInfo = ParseClassType( scope, "", isTemplate, true, src );
576  if ( classInfo ) {
577  classes.Append( classInfo );
578  }
579 
580  } else if ( src.CheckTokenString( "struct" ) ) {
581 
582  // parse typedef struct
583  classInfo = ParseClassType( scope, "", isTemplate, true, src );
584  if ( classInfo ) {
585  classes.Append( classInfo );
586  }
587 
588  } else if ( src.CheckTokenString( "union" ) ) {
589 
590  // parse typedef union
591  classInfo = ParseClassType( scope, "", isTemplate, true, src );
592  if ( classInfo ) {
593  classes.Append( classInfo );
594  }
595 
596  } else if ( src.CheckTokenString( "enum" ) ) {
597 
598  // parse typedef enum
599  enumInfo = ParseEnumType( scope, isTemplate, true, src );
600  if ( enumInfo ) {
601  enums.Append( enumInfo );
602  }
603 
604  } else {
605 
606  // skip other typedefs
607  while( src.ReadToken( &token ) ) {
608  if ( token == "{" ) {
609  indent++;
610  } else if ( token == "}" ) {
611  indent--;
612  } else if ( token == ";" && indent == 1 ) {
613  break;
614  }
615  }
616  }
617 
618  varType = "";
619  isConst = false;
620  isStatic = false;
621 
622  } else if ( token == "const" ) {
623 
624  varType += token + " ";
625  isConst = true;
626 
627  } else if ( token == "static" ) {
628 
629  varType += token + " ";
630  isStatic = true;
631 
632  } else if ( token.type == TT_NAME ) {
633 
634  assert( indent == 1 );
635 
636  // if this is a class operator
637  if ( token == "operator" ) {
638  while( src.ReadToken( &token ) ) {
639  if ( token == "(" ) {
640  src.UnreadToken( &token );
641  break;
642  }
643  }
644  }
645 
646  // if this is a class method
647  if ( src.CheckTokenString( "(" ) ) {
648 
649  indent++;
650  while( indent > 1 && src.ReadToken( &token ) ) {
651  if ( token == "(" ) {
652  indent++;
653  } else if ( token == ")" ) {
654  indent--;
655  }
656  }
657 
658  if ( src.CheckTokenString( "(" ) ) {
659  indent++;
660  while( indent > 1 && src.ReadToken( &token ) ) {
661  if ( token == "(" ) {
662  indent++;
663  } else if ( token == ")" ) {
664  indent--;
665  }
666  }
667  }
668 
669  if ( src.CheckTokenString( "const" ) ) {
670  }
671 
672  if ( src.CheckTokenString( "=" ) ) {
673 
674  src.ExpectTokenString( "0" );
675 
676  } else if ( src.CheckTokenString( "{" ) ) {
677  indent++;
678  while( indent > 1 && src.ReadToken( &token ) ) {
679  if ( token == "{" ) {
680  indent++;
681  } else if ( token == "}" ) {
682  indent--;
683  }
684  }
685  }
686 
687  varType = "";
688  isConst = false;
689  isStatic = false;
690 
691  } else if ( ( isStatic || isConst ) && src.CheckTokenString( "=" ) ) {
692 
693  // constant
694  idConstantInfo *constantInfo = new idConstantInfo;
695  constantInfo->name = scope + token;
696  constantInfo->type = varType;
697  constantInfo->type.StripTrailing( ' ' );
698  ParseConstantValue( scope, src, constantInfo->value );
699  constants.Append( constantInfo );
700 
701  } else if ( isStatic ) {
702 
703  // static class variable
704  varType += token + " ";
705 
706  } else {
707 
708  // check for class variables
709  while( 1 ) {
710 
711  int arraySize = ParseArraySize( scope, src );
712 
713  if ( arraySize ) {
715 
716  var.name = token;
717  var.type = varType;
718  var.type.StripTrailing( ' ' );
719  var.type += va( "[%d]", arraySize );
720  var.bits = 0;
721  typeInfo->variables.Append( var );
722  if ( !src.CheckTokenString( "," ) ) {
723  varType = "";
724  isConst = false;
725  isStatic = false;
726  break;
727  }
728  varType.StripTrailing( "* " );
729 
730  } else {
731 
732  int bits = 0;
733 
734  if ( src.CheckTokenString( ":" ) ) {
735  idToken bitSize;
736  src.ExpectTokenType( TT_NUMBER, TT_INTEGER, &bitSize );
737  bits = bitSize.GetIntValue();
738  }
739 
740  if ( src.CheckTokenString( "," ) ) {
742 
743  var.name = token;
744  var.type = varType;
745  var.type.StripTrailing( ' ' );
746  var.bits = bits;
747  typeInfo->variables.Append( var );
748  varType.StripTrailing( "* " );
749 
750  } else if ( src.CheckTokenString( ";" ) ) {
752 
753  var.name = token;
754  var.type = varType;
755  var.type.StripTrailing( ' ' );
756  var.bits = bits;
757  typeInfo->variables.Append( var );
758  varType = "";
759  isConst = false;
760  isStatic = false;
761  break;
762 
763  } else {
764 
765  varType += token + " ";
766  break;
767  }
768  }
769 
770  while( src.CheckTokenString( "*" ) ) {
771  varType += "* ";
772  }
773 
774  if ( !src.ExpectTokenType( TT_NAME, 0, &token ) ) {
775  break;
776  }
777  }
778  }
779  } else {
780  varType += token + " ";
781  }
782  }
783 }
784 
785 /*
786 ================
787 idTypeInfoGen::AddDefine
788 ================
789 */
790 void idTypeInfoGen::AddDefine( const char *define ) {
791  defines.Append( define );
792 }
793 
794 /*
795 ================
796 idTypeInfoGen::CreateTypeInfo
797 ================
798 */
799 void idTypeInfoGen::CreateTypeInfo( const char *path ) {
800  int i, j, inheritance;
801  idStr fileName;
802  idFileList *files;
803  idParser src;
804 
805  common->Printf( "Type Info Generator v"TYPE_INFO_GEN_VERSION" (c) 2004 id Software\n" );
806  common->Printf( "%s\n", path );
807 
808  files = fileSystem->ListFilesTree( path, ".cpp" );
809 
810  for ( i = 0; i < files->GetNumFiles(); i++ ) {
811 
812  fileName = fileSystem->RelativePathToOSPath( files->GetFile( i ) );
813 
814  common->Printf( "processing '%s' for type info...\n", fileName.c_str() );
815 
816  if ( !src.LoadFile( fileName, true ) ) {
817  common->Warning( "couldn't load %s", fileName.c_str() );
818  continue;
819  }
820 
822 
823  for ( j = 0; j < defines.Num(); j++ ) {
824  src.AddDefine( defines[j] );
825  }
826 
827  idClassTypeInfo *typeInfo = new idClassTypeInfo;
828  ParseScope( "", false, src, typeInfo );
829  delete typeInfo;
830 
831  src.FreeSource();
832 
833  break;
834  }
835 
836  fileSystem->FreeFileList( files );
837 
838  numTemplates = 0;
839  for ( i = 0; i < classes.Num(); i++ ) {
840  if ( classes[i]->isTemplate ) {
841  numTemplates++;
842  }
843  }
844 
845  maxInheritance = 0;
846  maxInheritanceClass = "";
847  for ( i = 0; i < classes.Num(); i++ ) {
848  inheritance = GetInheritance( classes[i]->typeName );
849  if ( inheritance > maxInheritance ) {
850  maxInheritance = inheritance;
851  maxInheritanceClass = classes[i]->typeName;
852  }
853  }
854 
855  common->Printf( "%d constants\n", constants.Num() );
856  common->Printf( "%d enums\n", enums.Num() );
857  common->Printf( "%d classes/structs/unions\n", classes.Num() );
858  common->Printf( "%d templates\n", numTemplates );
859  common->Printf( "%d max inheritance level for '%s'\n", maxInheritance, maxInheritanceClass.c_str() );
860 }
861 
862 /*
863 ================
864 CleanName
865 ================
866 */
867 void CleanName( idStr &name ) {
868  name.Replace( "::", "_" );
869  name.Replace( " , ", "_" );
870  name.Replace( "< ", "_" );
871  name.Replace( " >", "_" );
872  name.Replace( " ", "_" );
873 }
874 
875 /*
876 ================
877 idTypeInfoGen::WriteTypeInfo
878 ================
879 */
880 void idTypeInfoGen::WriteTypeInfo( const char *fileName ) const {
881  int i, j;
882  idStr path, define;
883  idFile *file;
884 
885  path = fileSystem->RelativePathToOSPath( fileName );
886 
887  file = fileSystem->OpenExplicitFileWrite( path );
888  if ( !file ) {
889  common->Warning( "couldn't open %s", path.c_str() );
890  return;
891  }
892 
893  common->Printf( "writing %s...\n", path.c_str() );
894 
895  path.ExtractFileName( define );
896  define.Replace( ".", "_" );
897  define.ToUpper();
898 
899  file->WriteFloatString(
900  "\n"
901  "#ifndef __%s__\n"
902  "#define __%s__\n"
903  "\n"
904  "/*\n"
905  "===================================================================================\n"
906  "\n"
907  "\tThis file has been generated with the Type Info Generator v"TYPE_INFO_GEN_VERSION" (c) 2004 id Software\n"
908  "\n"
909  "\t%d constants\n"
910  "\t%d enums\n"
911  "\t%d classes/structs/unions\n"
912  "\t%d templates\n"
913  "\t%d max inheritance level for '%s'\n"
914  "\n"
915  "===================================================================================\n"
916  "*/\n"
917  "\n", define.c_str(), define.c_str(), constants.Num(), enums.Num(), classes.Num(),
919 
920  file->WriteFloatString(
921  "typedef struct {\n"
922  "\t" "const char * name;\n"
923  "\t" "const char * type;\n"
924  "\t" "const char * value;\n"
925  "} constantInfo_t;\n"
926  "\n"
927  "typedef struct {\n"
928  "\t" "const char * name;\n"
929  "\t" "int value;\n"
930  "} enumValueInfo_t;\n"
931  "\n"
932  "typedef struct {\n"
933  "\t" "const char * typeName;\n"
934  "\t" "const enumValueInfo_t * values;\n"
935  "} enumTypeInfo_t;\n"
936  "\n"
937  "typedef struct {\n"
938  "\t" "const char * type;\n"
939  "\t" "const char * name;\n"
940  "\t" "int offset;\n"
941  "\t" "int size;\n"
942  "} classVariableInfo_t;\n"
943  "\n"
944  "typedef struct {\n"
945  "\t" "const char * typeName;\n"
946  "\t" "const char * superType;\n"
947  "\t" "int size;\n"
948  "\t" "const classVariableInfo_t * variables;\n"
949  "} classTypeInfo_t;\n"
950  "\n" );
951 
952  // constants
953  file->WriteFloatString( "static constantInfo_t constantInfo[] = {\n" );
954 
955  for ( i = 0; i < constants.Num(); i++ ) {
956  idConstantInfo *info = constants[i];
957  file->WriteFloatString( "\t{ \"%s\", \"%s\", \"%s\" },\n", info->type.c_str(), info->name.c_str(), info->value.c_str() );
958  }
959 
960  file->WriteFloatString( "\t{ NULL, NULL, NULL }\n" );
961  file->WriteFloatString( "};\n\n" );
962 
963  // enum values
964  for ( i = 0; i < enums.Num(); i++ ) {
965  idEnumTypeInfo *info = enums[i];
966 
967  idStr typeInfoName = info->scope + info->typeName;
968  CleanName( typeInfoName );
969 
970  file->WriteFloatString( "static enumValueInfo_t %s_typeInfo[] = {\n", typeInfoName.c_str() );
971 
972  for ( j = 0; j < info->values.Num(); j++ ) {
973  if ( info->isTemplate ) {
974  file->WriteFloatString( "//" );
975  }
976  file->WriteFloatString( "\t{ \"%s\", %d },\n", info->values[j].name.c_str(), info->values[j].value );
977  }
978 
979  file->WriteFloatString( "\t{ NULL, 0 }\n" );
980  file->WriteFloatString( "};\n\n" );
981  }
982 
983  // enums
984  file->WriteFloatString( "static enumTypeInfo_t enumTypeInfo[] = {\n" );
985 
986  for ( i = 0; i < enums.Num(); i++ ) {
987  idEnumTypeInfo *info = enums[i];
988 
989  idStr typeName = info->scope + info->typeName;
990  idStr typeInfoName = typeName;
991  CleanName( typeInfoName );
992 
993  if ( info->isTemplate ) {
994  file->WriteFloatString( "//" );
995  }
996  file->WriteFloatString( "\t{ \"%s\", %s_typeInfo },\n", typeName.c_str(), typeInfoName.c_str() );
997  }
998 
999  file->WriteFloatString( "\t{ NULL, NULL }\n" );
1000  file->WriteFloatString( "};\n\n" );
1001 
1002  // class variables
1003  for ( i = 0; i < classes.Num(); i++ ) {
1004  idClassTypeInfo *info = classes[i];
1005 
1006  idStr typeName = info->scope + info->typeName;
1007  idStr typeInfoName = typeName;
1008  CleanName( typeInfoName );
1009 
1010  file->WriteFloatString( "static classVariableInfo_t %s_typeInfo[] = {\n", typeInfoName.c_str() );
1011 
1012  for ( j = 0; j < info->variables.Num(); j++ ) {
1013  const char *varName = info->variables[j].name.c_str();
1014  const char *varType = info->variables[j].type.c_str();
1015 
1016  if ( info->unnamed || info->isTemplate || info->variables[j].bits != 0 ) {
1017  file->WriteFloatString( "//" );
1018  }
1019  file->WriteFloatString( "\t{ \"%s\", \"%s\", (int)(&((%s *)0)->%s), sizeof( ((%s *)0)->%s ) },\n",
1020  varType, varName, typeName.c_str(), varName, typeName.c_str(), varName );
1021  }
1022 
1023  file->WriteFloatString( "\t{ NULL, 0 }\n" );
1024  file->WriteFloatString( "};\n\n" );
1025  }
1026 
1027  // classes
1028  file->WriteFloatString( "static classTypeInfo_t classTypeInfo[] = {\n" );
1029 
1030  for ( i = 0; i < classes.Num(); i++ ) {
1031  idClassTypeInfo *info = classes[i];
1032 
1033  idStr typeName = info->scope + info->typeName;
1034  idStr typeInfoName = typeName;
1035  CleanName( typeInfoName );
1036 
1037  if ( info->unnamed || info->isTemplate ) {
1038  file->WriteFloatString( "//" );
1039  }
1040  file->WriteFloatString( "\t{ \"%s\", \"%s\", sizeof(%s), %s_typeInfo },\n",
1041  typeName.c_str(), info->superType.c_str(), typeName.c_str(), typeInfoName.c_str() );
1042  }
1043 
1044  file->WriteFloatString( "\t{ NULL, NULL, 0, NULL }\n" );
1045  file->WriteFloatString( "};\n\n" );
1046 
1047  file->WriteFloatString( "#endif /* !__%s__ */\n", define.c_str() );
1048 
1049  fileSystem->CloseFile( file );
1050 }
idList< idEnumValueInfo > values
Definition: TypeInfoGen.h:63
int type
Definition: Token.h:77
GLsizei const GLfloat * value
Definition: glext.h:3614
int AddDefine(const char *string)
Definition: Parser.cpp:1177
assert(prefInfo.fullscreenBtn)
void UnreadToken(idToken *token)
Definition: Parser.cpp:2745
idEnumTypeInfo * ParseEnumType(const char *scope, bool isTemplate, bool typeDef, idParser &src)
idList< idClassTypeInfo * > classes
Definition: TypeInfoGen.h:97
void ParseScope(const char *scope, bool isTemplate, idParser &src, idClassTypeInfo *typeInfo)
idConstantInfo * FindConstant(const char *name)
void ToUpper(void)
Definition: Str.h:825
#define TT_NAME
Definition: Token.h:44
int Length(void) const
Definition: Str.h:702
int GetNumFiles(void) const
Definition: FileSystem.h:126
#define TT_INTEGER
Definition: Token.h:48
void WriteTypeInfo(const char *fileName) const
void StripTrailing(const char c)
Definition: Str.cpp:515
#define TYPE_INFO_GEN_VERSION
Definition: TypeInfoGen.cpp:33
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
int LoadMemory(const char *ptr, int length, const char *name)
Definition: Parser.cpp:3049
void FreeSource(bool keepDefines=false)
Definition: Parser.cpp:3084
int EvaluateIntegerString(const idStr &string)
Definition: TypeInfoGen.cpp:78
int ExpectTokenString(const char *string)
Definition: Parser.cpp:2402
Definition: Token.h:71
GLuint src
Definition: glext.h:5390
int i
Definition: process.py:33
idStr maxInheritanceClass
Definition: TypeInfoGen.h:101
idClassTypeInfo * ParseClassType(const char *scope, const char *templateArgs, bool isTemplate, bool typeDef, idParser &src)
float EvaluateFloatString(const idStr &string)
Definition: TypeInfoGen.cpp:95
#define TT_NUMBER
Definition: Token.h:43
Definition: File.h:50
int ReadToken(idToken *token)
Definition: Parser.cpp:2338
idList< idConstantInfo * > constants
Definition: TypeInfoGen.h:95
void ExtractFileName(idStr &dest) const
Definition: Str.cpp:921
int ParseInt(void)
Definition: Parser.cpp:2775
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
idTypeInfoGen(void)
Definition: TypeInfoGen.cpp:40
const char * GetFile(int index) const
Definition: FileSystem.h:127
void void Warning(const char *str,...) const id_attribute((format(printf
Definition: Parser.cpp:335
const char * path
Definition: sws.c:117
float ParseFloat(void)
Definition: Parser.cpp:2812
void DeleteContents(bool clear)
Definition: List.h:207
void SetFlags(int flags)
Definition: Parser.cpp:2990
virtual int WriteFloatString(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:294
void AddDefine(const char *define)
virtual void FreeFileList(idFileList *fileList)=0
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idStrList defines
Definition: TypeInfoGen.h:93
int ParseArraySize(const char *scope, idParser &src)
virtual const char * RelativePathToOSPath(const char *relativePath, const char *basePath="fs_devpath")=0
int Append(const type &obj)
Definition: List.h:646
#define bits
Definition: Unzip.cpp:3797
virtual idFile * OpenExplicitFileWrite(const char *OSPath)=0
void ParseConstantValue(const char *scope, idParser &src, idStr &value)
int GetInheritance(const char *typeName) const
Definition: TypeInfoGen.cpp:59
virtual idFileList * ListFilesTree(const char *relativePath, const char *extension, bool sort=false, const char *gamedir=NULL)=0
int Num(void) const
Definition: List.h:265
int LoadFile(const char *filename, bool OSPath=false)
Definition: Parser.cpp:3013
const GLcharARB * name
Definition: glext.h:3629
~idTypeInfoGen(void)
Definition: TypeInfoGen.cpp:48
GLsizeiptr size
Definition: glext.h:3112
int CheckTokenString(const char *string)
Definition: Parser.cpp:2491
Definition: Str.h:116
idList< idClassVariableInfo > variables
Definition: TypeInfoGen.h:80
int GetIntValue(void)
Definition: Token.h:152
const char * c_str(void) const
Definition: Str.h:487
void CleanName(idStr &name)
GLint j
Definition: qgl.h:264
idList< idEnumTypeInfo * > enums
Definition: TypeInfoGen.h:96
char * va(const char *fmt,...)
Definition: Str.cpp:1568
void CreateTypeInfo(const char *path)
virtual void CloseFile(idFile *f)=0
float GetFloatConstant(const char *scope, const char *name, idParser &src)
void Replace(const char *old, const char *nw)
Definition: Str.cpp:563
int GetIntegerConstant(const char *scope, const char *name, idParser &src)
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
int CheckTokenType(int type, int subtype, idToken *token)
Definition: Parser.cpp:2511
int ExpectTokenType(int type, int subtype, idToken *token)
Definition: Parser.cpp:2422