00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "command-line.h"
00021 #include "log.h"
00022 #include "config.h"
00023 #include "global-value.h"
00024 #include "type-id.h"
00025 #include "string.h"
00026 #include <stdlib.h>
00027
00028 NS_LOG_COMPONENT_DEFINE ("CommandLine");
00029
00030 namespace ns3 {
00031
00032 CommandLine::~CommandLine ()
00033 {
00034 for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
00035 {
00036 delete *i;
00037 }
00038 m_items.clear ();
00039 }
00040
00041 CommandLine::Item::~Item ()
00042 {}
00043
00044 void
00045 CommandLine::Parse (int iargc, char *argv[]) const
00046 {
00047 int argc = iargc;
00048 for (argc--, argv++; argc > 0; argc--, argv++)
00049 {
00050
00051 std::string param = *argv;
00052 std::string::size_type cur = param.find ("--");
00053 if (cur == 0)
00054 {
00055 param = param.substr (2, param.size () - 2);
00056 }
00057 else
00058 {
00059 cur = param.find ("-");
00060 if (cur == 0)
00061 {
00062 param = param.substr (1, param.size () - 1);
00063 }
00064 else
00065 {
00066
00067 continue;
00068 }
00069 }
00070 cur = param.find ("=");
00071 std::string name, value;
00072 if (cur == std::string::npos)
00073 {
00074 name = param;
00075 value = "";
00076 }
00077 else
00078 {
00079 name = param.substr (0, cur);
00080 value = param.substr (cur + 1, param.size () - (cur+1));
00081 }
00082 HandleArgument (name, value);
00083 }
00084 }
00085
00086 void
00087 CommandLine::PrintHelp (void) const
00088 {
00089 std::cout << "--PrintHelp: Print this help message." << std::endl;
00090 std::cout << "--PrintGroups: Print the list of groups." << std::endl;
00091 std::cout << "--PrintTypeIds: Print all TypeIds." << std::endl;
00092 std::cout << "--PrintGroup=[group]: Print all TypeIds of group." << std::endl;
00093 std::cout << "--PrintAttributes=[typeid]: Print all attributes of typeid." << std::endl;
00094 std::cout << "--PrintGlobals: Print the list of globals." << std::endl;
00095 if (!m_items.empty ())
00096 {
00097 std::cout << "User Arguments:" << std::endl;
00098 for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
00099 {
00100 std::cout << " --" << (*i)->m_name << ": " << (*i)->m_help << std::endl;
00101 }
00102 }
00103 exit (0);
00104 }
00105
00106 void
00107 CommandLine::PrintGlobals (void) const
00108 {
00109 for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
00110 {
00111 std::cout << " --" << (*i)->GetName () << "=[";
00112 Ptr<const AttributeChecker> checker = (*i)->GetChecker ();
00113 StringValue v;
00114 (*i)->GetValue (v);
00115 std::cout << v.Get () << "]: "
00116 << (*i)->GetHelp () << std::endl;
00117 }
00118 exit (0);
00119 }
00120
00121 void
00122 CommandLine::PrintAttributes (std::string type) const
00123 {
00124 TypeId tid;
00125 if (!TypeId::LookupByNameFailSafe (type, &tid))
00126 {
00127 NS_FATAL_ERROR ("Unknown type="<<type<<" in --PrintAttributes");
00128 }
00129 for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
00130 {
00131 std::cout << " --"<<tid.GetAttributeFullName (i)<<"=[";
00132 Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
00133 Ptr<const AttributeValue> initial = tid.GetAttributeInitialValue (i);
00134 std::cout << initial->SerializeToString (checker) << "]: "
00135 << tid.GetAttributeHelp (i) << std::endl;
00136 }
00137 exit (0);
00138 }
00139
00140
00141 void
00142 CommandLine::PrintGroup (std::string group) const
00143 {
00144 for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
00145 {
00146 TypeId tid = TypeId::GetRegistered (i);
00147 if (tid.GetGroupName () == group)
00148 {
00149 std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
00150 }
00151 }
00152 exit (0);
00153 }
00154
00155 void
00156 CommandLine::PrintTypeIds (void) const
00157 {
00158 for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
00159 {
00160 TypeId tid = TypeId::GetRegistered (i);
00161 std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
00162 }
00163 exit (0);
00164 }
00165
00166 void
00167 CommandLine::PrintGroups (void) const
00168 {
00169 std::list<std::string> groups;
00170 for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
00171 {
00172 TypeId tid = TypeId::GetRegistered (i);
00173 std::string group = tid.GetGroupName ();
00174 if (group == "")
00175 {
00176 continue;
00177 }
00178 bool found = false;
00179 for (std::list<std::string>::const_iterator j = groups.begin (); j != groups.end (); ++j)
00180 {
00181 if (*j == group)
00182 {
00183 found = true;
00184 break;
00185 }
00186 }
00187 if (!found)
00188 {
00189 groups.push_back (group);
00190 }
00191 }
00192 for (std::list<std::string>::const_iterator k = groups.begin (); k != groups.end (); ++k)
00193 {
00194 std::cout << " --PrintGroup="<<*k<<std::endl;
00195 }
00196 exit (0);
00197 }
00198
00199 void
00200 CommandLine::HandleArgument (std::string name, std::string value) const
00201 {
00202 NS_LOG_DEBUG ("Handle arg name="<<name<<" value="<<value);
00203 if (name == "PrintHelp")
00204 {
00205
00206 PrintHelp ();
00207 }
00208 if (name == "PrintGroups")
00209 {
00210
00211 PrintGroups ();
00212 }
00213 if (name == "PrintTypeIds")
00214 {
00215
00216 PrintTypeIds ();
00217 }
00218 if (name == "PrintGlobals")
00219 {
00220
00221 PrintGlobals ();
00222 }
00223 if (name == "PrintGroup")
00224 {
00225
00226 PrintGroup (value);
00227 }
00228 if (name == "PrintAttributes")
00229 {
00230
00231 PrintAttributes (value);
00232 }
00233 for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
00234 {
00235 if ((*i)->m_name == name)
00236 {
00237 if (!(*i)->Parse (value))
00238 {
00239 std::cerr << "Invalid argument value: "<<name<<"="<<value << std::endl;
00240 return;
00241 }
00242 else
00243 {
00244 return;
00245 }
00246 }
00247 }
00248 if (!Config::SetGlobalFailSafe (name, StringValue (value))
00249 && !Config::SetDefaultFailSafe (name, StringValue (value)))
00250 {
00251 std::cerr << "Invalid command-line arguments: --"<<name<<"="<<value<<std::endl;
00252 PrintHelp ();
00253 }
00254 }
00255
00256 bool
00257 CommandLine::CallbackItem::Parse (std::string value)
00258 {
00259 NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
00260 return m_callback (value);
00261 }
00262
00263 void
00264 CommandLine::AddValue (const std::string &name,
00265 const std::string &help,
00266 Callback<bool, std::string> callback)
00267 {
00268 NS_LOG_FUNCTION (this << name << help << "callback");
00269 CallbackItem *item = new CallbackItem ();
00270 item->m_name = name;
00271 item->m_help = help;
00272 item->m_callback = callback;
00273 m_items.push_back (item);
00274 }
00275
00276
00277 }
00278
00279 #ifdef RUN_SELF_TESTS
00280
00281 #include "test.h"
00282 #include <stdarg.h>
00283
00284 using namespace ns3;
00285
00286 class CommandLineTest : public Test
00287 {
00288 public:
00289 CommandLineTest ();
00290 virtual bool RunTests (void);
00291 private:
00292 void Parse (const CommandLine &cmd, int n, ...);
00293 };
00294
00295 CommandLineTest::CommandLineTest ()
00296 : Test ("CommandLine")
00297 {}
00298 void
00299 CommandLineTest::Parse (const CommandLine &cmd, int n, ...)
00300 {
00301 char **args = new char* [n+1];
00302 args[0] = (char *) "Test";
00303 va_list ap;
00304 va_start (ap, n);
00305 int i = 0;
00306 while (i < n)
00307 {
00308 char *arg = va_arg (ap, char *);
00309 args[i+1] = arg;
00310 i++;
00311 }
00312 int argc = n + 1;
00313 cmd.Parse (argc, args);
00314 delete [] args;
00315 }
00316 bool
00317 CommandLineTest::RunTests (void)
00318 {
00319 bool result = true;
00320
00321 bool myBool = false;
00322 uint32_t myUint32 = 10;
00323 std::string myStr = "MyStr";
00324 int32_t myInt32 = -1;
00325 CommandLine cmd;
00326
00327 cmd.AddValue ("my-bool", "help", myBool);
00328 Parse (cmd, 1, "--my-bool=0");
00329 NS_TEST_ASSERT_EQUAL (myBool, false);
00330 Parse (cmd, 1, "--my-bool=1");
00331 NS_TEST_ASSERT_EQUAL (myBool, true);
00332
00333 cmd.AddValue ("my-uint32", "help", myUint32);
00334 Parse (cmd, 2, "--my-bool=0", "--my-uint32=9");
00335 NS_TEST_ASSERT_EQUAL (myUint32, 9);
00336
00337 cmd.AddValue ("my-str", "help", myStr);
00338 Parse (cmd, 2, "--my-bool=0", "--my-str=XX");
00339 NS_TEST_ASSERT_EQUAL (myStr, "XX");
00340
00341 cmd.AddValue ("my-int32", "help", myInt32);
00342 Parse (cmd, 2, "--my-bool=0", "--my-int32=-3");
00343 NS_TEST_ASSERT_EQUAL (myInt32, -3);
00344 Parse (cmd, 2, "--my-bool=0", "--my-int32=+2");
00345 NS_TEST_ASSERT_EQUAL (myInt32, +2);
00346
00347 return result;
00348 }
00349
00350
00351 static CommandLineTest g_cmdLineTest;
00352
00353 #endif