mathieu@2602: #include mathieu@2602: #include "ns3/object.h" mathieu@2944: #include "ns3/pointer.h" mathieu@2944: #include "ns3/object-vector.h" mathieu@2944: #include "ns3/config.h" mathieu@2944: #include "ns3/log.h" mathieu@2944: #include "ns3/helper-module.h" mathieu@1368: mathieu@1368: using namespace ns3; mathieu@1368: mathieu@2944: NS_LOG_COMPONENT_DEFINE ("Main"); mathieu@2944: mathieu@2602: void mathieu@2602: PrintAttributes (TypeId tid, std::ostream &os) mathieu@2602: { mathieu@2602: os << "" << std::endl; mathieu@2602: } mathieu@1399: mathieu@2945: void mathieu@2945: PrintTraceSources (TypeId tid, std::ostream &os) mathieu@2945: { mathieu@2945: os << ""< Get (TypeId tid); mathieu@2944: mathieu@2944: private: mathieu@2944: std::string GetCurrentPath (void) const; mathieu@2944: void DoGather (TypeId tid); mathieu@2944: void RecordOutput (TypeId tid); mathieu@2944: bool HasAlreadyBeenProcessed (TypeId tid) const; mathieu@2944: std::vector > m_output; mathieu@2944: std::vector m_currentPath; mathieu@2944: std::vector m_alreadyProcessed; mathieu@2944: std::vector > m_aggregates; mathieu@2944: }; mathieu@2944: mathieu@2944: void mathieu@2944: StaticInformation::RecordAggregationInfo (std::string a, std::string b) mathieu@2944: { mathieu@2944: m_aggregates.push_back (std::make_pair (TypeId::LookupByName (a), TypeId::LookupByName (b))); mathieu@2944: } mathieu@2944: mathieu@2944: void mathieu@2944: StaticInformation::Print (void) const mathieu@2944: { mathieu@2944: for (std::vector >::const_iterator i = m_output.begin (); i != m_output.end (); ++i) mathieu@2944: { mathieu@2944: std::pair item = *i; mathieu@2944: std::cout << item.first.GetName () << " -> " << item.second << std::endl; mathieu@2944: } mathieu@2944: } mathieu@2944: mathieu@2944: std::string mathieu@2944: StaticInformation::GetCurrentPath (void) const mathieu@2944: { mathieu@2944: std::ostringstream oss; mathieu@2944: for (std::vector::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i) mathieu@2944: { mathieu@2944: std::string item = *i; mathieu@2944: oss << "/" << item; mathieu@2944: } mathieu@2944: return oss.str (); mathieu@2944: } mathieu@2944: mathieu@2944: void mathieu@2944: StaticInformation::RecordOutput (TypeId tid) mathieu@2944: { mathieu@2944: m_output.push_back (std::make_pair (tid, GetCurrentPath ())); mathieu@2944: } mathieu@2944: mathieu@2944: bool mathieu@2944: StaticInformation::HasAlreadyBeenProcessed (TypeId tid) const mathieu@2944: { mathieu@2944: for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i) mathieu@2944: { mathieu@2944: if (m_alreadyProcessed[i] == tid) mathieu@2944: { mathieu@2944: return true; mathieu@2944: } mathieu@2944: } mathieu@2944: return false; mathieu@2944: } mathieu@2944: mathieu@2944: std::vector mathieu@2944: StaticInformation::Get (TypeId tid) mathieu@2944: { mathieu@2944: std::vector paths; mathieu@2944: for (uint32_t i = 0; i < m_output.size (); ++i) mathieu@2944: { mathieu@2944: std::pair tmp = m_output[i]; mathieu@2944: if (tmp.first == tid) mathieu@2944: { mathieu@2944: paths.push_back (tmp.second); mathieu@2944: } mathieu@2944: } mathieu@2944: return paths; mathieu@2944: } mathieu@2944: mathieu@2944: void mathieu@2944: StaticInformation::Gather (TypeId tid) mathieu@2944: { mathieu@2944: DoGather (tid); mathieu@2944: mathieu@2944: std::sort (m_output.begin (), m_output.end ()); mathieu@2944: m_output.erase (std::unique (m_output.begin (), m_output.end ()), m_output.end ()); mathieu@2944: } mathieu@2944: mathieu@2944: void mathieu@2944: StaticInformation::DoGather (TypeId tid) mathieu@2944: { mathieu@2989: NS_LOG_FUNCTION (this); mathieu@2944: if (HasAlreadyBeenProcessed (tid)) mathieu@2944: { mathieu@2944: return; mathieu@2944: } mathieu@2944: RecordOutput (tid); mathieu@2944: for (uint32_t i = 0; i < tid.GetAttributeN (); ++i) mathieu@2944: { mathieu@2944: Ptr checker = tid.GetAttributeChecker (i); mathieu@2944: const PointerChecker *ptrChecker = dynamic_cast (PeekPointer (checker)); mathieu@2944: if (ptrChecker != 0) mathieu@2944: { mathieu@2944: TypeId pointee = ptrChecker->GetPointeeTypeId (); mathieu@2944: m_currentPath.push_back (tid.GetAttributeName (i)); mathieu@2944: m_alreadyProcessed.push_back (tid); mathieu@2944: DoGather (pointee); mathieu@2944: m_alreadyProcessed.pop_back (); mathieu@2944: m_currentPath.pop_back (); mathieu@2944: continue; mathieu@2944: } mathieu@2944: // attempt to cast to an object vector. mathieu@2944: const ObjectVectorChecker *vectorChecker = dynamic_cast (PeekPointer (checker)); mathieu@2944: if (vectorChecker != 0) mathieu@2944: { mathieu@2944: TypeId item = vectorChecker->GetItemTypeId (); mathieu@2944: m_currentPath.push_back (tid.GetAttributeName (i) + "/[i]"); mathieu@2944: m_alreadyProcessed.push_back (tid); mathieu@2944: DoGather (item); mathieu@2944: m_alreadyProcessed.pop_back (); mathieu@2944: m_currentPath.pop_back (); mathieu@2944: continue; mathieu@2944: } mathieu@2944: } mathieu@2944: for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++) mathieu@2944: { mathieu@2944: TypeId child = TypeId::GetRegistered (j); mathieu@2944: if (child.IsChildOf (tid)) mathieu@2944: { mathieu@2944: m_currentPath.push_back ("$%" + child.GetName ()); mathieu@2944: m_alreadyProcessed.push_back (tid); mathieu@2944: DoGather (child); mathieu@2944: m_alreadyProcessed.pop_back (); mathieu@2944: m_currentPath.pop_back (); mathieu@2944: } mathieu@2944: } mathieu@2944: for (uint32_t k = 0; k < m_aggregates.size (); ++k) mathieu@2944: { mathieu@2944: std::pair tmp = m_aggregates[k]; mathieu@2944: if (tmp.first == tid || tmp.second == tid) mathieu@2944: { mathieu@2944: TypeId other; mathieu@2944: if (tmp.first == tid) mathieu@2944: { mathieu@2944: other = tmp.second; mathieu@2944: } mathieu@2944: if (tmp.second == tid) mathieu@2944: { mathieu@2944: other = tmp.first; mathieu@2944: } mathieu@2944: // Note: we insert a % in the path below to ensure that doxygen does not mathieu@2944: // attempt to resolve the typeid names included in the string. mathieu@2944: m_currentPath.push_back ("$%" + other.GetName ()); mathieu@2944: m_alreadyProcessed.push_back (tid); mathieu@2944: DoGather (other); mathieu@2944: m_alreadyProcessed.pop_back (); mathieu@2944: m_currentPath.pop_back (); mathieu@2944: } mathieu@2944: } mathieu@2944: } mathieu@1399: mathieu@1368: int main (int argc, char *argv[]) mathieu@1368: { mathieu@2944: NodeContainer c; c.Create (1); mathieu@2944: mathieu@2944: StaticInformation info; tomh@3132: info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory"); tomh@3125: info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::Agent"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L4Demux"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol"); mathieu@2944: info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol"); mathieu@2944: mathieu@2944: for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i) mathieu@2944: { mathieu@2944: Ptr object = Config::GetRootNamespaceObject (i); mathieu@2944: info.Gather (object->GetInstanceTypeId ()); mathieu@2944: } mathieu@1368: mathieu@2602: for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++) mathieu@2602: { mathieu@2602: std::cout << "/*!" << std::endl; mathieu@2602: TypeId tid = TypeId::GetRegistered (i); mathieu@2602: if (tid.MustHideFromDocumentation ()) mathieu@2602: { mathieu@2602: continue; mathieu@2602: } mathieu@2602: std::cout << "\\fn static TypeId " << tid.GetName () << "::GetTypeId (void)" << std::endl; mathieu@2944: std::cout << "\\brief This method returns the TypeId associated to \\ref " << tid.GetName () mathieu@2944: << std::endl << std::endl; mathieu@2944: std::vector paths = info.Get (tid); mathieu@2944: if (!paths.empty ()) mathieu@2944: { mathieu@2944: std::cout << "This object is accessible through the following paths with Config::Set and Config::Connect:" mathieu@2944: << std::endl; mathieu@2944: std::cout << "
    " << std::endl; mathieu@2944: for (uint32_t k = 0; k < paths.size (); ++k) mathieu@2944: { mathieu@2944: std::string path = paths[k]; mathieu@2944: std::cout << "
  • " << path << "
  • " << std::endl; mathieu@2944: } mathieu@2944: std::cout << "
