Index: scripts/Python/python-typemaps.swig =================================================================== --- scripts/Python/python-typemaps.swig +++ scripts/Python/python-typemaps.swig @@ -139,30 +139,9 @@ // typemap for an outgoing buffer // See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). -%typemap(in) (const char *cstr, uint32_t cstr_len) { - using namespace lldb_private; - if (PythonString::Check($input)) { - PythonString str(PyRefType::Borrowed, $input); - $1 = (char*)str.GetString().data(); - $2 = str.GetSize(); - } - else if(PythonByteArray::Check($input)) { - PythonByteArray bytearray(PyRefType::Borrowed, $input); - $1 = (char*)bytearray.GetBytes().data(); - $2 = bytearray.GetSize(); - } - else if (PythonBytes::Check($input)) { - PythonBytes bytes(PyRefType::Borrowed, $input); - $1 = (char*)bytes.GetBytes().data(); - $2 = bytes.GetSize(); - } - else { - PyErr_SetString(PyExc_ValueError, "Expecting a string"); - return NULL; - } -} // Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). -%typemap(in) (const char *src, size_t src_len) { +%typemap(in) (const char *cstr, uint32_t cstr_len), + (const char *src, size_t src_len) { using namespace lldb_private; if (PythonString::Check($input)) { PythonString str(PyRefType::Borrowed, $input); @@ -184,32 +163,9 @@ return NULL; } } -// And SBProcess::WriteMemory. -%typemap(in) (const void *buf, size_t size) { - using namespace lldb_private; - if (PythonString::Check($input)) { - PythonString str(PyRefType::Borrowed, $input); - $1 = (void*)str.GetString().data(); - $2 = str.GetSize(); - } - else if(PythonByteArray::Check($input)) { - PythonByteArray bytearray(PyRefType::Borrowed, $input); - $1 = (void*)bytearray.GetBytes().data(); - $2 = bytearray.GetSize(); - } - else if (PythonBytes::Check($input)) { - PythonBytes bytes(PyRefType::Borrowed, $input); - $1 = (void*)bytes.GetBytes().data(); - $2 = bytes.GetSize(); - } - else { - PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); - return NULL; - } -} - -// For SBDebugger::DispatchInput -%typemap(in) (const void *data, size_t data_len) { +// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. +%typemap(in) (const void *buf, size_t size), + (const void *data, size_t data_len) { using namespace lldb_private; if (PythonString::Check($input)) { PythonString str(PyRefType::Borrowed, $input); @@ -264,142 +220,70 @@ free($1); } -// these typemaps allow Python users to pass list objects -// and have them turn into C++ arrays (this is useful, for instance -// when creating SBData objects from lists of numbers) -%typemap(in) (uint64_t* array, size_t array_len) { - /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - $2 = size; - $1 = (uint64_t*) malloc(size * sizeof(uint64_t)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyInt_Check(o)) { - $1[i] = PyInt_AsLong(o); - } - else if (PyLong_Check(o)) { - $1[i] = PyLong_AsUnsignedLongLong(o); - } - else { - PyErr_SetString(PyExc_TypeError,"list must contain numbers"); - free($1); - return NULL; - } - - if (PyErr_Occurred()) { - free($1); - return NULL; - } - } - } else if ($input == Py_None) { - $1 = NULL; - $2 = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } +%{ +namespace { +template +T PyLongAsT(PyObject *obj) { + static_assert(true, "unsupported type"); } -%typemap(freearg) (uint64_t* array, size_t array_len) { - free($1); +template <> uint64_t PyLongAsT(PyObject *obj) { + return static_cast(PyLong_AsUnsignedLongLong(obj)); } -%typemap(in) (uint32_t* array, size_t array_len) { - /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - $2 = size; - $1 = (uint32_t*) malloc(size * sizeof(uint32_t)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyInt_Check(o)) { - $1[i] = PyInt_AsLong(o); - } - else if (PyLong_Check(o)) { - $1[i] = PyLong_AsUnsignedLong(o); - } - else { - PyErr_SetString(PyExc_TypeError,"list must contain numbers"); - free($1); - return NULL; - } +template <> uint32_t PyLongAsT(PyObject *obj) { + return static_cast(PyLong_AsUnsignedLong(obj)); +} - if (PyErr_Occurred()) { - free($1); - return NULL; - } - } - } else if ($input == Py_None) { - $1 = NULL; - $2 = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } +template <> int64_t PyLongAsT(PyObject *obj) { + return static_cast(PyLong_AsLongLong(obj)); } -%typemap(freearg) (uint32_t* array, size_t array_len) { - free($1); +template <> int32_t PyLongAsT(PyObject *obj) { + return static_cast(PyLong_AsLong(obj)); } -%typemap(in) (int64_t* array, size_t array_len) { - /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - $2 = size; - $1 = (int64_t*) malloc(size * sizeof(int64_t)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyInt_Check(o)) { - $1[i] = PyInt_AsLong(o); - } - else if (PyLong_Check(o)) { - $1[i] = PyLong_AsLongLong(o); - } - else { - PyErr_SetString(PyExc_TypeError,"list must contain numbers"); - free($1); - return NULL; - } +template +bool SetNumberFromPyObject(T &number, PyObject *obj) { + if (PyInt_Check(obj)) + number = static_cast(PyInt_AsLong(obj)); + else if (PyLong_Check(obj)) + number = PyLongAsT(obj); + else return false; - if (PyErr_Occurred()) { - free($1); - return NULL; - } - } - } else if ($input == Py_None) { - $1 = NULL; - $2 = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } + return true; } -%typemap(freearg) (int64_t* array, size_t array_len) { - free($1); +template <> +bool SetNumberFromPyObject(double &number, PyObject *obj) { + if (PyFloat_Check(obj)) { + number = PyFloat_AsDouble(obj); + return true; + } + + return false; } -%typemap(in) (int32_t* array, size_t array_len) { +} // namespace +%} + +// these typemaps allow Python users to pass list objects +// and have them turn into C++ arrays (this is useful, for instance +// when creating SBData objects from lists of numbers) +%typemap(in) (uint64_t* array, size_t array_len), + (uint32_t* array, size_t array_len), + (int64_t* array, size_t array_len), + (int32_t* array, size_t array_len), + (double* array, size_t array_len) { /* Check if is a list */ if (PyList_Check($input)) { int size = PyList_Size($input); int i = 0; $2 = size; - $1 = (int32_t*) malloc(size * sizeof(int32_t)); + $1 = ($1_type) malloc(size * sizeof($*1_type)); for (i = 0; i < size; i++) { PyObject *o = PyList_GetItem($input,i); - if (PyInt_Check(o)) { - $1[i] = PyInt_AsLong(o); - } - else if (PyLong_Check(o)) { - $1[i] = PyLong_AsLong(o); - } - else { + if (!SetNumberFromPyObject($1[i], o)) { PyErr_SetString(PyExc_TypeError,"list must contain numbers"); free($1); return NULL; @@ -419,38 +303,11 @@ } } -%typemap(freearg) (int32_t* array, size_t array_len) { - free($1); -} - -%typemap(in) (double* array, size_t array_len) { - /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - $2 = size; - $1 = (double*) malloc(size * sizeof(double)); - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyFloat_Check(o)) { - $1[i] = PyFloat_AsDouble(o); - } - else { - PyErr_SetString(PyExc_TypeError,"list must contain floating-point numbers"); - free($1); - return NULL; - } - } - } else if ($input == Py_None) { - $1 = NULL; - $2 = 0; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return NULL; - } -} - -%typemap(freearg) (double* array, size_t array_len) { +%typemap(freearg) (uint64_t* array, size_t array_len), + (uint32_t* array, size_t array_len), + (int64_t* array, size_t array_len), + (int32_t* array, size_t array_len), + (double* array, size_t array_len) { free($1); }