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