1 //===-- PythonDataObjects.cpp ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // In order to guarantee correct working with Python, Python.h *MUST* be
11 // the *FIRST* header file included here.
12 #ifdef LLDB_DISABLE_PYTHON
13 
14 // Python is disabled in this build
15 
16 #else
17 
18 #if defined (__APPLE__)
19 #include <Python/Python.h>
20 #else
21 #include <Python.h>
22 #endif
23 
24 #include <stdio.h>
25 
26 #include "lldb/Core/Stream.h"
27 #include "lldb/Host/File.h"
28 #include "lldb/Interpreter/PythonDataObjects.h"
29 #include "lldb/Interpreter/ScriptInterpreter.h"
30 
31 using namespace lldb_private;
32 using namespace lldb;
33 
34 //----------------------------------------------------------------------
35 // PythonObject
36 //----------------------------------------------------------------------
PythonObject(const lldb::ScriptInterpreterObjectSP & script_object_sp)37 PythonObject::PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
38     m_py_obj (NULL)
39 {
40     if (script_object_sp)
41         Reset ((PyObject *)script_object_sp->GetObject());
42 }
43 
44 void
Dump(Stream & strm) const45 PythonObject::Dump (Stream &strm) const
46 {
47     if (m_py_obj)
48     {
49         FILE *file = ::tmpfile();
50         if (file)
51         {
52             ::PyObject_Print (m_py_obj, file, 0);
53             const long length = ftell (file);
54             if (length)
55             {
56                 ::rewind(file);
57                 std::vector<char> file_contents (length,'\0');
58                 const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
59                 if (length_read > 0)
60                     strm.Write (file_contents.data(), length_read);
61             }
62             ::fclose (file);
63         }
64     }
65     else
66         strm.PutCString ("NULL");
67 }
68 
69 PythonString
Repr()70 PythonObject::Repr ()
71 {
72     if (!m_py_obj)
73         return PythonString ();
74     PyObject *repr = PyObject_Repr(m_py_obj);
75     if (!repr)
76         return PythonString ();
77     return PythonString(repr);
78 }
79 
80 PythonString
Str()81 PythonObject::Str ()
82 {
83     if (!m_py_obj)
84         return PythonString ();
85     PyObject *str = PyObject_Str(m_py_obj);
86     if (!str)
87         return PythonString ();
88     return PythonString(str);
89 }
90 
91 //----------------------------------------------------------------------
92 // PythonString
93 //----------------------------------------------------------------------
94 
PythonString(PyObject * py_obj)95 PythonString::PythonString (PyObject *py_obj) :
96     PythonObject(py_obj)
97 {
98 }
99 
PythonString(const PythonObject & object)100 PythonString::PythonString (const PythonObject &object) :
101     PythonObject(object.GetPythonObject())
102 {
103 }
104 
PythonString(const lldb::ScriptInterpreterObjectSP & script_object_sp)105 PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
106     PythonObject (script_object_sp)
107 {
108 }
109 
PythonString(const char * string)110 PythonString::PythonString (const char* string) :
111     PythonObject(PyString_FromString(string))
112 {
113 }
114 
PythonString()115 PythonString::PythonString () :
116     PythonObject()
117 {
118 }
119 
~PythonString()120 PythonString::~PythonString ()
121 {
122 }
123 
124 bool
Reset(PyObject * py_obj)125 PythonString::Reset (PyObject *py_obj)
126 {
127     if (py_obj && PyString_Check(py_obj))
128         return PythonObject::Reset(py_obj);
129 
130     PythonObject::Reset(NULL);
131     return py_obj == NULL;
132 }
133 
134 const char*
GetString() const135 PythonString::GetString() const
136 {
137     if (m_py_obj)
138         return PyString_AsString(m_py_obj);
139     return NULL;
140 }
141 
142 size_t
GetSize() const143 PythonString::GetSize() const
144 {
145     if (m_py_obj)
146         return PyString_Size(m_py_obj);
147     return 0;
148 }
149 
150 void
SetString(const char * string)151 PythonString::SetString (const char* string)
152 {
153     PythonObject::Reset(PyString_FromString(string));
154 }
155 
156 //----------------------------------------------------------------------
157 // PythonInteger
158 //----------------------------------------------------------------------
159 
PythonInteger(PyObject * py_obj)160 PythonInteger::PythonInteger (PyObject *py_obj) :
161     PythonObject(py_obj)
162 {
163 }
164 
PythonInteger(const PythonObject & object)165 PythonInteger::PythonInteger (const PythonObject &object) :
166     PythonObject(object.GetPythonObject())
167 {
168 }
169 
PythonInteger(const lldb::ScriptInterpreterObjectSP & script_object_sp)170 PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
171     PythonObject (script_object_sp)
172 {
173 }
174 
PythonInteger(int64_t value)175 PythonInteger::PythonInteger (int64_t value) :
176     PythonObject(PyInt_FromLong(value))
177 {
178 }
179 
180 
~PythonInteger()181 PythonInteger::~PythonInteger ()
182 {
183 }
184 
185 bool
Reset(PyObject * py_obj)186 PythonInteger::Reset (PyObject *py_obj)
187 {
188     if (py_obj && PyInt_Check(py_obj))
189         return PythonObject::Reset(py_obj);
190 
191     PythonObject::Reset(NULL);
192     return py_obj == NULL;
193 }
194 
195 int64_t
GetInteger()196 PythonInteger::GetInteger()
197 {
198     if (m_py_obj)
199         return PyInt_AsLong(m_py_obj);
200     else
201         return UINT64_MAX;
202 }
203 
204 void
SetInteger(int64_t value)205 PythonInteger::SetInteger (int64_t value)
206 {
207     PythonObject::Reset(PyInt_FromLong(value));
208 }
209 
210 //----------------------------------------------------------------------
211 // PythonList
212 //----------------------------------------------------------------------
213 
PythonList()214 PythonList::PythonList () :
215     PythonObject(PyList_New(0))
216 {
217 }
218 
PythonList(uint32_t count)219 PythonList::PythonList (uint32_t count) :
220     PythonObject(PyList_New(count))
221 {
222 }
223 
PythonList(PyObject * py_obj)224 PythonList::PythonList (PyObject *py_obj) :
225     PythonObject(py_obj)
226 {
227 }
228 
229 
PythonList(const PythonObject & object)230 PythonList::PythonList (const PythonObject &object) :
231     PythonObject(object.GetPythonObject())
232 {
233 }
234 
PythonList(const lldb::ScriptInterpreterObjectSP & script_object_sp)235 PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
236     PythonObject (script_object_sp)
237 {
238 }
239 
~PythonList()240 PythonList::~PythonList ()
241 {
242 }
243 
244 bool
Reset(PyObject * py_obj)245 PythonList::Reset (PyObject *py_obj)
246 {
247     if (py_obj && PyList_Check(py_obj))
248         return PythonObject::Reset(py_obj);
249 
250     PythonObject::Reset(NULL);
251     return py_obj == NULL;
252 }
253 
254 uint32_t
GetSize()255 PythonList::GetSize()
256 {
257     if (m_py_obj)
258         return PyList_GET_SIZE(m_py_obj);
259     return 0;
260 }
261 
262 PythonObject
GetItemAtIndex(uint32_t index)263 PythonList::GetItemAtIndex (uint32_t index)
264 {
265     if (m_py_obj)
266         return PythonObject(PyList_GetItem(m_py_obj, index));
267     return NULL;
268 }
269 
270 void
SetItemAtIndex(uint32_t index,const PythonObject & object)271 PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
272 {
273     if (m_py_obj && object)
274         PyList_SetItem(m_py_obj, index, object.GetPythonObject());
275 }
276 
277 void
AppendItem(const PythonObject & object)278 PythonList::AppendItem (const PythonObject &object)
279 {
280     if (m_py_obj && object)
281         PyList_Append(m_py_obj, object.GetPythonObject());
282 }
283 
284 //----------------------------------------------------------------------
285 // PythonDictionary
286 //----------------------------------------------------------------------
287 
PythonDictionary()288 PythonDictionary::PythonDictionary () :
289     PythonObject(PyDict_New())
290 {
291 }
292 
PythonDictionary(PyObject * py_obj)293 PythonDictionary::PythonDictionary (PyObject *py_obj) :
294     PythonObject(py_obj)
295 {
296 }
297 
298 
PythonDictionary(const PythonObject & object)299 PythonDictionary::PythonDictionary (const PythonObject &object) :
300     PythonObject(object.GetPythonObject())
301 {
302 }
303 
PythonDictionary(const lldb::ScriptInterpreterObjectSP & script_object_sp)304 PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
305     PythonObject (script_object_sp)
306 {
307 }
308 
~PythonDictionary()309 PythonDictionary::~PythonDictionary ()
310 {
311 }
312 
313 bool
Reset(PyObject * py_obj)314 PythonDictionary::Reset (PyObject *py_obj)
315 {
316     if (py_obj && PyDict_Check(py_obj))
317         return PythonObject::Reset(py_obj);
318 
319     PythonObject::Reset(NULL);
320     return py_obj == NULL;
321 }
322 
323 uint32_t
GetSize()324 PythonDictionary::GetSize()
325 {
326     if (m_py_obj)
327         return PyDict_Size(m_py_obj);
328     return 0;
329 }
330 
331 PythonObject
GetItemForKey(const char * key) const332 PythonDictionary::GetItemForKey (const char *key) const
333 {
334     if (key && key[0])
335     {
336         PythonString python_key(key);
337         return GetItemForKey(python_key);
338     }
339     return NULL;
340 }
341 
342 
343 PythonObject
GetItemForKey(const PythonString & key) const344 PythonDictionary::GetItemForKey (const PythonString &key) const
345 {
346     if (m_py_obj && key)
347         return PythonObject(PyDict_GetItem(m_py_obj, key.GetPythonObject()));
348     return PythonObject();
349 }
350 
351 
352 const char *
GetItemForKeyAsString(const PythonString & key,const char * fail_value) const353 PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const
354 {
355     if (m_py_obj && key)
356     {
357         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
358         if (py_obj && PyString_Check(py_obj))
359             return PyString_AsString(py_obj);
360     }
361     return fail_value;
362 }
363 
364 int64_t
GetItemForKeyAsInteger(const PythonString & key,int64_t fail_value) const365 PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const
366 {
367     if (m_py_obj && key)
368     {
369         PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
370         if (py_obj)
371         {
372             if (PyInt_Check(py_obj))
373                 return PyInt_AsLong(py_obj);
374 
375             if (PyLong_Check(py_obj))
376                 return PyLong_AsLong(py_obj);
377         }
378     }
379     return fail_value;
380 }
381 
382 PythonList
GetKeys() const383 PythonDictionary::GetKeys () const
384 {
385     if (m_py_obj)
386         return PythonList(PyDict_Keys(m_py_obj));
387     return PythonList();
388 }
389 
390 PythonString
GetKeyAtPosition(uint32_t pos) const391 PythonDictionary::GetKeyAtPosition (uint32_t pos) const
392 {
393     PyObject *key, *value;
394     Py_ssize_t pos_iter = 0;
395 
396     if (m_py_obj)
397     {
398         while (PyDict_Next(m_py_obj, &pos_iter, &key, &value))
399         {
400             if (pos-- == 0)
401                 return PythonString(key);
402         }
403     }
404     return PythonString();
405 }
406 
407 PythonObject
GetValueAtPosition(uint32_t pos) const408 PythonDictionary::GetValueAtPosition (uint32_t pos) const
409 {
410     PyObject *key, *value;
411     Py_ssize_t pos_iter = 0;
412 
413     if (!m_py_obj)
414         return NULL;
415 
416     while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
417         if (pos-- == 0)
418             return PythonObject(value);
419     }
420     return PythonObject();
421 }
422 
423 void
SetItemForKey(const PythonString & key,const PythonObject & value)424 PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
425 {
426     if (m_py_obj && key && value)
427         PyDict_SetItem(m_py_obj, key.GetPythonObject(), value.GetPythonObject());
428 }
429 
430 #endif
431