Bug 289: CommandLine::AddValue is not wrapped
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Wed Nov 26 12:11:11 2008 +0000 (14 months ago)
changeset 3937b200bb6b89e6
parent 3936 974b8280b51c
child 3938 b51d8ebd4724
Bug 289: CommandLine::AddValue is not wrapped
bindings/python/callbacks_list.py
bindings/python/ns3_module_core.py
bindings/python/ns3module_helpers.cc
bindings/python/ns3modulegen_core_customizations.py
bindings/python/ns3modulescan.py
bindings/python/wscript
src/core/command-line.cc
src/core/command-line.h
utils/python-unit-tests.py
     1.1 --- a/bindings/python/callbacks_list.py	Wed Apr 29 19:08:39 2009 +0100
     1.2 +++ b/bindings/python/callbacks_list.py	Wed Nov 26 12:11:11 2008 +0000
     1.3 @@ -10,4 +10,5 @@
     1.4      ['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
     1.5      ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     1.6      ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'],
     1.7 +    ['bool', 'std::string', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     1.8  ]
     2.1 --- a/bindings/python/ns3_module_core.py	Wed Apr 29 19:08:39 2009 +0100
     2.2 +++ b/bindings/python/ns3_module_core.py	Wed Nov 26 12:11:11 2008 +0000
     2.3 @@ -12,7 +12,7 @@
     2.4      ## callback.h: ns3::CallbackImplBase [class]
     2.5      module.add_class('CallbackImplBase', allow_subclassing=True, memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
     2.6      ## command-line.h: ns3::CommandLine [class]
     2.7 -    module.add_class('CommandLine')
     2.8 +    module.add_class('CommandLine', allow_subclassing=True)
     2.9      ## system-mutex.h: ns3::CriticalSection [class]
    2.10      module.add_class('CriticalSection')
    2.11      ## global-value.h: ns3::GlobalValue [class]
    2.12 @@ -339,6 +339,10 @@
    2.13      cls.add_constructor([param('ns3::CommandLine const &', 'arg0')])
    2.14      ## command-line.h: ns3::CommandLine::CommandLine() [constructor]
    2.15      cls.add_constructor([])
    2.16 +    ## command-line.h: void ns3::CommandLine::AddValue(std::string const & name, std::string const & help, ns3::Callback<bool, std::string, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
    2.17 +    cls.add_method('AddValue', 
    2.18 +                   'void', 
    2.19 +                   [param('std::string const &', 'name'), param('std::string const &', 'help'), param('ns3::Callback< bool, std::string, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
    2.20      return
    2.21  
    2.22  def register_Ns3CriticalSection_methods(root_module, cls):
     3.1 --- a/bindings/python/ns3module_helpers.cc	Wed Apr 29 19:08:39 2009 +0100
     3.2 +++ b/bindings/python/ns3module_helpers.cc	Wed Nov 26 12:11:11 2008 +0000
     3.3 @@ -1,3 +1,4 @@
     3.4 +#include "ns3/ref-count-base.h"
     3.5  #include "ns3module.h"
     3.6  
     3.7  
     3.8 @@ -220,3 +221,61 @@
     3.9      
    3.10      return (PyObject *) py_tid;
    3.11  }
    3.12 +
    3.13 +
    3.14 +class CommandLinePythonValueSetter : public ns3::RefCountBase
    3.15 +{
    3.16 +    PyObject *m_namespace;
    3.17 +    std::string m_variable;
    3.18 +public:
    3.19 +    CommandLinePythonValueSetter (PyObject *ns, std::string const &variable) {
    3.20 +        Py_INCREF(ns);
    3.21 +        m_namespace = ns;
    3.22 +        m_variable = variable;
    3.23 +    }
    3.24 +    bool Parse (std::string value) {
    3.25 +        PyObject *pyvalue = PyString_FromStringAndSize (value.data(), value.size());
    3.26 +        PyObject_SetAttrString (m_namespace, m_variable.c_str(), pyvalue);
    3.27 +        if (PyErr_Occurred()) {
    3.28 +            PyErr_Print();
    3.29 +            return false;
    3.30 +        }
    3.31 +        return true;
    3.32 +    }
    3.33 +    virtual ~CommandLinePythonValueSetter () {
    3.34 +        Py_DECREF (m_namespace);
    3.35 +        m_namespace = NULL;
    3.36 +    }
    3.37 +    
    3.38 +};
    3.39 +
    3.40 +PyObject *
    3.41 +_wrap_CommandLine_AddValue(PyNs3CommandLine *self, PyObject *args, PyObject *kwargs,
    3.42 +                           PyObject **return_exception)
    3.43 +{
    3.44 +    const char *name, *help, *variable = NULL;
    3.45 +    PyObject *py_namespace = NULL;
    3.46 +    const char *keywords[] = {"name", "help", "variable", "namespace", NULL};
    3.47 +    
    3.48 +    if (!PyArg_ParseTupleAndKeywords(args, kwargs, (char *) "ss|sO", (char **) keywords, &name, &help, &variable, &py_namespace)) {
    3.49 +        PyObject *exc_type, *traceback;
    3.50 +        PyErr_Fetch(&exc_type, return_exception, &traceback);
    3.51 +        Py_XDECREF(exc_type);
    3.52 +        Py_XDECREF(traceback);
    3.53 +        return NULL;
    3.54 +    }
    3.55 +    
    3.56 +    if (variable == NULL) {
    3.57 +        variable = name;
    3.58 +    }
    3.59 +    if (py_namespace == NULL) {
    3.60 +        py_namespace = (PyObject *) self;
    3.61 +    }
    3.62 +
    3.63 +    ns3::Ptr<CommandLinePythonValueSetter> setter = ns3::Create<CommandLinePythonValueSetter> (py_namespace, variable);
    3.64 +    self->obj->AddValue (name, help, ns3::MakeCallback (&CommandLinePythonValueSetter::Parse, setter));
    3.65 +
    3.66 +    Py_INCREF(Py_None);
    3.67 +    return Py_None;
    3.68 +}
    3.69 +
     4.1 --- a/bindings/python/ns3modulegen_core_customizations.py	Wed Apr 29 19:08:39 2009 +0100
     4.2 +++ b/bindings/python/ns3modulegen_core_customizations.py	Wed Nov 26 12:11:11 2008 +0000
     4.3 @@ -292,6 +292,8 @@
     4.4      CommandLine = module['ns3::CommandLine']
     4.5      CommandLine.add_method('Parse', None, [ArgvParam(None, 'argv')],
     4.6                             is_static=False)
     4.7 +    CommandLine.add_custom_method_wrapper("AddValue", "_wrap_CommandLine_AddValue",
     4.8 +                                          flags=["METH_VARARGS", "METH_KEYWORDS"])
     4.9  
    4.10  
    4.11  def Object_customizations(module):
    4.12 @@ -522,5 +524,5 @@
    4.13      TypeId = module['ns3::TypeId']
    4.14      TypeId.add_custom_method_wrapper("LookupByNameFailSafe", "_wrap_TypeId_LookupByNameFailSafe",
    4.15                                       flags=["METH_VARARGS", "METH_KEYWORDS", "METH_STATIC"])
    4.16 -    
    4.17  
    4.18 +
     5.1 --- a/bindings/python/ns3modulescan.py	Wed Apr 29 19:08:39 2009 +0100
     5.2 +++ b/bindings/python/ns3modulescan.py	Wed Nov 26 12:11:11 2008 +0000
     5.3 @@ -56,6 +56,11 @@
     5.4          'automatic_type_narrowing': 'true',
     5.5          'allow_subclassing': 'false',
     5.6          },
     5.7 +
     5.8 +    '::ns3::CommandLine': {
     5.9 +        'allow_subclassing': 'true', # needed so that AddValue is able to set attributes on the object
    5.10 +        },
    5.11 +
    5.12      'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': {
    5.13          'ignore': None,
    5.14          },
     6.1 --- a/bindings/python/wscript	Wed Apr 29 19:08:39 2009 +0100
     6.2 +++ b/bindings/python/wscript	Wed Nov 26 12:11:11 2008 +0000
     6.3 @@ -272,6 +272,7 @@
     6.4     t1 > t2;
     6.5  }
     6.6  
     6.7 +
     6.8  }
     6.9  """
    6.10      outfile.close()
     7.1 --- a/src/core/command-line.cc	Wed Apr 29 19:08:39 2009 +0100
     7.2 +++ b/src/core/command-line.cc	Wed Nov 26 12:11:11 2008 +0000
     7.3 @@ -253,6 +253,27 @@
     7.4      }
     7.5  }
     7.6  
     7.7 +bool
     7.8 +CommandLine::CallbackItem::Parse (std::string value)
     7.9 +{
    7.10 +  NS_LOG_DEBUG ("CommandLine::CallbackItem::Parse \"" << value << "\"");
    7.11 +  return m_callback (value);
    7.12 +}
    7.13 +
    7.14 +void
    7.15 +CommandLine::AddValue (const std::string &name,
    7.16 +                       const std::string &help,
    7.17 +                       Callback<bool, std::string> callback)
    7.18 +{
    7.19 +  NS_LOG_FUNCTION (this << name << help << "callback");
    7.20 +  CallbackItem *item = new CallbackItem ();
    7.21 +  item->m_name = name;
    7.22 +  item->m_help = help;
    7.23 +  item->m_callback = callback;
    7.24 +  m_items.push_back (item);
    7.25 +}
    7.26 +
    7.27 +
    7.28  } // namespace ns3
    7.29  
    7.30  #ifdef RUN_SELF_TESTS
     8.1 --- a/src/core/command-line.h	Wed Apr 29 19:08:39 2009 +0100
     8.2 +++ b/src/core/command-line.h	Wed Nov 26 12:11:11 2008 +0000
     8.3 @@ -24,6 +24,8 @@
     8.4  #include <sstream>
     8.5  #include <list>
     8.6  
     8.7 +#include "ns3/callback.h"
     8.8 +
     8.9  namespace ns3 {
    8.10  
    8.11  /**
    8.12 @@ -56,6 +58,17 @@
    8.13  		 const std::string &help,
    8.14  		 T &value);
    8.15  
    8.16 +
    8.17 +  /**
    8.18 +   * \param name the name of the user-supplied argument
    8.19 +   * \param help some help text used by --PrintHelp
    8.20 +   * \param callback a callback function that will be invoked to parse
    8.21 +   * and collect the value.  This normally used by language bindings.
    8.22 +   */
    8.23 +  void AddValue (const std::string &name,
    8.24 +		 const std::string &help,
    8.25 +                 Callback<bool, std::string> callback);
    8.26 +
    8.27    /**
    8.28     * \param argc the 'argc' variable: number of arguments (including the
    8.29     *        main program name as first element).
    8.30 @@ -82,6 +95,13 @@
    8.31      virtual bool Parse (std::string value);
    8.32      T *m_valuePtr;
    8.33    };
    8.34 +  class CallbackItem : public Item
    8.35 +  {
    8.36 +  public:
    8.37 +    virtual bool Parse (std::string value);
    8.38 +    Callback<bool, std::string> m_callback;
    8.39 +  };
    8.40 +
    8.41    void HandleArgument (std::string name, std::string value) const;
    8.42    void PrintHelp (void) const;
    8.43    void PrintGlobals (void) const;
     9.1 --- a/utils/python-unit-tests.py	Wed Apr 29 19:08:39 2009 +0100
     9.2 +++ b/utils/python-unit-tests.py	Wed Nov 26 12:11:11 2008 +0000
     9.3 @@ -124,5 +124,26 @@
     9.4          
     9.5          self.assertRaises(KeyError, ns3.TypeId.LookupByNameFailSafe, "__InvalidTypeName__")
     9.6  
     9.7 +    def testCommandLine(self):
     9.8 +        cmd = ns3.CommandLine()
     9.9 +        cmd.AddValue("Test1", "this is a test option")
    9.10 +        cmd.AddValue("Test2", "this is a test option")
    9.11 +        cmd.AddValue("Test3", "this is a test option", variable="test_xxx")
    9.12 +        cmd.Test1 = None
    9.13 +        cmd.Test2 = None
    9.14 +        cmd.test_xxx = None
    9.15 +        class Foo:
    9.16 +            pass
    9.17 +        foo = Foo()
    9.18 +        foo.test_foo = None
    9.19 +        cmd.AddValue("Test4", "this is a test option", variable="test_foo", namespace=foo)
    9.20 +        
    9.21 +        cmd.Parse(["python", "--Test1=value1", "--Test2=value2", "--Test3=123", "--Test4=xpto"])
    9.22 +
    9.23 +        self.assertEqual(cmd.Test1, "value1")
    9.24 +        self.assertEqual(cmd.Test2, "value2")
    9.25 +        self.assertEqual(cmd.test_xxx, "123")
    9.26 +        self.assertEqual(foo.test_foo, "xpto")
    9.27 +
    9.28  if __name__ == '__main__':
    9.29      unittest.main()