[PATCH] core: Extending public interface of CommandLine class
authorAlexander Afanasyev <alexander.afanasyev@ucla.edu>
Tue, 13 Aug 2013 23:19:31 -0700
changeset 10143 48f66512ec9b
parent 10142 3dc19f3ac5a7
child 10144 0f1bb8770045
[PATCH] core: Extending public interface of CommandLine class
CHANGES.html
RELEASE_NOTES
src/core/model/command-line.cc
src/core/model/command-line.h
--- a/CHANGES.html	Tue Aug 13 22:56:39 2013 -0700
+++ b/CHANGES.html	Tue Aug 13 23:19:31 2013 -0700
@@ -113,6 +113,20 @@
 
 <h2>Changed behavior:</h2>
 <ul>
+  <li> Now it is possible to request printing command line arguments to the
+desired output stream using PrintHelp or operator &lt;&lt;
+<pre>
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+...
+
+  std::cerr << cmd;
+</pre>
+or
+<pre>
+  cmd.PrintHelp (std::cerr);
+</pre>
+   </li>
 </ul>
 
 <hr>
--- a/RELEASE_NOTES	Tue Aug 13 22:56:39 2013 -0700
+++ b/RELEASE_NOTES	Tue Aug 13 23:19:31 2013 -0700
@@ -44,6 +44,8 @@
 - Radvd application have a new Helper. See the updated 
   examples/ipv6/radvd.cc for an example.
 - 11n- It is now possible to create a high throughput (HT) node that used the new 11n data rates and preambles.
+- It is now possible to request printing command line arguments to the
+  desired output stream using PrintHelp or operator <<
 
 Bugs fixed
 ----------
@@ -75,6 +77,7 @@
 - Bug 1731 - lte-phy-error-model passes unexpectedly
 - Bug 1742 - IPv6 HbH and Dst Extension Header size is not correctly calculated
 - Bug 1752 - RadvdInterface m_defaultLifeTime is set to milliseconds instead of seconds
+- Bug 1754 - Missing GIL lock in generated callback destructor
 
 Known issues
 ------------
--- a/src/core/model/command-line.cc	Tue Aug 13 22:56:39 2013 -0700
+++ b/src/core/model/command-line.cc	Tue Aug 13 23:19:31 2013 -0700
@@ -147,17 +147,17 @@
 }
 
 void
-CommandLine::PrintHelp (void) const
+CommandLine::PrintHelp (std::ostream &os) const
 {
   NS_LOG_FUNCTION (this);
 
-  std::cout << m_name << " [Program Arguments] [General Arguments]"
-            << std::endl;
+  os << m_name << " [Program Arguments] [General Arguments]"
+     << std::endl;
   
   if (m_usage.length ())
     {
-      std::cout << std::endl;
-      std::cout << m_usage << std::endl;
+      os << std::endl;
+      os << m_usage << std::endl;
     }
   
   if (!m_items.empty ())
@@ -169,25 +169,25 @@
         }
       width += 3;
 
-      std::cout << std::endl;
-      std::cout << "Program Arguments:" << std::endl;
+      os << std::endl;
+      os << "Program Arguments:" << std::endl;
       for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
         {
-          std::cout << "    --"
-                    << std::left << std::setw (width) << ( (*i)->m_name + ":")
-                    << std::right
-                    << (*i)->m_help;
+          os << "    --"
+             << std::left << std::setw (width) << ( (*i)->m_name + ":")
+             << std::right
+             << (*i)->m_help;
 
           if ( (*i)->HasDefault ())
             {
-              std::cout << " [" << (*i)->GetDefault () << "]";
-            }
-          std::cout << std::endl;
-        }
+              os << " [" << (*i)->GetDefault () << "]";
+    }
+          os << std::endl;
+}
     }
 
-  std::cout << std::endl;
-  std::cout
+  os << std::endl;
+  os
     << "General Arguments:\n"
     << "    --PrintGlobals:              Print the list of globals.\n"
     << "    --PrintGroups:               Print the list of groups.\n"
@@ -199,80 +199,80 @@
 }
 
 void
