#include #include "ns3/object.h" #include "ns3/pointer.h" #include "ns3/object-vector.h" #include "ns3/config.h" #include "ns3/log.h" #include "ns3/global-value.h" #include "ns3/string.h" #include "ns3/helper-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("Main"); void PrintAttributes (TypeId tid, std::ostream &os) { os << "" << std::endl; } void PrintTraceSources (TypeId tid, std::ostream &os) { os << ""< Get (TypeId tid); private: std::string GetCurrentPath (void) const; void DoGather (TypeId tid); void RecordOutput (TypeId tid); bool HasAlreadyBeenProcessed (TypeId tid) const; void find_and_replace (std::string &source, const std::string find, std::string replace ); std::vector > m_output; std::vector m_currentPath; std::vector m_alreadyProcessed; std::vector > m_aggregates; }; void StaticInformation::RecordAggregationInfo (std::string a, std::string b) { m_aggregates.push_back (std::make_pair (TypeId::LookupByName (a), TypeId::LookupByName (b))); } void StaticInformation::Print (void) const { for (std::vector >::const_iterator i = m_output.begin (); i != m_output.end (); ++i) { std::pair item = *i; std::cout << item.first.GetName () << " -> " << item.second << std::endl; } } std::string StaticInformation::GetCurrentPath (void) const { std::ostringstream oss; for (std::vector::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i) { std::string item = *i; oss << "/" << item; } return oss.str (); } void StaticInformation::RecordOutput (TypeId tid) { m_output.push_back (std::make_pair (tid, GetCurrentPath ())); } bool StaticInformation::HasAlreadyBeenProcessed (TypeId tid) const { for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i) { if (m_alreadyProcessed[i] == tid) { return true; } } return false; } std::vector StaticInformation::Get (TypeId tid) { std::vector paths; for (uint32_t i = 0; i < m_output.size (); ++i) { std::pair tmp = m_output[i]; if (tmp.first == tid) { paths.push_back (tmp.second); } } return paths; } void StaticInformation::Gather (TypeId tid) { DoGather (tid); std::sort (m_output.begin (), m_output.end ()); m_output.erase (std::unique (m_output.begin (), m_output.end ()), m_output.end ()); } void StaticInformation::DoGather (TypeId tid) { NS_LOG_FUNCTION (this); if (HasAlreadyBeenProcessed (tid)) { return; } RecordOutput (tid); for (uint32_t i = 0; i < tid.GetAttributeN (); ++i) { Ptr checker = tid.GetAttributeChecker (i); const PointerChecker *ptrChecker = dynamic_cast (PeekPointer (checker)); if (ptrChecker != 0) { TypeId pointee = ptrChecker->GetPointeeTypeId (); m_currentPath.push_back (tid.GetAttributeName (i)); m_alreadyProcessed.push_back (tid); DoGather (pointee); m_alreadyProcessed.pop_back (); m_currentPath.pop_back (); continue; } // attempt to cast to an object vector. const ObjectVectorChecker *vectorChecker = dynamic_cast (PeekPointer (checker)); if (vectorChecker != 0) { TypeId item = vectorChecker->GetItemTypeId (); m_currentPath.push_back (tid.GetAttributeName (i) + "/[i]"); m_alreadyProcessed.push_back (tid); DoGather (item); m_alreadyProcessed.pop_back (); m_currentPath.pop_back (); continue; } } for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++) { TypeId child = TypeId::GetRegistered (j); if (child.IsChildOf (tid)) { //please take a look at the following note for an explanation std::string childName = "$%" + child.GetName (); find_and_replace(childName,"::","::%"); m_currentPath.push_back (childName); m_alreadyProcessed.push_back (tid); DoGather (child); m_alreadyProcessed.pop_back (); m_currentPath.pop_back (); } } for (uint32_t k = 0; k < m_aggregates.size (); ++k) { std::pair tmp = m_aggregates[k]; if (tmp.first == tid || tmp.second == tid) { TypeId other; if (tmp.first == tid) { other = tmp.second; } if (tmp.second == tid) { other = tmp.first; } /** * Note: we insert a % in the path below to ensure that doxygen does not * attempt to resolve the typeid names included in the string. * if the name contains ::, using the % sign will remove that sign * resulting for instance in $ns3MobilityModel instead of $ns3::MobilityModel * hence the output must be in the form $%ns3::%MobilityModel in order to * show correctly $ns3::MobilityModel * We add at the beginning of the name $% and we replace all the :: in the * string by ::%. */ std::string name = "$%" + other.GetName (); //finding and replacing :: by ::% find_and_replace(name,"::","::%"); m_currentPath.push_back (name); m_alreadyProcessed.push_back (tid); DoGather (other); m_alreadyProcessed.pop_back (); m_currentPath.pop_back (); } } } void StaticInformation::find_and_replace( std::string &source, const std::string find, std::string replace ) { size_t j; j = source.find (find); while (j != std::string::npos ) { source.replace (j, find.length (),replace); j = source.find (find,j+1); } } int main (int argc, char *argv[]) { NodeContainer c; c.Create (1); StaticInformation info; info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory"); info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory"); info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory"); info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol"); info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel"); info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol"); info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol"); for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i) { Ptr object = Config::GetRootNamespaceObject (i); info.Gather (object->GetInstanceTypeId ()); } for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++) { std::cout << "/*!" << std::endl; TypeId tid = TypeId::GetRegistered (i); if (tid.MustHideFromDocumentation ()) { continue; } std::cout << "\\fn static TypeId " << tid.GetName () << "::GetTypeId (void)" << std::endl; std::cout << "\\brief This method returns the TypeId associated to \\ref " << tid.GetName () << std::endl << std::endl; std::vector paths = info.Get (tid); if (!paths.empty ()) { std::cout << "This object is accessible through the following paths with Config::Set and Config::Connect:" << std::endl; std::cout << "
    " << std::endl; for (uint32_t k = 0; k < paths.size (); ++k) { std::string path = paths[k]; std::cout << "
  • " << path << "
  • " << std::endl; } std::cout << "
