bug 1082: Check that log component names are correct when taken from NS_LOG.
authorAnirudh Sivaraman <sk.anirudh@gmail.com>
Wed, 10 Aug 2011 12:23:15 -0400
changeset 7413 1e965c4c084b
parent 7412 d79278c6e51c
child 7414 231acc30d08f
bug 1082: Check that log component names are correct when taken from NS_LOG.
src/core/model/log.cc
--- a/src/core/model/log.cc	Wed Aug 10 11:48:19 2011 -0400
+++ b/src/core/model/log.cc	Wed Aug 10 12:23:15 2011 -0400
@@ -256,16 +256,24 @@
 LogComponentEnable (char const *name, enum LogLevel level)
 {
   ComponentList *components = GetComponentList ();
-  for (ComponentListI i = components->begin ();
-       i != components->end ();
+  ComponentListI i;
+  for (i = components->begin (); 
+       i != components->end (); 
        i++)
     {
       if (i->first.compare (name) == 0) 
         {
           i->second->Enable (level);
-          break;
+          return;
         }
     }
+    if (i == components->end())
+      {
+	// nothing matched
+        LogComponentPrintList();
+        NS_FATAL_ERROR ("Logging component \"" << name <<
+                        "\" not found. See above for a list of available log components");
+    }
 }
 
 void 
@@ -354,9 +362,117 @@
     }
 }
 
+static bool ComponentExists(std::string componentName) 
+{
+  char const*name=componentName.c_str();
+  ComponentList *components = GetComponentList ();
+  ComponentListI i;
+  for (i = components->begin ();
+       i != components->end ();
+       i++)
+     {
+       if (i->first.compare (name) == 0) 
+ 	{
+	  return true;
+ 	}
+    }
+  NS_ASSERT (i == components->end());
+  // nothing matched 
+  return false;    
+}
+
+static void CheckEnvironmentVariables (void)
+{
+#ifdef HAVE_GETENV
+  char *envVar = getenv ("NS_LOG");
+  if (envVar == 0 || strlen(envVar) == 0)
+    {
+      return;
+    }
+  std::string env = envVar;
+
+  std::string::size_type cur = 0;
+  std::string::size_type next = 0;
+  
+  while (next != std::string::npos)
+    {
+      next = env.find_first_of (":", cur);
+      std::string tmp = std::string (env, cur, next-cur);
+      std::string::size_type equal = tmp.find ("=");
+      std::string component;
+      if (equal == std::string::npos)
+        {
+          // ie no '=' characters found 
+          component = tmp;
+          if (ComponentExists(component) || component == "*")
+            {
+              return;
+            }
+	  else 
+            {
+	      LogComponentPrintList();
+              NS_FATAL_ERROR("Invalid or unregistered component name \"" << component <<
+                             "\" in env variable NS_LOG, see above for a list of valid components");
+            }
+        }
+      else
+        {
+          component = tmp.substr (0, equal);
+          if (ComponentExists(component) || component == "*")
+            {
+              std::string::size_type cur_lev;
+              std::string::size_type next_lev = equal;
+              do
+                {
+                  cur_lev = next_lev + 1;
+                  next_lev = tmp.find ("|", cur_lev);
+                  std::string lev = tmp.substr (cur_lev, next_lev - cur_lev);
+                  if (lev == "error"
+                      || lev == "warn"
+                      || lev == "debug"
+                      || lev == "info"
+                      || lev == "function"
+                      || lev == "logic"
+                      || lev == "all"
+                      || lev == "prefix_func"
+                      || lev == "prefix_time"
+                      || lev == "prefix_node"
+                      || lev == "level_error"
+                      || lev == "level_warn"
+                      || lev == "level_debug"
+                      || lev == "level_info"
+                      || lev == "level_function"
+                      || lev == "level_logic"
+                      || lev == "level_all"
+                      || lev == "*"
+		     )
+                    {
+                      continue;
+                    }
+		  else
+                    {
+                      NS_FATAL_ERROR("Invalid log level \"" << lev <<
+                                     "\" in env variable NS_LOG for component name " << component);
+                    }
+                } while (next_lev != std::string::npos);
+            }
+          else 
+            {
+              LogComponentPrintList();
+              NS_FATAL_ERROR("Invalid or unregistered component name \"" << component <<
+                             "\" in env variable NS_LOG, see above for a list of valid components");
+            }
+        }
+      cur = next + 1;	// parse next component
+    }
+#endif
+}
 void LogSetTimePrinter (LogTimePrinter printer)
 {
   g_logTimePrinter = printer;
+  // This is the only place where we are more or less sure that all log variables
+  // are registered. See bug 1082 for details.
+  CheckEnvironmentVariables(); 
 }
 LogTimePrinter LogGetTimePrinter (void)
 {