--- a/RELEASE_NOTES Fri Feb 21 16:25:43 2014 -0800
+++ b/RELEASE_NOTES Fri Feb 21 16:27:43 2014 -0800
@@ -46,6 +46,7 @@
- Bug 1852 - cairo-wideint-private.h error cannot find definitions for fixed-width integral types
- Bug 1853 - NS_LOG_FUNCTION broken on OSX 10.9
- Bug 1855 - SixLowPanNetDevice is not correctly indexed
+- Bug 1862 - NS_LOG="Time=*|prefix_time" causes stack overflow
Release 3.19
=============
--- a/src/core/model/attribute-accessor-helper.h Fri Feb 21 16:25:43 2014 -0800
+++ b/src/core/model/attribute-accessor-helper.h Fri Feb 21 16:27:43 2014 -0800
@@ -28,6 +28,7 @@
* \ingroup AttributeHelper
*/
template <typename V, typename T1>
+inline
Ptr<const AttributeAccessor>
MakeAccessorHelper (T1 a1);
@@ -35,6 +36,7 @@
* \ingroup AttributeHelper
*/
template <typename V, typename T1, typename T2>
+inline
Ptr<const AttributeAccessor>
MakeAccessorHelper (T1 a1, T2 a2);
@@ -94,6 +96,7 @@
};
template <typename V, typename T, typename U>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperOne (U T::*memberVariable)
{
@@ -132,6 +135,7 @@
}
template <typename V, typename T, typename U>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperOne (U (T::*getter)(void) const)
{
@@ -163,6 +167,7 @@
template <typename V, typename T, typename U>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperOne (void (T::*setter)(U))
{
@@ -199,6 +204,7 @@
}
template <typename W, typename T, typename U, typename V>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperTwo (void (T::*setter)(U),
V (T::*getter)(void) const)
@@ -240,6 +246,7 @@
}
template <typename W, typename T, typename U, typename V>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperTwo (V (T::*getter)(void) const,
void (T::*setter)(U))
@@ -248,6 +255,7 @@
}
template <typename W, typename T, typename U, typename V>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperTwo (bool (T::*setter)(U),
V (T::*getter)(void) const)
@@ -289,6 +297,7 @@
}
template <typename W, typename T, typename U, typename V>
+inline
Ptr<const AttributeAccessor>
DoMakeAccessorHelperTwo (bool (T::*getter)(void) const,
void (T::*setter)(U))
@@ -297,6 +306,7 @@
}
template <typename V, typename T1>
+inline
Ptr<const AttributeAccessor>
MakeAccessorHelper (T1 a1)
{
@@ -304,6 +314,7 @@
}
template <typename V, typename T1, typename T2>
+inline
Ptr<const AttributeAccessor>
MakeAccessorHelper (T1 a1, T2 a2)
{
--- a/src/core/model/log.cc Fri Feb 21 16:25:43 2014 -0800
+++ b/src/core/model/log.cc Fri Feb 21 16:27:43 2014 -0800
@@ -84,10 +84,11 @@
}
-LogComponent::LogComponent (const std::string & name)
- : m_levels (0), m_name (name)
+LogComponent::LogComponent (const std::string & name,
+ const enum LogLevel mask /* = 0 */)
+ : m_levels (0), m_mask (mask), m_name (name)
{
- EnvVarCheck (name);
+ EnvVarCheck ();
ComponentList *components = GetComponentList ();
for (ComponentListI i = components->begin ();
@@ -103,7 +104,7 @@
}
void
-LogComponent::EnvVarCheck (const std::string & name)
+LogComponent::EnvVarCheck (void)
{
#ifdef HAVE_GETENV
char *envVar = getenv ("NS_LOG");
@@ -112,7 +113,6 @@
return;
}
std::string env = envVar;
- std::string myName = name;
std::string::size_type cur = 0;
std::string::size_type next = 0;
@@ -125,7 +125,7 @@
if (equal == std::string::npos)
{
component = tmp;
- if (component == myName || component == "*" || component == "***")
+ if (component == m_name || component == "*" || component == "***")
{
int level = LOG_LEVEL_ALL | LOG_PREFIX_ALL;
Enable ((enum LogLevel)level);
@@ -135,7 +135,7 @@
else
{
component = tmp.substr (0, equal);
- if (component == myName || component == "*")
+ if (component == m_name || component == "*")
{
int level = 0;
std::string::size_type cur_lev;
@@ -242,7 +242,7 @@
bool
-LogComponent::IsEnabled (enum LogLevel level) const
+LogComponent::IsEnabled (const enum LogLevel level) const
{
// LogComponentEnableEnvVar ();
return (level & m_levels) ? 1 : 0;
@@ -255,13 +255,19 @@
}
void
-LogComponent::Enable (enum LogLevel level)
+LogComponent::SetMask (const enum LogLevel level)
{
- m_levels |= level;
+ m_mask |= level;
}
void
-LogComponent::Disable (enum LogLevel level)
+LogComponent::Enable (const enum LogLevel level)
+{
+ m_levels |= (level & ~m_mask);
+}
+
+void
+LogComponent::Disable (const enum LogLevel level)
{
m_levels &= ~level;
}
@@ -272,8 +278,9 @@
return m_name.c_str ();
}
+/* static */
std::string
-LogComponent::GetLevelLabel(const enum LogLevel level) const
+LogComponent::GetLevelLabel(const enum LogLevel level)
{
if (level == LOG_ERROR)
{
--- a/src/core/model/log.h Fri Feb 21 16:25:43 2014 -0800
+++ b/src/core/model/log.h Fri Feb 21 16:27:43 2014 -0800
@@ -66,34 +66,34 @@
* Logging severity classes and levels.
*/
enum LogLevel {
- LOG_NONE = 0x00000000, // no logging
+ LOG_NONE = 0x00000000, //!< no logging
- LOG_ERROR = 0x00000001, // serious error messages only
+ LOG_ERROR = 0x00000001, //!< serious error messages only
LOG_LEVEL_ERROR = 0x00000001,
- LOG_WARN = 0x00000002, // warning messages
+ LOG_WARN = 0x00000002, //!< warning messages
LOG_LEVEL_WARN = 0x00000003,
- LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages
+ LOG_DEBUG = 0x00000004, //!< rare ad-hoc debug messages
LOG_LEVEL_DEBUG = 0x00000007,
- LOG_INFO = 0x00000008, // informational messages (e.g., banners)
+ LOG_INFO = 0x00000008, //!< informational messages (e.g., banners)
LOG_LEVEL_INFO = 0x0000000f,
- LOG_FUNCTION = 0x00000010, // function tracing
+ LOG_FUNCTION = 0x00000010, //!< function tracing
LOG_LEVEL_FUNCTION = 0x0000001f,
- LOG_LOGIC = 0x00000020, // control flow tracing within functions
+ LOG_LOGIC = 0x00000020, //!< control flow tracing within functions
LOG_LEVEL_LOGIC = 0x0000003f,
- LOG_ALL = 0x0fffffff, // print everything
+ LOG_ALL = 0x0fffffff, //!< print everything
LOG_LEVEL_ALL = LOG_ALL,
- LOG_PREFIX_FUNC = 0x80000000, // prefix all trace prints with function
- LOG_PREFIX_TIME = 0x40000000, // prefix all trace prints with simulation time
- LOG_PREFIX_NODE = 0x20000000, // prefix all trace prints with simulation node
- LOG_PREFIX_LEVEL = 0x10000000, // prefix all trace prints with log level (severity)
- LOG_PREFIX_ALL = 0xf0000000 // all prefixes
+ LOG_PREFIX_FUNC = 0x80000000, //!< prefix all trace prints with function
+ LOG_PREFIX_TIME = 0x40000000, //!< prefix all trace prints with simulation time
+ LOG_PREFIX_NODE = 0x20000000, //!< prefix all trace prints with simulation node
+ LOG_PREFIX_LEVEL = 0x10000000, //!< prefix all trace prints with log level (severity)
+ LOG_PREFIX_ALL = 0xf0000000 //!< all prefixes
};
/**
@@ -146,7 +146,6 @@
/**
* \ingroup logging
- * \param name a string
*
* Define a Log component with a specific name.
*
@@ -166,13 +165,25 @@
*
* Note the closing ';' is not on the same line; this prevents
* Doxygen from spuriously warning that the macro invocation is undocumented.
-
+ *
+ * \param name a string
*/
#define NS_LOG_COMPONENT_DEFINE(name) \
static ns3::LogComponent g_log = ns3::LogComponent (name)
/**
* \ingroup logging
+ *
+ * Define a logging component with a default mask.
+ *
+ * \param name a string
+ * \param mask the default mask
+ */
+#define NS_LOG_COMPONENT_DEFINE_MASK(name, mask) \
+ static ns3::LogComponent g_log = ns3::LogComponent (name, mask)
+
+/**
+ * \ingroup logging
* Append the simulation time to a log message.
*/
#define NS_LOG_APPEND_TIME_PREFIX \
@@ -416,22 +427,76 @@
LogNodePrinter LogGetNodePrinter (void);
-class LogComponent {
+/**
+ * \ingroup logging
+ *
+ * A single log component configuration.
+ */
+class LogComponent
+{
public:
- LogComponent (const std::string & name);
- void EnvVarCheck (const std::string & name);
- bool IsEnabled (enum LogLevel level) const;
+ /**
+ * Constructor
+ *
+ * \param [in] name the user-visible name for this component.
+ */
+ LogComponent (const std::string & name, const enum LogLevel mask = LOG_NONE);
+ /**
+ * Check if this LogComponent is enabled for \pname{level}
+ *
+ * \param [in] level the level to check for.
+ * \return true if \pname{level} is enabled.
+ */
+ bool IsEnabled (const enum LogLevel level) const;
+ /**
+ * Check if all levels are disabled.
+ *
+ * \return true if all levels are disabled.
+ */
bool IsNoneEnabled (void) const;
- void Enable (enum LogLevel level);
- void Disable (enum LogLevel level);
+ /**
+ * Enable this LogComponent at \pname{level}
+ *
+ * \param [in] level the LogLevel to enable.
+ */
+ void Enable (const enum LogLevel level);
+ /**
+ * Disable logging at \pname{level} for this LogComponent.
+ *
+ * \param [in] level the LogLevel to disable.
+ */
+ void Disable (const enum LogLevel level);
+ /**
+ * Get the name of this LogComponent.
+ *
+ * \return the name of this LogComponent.
+ */
char const *Name (void) const;
- std::string GetLevelLabel(const enum LogLevel level) const;
+ /**
+ * Get the string label for the given LogLevel.
+ *
+ * \param [in] level the LogLevel to get the label for.
+ * \return the string label for \pname{level}
+ */
+ static std::string GetLevelLabel(const enum LogLevel level);
+ /**
+ * Prevent the enabling of a specific LogLevel.
+ *
+ * \param level the LogLevel to block
+ */
+ void SetMask (const enum LogLevel level);
private:
- int32_t m_levels;
- std::string m_name;
-};
+ /**
+ * Parse the `NS_LOG` environment variable for options relating to this
+ * LogComponent.
+ */
+ void EnvVarCheck (void);
-class ParameterLogger : public std::ostream
+ int32_t m_levels; //!< Enabled LogLevels
+ int32_t m_mask; //!< Blocked LogLevels
+ std::string m_name; //!< LogComponent name
+
+}; // class LogComponent
/**
* \ingroup logging
--- a/src/core/model/time.cc Fri Feb 21 16:25:43 2014 -0800
+++ b/src/core/model/time.cc Fri Feb 21 16:27:43 2014 -0800
@@ -32,7 +32,7 @@
#include <iomanip> // showpos
#include <sstream>
-NS_LOG_COMPONENT_DEFINE ("Time");
+NS_LOG_COMPONENT_DEFINE_MASK ("Time", ns3::LOG_PREFIX_TIME);
namespace ns3 {
--- a/src/core/model/unix-system-mutex.cc Fri Feb 21 16:25:43 2014 -0800
+++ b/src/core/model/unix-system-mutex.cc Fri Feb 21 16:27:43 2014 -0800
@@ -27,7 +27,7 @@
#include "log.h"
-NS_LOG_COMPONENT_DEFINE ("SystemMutex");
+NS_LOG_COMPONENT_DEFINE_MASK ("SystemMutex", ns3::LOG_PREFIX_TIME);
namespace ns3 {