1/* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */ 2 3%inline %{ 4 5#include "../bindings/python/python-typemaps.h" 6 7%} 8 9%typemap(in) char ** { 10 /* Check if is a list */ 11 if (PythonList::Check($input)) { 12 PythonList list(PyRefType::Borrowed, $input); 13 int size = list.GetSize(); 14 int i = 0; 15 $1 = (char**)malloc((size+1)*sizeof(char*)); 16 for (i = 0; i < size; i++) { 17 PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); 18 if (!py_str.IsAllocated()) { 19 PyErr_SetString(PyExc_TypeError,"list must contain strings"); 20 free($1); 21 return nullptr; 22 } 23 24 $1[i] = const_cast<char*>(py_str.GetString().data()); 25 } 26 $1[i] = 0; 27 } else if ($input == Py_None) { 28 $1 = NULL; 29 } else { 30 PyErr_SetString(PyExc_TypeError,"not a list"); 31 return NULL; 32 } 33} 34 35%typemap(typecheck) char ** { 36 /* Check if is a list */ 37 $1 = 1; 38 if (PythonList::Check($input)) { 39 PythonList list(PyRefType::Borrowed, $input); 40 int size = list.GetSize(); 41 int i = 0; 42 for (i = 0; i < size; i++) { 43 PythonString s = list.GetItemAtIndex(i).AsType<PythonString>(); 44 if (!s.IsAllocated()) { $1 = 0; } 45 } 46 } 47 else 48 { 49 $1 = ( ($input == Py_None) ? 1 : 0); 50 } 51} 52 53%typemap(freearg) char** { 54 free((char *) $1); 55} 56 57%typemap(out) char** { 58 int len; 59 int i; 60 len = 0; 61 while ($1[len]) len++; 62 PythonList list(len); 63 for (i = 0; i < len; i++) 64 list.SetItemAtIndex(i, PythonString($1[i])); 65 $result = list.release(); 66} 67 68%typemap(in) lldb::tid_t { 69 PythonObject obj = Retain<PythonObject>($input); 70 lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj)); 71 if (PyErr_Occurred()) 72 return nullptr; 73 $1 = value; 74} 75 76%typemap(in) lldb::StateType { 77 PythonObject obj = Retain<PythonObject>($input); 78 unsigned long long state_type_value = 79 unwrapOrSetPythonException(As<unsigned long long>(obj)); 80 if (PyErr_Occurred()) 81 return nullptr; 82 if (state_type_value > lldb::StateType::kLastStateType) { 83 PyErr_SetString(PyExc_ValueError, "Not a valid StateType value"); 84 return nullptr; 85 } 86 $1 = static_cast<lldb::StateType>(state_type_value); 87} 88 89/* Typemap definitions to allow SWIG to properly handle char buffer. */ 90 91// typemap for a char buffer 92%typemap(in) (char *dst, size_t dst_len) { 93 if (!PyInt_Check($input)) { 94 PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 95 return NULL; 96 } 97 $2 = PyInt_AsLong($input); 98 if ($2 <= 0) { 99 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 100 return NULL; 101 } 102 $1 = (char *) malloc($2); 103} 104// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 105// as char data instead of byte data. 106%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 107 108// Return the char buffer. Discarding any previous return result 109%typemap(argout) (char *dst, size_t dst_len) { 110 Py_XDECREF($result); /* Blow away any previous result */ 111 if (result == 0) { 112 PythonString string(""); 113 $result = string.release(); 114 Py_INCREF($result); 115 } else { 116 llvm::StringRef ref(static_cast<const char*>($1), result); 117 PythonString string(ref); 118 $result = string.release(); 119 } 120 free($1); 121} 122// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated 123// as char data instead of byte data. 124%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); 125 126 127// typemap for handling an snprintf-like API like SBThread::GetStopDescription. 128%typemap(in) (char *dst_or_null, size_t dst_len) { 129 if (!PyInt_Check($input)) { 130 PyErr_SetString(PyExc_ValueError, "Expecting an integer"); 131 return NULL; 132 } 133 $2 = PyInt_AsLong($input); 134 if ($2 <= 0) { 135 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 136 return NULL; 137 } 138 $1 = (char *) malloc($2); 139} 140%typemap(argout) (char *dst_or_null, size_t dst_len) { 141 Py_XDECREF($result); /* Blow away any previous result */ 142 llvm::StringRef ref($1); 143 PythonString string(ref); 144 $result = string.release(); 145 free($1); 146} 147 148 149// typemap for an outgoing buffer 150// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). 151// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). 152%typemap(in) (const char *cstr, uint32_t cstr_len), 153 (const char *src, size_t src_len) { 154 if (PythonString::Check($input)) { 155 PythonString str(PyRefType::Borrowed, $input); 156 $1 = (char*)str.GetString().data(); 157 $2 = str.GetSize(); 158 } 159 else if(PythonByteArray::Check($input)) { 160 PythonByteArray bytearray(PyRefType::Borrowed, $input); 161 $1 = (char*)bytearray.GetBytes().data(); 162 $2 = bytearray.GetSize(); 163 } 164 else if (PythonBytes::Check($input)) { 165 PythonBytes bytes(PyRefType::Borrowed, $input); 166 $1 = (char*)bytes.GetBytes().data(); 167 $2 = bytes.GetSize(); 168 } 169 else { 170 PyErr_SetString(PyExc_ValueError, "Expecting a string"); 171 return NULL; 172 } 173} 174// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. 175%typemap(in) (const void *buf, size_t size), 176 (const void *data, size_t data_len) { 177 if (PythonString::Check($input)) { 178 PythonString str(PyRefType::Borrowed, $input); 179 $1 = (void*)str.GetString().data(); 180 $2 = str.GetSize(); 181 } 182 else if(PythonByteArray::Check($input)) { 183 PythonByteArray bytearray(PyRefType::Borrowed, $input); 184 $1 = (void*)bytearray.GetBytes().data(); 185 $2 = bytearray.GetSize(); 186 } 187 else if (PythonBytes::Check($input)) { 188 PythonBytes bytes(PyRefType::Borrowed, $input); 189 $1 = (void*)bytes.GetBytes().data(); 190 $2 = bytes.GetSize(); 191 } 192 else { 193 PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); 194 return NULL; 195 } 196} 197 198// typemap for an incoming buffer 199// See also SBProcess::ReadMemory. 200%typemap(in) (void *buf, size_t size) { 201 if (PyInt_Check($input)) { 202 $2 = PyInt_AsLong($input); 203 } else if (PyLong_Check($input)) { 204 $2 = PyLong_AsLong($input); 205 } else { 206 PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object"); 207 return NULL; 208 } 209 if ($2 <= 0) { 210 PyErr_SetString(PyExc_ValueError, "Positive integer expected"); 211 return NULL; 212 } 213 $1 = (void *) malloc($2); 214} 215 216// Return the buffer. Discarding any previous return result 217// See also SBProcess::ReadMemory. 218%typemap(argout) (void *buf, size_t size) { 219 Py_XDECREF($result); /* Blow away any previous result */ 220 if (result == 0) { 221 $result = Py_None; 222 Py_INCREF($result); 223 } else { 224 PythonBytes bytes(static_cast<const uint8_t*>($1), result); 225 $result = bytes.release(); 226 } 227 free($1); 228} 229 230%{ 231namespace { 232template <class T> 233T PyLongAsT(PyObject *obj) { 234 static_assert(true, "unsupported type"); 235} 236 237template <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) { 238 return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj)); 239} 240 241template <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) { 242 return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj)); 243} 244 245template <> int64_t PyLongAsT<int64_t>(PyObject *obj) { 246 return static_cast<int64_t>(PyLong_AsLongLong(obj)); 247} 248 249template <> int32_t PyLongAsT<int32_t>(PyObject *obj) { 250 return static_cast<int32_t>(PyLong_AsLong(obj)); 251} 252 253template <class T> 254bool SetNumberFromPyObject(T &number, PyObject *obj) { 255 if (PyInt_Check(obj)) 256 number = static_cast<T>(PyInt_AsLong(obj)); 257 else if (PyLong_Check(obj)) 258 number = PyLongAsT<T>(obj); 259 else return false; 260 261 return true; 262} 263 264template <> 265bool SetNumberFromPyObject<double>(double &number, PyObject *obj) { 266 if (PyFloat_Check(obj)) { 267 number = PyFloat_AsDouble(obj); 268 return true; 269 } 270 271 return false; 272} 273 274} // namespace 275%} 276 277// these typemaps allow Python users to pass list objects 278// and have them turn into C++ arrays (this is useful, for instance 279// when creating SBData objects from lists of numbers) 280%typemap(in) (uint64_t* array, size_t array_len), 281 (uint32_t* array, size_t array_len), 282 (int64_t* array, size_t array_len), 283 (int32_t* array, size_t array_len), 284 (double* array, size_t array_len) { 285 /* Check if is a list */ 286 if (PyList_Check($input)) { 287 int size = PyList_Size($input); 288 int i = 0; 289 $2 = size; 290 $1 = ($1_type) malloc(size * sizeof($*1_type)); 291 for (i = 0; i < size; i++) { 292 PyObject *o = PyList_GetItem($input,i); 293 if (!SetNumberFromPyObject($1[i], o)) { 294 PyErr_SetString(PyExc_TypeError,"list must contain numbers"); 295 free($1); 296 return NULL; 297 } 298 299 if (PyErr_Occurred()) { 300 free($1); 301 return NULL; 302 } 303 } 304 } else if ($input == Py_None) { 305 $1 = NULL; 306 $2 = 0; 307 } else { 308 PyErr_SetString(PyExc_TypeError,"not a list"); 309 return NULL; 310 } 311} 312 313%typemap(freearg) (uint64_t* array, size_t array_len), 314 (uint32_t* array, size_t array_len), 315 (int64_t* array, size_t array_len), 316 (int32_t* array, size_t array_len), 317 (double* array, size_t array_len) { 318 free($1); 319} 320 321// these typemaps wrap SBModule::GetVersion() from requiring a memory buffer 322// to the more Pythonic style where a list is returned and no previous allocation 323// is necessary - this will break if more than 50 versions are ever returned 324%typemap(typecheck) (uint32_t *versions, uint32_t num_versions) { 325 $1 = ($input == Py_None ? 1 : 0); 326} 327 328%typemap(in, numinputs=0) (uint32_t *versions) { 329 $1 = (uint32_t*)malloc(sizeof(uint32_t) * 50); 330} 331 332%typemap(in, numinputs=0) (uint32_t num_versions) { 333 $1 = 50; 334} 335 336%typemap(argout) (uint32_t *versions, uint32_t num_versions) { 337 uint32_t count = result; 338 if (count >= $2) 339 count = $2; 340 PyObject* list = PyList_New(count); 341 for (uint32_t j = 0; j < count; j++) 342 { 343 PyObject* item = PyInt_FromLong($1[j]); 344 int ok = PyList_SetItem(list,j,item); 345 if (ok != 0) 346 { 347 $result = Py_None; 348 break; 349 } 350 } 351 $result = list; 352} 353 354%typemap(freearg) (uint32_t *versions) { 355 free($1); 356} 357 358 359// For Log::LogOutputCallback 360%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { 361 if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) { 362 PyErr_SetString(PyExc_TypeError, "Need a callable object or None!"); 363 return NULL; 364 } 365 366 // FIXME (filcab): We can't currently check if our callback is already 367 // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous 368 // baton) nor can we just remove all traces of a callback, if we want to 369 // revert to a file logging mechanism. 370 371 // Don't lose the callback reference 372 Py_INCREF($input); 373 $1 = LLDBSwigPythonCallPythonLogOutputCallback; 374 $2 = $input; 375} 376 377%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) { 378 $1 = $input == Py_None; 379 $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject*>($input)); 380} 381 382 383%typemap(in) lldb::FileSP { 384 PythonFile py_file(PyRefType::Borrowed, $input); 385 if (!py_file) { 386 PyErr_SetString(PyExc_TypeError, "not a file"); 387 return nullptr; 388 } 389 auto sp = unwrapOrSetPythonException(py_file.ConvertToFile()); 390 if (!sp) 391 return nullptr; 392 $1 = sp; 393} 394 395%typemap(in) lldb::FileSP FORCE_IO_METHODS { 396 PythonFile py_file(PyRefType::Borrowed, $input); 397 if (!py_file) { 398 PyErr_SetString(PyExc_TypeError, "not a file"); 399 return nullptr; 400 } 401 auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods()); 402 if (!sp) 403 return nullptr; 404 $1 = sp; 405} 406 407%typemap(in) lldb::FileSP BORROWED { 408 PythonFile py_file(PyRefType::Borrowed, $input); 409 if (!py_file) { 410 PyErr_SetString(PyExc_TypeError, "not a file"); 411 return nullptr; 412 } 413 auto sp = unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true)); 414 if (!sp) 415 return nullptr; 416 $1 = sp; 417} 418 419%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS { 420 PythonFile py_file(PyRefType::Borrowed, $input); 421 if (!py_file) { 422 PyErr_SetString(PyExc_TypeError, "not a file"); 423 return nullptr; 424 } 425 auto sp = unwrapOrSetPythonException(py_file.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true)); 426 if (!sp) 427 return nullptr; 428 $1 = sp; 429} 430 431%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { 432 if (PythonFile::Check($input)) { 433 $1 = 1; 434 } else { 435 PyErr_Clear(); 436 $1 = 0; 437 } 438} 439 440%typemap(out) lldb::FileSP { 441 $result = nullptr; 442 lldb::FileSP &sp = $1; 443 if (sp) { 444 PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp)); 445 if (!pyfile.IsValid()) 446 return nullptr; 447 $result = pyfile.release(); 448 } 449 if (!$result) 450 { 451 $result = Py_None; 452 Py_INCREF(Py_None); 453 } 454} 455 456%typemap(in) (const char* string, int len) { 457 if ($input == Py_None) 458 { 459 $1 = NULL; 460 $2 = 0; 461 } 462 else if (PythonString::Check($input)) 463 { 464 PythonString py_str(PyRefType::Borrowed, $input); 465 llvm::StringRef str = py_str.GetString(); 466 $1 = const_cast<char*>(str.data()); 467 $2 = str.size(); 468 // In Python 2, if $input is a PyUnicode object then this 469 // will trigger a Unicode -> String conversion, in which 470 // case the `PythonString` will now own the PyString. Thus 471 // if it goes out of scope, the data will be deleted. The 472 // only way to avoid this is to leak the Python object in 473 // that case. Note that if there was no conversion, then 474 // releasing the string will not leak anything, since we 475 // created this as a borrowed reference. 476 py_str.release(); 477 } 478 else 479 { 480 PyErr_SetString(PyExc_TypeError,"not a string-like object"); 481 return NULL; 482 } 483} 484 485// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i, 486// and fixed so they will not crash if PyObject_GetBuffer fails. 487// https://github.com/swig/swig/issues/1640 488// 489// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper, 490// doing it right away is not legal according to the python buffer protocol. 491 492%define %pybuffer_mutable_binary(TYPEMAP, SIZE) 493%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 494 int res; Py_ssize_t size = 0; void *buf = 0; 495 res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE); 496 if (res < 0) { 497 PyErr_Clear(); 498 %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 499 } 500 size = view.buffer.len; 501 buf = view.buffer.buf; 502 $1 = ($1_ltype) buf; 503 $2 = ($2_ltype) (size/sizeof($*1_type)); 504} 505%enddef 506 507%define %pybuffer_binary(TYPEMAP, SIZE) 508%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) { 509 int res; Py_ssize_t size = 0; const void *buf = 0; 510 res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO); 511 if (res < 0) { 512 PyErr_Clear(); 513 %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum); 514 } 515 size = view.buffer.len; 516 buf = view.buffer.buf; 517 $1 = ($1_ltype) buf; 518 $2 = ($2_ltype) (size / sizeof($*1_type)); 519} 520%enddef 521 522%pybuffer_binary(const uint8_t *buf, size_t num_bytes); 523%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes); 524