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