A Discrete-Event Network Simulator
API
print-introspected-doxygen.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
27 #include <iostream>
28 #include <algorithm>
29 #include <map>
30 #include <climits> // CHAR_BIT
31 
32 #include "ns3/command-line.h"
33 #include "ns3/config.h"
34 #include "ns3/global-value.h"
35 #include "ns3/log.h"
36 #include "ns3/object-vector.h"
37 #include "ns3/object.h"
38 #include "ns3/pointer.h"
39 #include "ns3/string.h"
40 #include "ns3/node-container.h"
41 #include "ns3/simple-channel.h"
42 
43 using namespace ns3;
44 
45 NS_LOG_COMPONENT_DEFINE ("PrintIntrospectedDoxygen");
46 
47 namespace
48 {
49  std::string anchor;
50  std::string argument;
51  std::string boldStart;
52  std::string boldStop;
53  std::string breakBoth;
54  std::string breakHtmlOnly;
55  std::string breakTextOnly;
56  std::string brief;
57  std::string classStart;
58  std::string classStop;
59  std::string codeWord;
60  std::string commentStart;
61  std::string commentStop;
62  std::string copyDoc;
63  std::string flagSpanStart;
64  std::string flagSpanStop;
65  std::string functionStart;
66  std::string functionStop;
67  std::string headingStart;
68  std::string headingStop;
69  std::string indentHtmlOnly;
70  std::string listLineStart;
71  std::string listLineStop;
72  std::string listStart;
73  std::string listStop;
74  std::string page;
75  std::string reference;
76  std::string returns;
77  std::string sectionStart;
78  std::string seeAlso;
79  std::string subSectionStart;
80  std::string templateArgument;
81  std::string templArgExplicit;
82  std::string templArgDeduced;
83  std::string variable;
84 
85 } // anonymous namespace
86 
87 
93 void
94 SetMarkup (bool outputText)
95 {
96  NS_LOG_FUNCTION (outputText);
97  if (outputText)
98  {
99  anchor = "";
100  argument = " Arg: ";
101  boldStart = "";
102  boldStop = "";
103  breakBoth = "\n";
104  breakHtmlOnly = "";
105  breakTextOnly = "\n";
106  brief = "";
107  classStart = "";
108  classStop = "\n\n";
109  codeWord = " ";
110  commentStart = "===============================================================\n";
111  commentStop = "";
112  copyDoc = " See: ";
113  flagSpanStart = "";
114  flagSpanStop = "";
115  functionStart = "";
116  functionStop = "\n\n";
117  headingStart = "";
118  headingStop = "";
119  indentHtmlOnly = "";
120  page = "Page ";
121  listStart = "";
122  listStop = "";
123  listLineStart = " * ";
124  listLineStop = "";
125  reference = " ";
126  returns = " Returns: ";
127  sectionStart = "Section ";
128  seeAlso = " See: ";
129  subSectionStart = "Subsection ";
130  templateArgument = "Template Arg: ";
131  templArgDeduced = "[deduced] ";
132  templArgExplicit = "[explicit] ";
133  variable = "Variable: ";
134  }
135  else
136  {
137  anchor = "\\anchor ";
138  argument = "\\param ";
139  boldStart = "<b>";
140  boldStop = "</b>";
141  breakBoth = "<br>";
142  breakHtmlOnly = "<br>";
143  breakTextOnly = "";
144  brief = "\\brief ";
145  classStart = "\\class ";
146  classStop = "";
147  codeWord = "\\p ";
148  commentStart = "/*!\n";
149  commentStop = "*/\n";
150  copyDoc = "\\copydoc ";
151  flagSpanStart = "<span class=\"mlabel\">";
152  flagSpanStop = "</span>";
153  functionStart = "\\fn ";
154  functionStop = "";
155  headingStart = "<h3>";
156  headingStop = "</h3>";
157  indentHtmlOnly = " ";
158  page = "\\page ";
159  listStart = "<ul>";
160  listStop = "</ul>";
161  listLineStart = "<li>";
162  listLineStop = "</li>";
163  reference = " \\ref ";
164  returns = "\\returns ";
165  sectionStart = "\\ingroup ";
166  seeAlso = "\\see ";
167  subSectionStart = "\\addtogroup ";
168  templateArgument = "\\tparam ";
169  templArgDeduced = "\\deduced ";
170  templArgExplicit = "\\explicit ";
171  variable = "\\var ";
172  }
173 } // SetMarkup ()
174 
175 
176 /***************************************************************
177  * Docs for a single TypeId
178  ***************************************************************/
179 
188 void
189 PrintAttributesTid (std::ostream &os, const TypeId tid)
190 {
191  NS_LOG_FUNCTION (tid);
192  os << listStart << std::endl;
193  for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
194  {
195  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
196  os << listLineStart
197  << boldStart << info.name << boldStop << ": "
198  << info.help
199  << std::endl;
200  os << " "
201  << listStart << std::endl;
202  os << " "
203  << listLineStart
204  << "Set with class: " << reference
205  << info.checker->GetValueTypeName ()
206  << listLineStop
207  << std::endl;
208  if (info.checker->HasUnderlyingTypeInformation ())
209  {
210  os << " "
211  << listLineStart
212  << "Underlying type: ";
213 
214  std::string valType = info.checker->GetValueTypeName ();
215  std::string underType = info.checker->GetUnderlyingTypeInformation ();
216  if ((valType != "ns3::EnumValue") && (underType != "std::string"))
217  {
218  // Indirect cases to handle
219  bool handled = false;
220 
221  if (valType == "ns3::PointerValue")
222  {
223  const PointerChecker *ptrChecker =
224  dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
225  if (ptrChecker != 0)
226  {
227  os << reference << "ns3::Ptr" << "< "
228  << reference << ptrChecker->GetPointeeTypeId ().GetName ()
229  << ">";
230  handled = true;
231  }
232  }
233  else if (valType == "ns3::ObjectPtrContainerValue")
234  {
235  const ObjectPtrContainerChecker * ptrChecker =
236  dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
237  if (ptrChecker != 0)
238  {
239  os << reference << "ns3::Ptr" << "< "
240  << reference << ptrChecker->GetItemTypeId ().GetName ()
241  << ">";
242  handled = true;
243  }
244  }
245  // Helper to match first part of string
246  class StringBeginMatcher
247  {
248  public:
249  StringBeginMatcher (const std::string s)
250  : m_string (s) { };
251  bool operator () (const std::string t)
252  {
253  std::size_t pos = m_string.find (t);
254  return pos == 0;
255  };
256  private:
257  std::string m_string;
258  };
259  StringBeginMatcher match (underType);
260 
261  if ( match ("bool") || match ("double") ||
262  match ("int8_t") || match ("uint8_t") ||
263  match ("int16_t") || match ("uint16_t") ||
264  match ("int32_t") || match ("uint32_t") ||
265  match ("int64_t") || match ("uint64_t")
266  )
267  {
268  os << underType;
269  handled = true;
270  }
271  if (! handled)
272  {
273  os << reference << underType;
274  }
275  }
276  os << listLineStop << std::endl;
277  }
278  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
279  {
280  os << " "
281  << listLineStart
282  << "Initial value: "
283  << info.initialValue->SerializeToString (info.checker)
284  << listLineStop
285  << std::endl;
286  }
287  os << " " << listLineStart << "Flags: ";
288  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
289  {
290  os << flagSpanStart << "construct " << flagSpanStop;
291  }
292  if (info.flags & TypeId::ATTR_SET && info.accessor->HasSetter ())
293  {
294  os << flagSpanStart << "write " << flagSpanStop;
295  }
296  if (info.flags & TypeId::ATTR_GET && info.accessor->HasGetter ())
297  {
298  os << flagSpanStart << "read " << flagSpanStop;
299  }
300  os << listLineStop << std::endl;
301  os << " "
302  << listStop
303  << " " << std::endl;
304 
305  }
306  os << listStop << std::endl;
307 } // PrintAttributesTid ()
308 
309 
320 void
321 PrintAttributes (std::ostream & os, const TypeId tid)
322 {
323  NS_LOG_FUNCTION (tid);
324  if (tid.GetAttributeN () == 0)
325  {
326  os << "No Attributes are defined for this type."
327  << breakBoth
328  << std::endl;
329  }
330  else
331  {
332  os << headingStart
333  << "Attributes"
334  << headingStop
335  << std::endl;
336  PrintAttributesTid (os, tid);
337  }
338 
339  // Attributes from base classes
340  TypeId tmp = tid.GetParent ();
341  while (tmp.GetParent () != tmp)
342  {
343  if (tmp.GetAttributeN () != 0)
344  {
345  os << headingStart
346  << "Attributes defined in parent class "
347  << tmp.GetName ()
348  << headingStop
349  << std::endl;
350  PrintAttributesTid (os, tmp);
351  }
352  tmp = tmp.GetParent ();
353 
354  } // Attributes
355 } // PrintAttributes ()
356 
357 
366 void
367 PrintTraceSourcesTid (std::ostream & os, const TypeId tid)
368 {
369  NS_LOG_FUNCTION (tid);
370  os << listStart << std::endl;
371  for (uint32_t i = 0; i < tid.GetTraceSourceN (); ++i)
372  {
373  struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i);
374  os << listLineStart
375  << boldStart << info.name << boldStop << ": "
376  << info.help << breakBoth
377  // '%' prevents doxygen from linking to the Callback class...
378  << "%Callback signature: "
379  << info.callback
380  << std::endl;
381  os << listLineStop << std::endl;
382  }
383  os << listStop << std::endl;
384 } // PrintTraceSourcesTid ()
385 
386 
397 void
398 PrintTraceSources (std::ostream & os, const TypeId tid)
399 {
400  NS_LOG_FUNCTION (tid);
401  if (tid.GetTraceSourceN () == 0)
402  {
403  os << "No TraceSources are defined for this type."
404  << breakBoth
405  << std::endl;
406  }
407  else
408  {
409  os << headingStart
410  << "TraceSources"
411  << headingStop << std::endl;
412  PrintTraceSourcesTid (os, tid);
413  }
414 
415  // Trace sources from base classes
416  TypeId tmp = tid.GetParent ();
417  while (tmp.GetParent () != tmp)
418  {
419  if (tmp.GetTraceSourceN () != 0)
420  {
421  os << headingStart
422  << "TraceSources defined in parent class "
423  << tmp.GetName ()
424  << headingStop << std::endl;
425  PrintTraceSourcesTid (os, tmp);
426  }
427  tmp = tmp.GetParent ();
428  }
429 
430 } // PrintTraceSources ()
431 
438 void PrintSize (std::ostream & os, const TypeId tid)
439 {
440  NS_LOG_FUNCTION (tid);
441  NS_ASSERT_MSG (CHAR_BIT != 0, "CHAR_BIT is zero");
442 
443  std::size_t arch = (sizeof (void *) * CHAR_BIT);
444 
445  os << boldStart << "Size" << boldStop
446  << " of this type is " << tid.GetSize ()
447  << " bytes (on a " << arch << "-bit architecture)."
448  << std::endl;
449 } // PrintSize ()
450 
451 
452 /***************************************************************
453  * Lists of All things
454  ***************************************************************/
455 
461 void
462 PrintAllAttributes (std::ostream & os)
463 {
465  os << commentStart << page << "AttributeList All Attributes\n"
466  << std::endl;
467  os << "This is a list of all" << reference << "attribute by class. "
468  << "For more information see the" << reference << "attribute "
469  << "section of this API documentation and the Attributes sections "
470  << "in the Tutorial and Manual.\n"
471  << std::endl;
472 
473  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
474  {
475  TypeId tid = TypeId::GetRegistered (i);
476  if (tid.GetAttributeN () == 0 ||
478  {
479  continue;
480  }
481  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
482  << std::endl;
483 
484  os << listStart << std::endl;
485  for (uint32_t j = 0; j < tid.GetAttributeN (); ++j)
486  {
487  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
488  os << listLineStart
489  << boldStart << info.name << boldStop
490  << ": " << info.help
491  << listLineStop
492  << std::endl;
493  }
494  os << listStop << std::endl;
495  }
496  os << commentStop << std::endl;
497 
498 } // PrintAllAttributes ()
499 
500 
506 void
507 PrintAllGlobals (std::ostream & os)
508 {
510  os << commentStart << page << "GlobalValueList All GlobalValues\n"
511  << std::endl;
512  os << "This is a list of all" << reference << "ns3::GlobalValue instances.\n"
513  << std::endl;
514 
515  os << listStart << std::endl;
517  i != GlobalValue::End ();
518  ++i)
519  {
520  StringValue val;
521  (*i)->GetValue (val);
522  os << indentHtmlOnly
523  << listLineStart
524  << boldStart
525  << anchor
526  << "GlobalValue" << (*i)->GetName () << " " << (*i)->GetName ()
527  << boldStop
528  << ": " << (*i)->GetHelp ()
529  << ". Default value: " << val.Get () << "."
530  << listLineStop
531  << std::endl;
532  }
533  os << listStop << std::endl;
534  os << commentStop << std::endl;
535 
536 } // PrintAllGlobals ()
537 
538 
544 void
545 PrintAllLogComponents (std::ostream & os)
546 {
548  os << commentStart << page << "LogComponentList All LogComponents\n"
549  << std::endl;
550  os << "This is a list of all" << reference << "ns3::LogComponent instances.\n"
551  << std::endl;
552 
557  os << listStart << std::endl;
559  LogComponent::ComponentList::const_iterator it;
560  for (it = logs->begin (); it != logs->end (); ++it)
561  {
562  std::string file = it->second->File ();
563  // Strip leading "../" related to depth in build directory
564  // since doxygen only sees the path starting with "src/", etc.
565  while (file.find ("../") == 0)
566  {
567  file = file.substr (3);
568  }
569 
570  os << listLineStart
571  << boldStart << it->first << boldStop << ": " << file
572  << listLineStop
573  << std::endl;
574  }
575  os << listStop << std::endl;
576  os << commentStop << std::endl;
577 } // PrintAllLogComponents ()
578 
579 
585 void
586 PrintAllTraceSources (std::ostream & os)
587 {
589  os << commentStart << page << "TraceSourceList All TraceSources\n"
590  << std::endl;
591  os << "This is a list of all" << reference << "tracing sources. "
592  << "For more information see the " << reference << "tracing "
593  << "section of this API documentation and the Tracing sections "
594  << "in the Tutorial and Manual.\n"
595  << std::endl;
596 
597  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
598  {
599  TypeId tid = TypeId::GetRegistered (i);
600  if (tid.GetTraceSourceN () == 0 ||
602  {
603  continue;
604  }
605  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
606  << std::endl;
607 
608  os << listStart << std::endl;
609  for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j)
610  {
611  struct TypeId::TraceSourceInformation info = tid.GetTraceSource(j);
612  os << listLineStart
613  << boldStart << info.name << boldStop
614  << ": " << info.help
615  << listLineStop
616  << std::endl;
617  }
618  os << listStop << std::endl;
619  }
620  os << commentStop << std::endl;
621 
622 } // PrintAllTraceSources ()
623 
624 
625 /***************************************************************
626  * Docs for Attribute classes
627  ***************************************************************/
628 
629 
643 void
644 PrintAttributeValueSection (std::ostream & os,
645  const std::string & name,
646  const bool seeBase = true)
647 {
648  NS_LOG_FUNCTION (name);
649  std::string section = "attribute_" + name;
650 
651  // \ingroup attribute
652  // \defgroup attribute_<name>Value <name> Attribute
653  os << commentStart << sectionStart << "attribute\n"
654  << subSectionStart << "attribute_" << name << " "
655  << name << " Attribute\n"
656  << "Attribute implementation for " << name << "\n";
657  if (seeBase)
658  {
659  // Some classes don't live in ns3::. Yuck
660  if (name != "IeMeshId")
661  {
662  os << seeAlso << "ns3::" << name << "\n";
663  }
664  else
665  {
666  os << seeAlso << "ns3::dot11s::" << name << "\n";
667  }
668  }
669  os << commentStop;
670 
671 } // PrintAttributeValueSection ()
672 
673 
684 void
685 PrintAttributeValueWithName (std::ostream & os,
686  const std::string & name,
687  const std::string & type,
688  const std::string & header)
689 {
690  NS_LOG_FUNCTION (name << type << header);
691  std::string sectAttr = sectionStart + "attribute_" + name;
692 
693  // \ingroup attribute_<name>Value
694  // \class ns3::<name>Value "header"
695  std::string valClass = name + "Value";
696  std::string qualClass = " ns3::" + valClass;
697 
698  os << commentStart << sectAttr << std::endl;
699  os << classStart << qualClass << " \"" << header << "\"" << std::endl;
700  os << "AttributeValue implementation for " << name << "." << std::endl;
701  os << seeAlso << "AttributeValue" << std::endl;
702  os << commentStop;
703 
704  // Copy ctor: <name>Value::<name>Value
705  os << commentStart
706  << functionStart << name
707  << qualClass << "::" << valClass;
708  if ( (name == "EmptyAttribute") ||
709  (name == "ObjectPtrContainer") )
710  {
711  // Just default constructors.
712  os << "(void)\n";
713  }
714  else
715  {
716  // Copy constructors
717  os << "(const " << type << " & value)\n"
718  << "Copy constructor.\n"
719  << argument << "[in] value The " << name << " value to copy.\n";
720  }
721  os << commentStop;
722 
723  // <name>Value::Get (void) const
724  os << commentStart
725  << functionStart << type
726  << qualClass << "::Get (void) const\n"
727  << returns << "The " << name << " value.\n"
728  << commentStop;
729 
730  // <name>Value::GetAccessor (T & value) const
731  os << commentStart
732  << functionStart << "bool"
733  << qualClass << "::GetAccessor (T & value) const\n"
734  << "Access the " << name << " value as type " << codeWord << "T.\n"
735  << templateArgument << "T " << templArgExplicit << "The type to cast to.\n"
736  << argument << "[out] value The " << name << " value, as type "
737  << codeWord << "T.\n"
738  << returns << "true.\n"
739  << commentStop;
740 
741  // <name>Value::Set (const name & value)
742  if (type != "Callback") // Yuck
743  {
744  os << commentStart
745  << functionStart << "void"
746  << qualClass << "::Set (const " << type << " & value)\n"
747  << "Set the value.\n"
748  << argument << "[in] value The value to adopt.\n"
749  << commentStop;
750  }
751 
752  // <name>Value::m_value
753  os << commentStart
754  << variable << type
755  << qualClass << "::m_value\n"
756  << "The stored " << name << " instance.\n"
757  << commentStop
758  << std::endl;
759 
760 } // PrintAttributeValueWithName ()
761 
762 
771 void
772 PrintMakeAccessors (std::ostream & os, const std::string & name)
773 {
774  NS_LOG_FUNCTION (name);
775  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
776  std::string make = "ns3::Make" + name + "Accessor ";
777 
778  // \ingroup attribute_<name>Value
779  // Make<name>Accessor (T1 a1)
780  os << commentStart << sectAttr
781  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
782  << make << "(T1 a1)\n"
783  << copyDoc << "ns3::MakeAccessorHelper(T1)\n"
784  << seeAlso << "AttributeAccessor\n"
785  << commentStop;
786 
787  // \ingroup attribute_<name>Value
788  // Make<name>Accessor (T1 a1)
789  os << commentStart << sectAttr
790  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
791  << make << "(T1 a1, T2 a2)\n"
792  << copyDoc << "ns3::MakeAccessorHelper(T1,T2)\n"
793  << seeAlso << "AttributeAccessor\n"
794  << commentStop;
795 } // PrintMakeAccessors ()
796 
797 
807 void
808 PrintMakeChecker (std::ostream & os,
809  const std::string & name,
810  const std::string & header)
811 {
812  NS_LOG_FUNCTION (name << header);
813  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
814  std::string make = "ns3::Make" + name + "Checker ";
815 
816  // \ingroup attribute_<name>Value
817  // class <name>Checker
818  os << commentStart << sectAttr << std::endl;
819  os << classStart << " ns3::" << name << "Checker"
820  << " \"" << header << "\"" << std::endl;
821  os << "AttributeChecker implementation for " << name << "Value." << std::endl;
822  os << seeAlso << "AttributeChecker" << std::endl;
823  os << commentStop;
824 
825  // \ingroup attribute_<name>Value
826  // Make<name>Checker (void)
827  os << commentStart << sectAttr
828  << functionStart << "ns3::Ptr<const ns3::AttributeChecker> "
829  << make << "(void)\n"
830  << returns << "The AttributeChecker.\n"
831  << seeAlso << "AttributeChecker\n"
832  << commentStop;
833 } // PrintMakeChecker ()
834 
835 
837 typedef struct {
838  const std::string m_name;
839  const std::string m_type;
840  const bool m_seeBase;
841  const std::string m_header;
843 
844 
853 void
854 PrintAttributeHelper (std::ostream & os,
855  const AttributeDescriptor & attr)
856 {
857  NS_LOG_FUNCTION (attr.m_name << attr.m_type << attr.m_seeBase <<
858  attr.m_header);
860  PrintAttributeValueWithName (os, attr.m_name, attr.m_type, attr.m_header);
861  PrintMakeAccessors (os, attr.m_name);
862  PrintMakeChecker (os, attr.m_name, attr.m_header);
863 } // PrintAttributeHelper ()
864 
865 
869 void
870 PrintAttributeImplementations (std::ostream & os)
871 {
873 
874  const AttributeDescriptor attributes [] =
875  {
876  // Users of ATTRIBUTE_HELPER_HEADER
877  //
878  { "Address", "Address", true, "address.h" },
879  { "Box", "Box", true, "box.h" },
880  { "DataRate", "DataRate", true, "data-rate.h" },
881  { "HtCapabilities", "HtCapabilities", true, "ht-capabilities.h" },
882  { "IeMeshId", "IeMeshId", true, "ie-dot11s-id.h" },
883  { "Ipv4Address", "Ipv4Address", true, "ipv4-address.h" },
884  { "Ipv4Mask", "Ipv4Mask", true, "ipv4-address.h" },
885  { "Ipv6Address", "Ipv6Address", true, "ipv6-address.h" },
886  { "Ipv6Prefix", "Ipv6Prefix", true, "ipv6-address.h" },
887  { "Mac16Address", "Mac16Address", true, "mac16-address.h" },
888  { "Mac48Address", "Mac48Address", true, "mac48-address.h" },
889  { "Mac64Address", "Mac64Address", true, "mac64-address.h" },
890  { "ObjectFactory", "ObjectFactory", true, "object-factory.h" },
891  { "OrganizationIdentifier",
892  "OrganizationIdentifier",
893  true, "vendor-specific-action.h" },
894  { "Rectangle", "Rectangle", true, "rectangle.h" },
895  { "Ssid", "Ssid", true, "ssid.h" },
896  { "TypeId", "TypeId", true, "type-id.h" },
897  { "UanModesList", "UanModesList", true, "uan-tx-mode.h" },
898  { "ValueClassTest", "ValueClassTest", false, "" /* outside ns3 */ },
899  { "Vector2D", "Vector2D", true, "vector.h" },
900  { "Vector3D", "Vector3D", true, "vector.h" },
901  { "Waypoint", "Waypoint", true, "waypoint.h" },
902  { "WifiMode", "WifiMode", true, "wifi-mode.h" },
903 
904  // All three (Value, Access and Checkers) defined, but custom
905  { "Boolean", "Boolean", false, "boolean.h" },
906  { "Callback", "Callback", true, "callback.h" },
907  { "Double", "double", false, "double.h" },
908  { "Enum", "int", false, "enum.h" },
909  { "Integer", "int64_t", false, "integer.h" },
910  { "Pointer", "Pointer", false, "pointer.h" },
911  { "RandomVariable", "RandomVariable", true, "random-variable-stream.h" },
912  { "String", "std::string", false, "string.h" },
913  { "Time", "Time", true, "nstime.h" },
914  { "Uinteger", "uint64_t", false, "uinteger.h" },
915  { "", "", false, "last placeholder" }
916  };
917 
918  int i = 0;
919  while (attributes[i].m_name != "")
920  {
921  PrintAttributeHelper (os, attributes[i]);
922  ++i;
923  }
924 
925  // Special cases
926  PrintAttributeValueSection (os, "EmptyAttribute", false);
927  PrintAttributeValueWithName (os, "EmptyAttribute", "EmptyAttribute",
928  "attribute.h");
929 
930  PrintAttributeValueSection (os, "ObjectPtrContainer", false);
931  PrintAttributeValueWithName (os, "ObjectPtrContainer", "ObjectPtrContainer", "object-ptr-container.h");
932  PrintMakeChecker (os, "ObjectPtrContainer", "object-ptr-container.h");
933 
934  PrintAttributeValueSection (os, "ObjectVector", false);
935  PrintMakeAccessors (os, "ObjectVector");
936  PrintMakeChecker (os, "ObjectVector", "object-vector.h");
937 
938  PrintAttributeValueSection (os, "ObjectMap", false);
939  PrintMakeAccessors (os, "ObjectMap");
940  PrintMakeChecker (os, "ObjectMap", "object-map.h");
941 
942 } // PrintAttributeImplementations ()
943 
944 
945 /***************************************************************
946  * Aggregation and configuration paths
947  ***************************************************************/
948 
953 {
954 public:
961  void RecordAggregationInfo (std::string a, std::string b);
967  void Gather (TypeId tid);
971  void Print (void) const;
972 
978  std::vector<std::string> Get (TypeId tid) const;
979 
983  std::vector<std::string> GetNoTypeIds (void) const;
984 
985 private:
989  std::string GetCurrentPath (void) const;
995  void DoGather (TypeId tid);
1001  void RecordOutput (TypeId tid);
1007  bool HasAlreadyBeenProcessed (TypeId tid) const;
1011  std::vector<std::pair<TypeId,std::string> > m_output;
1015  std::vector<std::string> m_currentPath;
1019  std::vector<TypeId> m_alreadyProcessed;
1023  std::vector<std::pair<TypeId,TypeId> > m_aggregates;
1030  mutable std::vector<std::string> m_noTids;
1031 
1032 }; // class StaticInformation
1033 
1034 
1035 void
1036 StaticInformation::RecordAggregationInfo (std::string a, std::string b)
1037 {
1038  NS_LOG_FUNCTION (this << a << b);
1039  TypeId aTid;
1040  bool found = TypeId::LookupByNameFailSafe (a, &aTid);
1041  if (!found)
1042  {
1043  m_noTids.push_back (a);
1044  return;
1045  }
1046  TypeId bTid;
1047  found = TypeId::LookupByNameFailSafe (b, &bTid);
1048  if (!found)
1049  {
1050  m_noTids.push_back (b);
1051  return;
1052  }
1053 
1054  m_aggregates.push_back (std::make_pair (aTid, bTid));
1055 }
1056 
1057 
1058 void
1060 {
1061  NS_LOG_FUNCTION (this);
1062  for (std::vector<std::pair<TypeId,std::string> >::const_iterator i = m_output.begin (); i != m_output.end (); ++i)
1063  {
1064  std::pair<TypeId,std::string> item = *i;
1065  std::cout << item.first.GetName () << " -> " << item.second << std::endl;
1066  }
1067 }
1068 
1069 
1070 std::string
1072 {
1073  NS_LOG_FUNCTION (this);
1074  std::ostringstream oss;
1075  for (std::vector<std::string>::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i)
1076  {
1077  std::string item = *i;
1078  oss << "/" << item;
1079  }
1080  return oss.str ();
1081 }
1082 
1083 
1084 void
1086 {
1087  NS_LOG_FUNCTION (this << tid);
1088  m_output.push_back (std::make_pair (tid, GetCurrentPath ()));
1089 }
1090 
1091 
1092 bool
1094 {
1095  NS_LOG_FUNCTION (this << tid);
1096  for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i)
1097  {
1098  if (m_alreadyProcessed[i] == tid)
1099  {
1100  return true;
1101  }
1102  }
1103  return false;
1104 }
1105 
1106 
1107 std::vector<std::string>
1109 {
1110  NS_LOG_FUNCTION (this << tid);
1111  std::vector<std::string> paths;
1112  for (uint32_t i = 0; i < m_output.size (); ++i)
1113  {
1114  std::pair<TypeId,std::string> tmp = m_output[i];
1115  if (tmp.first == tid)
1116  {
1117  paths.push_back (tmp.second);
1118  }
1119  }
1120  return paths;
1121 }
1122 
1138 template <typename T>
1139 void
1141 {
1142  std::sort (t.begin (), t.end ());
1143  t.erase (std::unique (t.begin (), t.end ()), t.end ());
1144 }
1145 
1146 std::vector<std::string>
1148 {
1149  NS_LOG_FUNCTION (this);
1150  Uniquefy (m_noTids);
1151  return m_noTids;
1152 }
1153 
1154 
1155 void
1157 {
1158  NS_LOG_FUNCTION (this << tid);
1159  DoGather (tid);
1160  Uniquefy (m_output);
1161 }
1162 
1163 
1164 void
1166 {
1167  NS_LOG_FUNCTION (this << tid);
1168  if (HasAlreadyBeenProcessed (tid))
1169  {
1170  return;
1171  }
1172  RecordOutput (tid);
1173  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
1174  {
1175  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
1176  const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
1177  if (ptrChecker != 0)
1178  {
1179  TypeId pointee = ptrChecker->GetPointeeTypeId ();
1180 
1181  // See if this is a pointer to an Object.
1182  Ptr<Object> object = CreateObject<Object> ();
1183  TypeId objectTypeId = object->GetTypeId ();
1184  if (objectTypeId == pointee)
1185  {
1186  // Stop the recursion at this attribute if it is a
1187  // pointer to an Object, which create too many spurious
1188  // paths in the list of attribute paths because any
1189  // Object can be in that part of the path.
1190  continue;
1191  }
1192 
1193  m_currentPath.push_back (info.name);
1194  m_alreadyProcessed.push_back (tid);
1195  DoGather (pointee);
1196  m_alreadyProcessed.pop_back ();
1197  m_currentPath.pop_back ();
1198  continue;
1199  }
1200  // attempt to cast to an object vector.
1201  const ObjectPtrContainerChecker *vectorChecker = dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
1202  if (vectorChecker != 0)
1203  {
1204  TypeId item = vectorChecker->GetItemTypeId ();
1205  m_currentPath.push_back (info.name + "/[i]");
1206  m_alreadyProcessed.push_back (tid);
1207  DoGather (item);
1208  m_alreadyProcessed.pop_back ();
1209  m_currentPath.pop_back ();
1210  continue;
1211  }
1212  }
1213  for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++)
1214  {
1215  TypeId child = TypeId::GetRegistered (j);
1216  if (child.IsChildOf (tid))
1217  {
1218  std::string childName = "$" + child.GetName ();
1219  m_currentPath.push_back (childName);
1220  m_alreadyProcessed.push_back (tid);
1221  DoGather (child);
1222  m_alreadyProcessed.pop_back ();
1223  m_currentPath.pop_back ();
1224  }
1225  }
1226  for (uint32_t k = 0; k < m_aggregates.size (); ++k)
1227  {
1228  std::pair<TypeId,TypeId> tmp = m_aggregates[k];
1229  if (tmp.first == tid || tmp.second == tid)
1230  {
1231  TypeId other;
1232  if (tmp.first == tid)
1233  {
1234  other = tmp.second;
1235  }
1236  if (tmp.second == tid)
1237  {
1238  other = tmp.first;
1239  }
1240  std::string name = "$" + other.GetName ();
1241  m_currentPath.push_back (name);
1242  m_alreadyProcessed.push_back (tid);
1243  DoGather (other);
1244  m_alreadyProcessed.pop_back ();
1245  m_currentPath.pop_back ();
1246  }
1247  }
1248 } // StaticInformation::DoGather ()
1249 
1250 
1253 {
1255  // The below statements register typical aggregation relationships
1256  // in ns-3 programs, that otherwise aren't picked up automatically
1257  // by the creation of the above node. To manually list other common
1258  // aggregation relationships that you would like to see show up in
1259  // the list of configuration paths in the doxygen, add additional
1260  // statements below.
1261  StaticInformation info;
1262  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
1263  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
1264  info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
1265  info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
1266  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
1267  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4NixVectorRouting");
1268  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1269  info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");
1270  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1271  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpL4Protocol");
1272  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv6L3Protocol");
1273  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv6L4Protocol");
1274  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpL4Protocol");
1275  info.RecordAggregationInfo ("ns3::Node", "ns3::RipNg");
1276  info.RecordAggregationInfo ("ns3::Node", "ns3::GlobalRouter");
1277  info.RecordAggregationInfo ("ns3::Node", "ns3::aodv::RoutingProtocol");
1278  info.RecordAggregationInfo ("ns3::Node", "ns3::dsdv::RoutingProtocol");
1279  info.RecordAggregationInfo ("ns3::Node", "ns3::dsr::DsrRouting");
1280  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
1281  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergyHarvesterContainer");
1282  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergySourceContainer");
1283 
1284  // Create a channel object so that channels appear in the namespace
1285  // paths that will be generated here.
1286  Ptr<SimpleChannel> simpleChannel;
1287  simpleChannel = CreateObject<SimpleChannel> ();
1288 
1289  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
1290  {
1292  info.Gather (object->GetInstanceTypeId ());
1293  }
1294 
1295  return info;
1296 
1297 } // GetTypicalAggregations ()
1298 
1299 
1300 // Map from TypeId name to tid
1301 typedef std::map< std::string, int32_t> NameMap;
1302 typedef NameMap::const_iterator NameMapIterator;
1303 
1304 
1305 // Create a map from the class names to their index in the vector of
1306 // TypeId's so that the names will end up in alphabetical order.
1307 NameMap
1309 {
1311  NameMap nameMap;
1312 
1313  // Registered types
1314  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
1315  {
1316  TypeId tid = TypeId::GetRegistered (i);
1317  if (tid.MustHideFromDocumentation ())
1318  {
1319  continue;
1320  }
1321 
1322  // Capitalize all of letters in the name so that it sorts
1323  // correctly in the map.
1324  std::string name = tid.GetName ();
1325  for (uint32_t j = 0; j < name.length (); j++)
1326  {
1327  name[j] = toupper (name[j]);
1328  }
1329 
1330  // Save this name's index.
1331  nameMap[name] = i;
1332  }
1333 
1334  // Type names without TypeIds
1335  std::vector<std::string> noTids = info.GetNoTypeIds ();
1336  for (std::vector<std::string>::const_iterator i = noTids.begin ();
1337  i != noTids.end ();
1338  ++i)
1339  {
1340  nameMap[*i] = -1;
1341  }
1342 
1343  return nameMap;
1344 } // GetNameMap ()
1345 
1346 
1347 void
1348 PrintConfigPaths (std::ostream & os, const StaticInformation & info,
1349  const TypeId tid)
1350 {
1351  NS_LOG_FUNCTION (tid);
1352  std::vector<std::string> paths = info.Get (tid);
1353 
1354  // Config --------------
1355  if (paths.empty ())
1356  {
1357  os << "Introspection did not find any typical Config paths."
1358  << breakBoth
1359  << std::endl;
1360  }
1361  else
1362  {
1363  os << headingStart
1364  << "Config Paths"
1365  << headingStop
1366  << std::endl;
1367  os << std::endl;
1368  os << tid.GetName ()
1369  << " is accessible through the following paths"
1370  << " with Config::Set and Config::Connect:"
1371  << std::endl;
1372  os << listStart << std::endl;
1373  for (uint32_t k = 0; k < paths.size (); ++k)
1374  {
1375  std::string path = paths[k];
1376  os << listLineStart
1377  << "\"" << path << "\""
1378  << listLineStop
1379  << breakTextOnly
1380  << std::endl;
1381  }
1382  os << listStop << std::endl;
1383  }
1384 } // PrintConfigPaths ()
1385 
1386 
1387 /***************************************************************
1388  * Main
1389  ***************************************************************/
1390 
1391 int main (int argc, char *argv[])
1392 {
1394  bool outputText = false;
1395 
1396  CommandLine cmd;
1397  cmd.Usage ("Generate documentation for all ns-3 registered types, "
1398  "trace sources, attributes and global variables.");
1399  cmd.AddValue ("output-text", "format output as plain text", outputText);
1400  cmd.Parse (argc, argv);
1401 
1402  SetMarkup (outputText);
1403 
1404 
1405  // Create a Node, to force linking and instantiation of our TypeIds
1406  NodeContainer c;
1407  c.Create (1);
1408 
1409  // mode-line: helpful when debugging introspected-doxygen.h
1410  if (!outputText)
1411  {
1412  std::cout << "/* -*- Mode:C++; c-file-style:\"gnu\"; "
1413  "indent-tabs-mode:nil; -*- */\n"
1414  << std::endl;
1415  }
1416 
1417  // Get typical aggregation relationships.
1419 
1420  NameMap nameMap = GetNameMap (info);
1421 
1422  // Iterate over the map, which will print the class names in
1423  // alphabetical order.
1424  for (NameMapIterator nameMapIterator = nameMap.begin ();
1425  nameMapIterator != nameMap.end ();
1426  nameMapIterator++)
1427  {
1428  // Get the class's index out of the map;
1429  std::string name = nameMapIterator->first;
1430  int32_t i = nameMapIterator->second;
1431  TypeId tid;
1432 
1433  if (i >= 0)
1434  {
1435  tid = TypeId::GetRegistered (i);
1436  if (tid.MustHideFromDocumentation ())
1437  {
1438  continue;
1439  }
1440  name = tid.GetName ();
1441  }
1442 
1443  std::cout << commentStart << std::endl;
1444 
1445  std::cout << classStart << name << std::endl;
1446  std::cout << std::endl;
1447 
1448  if (i >= 0)
1449  {
1450  PrintConfigPaths (std::cout, info, tid);
1451  PrintAttributes (std::cout, tid);
1452  PrintTraceSources (std::cout, tid);
1453  PrintSize (std::cout, tid);
1454  }
1455  else
1456  {
1457  std::cout << "Introspection could not find Config paths for " << name
1458  << " in this build because the parent module"
1459  << " was not included in the waf configuration."
1460  << breakBoth
1461  << std::endl;
1462  }
1463 
1464  std::cout << commentStop << std::endl;
1465  } // class documentation
1466 
1467 
1468  PrintAllAttributes (std::cout);
1469  PrintAllGlobals (std::cout);
1470  PrintAllLogComponents (std::cout);
1471  PrintAllTraceSources (std::cout);
1472  PrintAttributeImplementations (std::cout);
1473 
1474  return 0;
1475 }
uint32_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1058
std::vector< std::string > GetNoTypeIds(void) const
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::string Get(void) const
Definition: string.cc:31
std::string help
Trace help string.
Definition: type-id.h:101
const std::string m_header
The header file name.
void RecordOutput(TypeId tid)
Record the current config path for tid.
std::vector< std::pair< TypeId, std::string > > m_output
Configuration path for each TypeId.
Hold variables of type string.
Definition: string.h:41
std::string templArgDeduced
template argument deduced from function
TraceSource implementation.
Definition: type-id.h:97
std::string headingStart
start of section heading (h3)
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:562
const std::string m_type
The name of the underlying type.
std::vector< std::string > Get(TypeId tid) const
virtual TypeId GetPointeeTypeId(void) const =0
Get the TypeId of the base type.
std::string flagSpanStart
start of Attribute flag value
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
TypeId GetParent(void) const
Get the parent of this TypeId.
Definition: type-id.cc:925
Vector::const_iterator Iterator
Iterator type for the list of all global values.
Definition: global-value.h:77
std::string templArgExplicit
template argument required
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:821
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual TypeId GetItemTypeId(void) const =0
Get the TypeId of the container class type.
tuple cmd
Definition: second.py:35
The attribute can be written at construction-time.
Definition: type-id.h:65
std::string breakTextOnly
linebreak for text output only
void Usage(const std::string usage)
Supply the program usage and documentation.
Definition: command-line.cc:96
void DoGather(TypeId tid)
Gather attribute, configuration path information for tid.
bool MustHideFromDocumentation(void) const
Check if this TypeId should not be listed in documentation.
Definition: type-id.cc:1050
Ptr< const AttributeAccessor > accessor
Accessor object.
Definition: type-id.h:88
static uint32_t GetRegisteredN(void)
Get the number of registered TypeIds.
Definition: type-id.cc:853
bool HasAlreadyBeenProcessed(TypeId tid) const
const std::string m_name
The base name of the resulting AttributeValue type.
static Iterator Begin(void)
The Begin iterator.
Ptr< const AttributeValue > initialValue
Configured initial value.
Definition: type-id.h:86
std::string sectionStart
start of a section or group
Ptr< Object > GetRootNamespaceObject(uint32_t i)
Definition: config.cc:870
AttributeChecker implementation for ObjectPtrContainerValue.
uint32_t GetTraceSourceN(void) const
Get the number of Trace sources.
Definition: type-id.cc:1079
static TypeId GetRegistered(uint32_t i)
Get a TypeId by index.
Definition: type-id.cc:859
uint32_t GetRootNamespaceObjectN(void)
Definition: config.cc:864
Attribute implementation.
Definition: type-id.h:76
Parse command-line arguments.
Definition: command-line.h:205
uint32_t flags
AttributeFlags value.
Definition: type-id.h:82
std::string breakHtmlOnly
linebreak for html output only
The attribute can be written.
Definition: type-id.h:64
std::map< std::string, LogComponent * > ComponentList
LogComponent name map.
Definition: log.h:383
Ptr< const AttributeChecker > checker
Checker object.
Definition: type-id.h:90
std::string codeWord
format next word as source code
void Print(void) const
Print output in "a -> b" form on std::cout.
std::vector< std::string > m_noTids
List of type names without TypeIds, because those modules aren't enabled.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
std::string name
Attribute name.
Definition: type-id.h:78
virtual TypeId GetInstanceTypeId(void) const
Implement the GetInstanceTypeId method defined in ObjectBase.
Definition: object.cc:79
std::string name
Trace name.
Definition: type-id.h:99
static ComponentList * GetComponentList(void)
Get the list of LogComponnents.
Definition: log.cc:79
std::string GetName(void) const
Get the name.
Definition: type-id.cc:958
const bool m_seeBase
Print a "see also" pointing to the base class.
std::vector< TypeId > m_alreadyProcessed
List of TypeIds we've already processed.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
AttributeChecker implementation for PointerValue.
Definition: pointer.h:97
The attribute can be read.
Definition: type-id.h:63
Descriptor for an AttributeValue.
std::size_t GetSize(void) const
Get the size of this object.
Definition: type-id.cc:972
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:495
static Iterator End(void)
The End iterator.
Gather aggregation and configuration path information from registered types.
std::string copyDoc
copy (or refer) to docs elsewhere
std::vector< std::string > m_currentPath
Current configuration path.
std::string callback
Callback function signature type.
Definition: type-id.h:103
void Gather(TypeId tid)
Gather aggregation and configuration path information for tid.
void Parse(int argc, char *argv[])
Parse the program arguments.
bool IsChildOf(TypeId other) const
Check if this TypeId is a child of another.
Definition: type-id.cc:939
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
struct TypeId::TraceSourceInformation GetTraceSource(uint32_t i) const
Get the trace source by index.
Definition: type-id.cc:1085
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Get Attribute information by index.
Definition: type-id.cc:1065
std::vector< std::pair< TypeId, TypeId > > m_aggregates
List of aggregation relationships.
std::string flagSpanStop
end of Attribute flag value
a unique identifier for an interface.
Definition: type-id.h:58
std::string help
Attribute help string.
Definition: type-id.h:80
std::string GetCurrentPath(void) const
void RecordAggregationInfo(std::string a, std::string b)
Record the a -> b aggregation relation.