mathieu@2581: /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ mathieu@2581: /* mathieu@2581: * Copyright (c) 2008 INRIA mathieu@2581: * mathieu@2581: * This program is free software; you can redistribute it and/or modify mathieu@2581: * it under the terms of the GNU General Public License version 2 as mathieu@2581: * published by the Free Software Foundation; mathieu@2581: * mathieu@2581: * This program is distributed in the hope that it will be useful, mathieu@2581: * but WITHOUT ANY WARRANTY; without even the implied warranty of mathieu@2581: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the mathieu@2581: * GNU General Public License for more details. mathieu@2581: * mathieu@2581: * You should have received a copy of the GNU General Public License mathieu@2581: * along with this program; if not, write to the Free Software mathieu@2581: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mathieu@2581: * mathieu@2581: * Authors: Mathieu Lacage mathieu@2581: */ mathieu@2575: #include "command-line.h" mathieu@2575: #include "log.h" mathieu@2575: #include "config.h" mathieu@2575: #include "global-value.h" mathieu@2965: #include "type-id.h" mathieu@2575: #include "string.h" mathieu@2575: #include raj@439: mathieu@2575: NS_LOG_COMPONENT_DEFINE ("CommandLine"); raj@439: raj@439: namespace ns3 { raj@439: mathieu@2575: CommandLine::~CommandLine () gjc@1703: { mathieu@2575: for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i) gjc@1703: { mathieu@2575: delete *i; gjc@1703: } mathieu@2575: m_items.clear (); gjc@1703: } gjc@1703: mathieu@2575: CommandLine::Item::~Item () mathieu@2575: {} raj@439: raj@439: void mathieu@2915: CommandLine::Parse (int iargc, char *argv[]) const raj@439: { mathieu@2575: int argc = iargc; gjc@1533: for (argc--, argv++; argc > 0; argc--, argv++) raj@439: { raj@439: // remove "--" or "-" heading. raj@439: std::string param = *argv; raj@439: std::string::size_type cur = param.find ("--"); mathieu@2575: if (cur == 0) mathieu@2575: { mathieu@2575: param = param.substr (2, param.size () - 2); mathieu@2575: } mathieu@2575: else mathieu@2575: { mathieu@2575: cur = param.find ("-"); mathieu@2575: if (cur == 0) mathieu@2575: { mathieu@2575: param = param.substr (1, param.size () - 1); mathieu@2575: } mathieu@2575: else mathieu@2575: { mathieu@2575: // invalid argument. ignore. mathieu@2575: continue; mathieu@2575: } mathieu@2575: } raj@439: cur = param.find ("="); raj@439: std::string name, value; raj@439: if (cur == std::string::npos) raj@439: { mathieu@2575: name = param; mathieu@2575: value = ""; raj@439: } raj@439: else raj@439: { mathieu@2575: name = param.substr (0, cur); mathieu@2575: value = param.substr (cur + 1, param.size () - (cur+1)); raj@439: } mathieu@2575: HandleArgument (name, value); raj@439: } raj@439: } raj@439: mathieu@2575: void mathieu@2575: CommandLine::PrintHelp (void) const mathieu@2575: { mathieu@2575: std::cout << "--PrintHelp: Print this help message." << std::endl; mathieu@2575: std::cout << "--PrintGroups: Print the list of groups." << std::endl; mathieu@2575: std::cout << "--PrintTypeIds: Print all TypeIds." << std::endl; mathieu@2575: std::cout << "--PrintGroup=[group]: Print all TypeIds of group." << std::endl; mathieu@2575: std::cout << "--PrintAttributes=[typeid]: Print all attributes of typeid." << std::endl; mathieu@2575: std::cout << "--PrintGlobals: Print the list of globals." << std::endl; mathieu@2575: if (!m_items.empty ()) mathieu@2575: { mathieu@2575: std::cout << "User Arguments:" << std::endl; mathieu@2575: for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i) mathieu@2575: { mathieu@2575: std::cout << " --" << (*i)->m_name << ": " << (*i)->m_help << std::endl; mathieu@2575: } mathieu@2575: } mathieu@2575: } mathieu@2575: mathieu@2575: void mathieu@2575: CommandLine::PrintGlobals (void) const mathieu@2575: { mathieu@2575: for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i) mathieu@2575: { mathieu@2575: std::cout << " --" << (*i)->GetName () << "=["; mathieu@2575: Ptr checker = (*i)->GetChecker (); mathieu@2965: StringValue v; mathieu@2965: (*i)->GetValue (v); mathieu@2965: std::cout << v.Get () << "]: " mathieu@2575: << (*i)->GetHelp () << std::endl; mathieu@2575: } mathieu@2575: } mathieu@2575: mathieu@2575: void mathieu@2575: CommandLine::PrintAttributes (std::string type) const mathieu@2575: { mathieu@2575: TypeId tid; mathieu@2575: if (!TypeId::LookupByNameFailSafe (type, &tid)) mathieu@2575: { mathieu@2575: NS_FATAL_ERROR ("Unknown type="< checker = tid.GetAttributeChecker (i); mathieu@2965: Ptr initial = tid.GetAttributeInitialValue (i); mathieu@2965: std::cout << initial->SerializeToString (checker) << "]: " mathieu@2575: << tid.GetAttributeHelp (i) << std::endl; mathieu@2575: } mathieu@2575: } gjc@1702: gjc@1702: mathieu@2575: void mathieu@2575: CommandLine::PrintGroup (std::string group) const mathieu@2575: { mathieu@2575: for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i) mathieu@2575: { mathieu@2575: TypeId tid = TypeId::GetRegistered (i); mathieu@2575: if (tid.GetGroupName () == group) mathieu@2575: { mathieu@2575: std::cout << " --PrintAttributes=" <::const_iterator j = groups.begin (); j != groups.end (); ++j) mathieu@2575: { mathieu@2575: if (*j == group) mathieu@2575: { mathieu@2575: found = true; mathieu@2575: break; mathieu@2575: } mathieu@2575: } mathieu@2575: if (!found) mathieu@2575: { mathieu@2575: groups.push_back (group); mathieu@2575: } mathieu@2575: } mathieu@2575: for (std::list::const_iterator k = groups.begin (); k != groups.end (); ++k) mathieu@2575: { mathieu@2575: std::cout << " --PrintGroup="<<*k<m_name == name) mathieu@4490: { mathieu@4490: if (!(*i)->Parse (value)) mathieu@4490: { mathieu@4490: std::cerr << "Invalid argument value: "< callback) gjc@3929: { gjc@3929: NS_LOG_FUNCTION (this << name << help << "callback"); gjc@3929: CallbackItem *item = new CallbackItem (); gjc@3929: item->m_name = name; gjc@3929: item->m_help = help; gjc@3929: item->m_callback = callback; gjc@3929: m_items.push_back (item); gjc@3929: } gjc@3929: gjc@3929: mathieu@2575: } // namespace ns3 gjc@1702: gjc@1702: #ifdef RUN_SELF_TESTS mathieu@2575: gjc@1702: #include "test.h" mathieu@2575: #include gjc@1702: mathieu@2575: using namespace ns3; gjc@1702: gjc@1702: class CommandLineTest : public Test gjc@1702: { gjc@1702: public: mathieu@2575: CommandLineTest (); mathieu@2575: virtual bool RunTests (void); mathieu@2575: private: mathieu@2575: void Parse (const CommandLine &cmd, int n, ...); mathieu@2575: }; gjc@1702: mathieu@2575: CommandLineTest::CommandLineTest () mathieu@2575: : Test ("CommandLine") mathieu@2575: {} mathieu@2575: void mathieu@2575: CommandLineTest::Parse (const CommandLine &cmd, int n, ...) mathieu@2575: { mathieu@2575: char **args = new char* [n+1]; gjc@2612: args[0] = (char *) "Test"; mathieu@2575: va_list ap; mathieu@2575: va_start (ap, n); mathieu@2575: int i = 0; mathieu@2575: while (i < n) gjc@1702: { mathieu@2575: char *arg = va_arg (ap, char *); mathieu@2575: args[i+1] = arg; mathieu@2575: i++; gjc@1702: } mathieu@2575: int argc = n + 1; mathieu@2575: cmd.Parse (argc, args); mathieu@2575: delete [] args; mathieu@2575: } mathieu@2575: bool mathieu@2575: CommandLineTest::RunTests (void) mathieu@2575: { mathieu@2575: bool result = true; mathieu@2575: mathieu@2575: bool myBool = false; mathieu@2575: uint32_t myUint32 = 10; mathieu@2575: std::string myStr = "MyStr"; mathieu@2575: int32_t myInt32 = -1; mathieu@2575: CommandLine cmd; gjc@1702: mathieu@2575: cmd.AddValue ("my-bool", "help", myBool); mathieu@2575: Parse (cmd, 1, "--my-bool=0"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myBool, false); mathieu@2575: Parse (cmd, 1, "--my-bool=1"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myBool, true); mathieu@2575: mathieu@2575: cmd.AddValue ("my-uint32", "help", myUint32); mathieu@2575: Parse (cmd, 2, "--my-bool=0", "--my-uint32=9"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myUint32, 9); gjc@1702: mathieu@2575: cmd.AddValue ("my-str", "help", myStr); mathieu@2575: Parse (cmd, 2, "--my-bool=0", "--my-str=XX"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myStr, "XX"); gjc@1702: mathieu@2575: cmd.AddValue ("my-int32", "help", myInt32); mathieu@2575: Parse (cmd, 2, "--my-bool=0", "--my-int32=-3"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myInt32, -3); mathieu@2575: Parse (cmd, 2, "--my-bool=0", "--my-int32=+2"); mathieu@2575: NS_TEST_ASSERT_EQUAL (myInt32, +2); mathieu@2575: mathieu@2575: return result; mathieu@2575: } gjc@1702: gjc@1702: mathieu@2575: static CommandLineTest g_cmdLineTest; gjc@1702: gjc@1702: #endif /* RUN_SELF_TESTS */