-CommandLine::PrintGlobals (void) const
+CommandLine::PrintGlobals (std::ostream &os) const
 {
   NS_LOG_FUNCTION (this);
 
-  std::cout << "Global values:" << std::endl;
+  os << "Global values:" << std::endl;
   
   for (GlobalValue::Iterator i = GlobalValue::Begin ();
        i != GlobalValue::End ();
        ++i)
     {
-      std::cout << "    --" << (*i)->GetName () << "=[";
+      os << "    --" << (*i)->GetName () << "=[";
       Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
       StringValue v;
       (*i)->GetValue (v);
-      std::cout << v.Get () << "]" << std::endl;
-      std::cout << "        " << (*i)->GetHelp () << std::endl;
+      os << v.Get () << "]" << std::endl;
+      os << "        " << (*i)->GetHelp () << std::endl;
     }
 }
 
 void
-CommandLine::PrintAttributes (std::string type) const
+CommandLine::PrintAttributes (std::ostream &os, const std::string &type) const
 {
   NS_LOG_FUNCTION (this);
 
   TypeId tid;
   if (!TypeId::LookupByNameFailSafe (type, &tid))
     {
-      NS_FATAL_ERROR ("Unknown type=" << type << " in --PrintAttributes");
+      NS_FATAL_ERROR ("Unknown type="<<type<<" in --PrintAttributes");
     }
 
-  std::cout << "Attributes for TypeId " << tid.GetName () << std::endl;
+  os << "Attributes for TypeId " << tid.GetName () << std::endl;
   
   for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
     {
-      std::cout << "    --" << tid.GetAttributeFullName (i) << "=[";
+      os << "    --" << tid.GetAttributeFullName (i) << "=[";
       struct TypeId::AttributeInformation info = tid.GetAttribute (i);
-      std::cout << info.initialValue->SerializeToString (info.checker) << "]"
+      os << info.initialValue->SerializeToString (info.checker) << "]"
                 << std::endl;
-      std::cout << "        " << info.help << std::endl;
+      os << "        " << info.help << std::endl;
     }
 }
 
 
 void
-CommandLine::PrintGroup (std::string group) const
+CommandLine::PrintGroup (std::ostream &os, const std::string &group) const
 {
   NS_LOG_FUNCTION (this);
 
-  std::cout << "TypeIds in group " << group << ":" << std::endl;
+  os << "TypeIds in group " << group << ":" << std::endl;
   
   for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
     {
       TypeId tid = TypeId::GetRegistered (i);
       if (tid.GetGroupName () == group)
         {
-          std::cout << "    " <<tid.GetName () << std::endl;
+          os << "    " <<tid.GetName () << std::endl;
         }
     }
 }
 
 void
-CommandLine::PrintTypeIds (void) const
+CommandLine::PrintTypeIds (std::ostream &os) const
 {
   NS_LOG_FUNCTION (this);
-  std::cout << "Registered TypeIds:" << std::endl;
+  os << "Registered TypeIds:" << std::endl;
   for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
     {
       TypeId tid = TypeId::GetRegistered (i);
-      std::cout << "    " << tid.GetName () << std::endl;
+      os << "    " << tid.GetName () << std::endl;
     }
 }
 
 void
-CommandLine::PrintGroups (void) const
+CommandLine::PrintGroups (std::ostream &os) const
 {
   NS_LOG_FUNCTION (this);
 
@@ -302,56 +302,56 @@
         }
     }
   
-  std::cout << "Registered TypeId groups:" << std::endl;
+  os << "Registered TypeId groups:" << std::endl;
   
   for (std::list<std::string>::const_iterator k = groups.begin ();
        k != groups.end ();
        ++k)
     {
-      std::cout << "    " << *k << std::endl;
+      os << "    " << *k << std::endl;
     }
 }
 
 void