" << std::endl; mathieu@2944: } mathieu@2693: if (tid.GetAttributeN () == 0) mathieu@2602: { mathieu@2971: std::cout << "No Attributes defined for this type.
" << std::endl; mathieu@2602: } mathieu@2602: else mathieu@2602: { mathieu@2971: std::cout << "Attributes defined for this type:
" << std::endl; mathieu@2602: PrintAttributes (tid, std::cout); mathieu@2602: } mathieu@2945: { mathieu@2945: TypeId tmp = tid.GetParent (); mathieu@2945: while (tmp.GetParent () != tmp) mathieu@2945: { mathieu@2945: if (tmp.GetAttributeN () != 0) mathieu@2945: { mathieu@2945: std::cout << "Attributes defined in parent class " << tmp.GetName () << ":
" << std::endl; mathieu@2945: PrintAttributes (tmp, std::cout); mathieu@2945: } mathieu@2945: tmp = tmp.GetParent (); mathieu@2945: } mathieu@2945: } mathieu@2945: if (tid.GetTraceSourceN () == 0) mathieu@2602: { mathieu@2971: std::cout << "No TraceSources defined for this type.
" << std::endl; mathieu@2945: } mathieu@2945: else mathieu@2945: { mathieu@2971: std::cout << "TraceSources defined for this type:
" << std::endl; mathieu@2945: PrintTraceSources (tid, std::cout); mathieu@2602: } mathieu@2945: { mathieu@2945: TypeId tmp = tid.GetParent (); mathieu@2945: while (tmp.GetParent () != tmp) mathieu@2945: { mathieu@2945: if (tmp.GetTraceSourceN () != 0) mathieu@2945: { mathieu@2945: std::cout << "TraceSources defined in parent class " << tmp.GetName () << ":
" << std::endl; mathieu@2945: PrintTraceSources (tmp, std::cout); mathieu@2945: } mathieu@2945: tmp = tmp.GetParent (); mathieu@2945: } mathieu@2945: } mathieu@2602: std::cout << "*/" << std::endl; mathieu@2602: } mathieu@1368: mathieu@1853: mathieu@2964: std::cout << "/*!" << std::endl mathieu@2964: << "\\ingroup core" << std::endl mathieu@2964: << "\\defgroup TraceSourceList The list of all trace sources." << std::endl; mathieu@2964: for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i) mathieu@2964: { mathieu@2964: TypeId tid = TypeId::GetRegistered (i); mathieu@2964: if (tid.GetTraceSourceN () == 0 || mathieu@2964: tid.MustHideFromDocumentation ()) mathieu@2964: { mathieu@2964: continue; mathieu@2964: } mathieu@2964: std::cout << "" << tid.GetName () << "
" << std::endl mathieu@2964: << "
    " << std::endl; mathieu@2964: for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j) mathieu@2964: { mathieu@2964: std::cout << "
  • " << tid.GetTraceSourceName (j) << ": " << tid.GetTraceSourceHelp (j) << "
  • " << std::endl; mathieu@2964: } mathieu@2964: std::cout << "
" << std::endl; mathieu@2964: } mathieu@2964: std::cout << "*/" << std::endl; mathieu@2964: mathieu@2964: mathieu@2964: std::cout << "/*!" << std::endl mathieu@2964: << "\\ingroup core" << std::endl mathieu@2964: << "\\defgroup AttributeList The list of all attributes." << std::endl; mathieu@2964: for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i) mathieu@2964: { mathieu@2964: TypeId tid = TypeId::GetRegistered (i); mathieu@2964: if (tid.GetAttributeN () == 0 || mathieu@2964: tid.MustHideFromDocumentation ()) mathieu@2964: { mathieu@2964: continue; mathieu@2964: } mathieu@2964: std::cout << "" << tid.GetName () << "
" << std::endl mathieu@2964: << "
    " << std::endl; mathieu@2964: for (uint32_t j = 0; j < tid.GetAttributeN (); ++j) mathieu@2964: { mathieu@2964: std::cout << "
  • " << tid.GetAttributeName (j) << ": " << tid.GetAttributeHelp (j) << "
  • " << std::endl; mathieu@2964: } mathieu@2964: std::cout << "
" << std::endl; mathieu@2964: } mathieu@2964: std::cout << "*/" << std::endl; mathieu@2964: mathieu@2964: mathieu@2964: mathieu@1368: return 0; mathieu@1368: }