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%typemap(in) lldb::tid_t {
63  PythonObject obj = Retain<PythonObject>($input);
64  lldb::tid_t value = unwrapOrSetPythonException(As<unsigned long long>(obj)); 
65  if (PyErr_Occurred())
66    return nullptr;
67  $1 = value;
68}
69
70%typemap(in) lldb::StateType {
71  PythonObject obj = Retain<PythonObject>($input);
72  unsigned long long state_type_value =
73    unwrapOrSetPythonException(As<unsigned long long>(obj));
74  if (PyErr_Occurred())
75    return nullptr;
76  if (state_type_value > lldb::StateType::kLastStateType) {
77    PyErr_SetString(PyExc_ValueError, "Not a valid StateType value");
78    return nullptr;
79  }
80  $1 = static_cast<lldb::StateType>(state_type_value);
81}
82
83/* Typemap definitions to allow SWIG to properly handle char buffer. */
84
85// typemap for a char buffer
86%typemap(in) (char *dst, size_t dst_len) {
87   if (!PyInt_Check($input)) {
88       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
89       return NULL;
90   }
91   $2 = PyInt_AsLong($input);
92   if ($2 <= 0) {
93       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
94       return NULL;
95   }
96   $1 = (char *) malloc($2);
97}
98// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
99// as char data instead of byte data.
100%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
101
102// Return the char buffer.  Discarding any previous return result
103%typemap(argout) (char *dst, size_t dst_len) {
104   Py_XDECREF($result);   /* Blow away any previous result */
105   if (result == 0) {
106      PythonString string("");
107      $result = string.release();
108      Py_INCREF($result);
109   } else {
110      llvm::StringRef ref(static_cast<const char*>($1), result);
111      PythonString string(ref);
112      $result = string.release();
113   }
114   free($1);
115}
116// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated
117// as char data instead of byte data.
118%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len);
119
120
121// typemap for handling an snprintf-like API like SBThread::GetStopDescription.
122%typemap(in) (char *dst_or_null, size_t dst_len) {
123   if (!PyInt_Check($input)) {
124       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
125       return NULL;
126   }
127   $2 = PyInt_AsLong($input);
128   if ($2 <= 0) {
129       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
130       return NULL;
131   }
132   $1 = (char *) malloc($2);
133}
134%typemap(argout) (char *dst_or_null, size_t dst_len) {
135   Py_XDECREF($result);   /* Blow away any previous result */
136   llvm::StringRef ref($1);
137   PythonString string(ref);
138   $result = string.release();
139   free($1);
140}
141
142
143// typemap for an outgoing buffer
144// See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len).
145// Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
146%typemap(in) (const char *cstr, uint32_t cstr_len),
147             (const char *src, size_t src_len) {
148   if (PythonString::Check($input)) {
149      PythonString str(PyRefType::Borrowed, $input);
150      $1 = (char*)str.GetString().data();
151      $2 = str.GetSize();
152   }
153   else if(PythonByteArray::Check($input)) {
154      PythonByteArray bytearray(PyRefType::Borrowed, $input);
155      $1 = (char*)bytearray.GetBytes().data();
156      $2 = bytearray.GetSize();
157   }
158   else if (PythonBytes::Check($input)) {
159      PythonBytes bytes(PyRefType::Borrowed, $input);
160      $1 = (char*)bytes.GetBytes().data();
161      $2 = bytes.GetSize();
162   }
163   else {
164      PyErr_SetString(PyExc_ValueError, "Expecting a string");
165      return NULL;
166   }
167}
168// For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
169%typemap(in) (const void *buf, size_t size),
170             (const void *data, size_t data_len) {
171   if (PythonString::Check($input)) {
172      PythonString str(PyRefType::Borrowed, $input);
173      $1 = (void*)str.GetString().data();
174      $2 = str.GetSize();
175   }
176   else if(PythonByteArray::Check($input)) {
177      PythonByteArray bytearray(PyRefType::Borrowed, $input);
178      $1 = (void*)bytearray.GetBytes().data();
179      $2 = bytearray.GetSize();
180   }
181   else if (PythonBytes::Check($input)) {
182      PythonBytes bytes(PyRefType::Borrowed, $input);
183      $1 = (void*)bytes.GetBytes().data();
184      $2 = bytes.GetSize();
185   }
186   else {
187      PyErr_SetString(PyExc_ValueError, "Expecting a buffer");
188      return NULL;
189   }
190}
191
192// typemap for an incoming buffer
193// See also SBProcess::ReadMemory.
194%typemap(in) (void *buf, size_t size) {
195   if (PyInt_Check($input)) {
196      $2 = PyInt_AsLong($input);
197   } else if (PyLong_Check($input)) {
198      $2 = PyLong_AsLong($input);
199   } else {
200      PyErr_SetString(PyExc_ValueError, "Expecting an integer or long object");
201      return NULL;
202   }
203   if ($2 <= 0) {
204       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
205       return NULL;
206   }
207   $1 = (void *) malloc($2);
208}
209
210// Return the buffer.  Discarding any previous return result
211// See also SBProcess::ReadMemory.
212%typemap(argout) (void *buf, size_t size) {
213   Py_XDECREF($result);   /* Blow away any previous result */
214   if (result == 0) {
215      $result = Py_None;
216      Py_INCREF($result);
217   } else {
218      PythonBytes bytes(static_cast<const uint8_t*>($1), result);
219      $result = bytes.release();
220   }
221   free($1);
222}
223
224%{
225namespace {
226template <class T>
227T PyLongAsT(PyObject *obj) {
228  static_assert(true, "unsupported type");
229}
230
231template <> uint64_t PyLongAsT<uint64_t>(PyObject *obj) {
232  return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(obj));
233}
234
235template <> uint32_t PyLongAsT<uint32_t>(PyObject *obj) {
236  return static_cast<uint32_t>(PyLong_AsUnsignedLong(obj));
237}
238
239template <> int64_t PyLongAsT<int64_t>(PyObject *obj) {
240  return static_cast<int64_t>(PyLong_AsLongLong(obj));
241}
242
243template <> int32_t PyLongAsT<int32_t>(PyObject *obj) {
244  return static_cast<int32_t>(PyLong_AsLong(obj));
245}
246
247template <class T>
248bool 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 return false;
254
255  return true;
256}
257
258template <>
259bool 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        return NULL;
291      }
292
293      if (PyErr_Occurred()) {
294        free($1);
295        return NULL;
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    return NULL;
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    {
337        PyObject* item = PyInt_FromLong($1[j]);
338        int ok = PyList_SetItem(list,j,item);
339        if (ok != 0)
340        {
341            $result = Py_None;
342            break;
343        }
344    }
345    $result = list;
346}
347
348%typemap(freearg) (uint32_t *versions) {
349    free($1);
350}
351
352
353// For Log::LogOutputCallback
354%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
355  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
356    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
357    return NULL;
358  }
359
360  // FIXME (filcab): We can't currently check if our callback is already
361  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
362  // baton) nor can we just remove all traces of a callback, if we want to
363  // revert to a file logging mechanism.
364
365  // Don't lose the callback reference
366  Py_INCREF($input);
367  $1 = LLDBSwigPythonCallPythonLogOutputCallback;
368  $2 = $input;
369}
370
371%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
372  $1 = $input == Py_None;
373  $1 = $1 || PyCallable_Check(reinterpret_cast<PyObject*>($input));
374}
375
376
377%typemap(in) lldb::FileSP {
378  PythonFile py_file(PyRefType::Borrowed, $input);
379  if (!py_file) {
380    PyErr_SetString(PyExc_TypeError, "not a file");
381    return nullptr;
382  }
383  auto sp = unwrapOrSetPythonException(py_file.ConvertToFile());
384  if (!sp)
385    return nullptr;
386  $1 = sp;
387}
388
389%typemap(in) lldb::FileSP FORCE_IO_METHODS {
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.ConvertToFileForcingUseOfScriptingIOMethods());
396  if (!sp)
397    return nullptr;
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    return nullptr;
406  }
407  auto sp = unwrapOrSetPythonException(py_file.ConvertToFile(/*borrowed=*/true));
408  if (!sp)
409    return nullptr;
410  $1 = sp;
411}
412
413%typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS {
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.ConvertToFileForcingUseOfScriptingIOMethods(/*borrowed=*/true));
420  if (!sp)
421    return nullptr;
422  $1 = sp;
423}
424
425%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
426  if (PythonFile::Check($input)) {
427    $1 = 1;
428  } else {
429    PyErr_Clear();
430    $1 = 0;
431  }
432}
433
434%typemap(out) lldb::FileSP {
435  $result = nullptr;
436  lldb::FileSP &sp = $1;
437  if (sp) {
438    PythonFile pyfile = unwrapOrSetPythonException(PythonFile::FromFile(*sp));
439    if (!pyfile.IsValid())
440      return nullptr;
441    $result = pyfile.release();
442  }
443  if (!$result)
444  {
445      $result = Py_None;
446      Py_INCREF(Py_None);
447  }
448}
449
450%typemap(in) (const char* string, int len) {
451    if ($input == Py_None)
452    {
453        $1 = NULL;
454        $2 = 0;
455    }
456    else if (PythonString::Check($input))
457    {
458        PythonString py_str(PyRefType::Borrowed, $input);
459        llvm::StringRef str = py_str.GetString();
460        $1 = const_cast<char*>(str.data());
461        $2 = str.size();
462        // In Python 2, if $input is a PyUnicode object then this
463        // will trigger a Unicode -> String conversion, in which
464        // case the `PythonString` will now own the PyString.  Thus
465        // if it goes out of scope, the data will be deleted.  The
466        // only way to avoid this is to leak the Python object in
467        // that case.  Note that if there was no conversion, then
468        // releasing the string will not leak anything, since we
469        // created this as a borrowed reference.
470        py_str.release();
471    }
472    else
473    {
474        PyErr_SetString(PyExc_TypeError,"not a string-like object");
475        return NULL;
476    }
477}
478
479%inline %{
480
481struct Py_buffer_RAII {
482  Py_buffer buffer = {};
483  Py_buffer_RAII() {};
484  Py_buffer &operator=(const Py_buffer_RAII &) = delete;
485  Py_buffer_RAII(const Py_buffer_RAII &) = delete;
486  ~Py_buffer_RAII() {
487    if (buffer.obj)
488      PyBuffer_Release(&buffer);
489  }
490};
491
492%}
493
494// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
495// and fixed so they will not crash if PyObject_GetBuffer fails.
496// https://github.com/swig/swig/issues/1640
497//
498// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper,
499// doing it right away is not legal according to the python buffer protocol.
500
501%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
502%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
503  int res; Py_ssize_t size = 0; void *buf = 0;
504  res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE);
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%define %pybuffer_binary(TYPEMAP, SIZE)
517%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
518  int res; Py_ssize_t size = 0; const void *buf = 0;
519  res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO);
520  if (res < 0) {
521    PyErr_Clear();
522    %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
523  }
524  size = view.buffer.len;
525  buf = view.buffer.buf;
526  $1 = ($1_ltype) buf;
527  $2 = ($2_ltype) (size / sizeof($*1_type));
528}
529%enddef
530
531%pybuffer_binary(const uint8_t *buf, size_t num_bytes);
532%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);
533