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 #include "ns3/system-path.h"
43 
44 using namespace ns3;
45 
46 NS_LOG_COMPONENT_DEFINE ("PrintIntrospectedDoxygen");
47 
48 namespace
49 {
50  std::string anchor;
51  std::string argument;
52  std::string boldStart;
53  std::string boldStop;
54  std::string breakBoth;
55  std::string breakHtmlOnly;
56  std::string breakTextOnly;
57  std::string brief;
58  std::string classStart;
59  std::string classStop;
60  std::string codeWord;
61  std::string commentStart;
62  std::string commentStop;
63  std::string copyDoc;
64  std::string file;
65  std::string flagSpanStart;
66  std::string flagSpanStop;
67  std::string functionStart;
68  std::string functionStop;
69  std::string headingStart;
70  std::string headingStop;
71  std::string indentHtmlOnly;
72  std::string listLineStart;
73  std::string listLineStop;
74  std::string listStart;
75  std::string listStop;
76  std::string note;
77  std::string page;
78  std::string reference;
79  std::string returns;
80  std::string sectionStart;
81  std::string seeAlso;
82  std::string subSectionStart;
83  std::string templArgDeduced;
84  std::string templArgExplicit;
85  std::string templateArgument;
86  std::string variable;
87 
88 } // unnamed namespace
89 
90 
96 void
97 SetMarkup (bool outputText)
98 {
99  NS_LOG_FUNCTION (outputText);
100  if (outputText)
101  {
102  anchor = "";
103  argument = " Arg: ";
104  boldStart = "";
105  boldStop = "";
106  breakBoth = "\n";
107  breakHtmlOnly = "";
108  breakTextOnly = "\n";
109  brief = "";
110  classStart = "";
111  classStop = "\n\n";
112  codeWord = " ";
113  commentStart = "===============================================================\n";
114  commentStop = "";
115  copyDoc = " See: ";
116  file = "File: ";
117  flagSpanStart = "";
118  flagSpanStop = "";
119  functionStart = "";
120  functionStop = "\n\n";
121  headingStart = "";
122  headingStop = "";
123  indentHtmlOnly = "";
124  listLineStart = " * ";
125  listLineStop = "";
126  listStart = "";
127  listStop = "";
128  note = "Note: ";
129  page = "Page ";
130  reference = " ";
131  returns = " Returns: ";
132  sectionStart = "Section ";
133  seeAlso = " See: ";
134  subSectionStart = "Subsection ";
135  templArgDeduced = "[deduced] ";
136  templArgExplicit = "[explicit] ";
137  templateArgument = "Template Arg: ";
138  variable = "Variable: ";
139  }
140  else
141  {
142  anchor = "\\anchor ";
143  argument = "\\param ";
144  boldStart = "<b>";
145  boldStop = "</b>";
146  breakBoth = "<br>";
147  breakHtmlOnly = "<br>";
148  breakTextOnly = "";
149  brief = "\\brief ";
150  classStart = "\\class ";
151  classStop = "";
152  codeWord = "\\p ";
153  commentStart = "/*!\n";
154  commentStop = "*/\n";
155  copyDoc = "\\copydoc ";
156  file = "\\file ";
157  flagSpanStart = "<span class=\"mlabel\">";
158  flagSpanStop = "</span>";
159  functionStart = "\\fn ";
160  functionStop = "";
161  headingStart = "<h3>";
162  headingStop = "</h3>";
163  indentHtmlOnly = " ";
164  listLineStart = "<li>";
165  listLineStop = "</li>";
166  listStart = "<ul>";
167  listStop = "</ul>";
168  note = "\\note ";
169  page = "\\page ";
170  reference = " \\ref ";
171  returns = "\\returns ";
172  sectionStart = "\\ingroup ";
173  seeAlso = "\\see ";
174  subSectionStart = "\\addtogroup ";
175  templArgDeduced = "\\deduced ";
176  templArgExplicit = "\\explicit ";
177  templateArgument = "\\tparam ";
178  variable = "\\var ";
179  }
180 } // SetMarkup ()
181 
182 
183 /***************************************************************
184  * Docs for a single TypeId
185  ***************************************************************/
186 
195 void
196 PrintAttributesTid (std::ostream &os, const TypeId tid)
197 {
198  NS_LOG_FUNCTION (tid);
199  os << listStart << std::endl;
200  for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
201  {
202  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
203  os << listLineStart
204  << boldStart << info.name << boldStop << ": "
205  << info.help
206  << std::endl;
207  os << " "
208  << listStart << std::endl;
209  os << " "
210  << listLineStart
211  << "Set with class: " << reference
212  << info.checker->GetValueTypeName ()
213  << listLineStop
214  << std::endl;
215  if (info.checker->HasUnderlyingTypeInformation ())
216  {
217  os << " "
218  << listLineStart
219  << "Underlying type: ";
220 
221  std::string valType = info.checker->GetValueTypeName ();
222  std::string underType = info.checker->GetUnderlyingTypeInformation ();
223  if ((valType != "ns3::EnumValue") && (underType != "std::string"))
224  {
225  // Indirect cases to handle
226  bool handled = false;
227 
228  if (valType == "ns3::PointerValue")
229  {
230  const PointerChecker *ptrChecker =
231  dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
232  if (ptrChecker != 0)
233  {
234  os << reference << "ns3::Ptr" << "< "
235  << reference << ptrChecker->GetPointeeTypeId ().GetName ()
236  << ">";
237  handled = true;
238  }
239  }
240  else if (valType == "ns3::ObjectPtrContainerValue")
241  {
242  const ObjectPtrContainerChecker * ptrChecker =
243  dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
244  if (ptrChecker != 0)
245  {
246  os << reference << "ns3::Ptr" << "< "
247  << reference << ptrChecker->GetItemTypeId ().GetName ()
248  << ">";
249  handled = true;
250  }
251  }
252  // Helper to match first part of string
253  class StringBeginMatcher
254  {
255  public:
256  StringBeginMatcher (const std::string s)
257  : m_string (s) { };
258  bool operator () (const std::string t)
259  {
260  std::size_t pos = m_string.find (t);
261  return pos == 0;
262  };
263  private:
264  std::string m_string;
265  };
266  StringBeginMatcher match (underType);
267 
268  if ( match ("bool") || match ("double") ||
269  match ("int8_t") || match ("uint8_t") ||
270  match ("int16_t") || match ("uint16_t") ||
271  match ("int32_t") || match ("uint32_t") ||
272  match ("int64_t") || match ("uint64_t")
273  )
274  {
275  os << underType;
276  handled = true;
277  }
278  if (! handled)
279  {
280  os << reference << underType;
281  }
282  }
283  os << listLineStop << std::endl;
284  }
285  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
286  {
287  os << " "
288  << listLineStart
289  << "Initial value: "
290  << info.initialValue->SerializeToString (info.checker)
291  << listLineStop
292  << std::endl;
293  }
294  os << " " << listLineStart << "Flags: ";
295  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
296  {
297  os << flagSpanStart << "construct " << flagSpanStop;
298  }
299  if (info.flags & TypeId::ATTR_SET && info.accessor->HasSetter ())
300  {
301  os << flagSpanStart << "write " << flagSpanStop;
302  }
303  if (info.flags & TypeId::ATTR_GET && info.accessor->HasGetter ())
304  {
305  os << flagSpanStart << "read " << flagSpanStop;
306  }
307  os << listLineStop << std::endl;
308  os << " "
309  << listStop
310  << " " << std::endl;
311 
312  }
313  os << listStop << std::endl;
314 } // PrintAttributesTid ()
315 
316 
327 void
328 PrintAttributes (std::ostream & os, const TypeId tid)
329 {
330  NS_LOG_FUNCTION (tid);
331  if (tid.GetAttributeN () == 0)
332  {
333  os << "No Attributes are defined for this type."
334  << breakBoth
335  << std::endl;
336  }
337  else
338  {
339  os << headingStart
340  << "Attributes"
341  << headingStop
342  << std::endl;
343  PrintAttributesTid (os, tid);
344  }
345 
346  // Attributes from base classes
347  TypeId tmp = tid.GetParent ();
348  while (tmp.GetParent () != tmp)
349  {
350  if (tmp.GetAttributeN () != 0)
351  {
352  os << headingStart
353  << "Attributes defined in parent class "
354  << tmp.GetName ()
355  << headingStop
356  << std::endl;
357  PrintAttributesTid (os, tmp);
358  }
359  tmp = tmp.GetParent ();
360 
361  } // Attributes
362 } // PrintAttributes ()
363 
364 
373 void
374 PrintTraceSourcesTid (std::ostream & os, const TypeId tid)
375 {
376  NS_LOG_FUNCTION (tid);
377  os << listStart << std::endl;
378  for (uint32_t i = 0; i < tid.GetTraceSourceN (); ++i)
379  {
380  struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i);
381  os << listLineStart
382  << boldStart << info.name << boldStop << ": "
383  << info.help << breakBoth
384  // '%' prevents doxygen from linking to the Callback class...
385  << "%Callback signature: "
386  << info.callback
387  << std::endl;
388  os << listLineStop << std::endl;
389  }
390  os << listStop << std::endl;
391 } // PrintTraceSourcesTid ()
392 
393 
404 void
405 PrintTraceSources (std::ostream & os, const TypeId tid)
406 {
407  NS_LOG_FUNCTION (tid);
408  if (tid.GetTraceSourceN () == 0)
409  {
410  os << "No TraceSources are defined for this type."
411  << breakBoth
412  << std::endl;
413  }
414  else
415  {
416  os << headingStart
417  << "TraceSources"
418  << headingStop << std::endl;
419  PrintTraceSourcesTid (os, tid);
420  }
421 
422  // Trace sources from base classes
423  TypeId tmp = tid.GetParent ();
424  while (tmp.GetParent () != tmp)
425  {
426  if (tmp.GetTraceSourceN () != 0)
427  {
428  os << headingStart
429  << "TraceSources defined in parent class "
430  << tmp.GetName ()
431  << headingStop << std::endl;
432  PrintTraceSourcesTid (os, tmp);
433  }
434  tmp = tmp.GetParent ();
435  }
436 
437 } // PrintTraceSources ()
438 
445 void PrintSize (std::ostream & os, const TypeId tid)
446 {
447  NS_LOG_FUNCTION (tid);
448  NS_ASSERT_MSG (CHAR_BIT != 0, "CHAR_BIT is zero");
449 
450  std::size_t arch = (sizeof (void *) * CHAR_BIT);
451 
452  os << boldStart << "Size" << boldStop
453  << " of this type is " << tid.GetSize ()
454  << " bytes (on a " << arch << "-bit architecture)."
455  << std::endl;
456 } // PrintSize ()
457 
458 
459 /***************************************************************
460  * Lists of All things
461  ***************************************************************/
462 
468 void
469 PrintAllAttributes (std::ostream & os)
470 {
472  os << commentStart << page << "AttributeList All Attributes\n"
473  << std::endl;
474  os << "This is a list of all" << reference << "attribute by class. "
475  << "For more information see the" << reference << "attribute "
476  << "section of this API documentation and the Attributes sections "
477  << "in the Tutorial and Manual.\n"
478  << std::endl;
479 
480  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
481  {
482  TypeId tid = TypeId::GetRegistered (i);
483  if (tid.GetAttributeN () == 0 ||
485  {
486  continue;
487  }
488  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
489  << std::endl;
490 
491  os << listStart << std::endl;
492  for (uint32_t j = 0; j < tid.GetAttributeN (); ++j)
493  {
494  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
495  os << listLineStart
496  << boldStart << info.name << boldStop
497  << ": " << info.help
498  << listLineStop
499  << std::endl;
500  }
501  os << listStop << std::endl;
502  }
503  os << commentStop << std::endl;
504 
505 } // PrintAllAttributes ()
506 
507 
513 void
514 PrintAllGlobals (std::ostream & os)
515 {
517  os << commentStart << page << "GlobalValueList All GlobalValues\n"
518  << std::endl;
519  os << "This is a list of all" << reference << "ns3::GlobalValue instances.\n"
520  << std::endl;
521 
522  os << listStart << std::endl;
524  i != GlobalValue::End ();
525  ++i)
526  {
527  StringValue val;
528  (*i)->GetValue (val);
529  os << indentHtmlOnly
530  << listLineStart
531  << boldStart
532  << anchor
533  << "GlobalValue" << (*i)->GetName () << " " << (*i)->GetName ()
534  << boldStop
535  << ": " << (*i)->GetHelp ()
536  << ". Default value: " << val.Get () << "."
537  << listLineStop
538  << std::endl;
539  }
540  os << listStop << std::endl;
541  os << commentStop << std::endl;
542 
543 } // PrintAllGlobals ()
544 
545 
551 void
552 PrintAllLogComponents (std::ostream & os)
553 {
555  os << commentStart << page << "LogComponentList All LogComponents\n"
556  << std::endl;
557  os << "This is a list of all" << reference << "ns3::LogComponent instances.\n"
558  << std::endl;
559 
564  os << listStart << std::endl;
566  LogComponent::ComponentList::const_iterator it;
567  for (it = logs->begin (); it != logs->end (); ++it)
568  {
569  std::string file = it->second->File ();
570  // Strip leading "../" related to depth in build directory
571  // since doxygen only sees the path starting with "src/", etc.
572  while (file.find ("../") == 0)
573  {
574  file = file.substr (3);
575  }
576 
577  os << listLineStart
578  << boldStart << it->first << boldStop << ": " << file
579  << listLineStop
580  << std::endl;
581  }
582  os << listStop << std::endl;
583  os << commentStop << std::endl;
584 } // PrintAllLogComponents ()
585 
586 
592 void
593 PrintAllTraceSources (std::ostream & os)
594 {
596  os << commentStart << page << "TraceSourceList All TraceSources\n"
597  << std::endl;
598  os << "This is a list of all" << reference << "tracing sources. "
599  << "For more information see the " << reference << "tracing "
600  << "section of this API documentation and the Tracing sections "
601  << "in the Tutorial and Manual.\n"
602  << std::endl;
603 
604  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
605  {
606  TypeId tid = TypeId::GetRegistered (i);
607  if (tid.GetTraceSourceN () == 0 ||
609  {
610  continue;
611  }
612  os << boldStart << tid.GetName () << boldStop << breakHtmlOnly
613  << std::endl;
614 
615  os << listStart << std::endl;
616  for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j)
617  {
618  struct TypeId::TraceSourceInformation info = tid.GetTraceSource(j);
619  os << listLineStart
620  << boldStart << info.name << boldStop
621  << ": " << info.help
622  << listLineStop
623  << std::endl;
624  }
625  os << listStop << std::endl;
626  }
627  os << commentStop << std::endl;
628 
629 } // PrintAllTraceSources ()
630 
631 
632 /***************************************************************
633  * Docs for Attribute classes
634  ***************************************************************/
635 
636 
650 void
651 PrintAttributeValueSection (std::ostream & os,
652  const std::string & name,
653  const bool seeBase = true)
654 {
655  NS_LOG_FUNCTION (name);
656  std::string section = "attribute_" + name;
657 
658  // \ingroup attribute
659  // \defgroup attribute_<name>Value <name> Attribute
660  os << commentStart << sectionStart << "attribute\n"
661  << subSectionStart << "attribute_" << name << " "
662  << name << " Attribute\n"
663  << "Attribute implementation for " << name << "\n";
664  if (seeBase)
665  {
666  // Some classes don't live in ns3::. Yuck
667  if (name != "IeMeshId")
668  {
669  os << seeAlso << "ns3::" << name << "\n";
670  }
671  else
672  {
673  os << seeAlso << "ns3::dot11s::" << name << "\n";
674  }
675  }
676  os << commentStop;
677 
678 } // PrintAttributeValueSection ()
679 
680 
691 void
692 PrintAttributeValueWithName (std::ostream & os,
693  const std::string & name,
694  const std::string & type,
695  const std::string & header)
696 {
697  NS_LOG_FUNCTION (name << type << header);
698  std::string sectAttr = sectionStart + "attribute_" + name;
699 
700  // \ingroup attribute_<name>Value
701  // \class ns3::<name>Value "header"
702  std::string valClass = name + "Value";
703  std::string qualClass = " ns3::" + valClass;
704 
705  os << commentStart << sectAttr << std::endl;
706  os << classStart << qualClass << " \"" << header << "\"" << std::endl;
707  os << "AttributeValue implementation for " << name << "." << std::endl;
708  os << seeAlso << "AttributeValue" << std::endl;
709  os << commentStop;
710 
711  // Copy ctor: <name>Value::<name>Value
712  os << commentStart
713  << functionStart << name
714  << qualClass << "::" << valClass;
715  if ( (name == "EmptyAttribute") ||
716  (name == "ObjectPtrContainer") )
717  {
718  // Just default constructors.
719  os << "(void)\n";
720  }
721  else
722  {
723  // Copy constructors
724  os << "(const " << type << " & value)\n"
725  << "Copy constructor.\n"
726  << argument << "[in] value The " << name << " value to copy.\n";
727  }
728  os << commentStop;
729 
730  // <name>Value::Get (void) const
731  os << commentStart
732  << functionStart << type
733  << qualClass << "::Get (void) const\n"
734  << returns << "The " << name << " value.\n"
735  << commentStop;
736 
737  // <name>Value::GetAccessor (T & value) const
738  os << commentStart
739  << functionStart << "bool"
740  << qualClass << "::GetAccessor (T & value) const\n"
741  << "Access the " << name << " value as type " << codeWord << "T.\n"
742  << templateArgument << "T " << templArgExplicit << "The type to cast to.\n"
743  << argument << "[out] value The " << name << " value, as type "
744  << codeWord << "T.\n"
745  << returns << "true.\n"
746  << commentStop;
747 
748  // <name>Value::Set (const name & value)
749  if (type != "Callback") // Yuck
750  {
751  os << commentStart
752  << functionStart << "void"
753  << qualClass << "::Set (const " << type << " & value)\n"
754  << "Set the value.\n"
755  << argument << "[in] value The value to adopt.\n"
756  << commentStop;
757  }
758 
759  // <name>Value::m_value
760  os << commentStart
761  << variable << type
762  << qualClass << "::m_value\n"
763  << "The stored " << name << " instance.\n"
764  << commentStop
765  << std::endl;
766 
767 } // PrintAttributeValueWithName ()
768 
769 
778 void
779 PrintMakeAccessors (std::ostream & os, const std::string & name)
780 {
781  NS_LOG_FUNCTION (name);
782  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
783  std::string make = "ns3::Make" + name + "Accessor ";
784 
785  // \ingroup attribute_<name>Value
786  // Make<name>Accessor (T1 a1)
787  os << commentStart << sectAttr
788  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
789  << make << "(T1 a1)\n"
790  << copyDoc << "ns3::MakeAccessorHelper(T1)\n"
791  << seeAlso << "AttributeAccessor\n"
792  << commentStop;
793 
794  // \ingroup attribute_<name>Value
795  // Make<name>Accessor (T1 a1)
796  os << commentStart << sectAttr
797  << functionStart << "ns3::Ptr<const ns3::AttributeAccessor> "
798  << make << "(T1 a1, T2 a2)\n"
799  << copyDoc << "ns3::MakeAccessorHelper(T1,T2)\n"
800  << seeAlso << "AttributeAccessor\n"
801  << commentStop;
802 } // PrintMakeAccessors ()
803 
804 
814 void
815 PrintMakeChecker (std::ostream & os,
816  const std::string & name,
817  const std::string & header)
818 {
819  NS_LOG_FUNCTION (name << header);
820  std::string sectAttr = sectionStart + "attribute_" + name + "\n";
821  std::string make = "ns3::Make" + name + "Checker ";
822 
823  // \ingroup attribute_<name>Value
824  // class <name>Checker
825  os << commentStart << sectAttr << std::endl;
826  os << classStart << " ns3::" << name << "Checker"
827  << " \"" << header << "\"" << std::endl;
828  os << "AttributeChecker implementation for " << name << "Value." << std::endl;
829  os << seeAlso << "AttributeChecker" << std::endl;
830  os << commentStop;
831 
832  // \ingroup attribute_<name>Value
833  // Make<name>Checker (void)
834  os << commentStart << sectAttr
835  << functionStart << "ns3::Ptr<const ns3::AttributeChecker> "
836  << make << "(void)\n"
837  << returns << "The AttributeChecker.\n"
838  << seeAlso << "AttributeChecker\n"
839  << commentStop;
840 } // PrintMakeChecker ()
841 
842 
844 typedef struct {
845  const std::string m_name;
846  const std::string m_type;
847  const bool m_seeBase;
848  const std::string m_header;
850 
851 
860 void
861 PrintAttributeHelper (std::ostream & os,
862  const AttributeDescriptor & attr)
863 {
864  NS_LOG_FUNCTION (attr.m_name << attr.m_type << attr.m_seeBase <<
865  attr.m_header);
867  PrintAttributeValueWithName (os, attr.m_name, attr.m_type, attr.m_header);
868  PrintMakeAccessors (os, attr.m_name);
869  PrintMakeChecker (os, attr.m_name, attr.m_header);
870 } // PrintAttributeHelper ()
871 
872 
876 void
877 PrintAttributeImplementations (std::ostream & os)
878 {
880 
881  const AttributeDescriptor attributes [] =
882  {
883  // Name Type see Base header-file
884  // Users of ATTRIBUTE_HELPER_HEADER
885  //
886  { "Address", "Address", true, "address.h" },
887  { "Box", "Box", true, "box.h" },
888  { "DataRate", "DataRate", true, "data-rate.h" },
889  { "DsssParameterSet",
890  "DsssParameterSet",
891  true, "dsss-parameter-set.h"},
892  { "EdcaParameterSet",
893  "EdcaParameterSet",
894  true, "edca-parameter-set.h"},
895  { "ErpInformation", "ErpInformation", true, "erp-information.h" },
896  { "HeCapabilities", "HeCapabilities", true, "he-capabilities.h" },
897  { "HtCapabilities", "HtCapabilities", true, "ht-capabilities.h" },
898  { "IeMeshId", "IeMeshId", true, "ie-dot11s-id.h" },
899  { "Ipv4Address", "Ipv4Address", true, "ipv4-address.h" },
900  { "Ipv4Mask", "Ipv4Mask", true, "ipv4-address.h" },
901  { "Ipv6Address", "Ipv6Address", true, "ipv6-address.h" },
902  { "Ipv6Prefix", "Ipv6Prefix", true, "ipv6-address.h" },
903  { "Mac16Address", "Mac16Address", true, "mac16-address.h" },
904  { "Mac48Address", "Mac48Address", true, "mac48-address.h" },
905  { "Mac64Address", "Mac64Address", true, "mac64-address.h" },
906  { "ObjectFactory", "ObjectFactory", true, "object-factory.h" },
907  { "OrganizationIdentifier",
908  "OrganizationIdentifier",
909  true, "vendor-specific-action.h" },
910  { "Rectangle", "Rectangle", true, "rectangle.h" },
911  { "Ssid", "Ssid", true, "ssid.h" },
912  { "TypeId", "TypeId", true, "type-id.h" },
913  { "UanModesList", "UanModesList", true, "uan-tx-mode.h" },
914  // { "ValueClassTest", "ValueClassTest", false, "" /* outside ns3 */ },
915  { "Vector2D", "Vector2D", true, "vector.h" },
916  { "Vector3D", "Vector3D", true, "vector.h" },
917  { "VhtCapabilities","VhtCapabilities",true, "vht-capabilities.h" },
918  { "VhtOperation", "VhtOperation", true, "vht-operation.h" },
919  { "Waypoint", "Waypoint", true, "waypoint.h" },
920  { "WifiMode", "WifiMode", true, "wifi-mode.h" },
921 
922  // All three (Value, Access and Checkers) defined, but custom
923  { "Boolean", "Boolean", false, "boolean.h" },
924  { "Callback", "Callback", true, "callback.h" },
925  { "Double", "double", false, "double.h" },
926  { "Enum", "int", false, "enum.h" },
927  { "Integer", "int64_t", false, "integer.h" },
928  { "Pointer", "Pointer", false, "pointer.h" },
929  { "RandomVariable", "RandomVariable", true, "random-variable-stream.h" },
930  { "String", "std::string", false, "string.h" },
931  { "Time", "Time", true, "nstime.h" },
932  { "Uinteger", "uint64_t", false, "uinteger.h" },
933  { "", "", false, "last placeholder" }
934  };
935 
936  int i = 0;
937  while (attributes[i].m_name != "")
938  {
939  PrintAttributeHelper (os, attributes[i]);
940  ++i;
941  }
942 
943  // Special cases
944  PrintAttributeValueSection (os, "EmptyAttribute", false);
945  PrintAttributeValueWithName (os, "EmptyAttribute", "EmptyAttribute",
946  "attribute.h");
947 
948  PrintAttributeValueSection (os, "ObjectPtrContainer", false);
949  PrintAttributeValueWithName (os, "ObjectPtrContainer", "ObjectPtrContainer", "object-ptr-container.h");
950  PrintMakeChecker (os, "ObjectPtrContainer", "object-ptr-container.h");
951 
952  PrintAttributeValueSection (os, "ObjectVector", false);
953  PrintMakeAccessors (os, "ObjectVector");
954  PrintMakeChecker (os, "ObjectVector", "object-vector.h");
955 
956  PrintAttributeValueSection (os, "ObjectMap", false);
957  PrintMakeAccessors (os, "ObjectMap");
958  PrintMakeChecker (os, "ObjectMap", "object-map.h");
959 
960 } // PrintAttributeImplementations ()
961 
962 
963 /***************************************************************
964  * Aggregation and configuration paths
965  ***************************************************************/
966 
971 {
972 public:
979  void RecordAggregationInfo (std::string a, std::string b);
985  void Gather (TypeId tid);
989  void Print (void) const;
990 
996  std::vector<std::string> Get (TypeId tid) const;
997 
1001  std::vector<std::string> GetNoTypeIds (void) const;
1002 
1003 private:
1007  std::string GetCurrentPath (void) const;
1013  void DoGather (TypeId tid);
1019  void RecordOutput (TypeId tid);
1025  bool HasAlreadyBeenProcessed (TypeId tid) const;
1029  std::vector<std::pair<TypeId,std::string> > m_output;
1033  std::vector<std::string> m_currentPath;
1037  std::vector<TypeId> m_alreadyProcessed;
1041  std::vector<std::pair<TypeId,TypeId> > m_aggregates;
1048  mutable std::vector<std::string> m_noTids;
1049 
1050 }; // class StaticInformation
1051 
1052 
1053 void
1054 StaticInformation::RecordAggregationInfo (std::string a, std::string b)
1055 {
1056  NS_LOG_FUNCTION (this << a << b);
1057  TypeId aTid;
1058  bool found = TypeId::LookupByNameFailSafe (a, &aTid);
1059  if (!found)
1060  {
1061  m_noTids.push_back (a);
1062  return;
1063  }
1064  TypeId bTid;
1065  found = TypeId::LookupByNameFailSafe (b, &bTid);
1066  if (!found)
1067  {
1068  m_noTids.push_back (b);
1069  return;
1070  }
1071 
1072  m_aggregates.push_back (std::make_pair (aTid, bTid));
1073 }
1074 
1075 
1076 void
1078 {
1079  NS_LOG_FUNCTION (this);
1080  for (std::vector<std::pair<TypeId,std::string> >::const_iterator i = m_output.begin (); i != m_output.end (); ++i)
1081  {
1082  std::pair<TypeId,std::string> item = *i;
1083  std::cout << item.first.GetName () << " -> " << item.second << std::endl;
1084  }
1085 }
1086 
1087 
1088 std::string
1090 {
1091  NS_LOG_FUNCTION (this);
1092  std::ostringstream oss;
1093  for (std::vector<std::string>::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i)
1094  {
1095  std::string item = *i;
1096  oss << "/" << item;
1097  }
1098  return oss.str ();
1099 }
1100 
1101 
1102 void
1104 {
1105  NS_LOG_FUNCTION (this << tid);
1106  m_output.push_back (std::make_pair (tid, GetCurrentPath ()));
1107 }
1108 
1109 
1110 bool
1112 {
1113  NS_LOG_FUNCTION (this << tid);
1114  for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i)
1115  {
1116  if (m_alreadyProcessed[i] == tid)
1117  {
1118  return true;
1119  }
1120  }
1121  return false;
1122 }
1123 
1124 
1125 std::vector<std::string>
1127 {
1128  NS_LOG_FUNCTION (this << tid);
1129  std::vector<std::string> paths;
1130  for (uint32_t i = 0; i < m_output.size (); ++i)
1131  {
1132  std::pair<TypeId,std::string> tmp = m_output[i];
1133  if (tmp.first == tid)
1134  {
1135  paths.push_back (tmp.second);
1136  }
1137  }
1138  return paths;
1139 }
1140 
1156 template <typename T>
1157 void
1159 {
1160  std::sort (t.begin (), t.end ());
1161  t.erase (std::unique (t.begin (), t.end ()), t.end ());
1162 }
1163 
1164 std::vector<std::string>
1166 {
1167  NS_LOG_FUNCTION (this);
1168  Uniquefy (m_noTids);
1169  return m_noTids;
1170 }
1171 
1172 
1173 void
1175 {
1176  NS_LOG_FUNCTION (this << tid);
1177  DoGather (tid);
1178  Uniquefy (m_output);
1179 }
1180 
1181 
1182 void
1184 {
1185  NS_LOG_FUNCTION (this << tid);
1186  if (HasAlreadyBeenProcessed (tid))
1187  {
1188  return;
1189  }
1190  RecordOutput (tid);
1191  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
1192  {
1193  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
1194  const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
1195  if (ptrChecker != 0)
1196  {
1197  TypeId pointee = ptrChecker->GetPointeeTypeId ();
1198 
1199  // See if this is a pointer to an Object.
1200  Ptr<Object> object = CreateObject<Object> ();
1201  TypeId objectTypeId = object->GetTypeId ();
1202  if (objectTypeId == pointee)
1203  {
1204  // Stop the recursion at this attribute if it is a
1205  // pointer to an Object, which create too many spurious
1206  // paths in the list of attribute paths because any
1207  // Object can be in that part of the path.
1208  continue;
1209  }
1210 
1211  m_currentPath.push_back (info.name);
1212  m_alreadyProcessed.push_back (tid);
1213  DoGather (pointee);
1214  m_alreadyProcessed.pop_back ();
1215  m_currentPath.pop_back ();
1216  continue;
1217  }
1218  // attempt to cast to an object vector.
1219  const ObjectPtrContainerChecker *vectorChecker = dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
1220  if (vectorChecker != 0)
1221  {
1222  TypeId item = vectorChecker->GetItemTypeId ();
1223  m_currentPath.push_back (info.name + "/[i]");
1224  m_alreadyProcessed.push_back (tid);
1225  DoGather (item);
1226  m_alreadyProcessed.pop_back ();
1227  m_currentPath.pop_back ();
1228  continue;
1229  }
1230  }
1231  for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++)
1232  {
1233  TypeId child = TypeId::GetRegistered (j);
1234  if (child.IsChildOf (tid))
1235  {
1236  std::string childName = "$" + child.GetName ();
1237  m_currentPath.push_back (childName);
1238  m_alreadyProcessed.push_back (tid);
1239  DoGather (child);
1240  m_alreadyProcessed.pop_back ();
1241  m_currentPath.pop_back ();
1242  }
1243  }
1244  for (uint32_t k = 0; k < m_aggregates.size (); ++k)
1245  {
1246  std::pair<TypeId,TypeId> tmp = m_aggregates[k];
1247  if (tmp.first == tid || tmp.second == tid)
1248  {
1249  TypeId other;
1250  if (tmp.first == tid)
1251  {
1252  other = tmp.second;
1253  }
1254  if (tmp.second == tid)
1255  {
1256  other = tmp.first;
1257  }
1258  std::string name = "$" + other.GetName ();
1259  m_currentPath.push_back (name);
1260  m_alreadyProcessed.push_back (tid);
1261  DoGather (other);
1262  m_alreadyProcessed.pop_back ();
1263  m_currentPath.pop_back ();
1264  }
1265  }
1266 } // StaticInformation::DoGather ()
1267 
1268 
1274 {
1276  // The below statements register typical aggregation relationships
1277  // in ns-3 programs, that otherwise aren't picked up automatically
1278  // by the creation of the above node. To manually list other common
1279  // aggregation relationships that you would like to see show up in
1280  // the list of configuration paths in the doxygen, add additional
1281  // statements below.
1282  StaticInformation info;
1283  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
1284  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
1285  info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
1286  info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
1287  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
1288  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4NixVectorRouting");
1289  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1290  info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");
1291  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
1292  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpL4Protocol");
1293  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv6L3Protocol");
1294  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv6L4Protocol");
1295  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpL4Protocol");
1296  info.RecordAggregationInfo ("ns3::Node", "ns3::RipNg");
1297  info.RecordAggregationInfo ("ns3::Node", "ns3::GlobalRouter");
1298  info.RecordAggregationInfo ("ns3::Node", "ns3::aodv::RoutingProtocol");
1299  info.RecordAggregationInfo ("ns3::Node", "ns3::dsdv::RoutingProtocol");
1300  info.RecordAggregationInfo ("ns3::Node", "ns3::dsr::DsrRouting");
1301  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
1302  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergyHarvesterContainer");
1303  info.RecordAggregationInfo ("ns3::Node", "ns3::EnergySourceContainer");
1304 
1305  // Create a channel object so that channels appear in the namespace
1306  // paths that will be generated here.
1307  Ptr<SimpleChannel> simpleChannel;
1308  simpleChannel = CreateObject<SimpleChannel> ();
1309 
1310  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
1311  {
1313  info.Gather (object->GetInstanceTypeId ());
1314  }
1315 
1316  return info;
1317 
1318 } // GetTypicalAggregations ()
1319 
1320 
1322 typedef std::map< std::string, int32_t> NameMap;
1323 typedef NameMap::const_iterator NameMapIterator;
1324 
1325 
1333 NameMap
1335 {
1337  NameMap nameMap;
1338 
1339  // Registered types
1340  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
1341  {
1342  TypeId tid = TypeId::GetRegistered (i);
1343  if (tid.MustHideFromDocumentation ())
1344  {
1345  continue;
1346  }
1347 
1348  // Capitalize all of letters in the name so that it sorts
1349  // correctly in the map.
1350  std::string name = tid.GetName ();
1351  for (uint32_t j = 0; j < name.length (); j++)
1352  {
1353  name[j] = toupper (name[j]);
1354  }
1355 
1356  // Save this name's index.
1357  nameMap[name] = i;
1358  }
1359 
1360  // Type names without TypeIds
1361  std::vector<std::string> noTids = info.GetNoTypeIds ();
1362  for (std::vector<std::string>::const_iterator i = noTids.begin ();
1363  i != noTids.end ();
1364  ++i)
1365  {
1366  nameMap[*i] = -1;
1367  }
1368 
1369  return nameMap;
1370 } // GetNameMap ()
1371 
1372 
1379 void
1380 PrintConfigPaths (std::ostream & os, const StaticInformation & info,
1381  const TypeId tid)
1382 {
1383  NS_LOG_FUNCTION (tid);
1384  std::vector<std::string> paths = info.Get (tid);
1385 
1386  // Config --------------
1387  if (paths.empty ())
1388  {
1389  os << "Introspection did not find any typical Config paths."
1390  << breakBoth
1391  << std::endl;
1392  }
1393  else
1394  {
1395  os << headingStart
1396  << "Config Paths"
1397  << headingStop
1398  << std::endl;
1399  os << std::endl;
1400  os << tid.GetName ()
1401  << " is accessible through the following paths"
1402  << " with Config::Set and Config::Connect:"
1403  << std::endl;
1404  os << listStart << std::endl;
1405  for (uint32_t k = 0; k < paths.size (); ++k)
1406  {
1407  std::string path = paths[k];
1408  os << listLineStart
1409  << "\"" << path << "\""
1410  << listLineStop
1411  << breakTextOnly
1412  << std::endl;
1413  }
1414  os << listStop << std::endl;
1415  }
1416 } // PrintConfigPaths ()
1417 
1418 
1419 /***************************************************************
1420  * Main
1421  ***************************************************************/
1422 
1423 int main (int argc, char *argv[])
1424 {
1426  bool outputText = false;
1427 
1428  CommandLine cmd;
1429  cmd.Usage ("Generate documentation for all ns-3 registered types, "
1430  "trace sources, attributes and global variables.");
1431  cmd.AddValue ("output-text", "format output as plain text", outputText);
1432  cmd.Parse (argc, argv);
1433 
1434  SetMarkup (outputText);
1435 
1436 
1437  // Create a Node, to force linking and instantiation of our TypeIds
1438  NodeContainer c;
1439  c.Create (1);
1440 
1441  // mode-line: helpful when debugging introspected-doxygen.h
1442  if (!outputText)
1443  {
1444  std::cout << "/* -*- Mode:C++; c-file-style:\"gnu\"; "
1445  "indent-tabs-mode:nil; -*- */\n"
1446  << std::endl;
1447  std::cout << "#include \"ns3/log.h\""
1448  << std::endl;
1449  }
1450 
1451  // Doxygen file header
1452  std::cout << std::endl;
1453  std::cout << commentStart
1454  << file << "\n"
1455  << sectionStart << "utils\n"
1456  << "Doxygen docs generated from the TypeId database.\n"
1457  << note << "This file is automatically generated by "
1458  << codeWord << "print-introspected-doxygen.cc. Do not edit this file! "
1459  << "Edit that file instead.\n"
1460  << commentStop
1461  << std::endl;
1462 
1463  // Get typical aggregation relationships.
1465 
1466  NameMap nameMap = GetNameMap (info);
1467 
1468  // Iterate over the map, which will print the class names in
1469  // alphabetical order.
1470  for (NameMapIterator nameMapIterator = nameMap.begin ();
1471  nameMapIterator != nameMap.end ();
1472  nameMapIterator++)
1473  {
1474  // Get the class's index out of the map;
1475  std::string name = nameMapIterator->first;
1476  int32_t i = nameMapIterator->second;
1477  TypeId tid;
1478 
1479  if (i >= 0)
1480  {
1481  tid = TypeId::GetRegistered (i);
1482  if (tid.MustHideFromDocumentation ())
1483  {
1484  continue;
1485  }
1486  name = tid.GetName ();
1487  }
1488 
1489  std::cout << commentStart << std::endl;
1490 
1491  std::cout << classStart << name << std::endl;
1492  std::cout << std::endl;
1493 
1494  if (i >= 0)
1495  {
1496  PrintConfigPaths (std::cout, info, tid);
1497  PrintAttributes (std::cout, tid);
1498  PrintTraceSources (std::cout, tid);
1499  PrintSize (std::cout, tid);
1500  }
1501  else
1502  {
1503  std::cout << "Introspection could not find Config paths for " << name
1504  << " in this build because the parent module"
1505  << " was not included in the waf configuration."
1506  << breakBoth
1507  << std::endl;
1508  }
1509 
1510  std::cout << commentStop << std::endl;
1511  } // class documentation
1512 
1513 
1514  PrintAllAttributes (std::cout);
1515  PrintAllGlobals (std::cout);
1516  PrintAllLogComponents (std::cout);
1517  PrintAllTraceSources (std::cout);
1518  PrintAttributeImplementations (std::cout);
1519 
1520  return 0;
1521 }
uint32_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1068
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:564
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:935
Vector::const_iterator Iterator
Iterator type for the list of all global values.
Definition: global-value.h:80
std::string templArgExplicit
template argument required
static bool LookupByNameFailSafe(std::string name, TypeId *tid)
Get a TypeId by name.
Definition: type-id.cc:831
#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:1060
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:863
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:878
AttributeChecker implementation for ObjectPtrContainerValue.
uint32_t GetTraceSourceN(void) const
Get the number of Trace sources.
Definition: type-id.cc:1089
static TypeId GetRegistered(uint32_t i)
Get a TypeId by index.
Definition: type-id.cc:869
uint32_t GetRootNamespaceObjectN(void)
Definition: config.cc:872
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:416
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
Get the most derived TypeId for this Object.
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:80
std::string GetName(void) const
Get the name.
Definition: type-id.cc:968
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:982
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:498
static Iterator End(void)
The End iterator.
Gather aggregation and configuration path information from registered types.
void Print(ComponentCarrier cc)
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:949
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:1095
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Get Attribute information by index.
Definition: type-id.cc:1075
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.