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