" << std::endl; } if (tid.GetAttributeN () == 0) { std::cout << "No Attributes defined for this type.
" << std::endl; } else { std::cout << "Attributes defined for this type:
" << std::endl; PrintAttributes (tid, std::cout); } { TypeId tmp = tid.GetParent (); while (tmp.GetParent () != tmp) { if (tmp.GetAttributeN () != 0) { std::cout << "Attributes defined in parent class " << tmp.GetName () << ":
" << std::endl; PrintAttributes (tmp, std::cout); } tmp = tmp.GetParent (); } } if (tid.GetTraceSourceN () == 0) { std::cout << "No TraceSources defined for this type.
" << std::endl; } else { std::cout << "TraceSources defined for this type:
" << std::endl; PrintTraceSources (tid, std::cout); } { TypeId tmp = tid.GetParent (); while (tmp.GetParent () != tmp) { if (tmp.GetTraceSourceN () != 0) { std::cout << "TraceSources defined in parent class " << tmp.GetName () << ":
" << std::endl; PrintTraceSources (tmp, std::cout); } tmp = tmp.GetParent (); } } std::cout << "*/" << std::endl; } std::cout << "/*!" << std::endl << "\\ingroup core" << std::endl << "\\defgroup TraceSourceList The list of all trace sources." << std::endl; for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i) { TypeId tid = TypeId::GetRegistered (i); if (tid.GetTraceSourceN () == 0 || tid.MustHideFromDocumentation ()) { continue; } std::cout << "" << tid.GetName () << "
" << std::endl << "
    " << std::endl; for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j) { std::cout << "
  • " << tid.GetTraceSourceName (j) << ": " << tid.GetTraceSourceHelp (j) << "
  • " << std::endl; } std::cout << "
" << std::endl; } std::cout << "*/" << std::endl; std::cout << "/*!" << std::endl << "\\ingroup core" << std::endl << "\\defgroup AttributeList The list of all attributes." << std::endl; for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i) { TypeId tid = TypeId::GetRegistered (i); if (tid.GetAttributeN () == 0 || tid.MustHideFromDocumentation ()) { continue; } std::cout << "" << tid.GetName () << "
" << std::endl << "
    " << std::endl; for (uint32_t j = 0; j < tid.GetAttributeN (); ++j) { std::cout << "
  • " << tid.GetAttributeName (j) << ": " << tid.GetAttributeHelp (j) << "
  • " << std::endl; } std::cout << "
" << std::endl; } std::cout << "*/" << std::endl; std::cout << "/*!" << std::endl << "\\ingroup core" << std::endl << "\\defgroup GlobalValueList The list of all global values." << std::endl << "
    " << std::endl; for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i) { StringValue val; (*i)->GetValue (val); std::cout << "
  • \\anchor GlobalValue" << (*i)->GetName () << " " << (*i)->GetName () << ": " << (*i)->GetHelp () << "(" << val.Get () << ")
  • " << std::endl; } std::cout << "
" << std::endl << "*/" << std::endl; return 0; }