/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007 INRIA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage */ #include "default-value.h" #include "fatal-error.h" namespace ns3 { DefaultValueBase::DefaultValueBase (const std::string &name, const std::string &help) : m_name (name), m_help (help) {} DefaultValueBase::~DefaultValueBase () {} std::string DefaultValueBase::GetName (void) const { return m_name; } std::string DefaultValueBase::GetHelp (void) const { return m_help; } bool DefaultValueBase::ParseValue (const std::string &value) { return DoParseValue (value); } std::string DefaultValueBase::GetType (void) const { return DoGetType (); } std::string DefaultValueBase::GetDefaultValue (void) const { return DoGetDefaultValue (); } DefaultValueList::Iterator DefaultValueList::Begin (void) { return GetList ()->begin (); } DefaultValueList::Iterator DefaultValueList::End (void) { return GetList ()->end (); } void DefaultValueList::Remove (const std::string &name) { DefaultValueList::List *list = GetList (); for (List::iterator i = list->begin (); i != list->end (); /* nothing */) { if ((*i)->GetName () == name) { i = list->erase (i); } else { i++; } } } void DefaultValueList::Add (DefaultValueBase *defaultValue) { GetList ()->push_back (defaultValue); } DefaultValueList::List * DefaultValueList::GetList (void) { static List list; return &list; } enum BindStatus { OK, INVALID_VALUE, NOT_FOUND }; static enum BindStatus BindSafe (std::string name, std::string value) { for (DefaultValueList::Iterator i = DefaultValueList::Begin (); i != DefaultValueList::End (); i++) { DefaultValueBase *cur = *i; if (cur->GetName () == name) { if (!cur->ParseValue (value)) { return INVALID_VALUE; } return OK; } } return NOT_FOUND; } void Bind (std::string name, std::string value) { switch (BindSafe (name, value)) { case INVALID_VALUE: NS_FATAL_ERROR ("Invalid value: "<::iterator i = m_possibleValues.begin (); i != m_possibleValues.end (); i++) { if (value == *i) { NS_FATAL_ERROR ("Value already exists: " << value); } } m_possibleValues.push_back (value); m_value = value; m_defaultValue = value; } void StringEnumDefaultValue::AddPossibleValue (const std::string &value) { for (std::list::iterator i = m_possibleValues.begin (); i != m_possibleValues.end (); i++) { if (value == *i) { NS_FATAL_ERROR ("Value already exists: " << value); } } m_possibleValues.push_back (value); } std::string StringEnumDefaultValue::GetValue (void) const { return m_value; } bool StringEnumDefaultValue::DoParseValue (const std::string &value) { for (std::list::iterator i = m_possibleValues.begin (); i != m_possibleValues.end (); i++) { if (value == *i) { m_value = value; return true; } } return false; } std::string StringEnumDefaultValue::DoGetType (void) const { std::string retval; retval += "("; for (std::list::const_iterator i = m_possibleValues.begin (); i != m_possibleValues.end (); i++) { if (i != m_possibleValues.begin ()) { retval += "|"; } retval += *i; } retval += ")"; return retval; } std::string StringEnumDefaultValue::DoGetDefaultValue (void) const { return m_defaultValue; } CommandDefaultValue::CommandDefaultValue (const std::string &name, const std::string &help, Callback cb) : DefaultValueBase (name, help), m_cb (cb) { DefaultValueList::Add (this); } bool CommandDefaultValue::DoParseValue (const std::string &value) { m_cb (); return true; } std::string CommandDefaultValue::DoGetType (void) const { return ""; } std::string CommandDefaultValue::DoGetDefaultValue (void) const { return ""; } }//namespace ns3 #ifdef RUN_SELF_TESTS #include "test.h" namespace ns3 { enum MyEnum { MY_ENUM_A, MY_ENUM_B, MY_ENUM_C, MY_ENUM_D, }; class DefaultValueTest : public Test { public: DefaultValueTest (); virtual bool RunTests (void); }; DefaultValueTest::DefaultValueTest () : Test ("DefaultValue") {} bool DefaultValueTest::RunTests (void) { bool ok = true; BooleanDefaultValue a ("bool-a", "help a", true); if (!a.GetValue ()) { ok = false; } Bind ("bool-a", "false"); if (a.GetValue ()) { ok = false; } BooleanDefaultValue b ("bool-b", "help b", false); Bind ("bool-b", "true"); if (!b.GetValue ()) { ok = false; } Bind ("bool-b", "0"); if (b.GetValue ()) { ok = false; } Bind ("bool-b", "1"); if (!b.GetValue ()) { ok = false; } Bind ("bool-b", "f"); if (b.GetValue ()) { ok = false; } Bind ("bool-b", "t"); if (!b.GetValue ()) { ok = false; } Bind ("bool-b", "false"); if (b.GetValue ()) { ok = false; } if (BindSafe ("bool-b", "tr") != INVALID_VALUE) { ok = false; } IntegerDefaultValue i ("test-i", "help-i", -1); if (i.GetValue () != -1) { ok = false; } Bind ("test-i", "-2"); if (i.GetValue () != -2) { ok = false; } Bind ("test-i", "+2"); if (i.GetValue () != 2) { ok = false; } if (i.GetType () != "int32_t(-2147483648:2147483647)") { ok = false; } IntegerDefaultValue ui32 ("test-ui32", "help-ui32", 10); if (ui32.GetType () != "uint32_t(0:4294967295)") { ok = false; } IntegerDefaultValue c ("test-c", "help-c", 10); if (c.GetValue () != 10) { ok = false; } Bind ("test-c", "257"); EnumDefaultValue e ("test-e", "help-e", MY_ENUM_C, "C", MY_ENUM_A, "A", MY_ENUM_B, "B", 0, (void*)0); if (e.GetValue () != MY_ENUM_C) { ok = false; } Bind ("test-e", "B"); if (e.GetValue () != MY_ENUM_B) { ok = false; } if (BindSafe ("test-e", "D") != INVALID_VALUE) { ok = false; } class MyEnumSubclass : public EnumDefaultValue { public: MyEnumSubclass () : EnumDefaultValue ("test-e1", "help-e1", MY_ENUM_B, "B", MY_ENUM_A, "A", 0, (void*)0) { AddPossibleValue (MY_ENUM_C, "C"); AddPossibleValue (MY_ENUM_D, "D"); } } e1 ; if (e1.GetValue () != MY_ENUM_B) { ok = false; } Bind ("test-e1", "D"); if (e1.GetValue () != MY_ENUM_D) { ok = false; } DefaultValueList::Remove ("test-e1"); DefaultValueList::Remove ("test-e"); DefaultValueList::Remove ("bool-b"); DefaultValueList::Remove ("bool-a"); DefaultValueList::Remove ("test-i"); DefaultValueList::Remove ("test-c"); DefaultValueList::Remove ("test-ui32"); return ok; } static DefaultValueTest g_default_value_tests; }//namespace ns3 #endif /* RUN_SELF_TESTS */