Bug 81 (CommandLine::AddArgValue not working correctly)
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue, 09 Oct 2007 11:38:01 +0100
changeset 1702 0fbe74581141
parent 1701 5e9bd24a8716
child 1703 3f808ee49c2f
child 1766 1207df3ad6f2
child 1941 c4eb28d51689
Bug 81 (CommandLine::AddArgValue not working correctly)
samples/main-default-value.cc
src/core/command-line.cc
src/core/command-line.h
--- a/samples/main-default-value.cc	Mon Oct 08 17:49:18 2007 +0100
+++ b/samples/main-default-value.cc	Tue Oct 09 11:38:01 2007 +0100
@@ -62,7 +62,7 @@
   //utilize the loops variable to show that it can be read from the command line
   if(loops>0)
   {
-    cout<<"You requested "<<loops<<" iterations of a loop";
+    std::cerr<<"You requested "<<loops<<" iterations of a loop";
     for(uint32_t i=0;i<loops;++i)
       cout<<"iteration "<<i;
   }
--- a/src/core/command-line.cc	Mon Oct 08 17:49:18 2007 +0100
+++ b/src/core/command-line.cc	Tue Oct 09 11:38:01 2007 +0100
@@ -20,6 +20,7 @@
  */
 
 #include "command-line.h"
+#include "ns3/debug.h"
 #include <unistd.h>
 
 namespace ns3 {
@@ -109,8 +110,15 @@
       std::string name, value;
       if (cur == std::string::npos)
         {
+          if (argc == 1)
+            {
+              // invalid argument. ignore it.
+              continue;
+            }
+          argv++;
+          argc--;
           name = param;
-          value = "";
+          value = *argv;
         }
       else
         {
@@ -124,7 +132,12 @@
           DefaultValueBase *item = *i;
           if (item->GetName () == name)
             {
-              item->ParseValue (value);
+              if (!item->ParseValue (value))
+                {
+                  std::cerr << "Warning: failed to parse command line argument `"
+                            << name << "' of type '" << item->GetType ()
+                            << "' with value `" << value << "'." << std::endl;
+                }
               continue;
             }
         }
@@ -144,3 +157,83 @@
 }
 
 }//namespace ns3
+
+
+
+#ifdef RUN_SELF_TESTS
+#include "test.h"
+#include <iostream>
+#include <sstream>
+
+namespace ns3 {
+
+
+class CommandLineTest : public Test
+{
+public:
+  CommandLineTest () : Test ("CommandLine") {}
+  virtual bool RunTests (void)
+  {
+    bool result = true;
+
+    // redirect stderr temporarily (else warnings appear during unit testing, which is not nice)
+    std::ostringstream nullout;
+    std::streambuf *origcerr = std::cerr.rdbuf (nullout.rdbuf ());
+    {
+      char *argv[] = {"run-tests", "--loops", "bad-value", NULL};
+      int argc = sizeof (argv) / sizeof (argv[0]) - 1;
+      
+      uint32_t loops = 123;
+      CommandLine::AddArgValue ("loops","a test of the command line", loops);
+      CommandLine::Parse (argc, argv);
+      
+      NS_TEST_ASSERT_EQUAL (loops, 123);
+    }
+
+    {
+      char *argv[] = {"run-tests", "--loops=bad-value", NULL};
+      int argc = sizeof (argv) / sizeof (argv[0]) - 1;
+      
+      uint32_t loops = 123;
+      CommandLine::AddArgValue ("loops","a test of the command line", loops);
+      CommandLine::Parse (argc, argv);
+      
+      NS_TEST_ASSERT_EQUAL (loops, 123);
+    }
+
+    {
+      char *argv[] = {"run-tests", "--loops", "456", NULL};
+      int argc = sizeof (argv) / sizeof (argv[0]) - 1;
+      
+      uint32_t loops = 123;
+      CommandLine::AddArgValue ("loops","a test of the command line", loops);
+      CommandLine::Parse (argc, argv);
+      
+      NS_TEST_ASSERT_EQUAL (loops, 456);
+    }
+
+    {
+      char *argv[] = {"run-tests", "--loops=456", NULL};
+      int argc = sizeof (argv) / sizeof (argv[0]) - 1;
+      
+      uint32_t loops = 123;
+      CommandLine::AddArgValue ("loops","a test of the command line", loops);
+      CommandLine::Parse (argc, argv);
+      
+      NS_TEST_ASSERT_EQUAL (loops, 456);
+    }
+
+    // unredirect cerr
+    std::cerr.rdbuf (origcerr);
+
+
+    return result;
+  }
+};
+
+
+static CommandLineTest g_commandLineTests;
+
+}//namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- a/src/core/command-line.h	Mon Oct 08 17:49:18 2007 +0100
+++ b/src/core/command-line.h	Tue Oct 09 11:38:01 2007 +0100
@@ -123,14 +123,18 @@
   iss.str (value);
   T v;
   iss >> v;
-  *m_valuePtr = v;
-  return !iss.bad () && !iss.fail ();
+  bool ok = (!iss.bad () && !iss.fail ());
+  if (ok)
+    {
+      *m_valuePtr = v;
+    }
+  return ok;
 }
 template <typename T>
 std::string
 CommandLine::UserDefaultValue<T>::DoGetType (void) const
 {
-  return "";
+  return TypeNameGet<T> ();
 }
 template <typename T>
 std::string