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