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