--- 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 <<
+<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 */