예제 #1
0
static bool dumpEngineDocs( const char *outputFile )
{
   // Create the output stream.
   FileStream stream;
   if ( !stream.open( outputFile, Torque::FS::File::Write ) )
   {
      Con::errorf( "dumpEngineDocs - Failed to open output file." );
      return false;
   }

   // First dump all global ConsoleDoc fragments.
   
   for( ConsoleDocFragment* fragment = ConsoleDocFragment::smFirst; fragment != NULL; fragment = fragment->mNext )
      if( !fragment->mClass )
         dumpFragment( stream, fragment );
   
   // Clear the doc groups before continuing,
   smDocGroups.clear();
   
   // Dump enumeration types.
   dumpEnums( stream );
   
   // Dump all global variables.
   dumpVariables( stream );

   // Now dump the global functions.
   Namespace *g = Namespace::find( NULL );
   while( g ) 
   {
      dumpNamespaceEntries( stream, g );
      
      // Dump callbacks.
      dumpGroupStart( stream, "Callbacks" );
      dumpNamespaceEntries( stream, g, true );
      dumpGroupEnd( stream );

      g = g->mParent;
   }

   // Now dump all the classes.
   dumpClasses( stream );

   // Dump pre-declarations for any groups we encountered
   // so that we don't have to explicitly define them.
   HashTable<String,U32>::Iterator iter = smDocGroups.begin();
   for ( ; iter != smDocGroups.end(); iter++ )
      stream.writeText( String::ToString( "/*! @addtogroup %s */\r\n\r\n", iter->key.c_str() ) );

   return true;
}
예제 #2
0
void StructureScope::dump(ostream *out, string shift){
	*out << shift << "Scope of structure '" << this->getName() << "':\n";

	dumpTypes(out, shift);

	dumpFunctions(out, shift);

	dumpVariables(out, shift);

	dumpStructures(out, shift);


	*out << shift <<  "end of struct scope '" << this->getName() << "';\n" << shift << "=====\n";

}
예제 #3
0
static void dumpClasses( Stream &stream )
{
   Namespace::trashCache();

   VectorPtr<Namespace*> vec;
   vec.reserve( 1024 );

   // We use mHashSequence to mark if we have traversed...
   // so mark all as zero to start.
   for ( Namespace *walk = Namespace::mNamespaceList; walk; walk = walk->mNext )
      walk->mHashSequence = 0;

   for(Namespace *walk = Namespace::mNamespaceList; walk; walk = walk->mNext)
   {
      VectorPtr<Namespace*> stack;
      stack.reserve( 1024 );

      // Get all the parents of this namespace... (and mark them as we go)
      Namespace *parentWalk = walk;
      while(parentWalk)
      {
         if(parentWalk->mHashSequence != 0)
            break;
         if(parentWalk->mPackage == 0)
         {
            parentWalk->mHashSequence = 1;   // Mark as traversed.
            stack.push_back(parentWalk);
         }
         parentWalk = parentWalk->mParent;
      }

      // Load stack into our results vector.
      while(stack.size())
      {
         vec.push_back(stack[stack.size() - 1]);
         stack.pop_back();
      }
   }

   // Go through previously discovered classes
   U32 i;
   for(i = 0; i < vec.size(); i++)
   {
      const char *className = vec[i]->mName;
      const char *superClassName = vec[i]->mParent ? vec[i]->mParent->mName : NULL;

      // Skip the global namespace, that gets dealt with in dumpFunctions
      if(!className) 
         continue;

      // We're just dumping engine functions, then we don't want to dump
      // a class that only contains script functions. So, we iterate over 
      // all the functions.
      bool found = false;
      for( Namespace::Entry *ewalk = vec[i]->mEntryList; ewalk; ewalk = ewalk->mNext )
      {
         if( ewalk->mType != Namespace::Entry::ConsoleFunctionType )
         {
            found = true;
            break;
         }
      }

      // If we don't have engine functions and the namespace name
      // doesn't match the class name... then its a script class.
      if ( !found && !vec[i]->isClass() )
         continue;
  
      // If we hit a class with no members and no classRep, do clever filtering.
      if(vec[i]->mEntryList == NULL && vec[i]->mClassRep == NULL)
      {
         // Print out a short stub so we get a proper class hierarchy.
         if ( superClassName )  
         { 
            // Filter hack; we don't want non-inheriting classes...
            dumpClassHeader( stream, NULL, className, superClassName );
            dumpClassFooter( stream );
         }
         continue;
      }

      // Skip over hidden or internal classes.
      if(   vec[i]->mUsage &&
            ( dStrstr( vec[i]->mUsage, "@hide" ) || dStrstr( vec[i]->mUsage, "@internal" ) ) )
         continue;

      // Print the header for the class..
      dumpClassHeader( stream, vec[i]->mUsage, className, superClassName );
      
      // Dump all fragments for this class.
      
      for( ConsoleDocFragment* fragment = ConsoleDocFragment::smFirst; fragment != NULL; fragment = fragment->mNext )
         if( fragment->mClass && dStricmp( fragment->mClass, className ) == 0 )
            dumpFragment( stream, fragment );

      // Dump member functions.
      dumpNamespaceEntries( stream, vec[ i ], false );
      
      // Dump callbacks.
      dumpGroupStart( stream, "Callbacks" );
      dumpNamespaceEntries( stream, vec[ i ], true );
      dumpGroupEnd( stream );
      
      // Dump static member variables.
      dumpVariables( stream, className );

      // Deal with the classRep (to get members)...
      AbstractClassRep *rep = vec[i]->mClassRep;
      AbstractClassRep::FieldList emptyList;
      AbstractClassRep::FieldList *parentList = &emptyList;
      AbstractClassRep::FieldList *fieldList = &emptyList;
      if ( rep )
      {
         // Get information about the parent's fields...
         AbstractClassRep *parentRep = vec[i]->mParent ? vec[i]->mParent->mClassRep : NULL;
         if(parentRep)
            parentList = &(parentRep->mFieldList);

         // Get information about our fields
         fieldList = &(rep->mFieldList);

         // Go through all our fields...
         for(U32 j = 0; j < fieldList->size(); j++)
         {
            const AbstractClassRep::Field &field = (*fieldList)[j];

            switch( field.type )
            {
            case AbstractClassRep::StartArrayFieldType:
            case AbstractClassRep::EndArrayFieldType:
               break;
            case AbstractClassRep::StartGroupFieldType:
               dumpGroupStart( stream, field.pGroupname, field.pFieldDocs );
               break;
            case AbstractClassRep::EndGroupFieldType:
               dumpGroupEnd( stream );
               break;
            default:
            case AbstractClassRep::DeprecatedFieldType:
               // Skip over fields that are already defined in
               // our parent class.
               if ( parentRep && parentRep->findField( field.pFieldname ) )
                  continue;
                     
               dumpClassMember( stream, field );
               break;
            }
         }
      }

      // Close the class/namespace.
      dumpClassFooter( stream );
   }
}