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