-CommandLine::HandleArgument (std::string name, std::string value) const
+CommandLine::HandleArgument (const std::string &name, const std::string &value) const
 {
   NS_LOG_FUNCTION (this << name << value);
 
-  NS_LOG_DEBUG ("Handle arg name=" << name << " value=" << value);
+  NS_LOG_DEBUG ("Handle arg name="<<name<<" value="<<value);
   if (name == "PrintHelp" || name == "help")
     {
       // method below never returns.
-      PrintHelp ();
+      PrintHelp (std::cout);
       std::exit (0);
     } 
   else if (name == "PrintGroups")
     {
       // method below never returns.
-      PrintGroups ();
+      PrintGroups (std::cout);
       std::exit (0);
     }
   else if (name == "PrintTypeIds")
     {
       // method below never returns.
-      PrintTypeIds ();
+      PrintTypeIds (std::cout);
       std::exit (0);
     }
   else if (name == "PrintGlobals")
     {
       // method below never returns.
-      PrintGlobals ();
+      PrintGlobals (std::cout);
       std::exit (0);
     }
   else if (name == "PrintGroup")
     {
       // method below never returns.
-      PrintGroup (value);
+      PrintGroup (std::cout, value);
       std::exit (0);
     }
   else if (name == "PrintAttributes")
     {
       // method below never returns.
-      PrintAttributes (value);
+      PrintAttributes (std::cout, value);
       std::exit (0);
     }
   else
@@ -378,7 +378,7 @@
     {
       std::cerr << "Invalid command-line arguments: --"
                 << name << "=" << value << std::endl;
-      PrintHelp ();
+      PrintHelp (std::cerr);
       std::exit (1);
     }
 }
--- a/src/core/model/command-line.h	Tue Aug 13 22:56:39 2013 -0700
+++ b/src/core/model/command-line.h	Tue Aug 13 23:19:31 2013 -0700
@@ -203,6 +203,22 @@
    */
   std::string GetName () const;
 
+  /**
+   * \brief Print program usage to the desired output stream
+   *
+   * Handler for \c \-\-PrintHelp and \c \-\-help:  print Usage(), argument names, and help strings
+   *
+   * Alternatively, an overloaded operator << can be used:
+   * @code
+   *       CommandLine cmd;
+   *       cmd.Parse (argc, argv);
+   *     ...
+   *
+   *       std::cerr << cmd;
+   * @endcode
+   */
+  void PrintHelp (std::ostream &os) const;
+
 private:
 
   /**
@@ -279,29 +295,25 @@
    * \param name the argument name
    * \param value the command line value
    */
-  void HandleArgument (std::string name, std::string value) const;
-  /**
-   * Handler for \c \-\-PrintHelp and \c \-\-help:  print Usage(), argument names, and help strings
-   */
-  void PrintHelp (void) const;
+  void HandleArgument (const std::string &name, const std::string &value) const;
   /** Handler for \c \-\-PrintGlobals:  print all global variables and values */
-  void PrintGlobals (void) const;
+  void PrintGlobals (std::ostream &os) const;
   /**
    * Handler for \c \-\-PrintAttributes:  print the attributes for a given type.
    *
    * \param type the TypeId whose Attributes should be displayed
    */
-  void PrintAttributes (std::string type) const;
+  void PrintAttributes (std::ostream &os, const std::string &type) const;
   /**
    * Handler for \c \-\-PrintGroup:  print all types belonging to a given group.
    *
    * \param group the name of the TypeId group to display
    */
-  void PrintGroup (std::string group) const;
+  void PrintGroup (std::ostream &os, const std::string &group) const;
   /** Handler for \c \-\-PrintTypeIds:  print all TypeId names. */
-  void PrintTypeIds (void) const;
+  void PrintTypeIds (std::ostream &os) const;
   /** Handler for \c \-\-PrintGroups:  print all TypeId group names */
-  void PrintGroups (void) const;
+  void PrintGroups (std::ostream &os) const;
   /**
    * Copy constructor
    *
@@ -399,6 +411,26 @@
   return !iss.bad () && !iss.fail ();
 }
 
+/**
+ * \brief Overloaded operator << to print program usage (shortcut for CommandLine::PrintHelper)
+ * \see CommandLine::PrintHelper
+ *
+ * Example usage:
+ * @code
+ *       CommandLine cmd;
+ *       cmd.Parse (argc, argv);
+ *       ...
+ *
+ *       std::cerr << cmd;
+ * @endcode
+ */
+inline std::ostream &
+operator << (std::ostream &os, const CommandLine &cmd)
+{
+  cmd.PrintHelp (os);
+  return os;
+}
+
 } // namespace ns3
 
 #endif /* COMMAND_LINE_H */