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 
21 #include <iostream>
22 #include <algorithm>
23 #include <map>
24 #include <climits> // CHAR_BIT
25 
26 #include "ns3/command-line.h"
27 #include "ns3/config.h"
28 #include "ns3/global-value.h"
29 #include "ns3/log.h"
30 #include "ns3/object-vector.h"
31 #include "ns3/object.h"
32 #include "ns3/pointer.h"
33 #include "ns3/string.h"
34 #include "ns3/node-container.h"
35 #include "ns3/simple-channel.h"
36 
37 using namespace ns3;
38 
39 NS_LOG_COMPONENT_DEFINE ("PrintIntrospectedDoxygen");
40 
41 namespace
42 {
43  std::string anchor;
44  std::string argument;
45  std::string boldStart;
46  std::string boldStop;
47  std::string breakBoth;
48  std::string breakHtmlOnly;
49  std::string breakTextOnly;
50  std::string brief;
51  std::string classStart;
52  std::string classStop;
53  std::string codeWord;
54  std::string commentStart;
55  std::string commentStop;
56  std::string copyDoc;
57  std::string flagSpanStart;
58  std::string flagSpanStop;
59  std::string functionStart;
60  std::string functionStop;
61  std::string headingStart;
62  std::string headingStop;
63  std::string indentHtmlOnly;
64  std::string listLineStart;
65  std::string listLineStop;
66  std::string listStart;
67  std::string listStop;
68  std::string page;
69  std::string reference;
70  std::string returns;
71  std::string sectionStart;
72  std::string seeAlso;
73  std::string subSectionStart;
74  std::string variable;
75 
76 } // anonymous namespace
77 
78 
84 void
85 SetMarkup (bool outputText)
86 {
87  NS_LOG_FUNCTION (outputText);
88  if (outputText)
89  {
90  anchor = "";
91  argument = " Arg: ";
92  boldStart = "";
93  boldStop = "";
94  breakBoth = "\n";
95  breakHtmlOnly = "";
96  breakTextOnly = "\n";
97  brief = "";
98  classStart = "";
99  classStop = "\n\n";
100  codeWord = " ";
101  commentStart = "===============================================================\n";
102  commentStop = "";
103  copyDoc = " See: ";
104  flagSpanStart = "";
105  flagSpanStop = "";
106  functionStart = "";
107  functionStop = "\n\n";
108  headingStart = "";
109  headingStop = "";
110  indentHtmlOnly = "";
111  page = "Page ";
112  listStart = "";
113  listStop = "";
114  listLineStart = " * ";
115  listLineStop = "";
116  reference = " ";
117  returns = " Returns: ";
118  sectionStart = "Section ";
119  seeAlso = " See: ";
120  subSectionStart = "Subsection ";
121  variable = "Variable: ";
122  }
123  else
124  {
125  anchor = "\\anchor ";
126  argument = "\\param ";
127  boldStart = "<b>";
128  boldStop = "</b>";
129  breakBoth = "<br>";
130  breakHtmlOnly = "<br>";
131  breakTextOnly = "";
132  brief = "\\brief ";
133  classStart = "\\class ";
134  classStop = "";
135  codeWord = "\\p ";
136  commentStart = "/*!\n";
137  commentStop = "*/\n";
138  copyDoc = "\\copydoc ";
139  flagSpanStart = "<span class=\"mlabel\">";
140  flagSpanStop = "</span>";
141  functionStart = "\\fn ";
142  functionStop = "";
143  headingStart = "<h3>";
144  headingStop = "</h3>";
145  indentHtmlOnly = " ";
146  page = "\\page ";
147  listStart = "<ul>";
148  listStop = "</ul>";
149  listLineStart = "<li>";
150  listLineStop = "</li>";
151  reference = " \\ref ";
152  returns = "\\returns ";
153  sectionStart = "\\ingroup ";
154  seeAlso = "\\see ";
155  subSectionStart = "\\addtogroup ";
156  variable = "\\var ";
157  }
158 } // SetMarkup ()
159 
160 
161 /***************************************************************
162  * Docs for a single TypeId
163  ***************************************************************/
164 
173 void
174 PrintAttributesTid (std::ostream &os, const TypeId tid)
175 {
176  NS_LOG_FUNCTION (tid);
177  os << listStart << std::endl;
178  for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
179  {
180  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
181  os << listLineStart
182  << boldStart << info.name << boldStop << ": "
183  << info.help
184  << std::endl;
185  os << " "
186  << listStart << std::endl;
187  os << " "
188  << listLineStart
189  << "Set with class: " << reference
190  << info.checker->GetValueTypeName ()
191  << listLineStop
192  << std::endl;
193  if (info.checker->HasUnderlyingTypeInformation ())
194  {
195  os << " "
196  << listLineStart
197  << "Underlying type: ";
198 
199  std::string valType = info.checker->GetValueTypeName ();
200  std::string underType = info.checker->GetUnderlyingTypeInformation ();
201  if ((valType != "ns3::EnumValue") && (underType != "std::string"))
202  {
203  // Indirect cases to handle
204  bool handled = false;
205 
206  if (valType == "ns3::PointerValue")
207  {
208  const PointerChecker *ptrChecker =
209  dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
210  if (ptrChecker != 0)
211  {
212  os << reference << "ns3::Ptr" << "< "
213  << reference << ptrChecker->GetPointeeTypeId ().GetName ()
214  << ">";
215  handled = true;
216  }
217  }
218  else if (valType == "ns3::ObjectPtrContainerValue")
219  {
220  const ObjectPtrContainerChecker * ptrChecker =
221  dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
222  if (ptrChecker != 0)
223  {
224  os << reference << "ns3::Ptr" << "< "
225  << reference << ptrChecker->GetItemTypeId ().GetName ()
226  << ">";
227  handled = true;
228  }
229  }
230  // Helper to match first part of string
231  class StringBeginMatcher
232  {
233  public:
234  StringBeginMatcher (const std::string s)
235  : m_string (s) { };
236  bool operator () (const std::string t)
237  {
238  std::size_t pos = m_string.find (t);
239  return pos == 0;
240  };
241  private:
242  std::string m_string;
243  };
244  StringBeginMatcher match (underType);
245 
246  if ( match ("bool") || match ("double") ||
247  match ("int8_t") || match ("uint8_t") ||
248  match ("int16_t") || match ("uint16_t") ||
249  match ("int32_t") || match ("uint32_t") ||
250  match ("int64_t") || match ("uint64_t")
251  )
252  {
253  os << underType;
254  handled = true;
255  }
256  if (! handled)
257  {
258  os << reference << underType;
259  }
260  }
261  os << listLineStop << std::endl;
262  }
263  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
264  {
265  os << " "
266  << listLineStart
267  << "Initial value: "
268  << info.initialValue->SerializeToString (info.checker)
269  << listLineStop
270  << std::endl;
271  }
272  os << " " << listLineStart << "Flags: ";
273  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
274  {
275  os << flagSpanStart << "construct " << flagSpanStop;
276  }
277  if (info.flags & TypeId::ATTR_SET && info.accessor->HasSetter ())
278  {
279  os << flagSpanStart << "write " << flagSpanStop;
280  }
281  if (info.flags & TypeId::ATTR_GET && info.accessor->HasGetter ())
282  {
283  os << flagSpanStart << "read " << flagSpanStop;
284  }
285  os << listLineStop << std::endl;
286  os << " "
287  << listStop
288  << " " << std::endl;
289 
290  }
291  os << listStop << std::endl;
292 } // PrintAttributesTid ()
293 
294 
305 void
306 PrintAttributes (std::ostream & os, const TypeId tid)
307 {
308  NS_LOG_FUNCTION (tid);
309  if (tid.GetAttributeN () == 0)
310  {
311  os << "No Attributes are defined for this type."
312  << breakBoth
313  << std::endl;
314  }
315  else
316  {
317  os << headingStart
318  << "Attributes"
319  << headingStop
320  << std::endl;
321  PrintAttributesTid (os, tid);
322  }
323 
324  // Attributes from base classes
325  TypeId tmp = tid.GetParent ();
326  while (tmp.GetParent () != tmp)
327  {
328  if (tmp.GetAttributeN () != 0)
329  {
330  os << headingStart
331  << "Attributes defined in parent class "
332  << tmp.GetName ()
333  << headingStop
334  << std::endl;
335  PrintAttributesTid (os, tmp);
336  }
337  tmp = tmp.GetParent ();
338 
339  } // Attributes
340 } // PrintAttributes ()
341 
342 
351 void
352 PrintTraceSourcesTid (std::ostream & os, const TypeId tid)
353 {
354  NS_LOG_FUNCTION (tid);
355  os << listStart << std::endl;
356  for (uint32_t i = 0; i < tid.GetTraceSourceN (); ++i)
357  {
358  struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i);
359  os << listLineStart
360  << boldStart << info.name << boldStop << ": "
361  << info.help << breakBoth
362  // '%' prevents doxygen from linking to the Callback class...
363  << "%Callback signature: "
364  << info.callback
365  << std::endl;
366  os << listLineStop << std::endl;
367  }
368  os << listStop << std::endl;
369 } // PrintTraceSourcesTid ()
370 
371 
382 void
383 PrintTraceSources (std::ostream & os, const TypeId tid)
384 {
385  NS_LOG_FUNCTION (tid);
386  if (tid.GetTraceSourceN () == 0)
387  {
388  os << "No TraceSources are defined for this type."
389  << breakBoth
390  << std::endl;
391  }
392  else
393  {
394  os << headingStart
395  << "TraceSources"
396  << headingStop << std::endl;
397  PrintTraceSourcesTid (os, tid);
398  }
399 
400  // Trace sources from base classes
401  TypeId tmp = tid.GetParent ();
402  while (tmp.GetParent () != tmp)
403  {
404  if (tmp.GetTraceSourceN () != 0)
405  {
406  os << headingStart
407  << "TraceSources defined in parent class "
408  << tmp.GetName ()
409  << headingStop << std::endl;
410  PrintTraceSourcesTid (os, tmp);
411  }
412  tmp = tmp.GetParent ();
413  }
414 
415 } // PrintTraceSources ()
416 
423 void PrintSize (std::ostream & os, const TypeId tid)
424 {
425  NS_LOG_FUNCTION (tid);
426  NS_ASSERT_MSG (CHAR_BIT != 0, "CHAR_BIT is zero");
427 
428  std::size_t arch = (sizeof (void *) * CHAR_BIT);
429 
430  os << boldStart << "Size" << boldStop
431  << " of this type is " << tid.GetSize ()
432  << " bytes (on a " << arch << "-bit architecture)."
433  << std::endl;
434 } // PrintSize ()
435 
436 
437 /***************************************************************
438  * Lists of All things
439  ***************************************************************/
440 
446 void
447 PrintAllAttributes (std::ostream & os)
448 {
450  os << commentStart << page << "AttributeList All Attributes\n"
451  << std::endl;
452  os << "This is a list of all" << reference << "attribute by class. "
453  << "For more information see the" << reference << "attribute "
454  << "section of this API documentation and the Attributes sections "
455  << "in the Tutorial and Manual.\n"
456  << std::endl;
457 
458  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
459  {
460  TypeId tid = TypeId::GetRegistered (i);
461  if (tid.GetAttributeN () == 0 ||
463  {
464  continue;
465  }
466  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
467  << std::endl;
468 
469  os << listStart << std::endl;
470  for (uint32_t j = 0; j < tid.GetAttributeN (); ++j)
471  {
472  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
473  os << listLineStart
474  << boldStart << info.name << boldStop
475  << ": " << info.help
476  << listLineStop
477  << std::endl;
478  }
479  os << listStop << std::endl;
480  }
481  os << commentStop << std::endl;
482 
483 } // PrintAllAttributes ()
484 
485 
491 void
492 PrintAllGlobals (std::ostream & os)
493 {
495  os << commentStart << page << "GlobalValueList All GlobalValues\n"
496  << std::endl;
497  os << "This is a list of all" << reference << "ns3::GlobalValue instances.\n"
498  << std::endl;
499 
500  os << listStart << std::endl;
502  i != GlobalValue::End ();
503  ++i)
504  {
505  StringValue val;
506  (*i)->GetValue (val);
507  os << indentHtmlOnly
508  << listLineStart
509  << boldStart
510  << anchor
511  << "GlobalValue" << (*i)->GetName () << " " << (*i)->GetName ()
512  << boldStop
513  << ": " << (*i)->GetHelp ()
514  << ". Default value: " << val.Get () << "."
515  << listLineStop
516  << std::endl;
517  }
518  os << listStop << std::endl;
519  os << commentStop << std::endl;
520 
521 } // PrintAllGlobals ()
522 
523 
529 void
530 PrintAllLogComponents (std::ostream & os)
531 {
533  os << commentStart << page << "LogComponentList All LogComponents\n"
534  << std::endl;
535  os << "This is a list of all" << reference << "ns3::LogComponent instances.\n"
536  << std::endl;
537 
542  os << listStart << std::endl;
544  LogComponent::ComponentList::const_iterator it;
545  for (it = logs->begin (); it != logs->end (); ++it)
546  {
547  std::string file = it->second->File ();
548  // Strip leading "../" related to depth in build directory
549  // since doxygen only sees the path starting with "src/", etc.
550  while (file.find ("../") == 0)
551  {
552  file = file.substr (3);
553  }
554 
555  os << listLineStart
556  << boldStart << it->first << boldStop << ": " << file
557  << listLineStop
558  << std::endl;
559  }
560  os << listStop << std::endl;
561  os << commentStop << std::endl;
562 } // PrintAllLogComponents ()
563 
564 
570 void
571 PrintAllTraceSources (std::ostream & os)
572 {
574  os << commentStart << page << "TraceSourceList All TraceSources\n"
575  << std::endl;
576  os << "This is a list of all" << reference << "tracing sources. "
577  << "For more information see the " << reference << "tracing "
578  << "section of this API documentation and the Tracing sections "
579  << "in the Tutorial and Manual.\n"
580  << std::endl;
581 
582  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
583  {
584  TypeId tid = TypeId::GetRegistered (i);
585  if (tid.GetTraceSourceN () == 0 ||
587  {
588  continue;
589  }
590  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
591  << std::endl;
592 
593  os << listStart << std::endl;
594  for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j)
595  {
596  struct TypeId::TraceSourceInformation info = tid.GetTraceSource(j);
597  os << listLineStart
598  << boldStart << info.name << boldStop
599  << ": " << info.help
600  << listLineStop
601  << std::endl;
602  }
603  os << listStop << std::endl;
604  }
605  os << commentStop << std::endl;
606 
607 } // PrintAllTraceSources ()
608 
609 
610 /***************************************************************
611  * Docs for Attribute classes
612  ***************************************************************/
613 
614 
628 void
629 PrintAttributeValueSection (std::ostream & os,
630  const std::string & name,
631  const bool seeBase = true)
632 {
633  NS_LOG_FUNCTION (name);
634  std::string section = "attribute_" + name;
635 
636  // \ingroup attribute
637  // \defgroup attribute_<name>Value <name> Attribute
638  os << commentStart << sectionStart << "attribute\n"
639  << subSectionStart << "attribute_" << name << " "
640  << name << " Attribute\n"
641  << "Attribute implementation for " << name << "\n";
642  if (seeBase)
643  {
644  // Some classes don't live in ns3::. Yuck
645  if (name != "IeMeshId")
646  {
647  os << seeAlso << "ns3::" << name << "\n";
648  }
649  else
650  {
651  os << seeAlso << "ns3::dot11s::" << name << "\n";
652  }
653  }
654  os << commentStop;
655 
656 } // PrintAttributeValueSection ()
657 
658 
669 void
670 PrintAttributeValueWithName (std::ostream & os,
671  const std::string & name,
672  const std::string & type,
673  const std::string & header)
674 {
675  NS_LOG_FUNCTION (name << type << header);
676  std::string sectAttr = sectionStart + "attribute_" + name;
677 
678  // \ingroup attribute_<name>Value
679  // \class ns3::<name>Value "header"
680  std::string valClass = name + "Value";
681  std::string qualClass = " ns3::" + valClass;
682 
683  os << commentStart << sectAttr << std::endl;
684  os << classStart << qualClass << " \"" << header << "\"" << std::endl;
685  os << "AttributeValue implementation for " << name << "." << std::endl;
686  os << seeAlso << "AttributeValue" << std::endl;
687  os << commentStop;
688 
689  // Copy ctor: <name>Value::<name>Value
690  os << commentStart
691  << functionStart << name
692  << qualClass << "::" << valClass;
693  if ( (name == "EmptyAttribute") ||
694  (name == "ObjectPtrContainer") )
695  {
696  // Just default constructors.
697  os << "(void)\n";
698  }
699  else
700  {
701  // Copy constructors
702  os << "(const " << type << " & value)\n"
703  << "Copy constructor.\n"
704  << argument << "[in] value The " << name << " value to copy.\n";
705  }
706  os << commentStop;
707 
708  // <name>Value::Get (void) const
709  os << commentStart
710  << functionStart << type
711  << qualClass << "::Get (void) const\n"
712  << returns << "The " << name << " value.\n"
713  << commentStop;
714 
715  // <name>Value::GetAccessor (T & value) const
716  os << commentStart
717  << functionStart << "bool"
718  << qualClass << "::GetAccessor (T & value) const\n"
719  << "Access the " << name << " value as type " << codeWord << "T.\n"
720  << argument << "[out] value The " << name << " value, as type "
721  << codeWord << "T.\n"
722  << returns << "true.\n"
723  << commentStop;
724 
725  // <name>Value::Set (const name & value)
726  if (type != "Callback") // Yuck
727  {
728  os << commentStart
729  << functionStart << "void"
730  << qualClass << "::Set (const " << type << " & value)\n"
731  << "Set the value.\n"
732  << argument << "[in] value The value to adopt.\n"
733  << commentStop;
734  }
735 
736  // <name>Value::m_value
737  os << commentStart
738  << variable << type
739  << qualClass << "::m_value\n"
740  << "The stored " << name << " instance.\n"
741  << commentStop
742  << std::endl;
743 
744 } // PrintAttributeValueWithName ()
745 
746 
755 void
756 PrintMakeAccessors (std::ostream & os, const std::string & name)
757 {
758  NS_LOG_FUNCTION (name);
759  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
760  std::string make = "ns3::Make" + name + "Accessor ";
761 
762  // \ingroup attribute_<name>Value
763  // Make<name>Accessor (T1 a1)
764  os << commentStart << sectAttr
765  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
766  << make << "(T1 a1)\n"
767  << copyDoc << "ns3::MakeAccessorHelper(T1)\n"
768  << seeAlso << "AttributeAccessor\n"
769  << commentStop;
770 
771  // \ingroup attribute_<name>Value
772  // Make<name>Accessor (T1 a1)
773  os << commentStart << sectAttr
774  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
775  << make << "(T1 a1, T2 a2)\n"
776  << copyDoc << "ns3::MakeAccessorHelper(T1,T2)\n"
777  << seeAlso << "AttributeAccessor\n"
778  << commentStop;
779 } // PrintMakeAccessors ()
780 
781 
791 void
792 PrintMakeChecker (std::ostream & os,
793  const std::string & name,
794  const std::string & header)
795 {
796  NS_LOG_FUNCTION (name << header);
797  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
798  std::string make = "ns3::Make" + name + "Checker ";
799 
800  // \ingroup attribute_<name>Value
801  // class <name>Checker
802  os << commentStart << sectAttr << std::endl;
803  os << classStart << " ns3::" << name << "Checker"
804  << " \"" << header << "\"" << std::endl;
805  os << "AttributeChecker implementation for " << name << "Value." << std::endl;
806  os << seeAlso << "AttributeChecker" << std::endl;
807  os << commentStop;
808 
809  // \ingroup attribute_<name>Value
810  // Make<name>Checker (void)
811  os << commentStart << sectAttr
812  << functionStart << "ns3::Ptr<const ns3::AttributeChecker> "
813  << make << "(void)\n"
814  << returns << "The AttributeChecker.\n"
815  << seeAlso << "AttributeChecker\n"
816  << commentStop;
817 } // PrintMakeChecker ()
818 
819 
821 typedef struct {
822  const std::string m_name;
823  const std::string m_type;
824  const bool m_seeBase;
825  const std::string m_header;
827 
828 
837 void
838 PrintAttributeHelper (std::ostream & os,
839  const AttributeDescriptor & attr)
840 {
841  NS_LOG_FUNCTION (attr.m_name << attr.m_type << attr.m_seeBase <<
842  attr.m_header);
844  PrintAttributeValueWithName (os, attr.m_name, attr.m_type, attr.m_header);
845  PrintMakeAccessors (os, attr.m_name);
846  PrintMakeChecker (os, attr.m_name, attr.m_header);
847 } // PrintAttributeHelper ()
848 
849 
853 void
854 PrintAttributeImplementations (std::ostream & os)
855 {
857 
858  const AttributeDescriptor attributes [] =
859  {
860  // Users of ATTRIBUTE_HELPER_HEADER
861  //
862  { "Address", "Address", true, "address.h" },
863  { "Box", "Box", true, "box.h" },
864  { "DataRate", "DataRate", true, "data-rate.h" },
865  { "HtCapabilities", "HtCapabilities", true, "ht-capabilities.h" },
866  { "IeMeshId", "IeMeshId", true, "id-dot11s-id.h" },
867  { "Ipv4Address", "Ipv4Address", true, "ipv4-address.h" },
868  { "Ipv4Mask", "Ipv4Mask", true, "ipv4-address.h" },
869  { "Ipv6Address", "Ipv6Address", true, "ipv6-address.h" },
870  { "Ipv6Prefix", "Ipv6Prefix", true, "ipv6-address.h" },
871  { "Mac16Address", "Mac16Address", true, "mac16-address.h" },
872  { "Mac48Address", "Mac48Address", true, "mac48-address.h" },
873  { "Mac64Address", "Mac64Address", true, "mac64-address.h" },
874  { "ObjectFactory", "ObjectFactory", true, "object-factory.h" },
875  { "OrganizationIdentifier",
876  "OrganizationIdentifier",
877  true, "vendor-specific-action.h" },
878  { "Rectangle", "Rectangle", true, "rectangle.h" },
879  { "Ssid", "Ssid", true, "ssid.h" },
880  { "TypeId", "TypeId", true, "type-id.h" },
881  { "UanModesList", "UanModesList", true, "uan-tx-mode.h" },
882  { "ValueClassTest", "ValueClassTest", false, "" /* outside ns3 */ },
883  { "Vector2D", "Vector2D", true, "vector.h" },
884  { "Vector3D", "Vector3D", true, "vector.h" },
885  { "Waypoint", "Waypoint", true, "waypoint.h" },
886  { "WifiMode", "WifiMode", true, "wifi-mode.h" },
887 
888  // All three (Value, Access and Checkers) defined, but custom
889  { "Boolean", "Boolean", false, "boolean.h" },
890  { "Callback", "Callback", true, "callback.h" },
891  { "Double", "double", false, "double.h" },
892  { "Enum", "int", false, "enum.h" },
893  { "Integer", "int64_t", false, "integer.h" },
894  { "Pointer", "Pointer", false, "pointer.h" },
895  { "RandomVariable", "RandomVariable", true, "random-variable.h" },
896  { "String", "std::string", false, "string.h" },
897  { "Time", "Time", true, "nstime.h" },
898  { "Uinteger", "uint64_t", false, "uinteger.h" },
899  { "", "", false, "last placeholder" }
900  };
901 
902  int i = 0;
903  while (attributes[i].m_name != "")
904  {
905  PrintAttributeHelper (os, attributes[i]);
906  ++i;
907  }
908 
909  // Special cases
910  PrintAttributeValueSection (os, "EmptyAttribute", false);
911  PrintAttributeValueWithName (os, "EmptyAttribute", "EmptyAttribute",
912  "attribute.h");
913 
914  PrintAttributeValueSection (os, "ObjectPtrContainer", false);
915  PrintAttributeValueWithName (os, "ObjectPtrContainer", "ObjectPtrContainer", "object-ptr-container.h");
916  PrintMakeChecker (os, "ObjectPtrContainer", "object-ptr-container.h");
917 
918  PrintAttributeValueSection (os, "ObjectVector", false);
919  PrintMakeAccessors (os, "ObjectVector");
920  PrintMakeChecker (os, "ObjectVector", "object-vector.h");
921 
922  PrintAttributeValueSection (os, "ObjectMap", false);
923  PrintMakeAccessors (os, "ObjectMap");
924  PrintMakeChecker (os, "ObjectMap", "object-map.h");
925 
926 } // PrintAttributeImplementations ()
927 
928 
929 /***************************************************************
930  * Aggregation and configuration paths
931  ***************************************************************/
932 
937 {
938 public:
945  void RecordAggregationInfo (std::string a, std::string b);
951  void Gather (TypeId tid);
955  void Print (void) const;
956 
962  std::vector<std::string> Get (TypeId tid) const;
963 
967  std::vector<std::string> GetNoTypeIds (void) const;
968 
969 private:
973  std::string GetCurrentPath (void) const;
979  void DoGather (TypeId tid);
985  void RecordOutput (TypeId tid);
991  bool HasAlreadyBeenProcessed (TypeId tid) const;
995  std::vector<std::pair<TypeId,std::string> > m_output;
999  std::vector<std::string> m_currentPath;
1003  std::vector<TypeId> m_alreadyProcessed;
1007  std::vector<std::pair<TypeId,TypeId> > m_aggregates;
1014  mutable std::vector<std::string> m_noTids;
1015 
1016 }; // class StaticInformation
1017 
1018 
1019 void
1020 StaticInformation::RecordAggregationInfo (std::string a, std::string b)
1021 {
1022  NS_LOG_FUNCTION (this << a << b);
1023  TypeId aTid;
1024  bool found = TypeId::LookupByNameFailSafe (a, &aTid);
1025  if (!found)
1026  {
1027  m_noTids.push_back (a);
1028  return;
1029  }
1030  TypeId bTid;
1031  found = TypeId::LookupByNameFailSafe (b, &bTid);
1032  if (!found)
1033  {
1034  m_noTids.push_back (b);
1035  return;
1036  }
1037 
1038  m_aggregates.push_back (std::make_pair (aTid, bTid));
1039 }
1040 
1041 
1042 void
1044 {
1045  NS_LOG_FUNCTION (this);
1046  for (std::vector<std::pair<TypeId,std::string> >::const_iterator i = m_output.begin (); i != m_output.end (); ++i)
1047  {
1048  std::pair<TypeId,std::string> item = *i;
1049  std::cout << item.first.GetName () << " -> " << item.second << std::endl;
1050  }
1051 }
1052 
1053 
1054 std::string
1056 {
1057  NS_LOG_FUNCTION (this);
1058  std::ostringstream oss;
1059  for (std::vector<std::string>::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i)
1060  {
1061  std::string item = *i;
1062  oss << "/" << item;
1063  }
1064  return oss.str ();
1065 }
1066 
1067 
1068 void
1070 {
1071  NS_LOG_FUNCTION (this << tid);
1072  m_output.push_back (std::make_pair (tid, GetCurrentPath ()));
1073 }
1074 
1075 
1076 bool
1078 {
1079  NS_LOG_FUNCTION (this << tid);
1080  for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i)
1081  {
1082  if (m_alreadyProcessed[i] == tid)
1083  {
1084  return true;
1085  }
1086  }
1087  return false;
1088 }
1089 
1090 
1091 std::vector<std::string>
1093 {
1094  NS_LOG_FUNCTION (this << tid);
1095  std::vector<std::string> paths;
1096  for (uint32_t i = 0; i < m_output.size (); ++i)
1097  {
1098  std::pair<TypeId,std::string> tmp = m_output[i];
1099  if (tmp.first == tid)
1100  {
1101  paths.push_back (tmp.second);
1102  }
1103  }
1104  return paths;
1105 }
1106 
1122 template <typename T>
1123 void
1125 {
1126  std::sort (t.begin (), t.end ());
1127  t.erase (std::unique (t.begin (), t.end ()), t.end ());
1128 }
1129 
1130 std::vector<std::string>
1132 {
1133  NS_LOG_FUNCTION (this);
1134  Uniquefy (m_noTids);
1135  return m_noTids;
1136 }
1137 
1138 
1139 void
1141 {
1142  NS_LOG_FUNCTION (this << tid);
1143  DoGather (tid);
1144  Uniquefy (m_output);
1145 }
1146 
1147 
1148 void
1150 {
1151  NS_LOG_FUNCTION (this << tid);
1152  if (HasAlreadyBeenProcessed (tid))
1153  {
1154  return;
1155  }
1156  RecordOutput (tid);
1157  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
1158  {
1159  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
1160  const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
1161  if (ptrChecker != 0)
1162  {
1163  TypeId pointee = ptrChecker->GetPointeeTypeId ();
1164 
1165  // See if this is a pointer to an Object.
1166  Ptr<Object> object = CreateObject<Object> ();
1167  TypeId objectTypeId = object->GetTypeId ();
1168  if (objectTypeId == pointee)
1169  {
1170  // Stop the recursion at this attribute if it is a
1171  // pointer to an Object, which create too many spurious
1172  // paths in the list of attribute paths because any
1173  // Object can be in that part of the path.
1174  continue;
1175  }
1176 
1177  m_currentPath.push_back (info.name);
1178  m_alreadyProcessed.push_back (tid);
1179  DoGather (pointee);
1180  m_alreadyProcessed.pop_back ();
1181  m_currentPath.pop_back ();
1182  continue;
1183  }
1184  // attempt to cast to an object vector.
1185  const ObjectPtrContainerChecker *vectorChecker = dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
1186  if (vectorChecker != 0)
1187  {
1188  TypeId item = vectorChecker->GetItemTypeId ();
1189  m_currentPath.push_back (info.name + "/[i]");
1190  m_alreadyProcessed.push_back (tid);
1191  DoGather (item);
1192  m_alreadyProcessed.pop_back ();
1193  m_currentPath.pop_back ();
1194  continue;
1195  }
1196  }
1197  for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++)
1198  {
1199  TypeId child = TypeId::GetRegistered (j);
1200  if (child.IsChildOf (tid))
1201  {
1202  std::string childName = "$" + child.GetName ();
1203  m_currentPath.push_back (childName);
1204  m_alreadyProcessed.push_back (tid);
1205  DoGather (child);
1206  m_alreadyProcessed.pop_back ();
1207  m_currentPath.pop_back ();
1208  }
1209  }
1210  for (uint32_t k = 0; k < m_aggregates.size (); ++k)
1211  {
1212  std::pair<TypeId,TypeId> tmp = m_aggregates[k];
1213  if (tmp.first == tid || tmp.second == tid)
1214  {
1215  TypeId other;
1216  if (tmp.first == tid)
1217  {
1218  other = tmp.second;
1219  }
1220  if (tmp.second == tid)
1221  {
1222  other = tmp.first;
1223  }
1224  std::string name = "$" + other.GetName ();
1225  m_currentPath.push_back (name);
1226  m_alreadyProcessed.push_back (tid);
1227  DoGather (other);
1228  m_alreadyProcessed.pop_back ();
1229  m_currentPath.pop_back ();
1230  }
1231  }
1232 } // StaticInformation::DoGather ()
1233 
1234 
1237 {
1239  // The below statements register typical aggregation relationships
1240  // in ns-3 programs, that otherwise aren't picked up automatically
1241  // by the creation of the above node. To manually list other common
1242  // aggregation relationships that you would like to see show up in
1243  // the list of configuration paths in the doxygen, add additional
1244  // statements below.
1245  StaticInformation info;
1246  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
1247  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
1248  info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
1249  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
1250  info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
1251  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
1252  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4NixVectorRouting");
1253  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1254  info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");
1255  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1256  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpL4Protocol");
1257  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv6L3Protocol");
1258  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv6L4Protocol");
1259  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpL4Protocol");
1260  info.RecordAggregationInfo ("ns3::Node", "ns3::RipNg");
1261  info.RecordAggregationInfo ("ns3::Node", "ns3::GlobalRouter");
1262  info.RecordAggregationInfo ("ns3::Node", "ns3::aodv::RoutingProtocol");
1263  info.RecordAggregationInfo ("ns3::Node", "ns3::dsdv::RoutingProtocol");
1264  info.RecordAggregationInfo ("ns3::Node", "ns3::dsr::DsrRouting");
1265  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
1266  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergyHarvesterContainer");
1267  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergySourceContainer");
1268 
1269  // Create a channel object so that channels appear in the namespace
1270  // paths that will be generated here.
1271  Ptr<SimpleChannel> simpleChannel;
1272  simpleChannel = CreateObject<SimpleChannel> ();
1273 
1274  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
1275  {
1277  info.Gather (object->GetInstanceTypeId ());
1278  }
1279 
1280  return info;
1281 
1282 } // GetTypicalAggregations ()
1283 
1284 
1285 // Map from TypeId name to tid
1286 typedef std::map< std::string, int32_t> NameMap;
1287 typedef NameMap::const_iterator NameMapIterator;
1288 
1289 
1290 // Create a map from the class names to their index in the vector of
1291 // TypeId's so that the names will end up in alphabetical order.
1292 NameMap
1294 {
1296  NameMap nameMap;
1297 
1298  // Registered types
1299  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
1300  {
1301  TypeId tid = TypeId::GetRegistered (i);
1302  if (tid.MustHideFromDocumentation ())
1303  {
1304  continue;
1305  }
1306 
1307  // Capitalize all of letters in the name so that it sorts
1308  // correctly in the map.
1309  std::string name = tid.GetName ();
1310  for (uint32_t j = 0; j < name.length (); j++)
1311  {
1312  name[j] = toupper (name[j]);
1313  }
1314 
1315  // Save this name's index.
1316  nameMap[name] = i;
1317  }
1318 
1319  // Type names without TypeIds
1320  std::vector<std::string> noTids = info.GetNoTypeIds ();
1321  for (std::vector<std::string>::const_iterator i = noTids.begin ();
1322  i != noTids.end ();
1323  ++i)
1324  {
1325  nameMap[*i] = -1;
1326  }
1327 
1328  return nameMap;
1329 } // GetNameMap ()
1330 
1331 
1332 void
1333 PrintConfigPaths (std::ostream & os, const StaticInformation & info,
1334  const TypeId tid)
1335 {
1336  NS_LOG_FUNCTION (tid);
1337  std::vector<std::string> paths = info.Get (tid);
1338 
1339  // Config --------------
1340  if (paths.empty ())
1341  {
1342  os << "Introspection did not find any typical Config paths."
1343  << breakBoth
1344  << std::endl;
1345  }
1346  else
1347  {
1348  os << headingStart
1349  << "Config Paths"
1350  << headingStop
1351  << std::endl;
1352  os << std::endl;
1353  os << tid.GetName ()
1354  << " is accessible through the following paths"
1355  << " with Config::Set and Config::Connect:"
1356  << std::endl;
1357  os << listStart << std::endl;
1358  for (uint32_t k = 0; k < paths.size (); ++k)
1359  {
1360  std::string path = paths[k];
1361  os << listLineStart
1362  << "\"" << path << "\""
1363  << listLineStop
1364  << breakTextOnly
1365  << std::endl;
1366  }
1367  os << listStop << std::endl;
1368  }
1369 } // PrintConfigPaths ()
1370 
1371 
1372 /***************************************************************
1373  * Main
1374  ***************************************************************/
1375 
1376 int main (int argc, char *argv[])
1377 {
1379  bool outputText = false;
1380 
1381  CommandLine cmd;
1382  cmd.Usage ("Generate documentation for all ns-3 registered types, "
1383  "trace sources, attributes and global variables.");
1384  cmd.AddValue ("output-text", "format output as plain text", outputText);
1385  cmd.Parse (argc, argv);
1386 
1387  SetMarkup (outputText);
1388 
1389 
1390  // Create a Node, to force linking and instantiation of our TypeIds
1391  NodeContainer c;
1392  c.Create (1);
1393 
1394  // mode-line: helpful when debugging introspected-doxygen.h
1395  if (!outputText)
1396  {
1397  std::cout << "/* -*- Mode:C++; c-file-style:\"gnu\"; "
1398  "indent-tabs-mode:nil; -*- */\n"
1399  << std::endl;
1400  }
1401 
1402  // Get typical aggregation relationships.
1404 
1405  NameMap nameMap = GetNameMap (info);
1406 
1407  // Iterate over the map, which will print the class names in
1408  // alphabetical order.
1409  for (NameMapIterator nameMapIterator = nameMap.begin ();
1410  nameMapIterator != nameMap.end ();
1411  nameMapIterator++)
1412  {
1413  // Get the class's index out of the map;
1414  std::string name = nameMapIterator->first;
1415  int32_t i = nameMapIterator->second;
1416  TypeId tid;
1417 
1418  if (i >= 0)
1419  {
1420  tid = TypeId::GetRegistered (i);
1421  if (tid.MustHideFromDocumentation ())
1422  {
1423  continue;
1424  }
1425  name = tid.GetName ();
1426  }
1427 
1428  std::cout << commentStart << std::endl;
1429 
1430  std::cout << classStart << name << std::endl;
1431  std::cout << std::endl;
1432 
1433  if (i >= 0)
1434  {
1435  PrintConfigPaths (std::cout, info, tid);
1436  PrintAttributes (std::cout, tid);
1437  PrintTraceSources (std::cout, tid);
1438  PrintSize (std::cout, tid);
1439  }
1440  else
1441  {
1442  std::cout << "Introspection could not find Config paths for " << name
1443  << " in this build because the parent module"
1444  << " was not included in the waf configuration."
1445  << breakBoth
1446  << std::endl;
1447  }
1448 
1449  std::cout << commentStop << std::endl;
1450  } // class documentation
1451 
1452 
1453  PrintAllAttributes (std::cout);
1454  PrintAllGlobals (std::cout);
1455  PrintAllLogComponents (std::cout);
1456  PrintAllTraceSources (std::cout);
1457  PrintAttributeImplementations (std::cout);
1458 
1459  return 0;
1460 }
uint32_t GetAttributeN(void) const
Definition: type-id.cc:780
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
virtual TypeId GetInstanceTypeId(void) const
Implement the GetInstanceTypeId method defined in ObjectBase.
Definition: object.cc:79
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 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
Definition: type-id.cc:659
Vector::const_iterator Iterator
Definition: global-value.h:58
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Definition: type-id.cc:571
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
The attribute can be written at construction-time.
Definition: type-id.h:66
virtual TypeId GetItemTypeId(void) const =0
Get the TypeId of the container class type.
std::string breakTextOnly
linebreak for text output only
void Usage(const std::string usage)
Supply the program usage and documentation.
Definition: command-line.cc:95
void DoGather(TypeId tid)
Gather attribute, configuration path information for tid.
The attribute can be read.
Definition: type-id.h:64
bool MustHideFromDocumentation(void) const
Definition: type-id.cc:772
Ptr< const AttributeAccessor > accessor
Definition: type-id.h:75
static uint32_t GetRegisteredN(void)
Definition: type-id.cc:603
bool HasAlreadyBeenProcessed(TypeId tid) const
const std::string m_name
The base name of the resulting AttributeValue type.
static Iterator Begin(void)
Ptr< const AttributeValue > initialValue
Definition: type-id.h:74
std::string sectionStart
start of a section or group
Ptr< Object > GetRootNamespaceObject(uint32_t i)
Definition: config.cc:779
AttributeChecker implementation for ObjectPtrContainerValue.
uint32_t GetTraceSourceN(void) const
Definition: type-id.cc:801
static TypeId GetRegistered(uint32_t i)
Definition: type-id.cc:609
uint32_t GetRootNamespaceObjectN(void)
Definition: config.cc:773
Parse command-line arguments.
Definition: command-line.h:201
std::string breakHtmlOnly
linebreak for html output only
std::map< std::string, LogComponent * > ComponentList
LogComponent name map.
Definition: log.h:383
Ptr< const AttributeChecker > checker
Definition: type-id.h:76
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.
The attribute can be written.
Definition: type-id.h:65
static ComponentList * GetComponentList(void)
Get the list of LogComponnents.
Definition: log.cc:79
std::string GetName(void) const
Definition: type-id.cc:692
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:93
Descriptor for an AttributeValue.
std::size_t GetSize(void) const
Definition: type-id.cc:706
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:491
static Iterator End(void)
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.
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
Definition: type-id.cc:673
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
Definition: type-id.cc:807
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Definition: type-id.cc:787
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:57
std::string GetCurrentPath(void) const
void RecordAggregationInfo(std::string a, std::string b)
Record the a -> b aggregation relation.