blob: 3d0dafa2545c2d98229163c91b08134d0a9df579 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ScriptInterpreterPython.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:
12
13#include <Python.h>
14
15#include "lldb/Interpreter/ScriptInterpreterPython.h"
16
17
18#include <sys/ioctl.h>
19#include <termios.h>
20#include <stdlib.h>
21#include <stdio.h>
22
23#include <string>
24
25#include "lldb/Breakpoint/Breakpoint.h"
26#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Clayton63094e02010-06-23 01:19:29 +000027#include "lldb/Breakpoint/StoppointCallbackContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Core/Debugger.h"
29#include "lldb/Core/FileSpec.h"
30#include "lldb/Core/InputReader.h"
31#include "lldb/Core/Stream.h"
32#include "lldb/Core/StreamString.h"
33#include "lldb/Core/Timer.h"
34#include "lldb/Host/Host.h"
35#include "lldb/Interpreter/CommandInterpreter.h"
36#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton63094e02010-06-23 01:19:29 +000037#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
39
Greg Clayton121f3312010-07-07 18:40:03 +000040// This function is in the C++ output file generated by SWIG after it is
41// run on all of the headers in "lldb/API/SB*.h"
Chris Lattner24943d22010-06-08 16:52:24 +000042extern "C" void init_lldb (void);
43
44using namespace lldb;
45using namespace lldb_private;
46
47const char embedded_interpreter_string[] =
48"import readline\n\
49import code\n\
50import sys\n\
51import traceback\n\
52\n\
53class SimpleREPL(code.InteractiveConsole):\n\
54 def __init__(self, prompt, dict):\n\
55 code.InteractiveConsole.__init__(self,dict)\n\
56 self.prompt = prompt\n\
57 self.loop_exit = False\n\
58 self.dict = dict\n\
59\n\
60 def interact(self):\n\
61 try:\n\
62 sys.ps1\n\
63 except AttributeError:\n\
64 sys.ps1 = \">>> \"\n\
65 try:\n\
66 sys.ps2\n\
67 except AttributeError:\n\
68 sys.ps2 = \"... \"\n\
69\n\
70 while not self.loop_exit:\n\
71 try:\n\
72 self.read_py_command()\n\
73 except (SystemExit, EOFError):\n\
74 # EOF while in Python just breaks out to top level.\n\
75 self.write('\\n')\n\
76 self.loop_exit = True\n\
77 break\n\
78 except KeyboardInterrupt:\n\
79 self.write(\"\\nKeyboardInterrupt\\n\")\n\
80 self.resetbuffer()\n\
81 more = 0\n\
82 except:\n\
83 traceback.print_exc()\n\
84\n\
85 def process_input (self, in_str):\n\
86 # Canonicalize the format of the input string\n\
87 temp_str = in_str\n\
88 temp_str.strip(' \t')\n\
89 words = temp_str.split()\n\
90 temp_str = ('').join(words)\n\
91\n\
92 # Check the input string to see if it was the quit\n\
93 # command. If so, intercept it, so that it doesn't\n\
94 # close stdin on us!\n\
Jason Molendaa8a5e562010-06-09 21:56:00 +000095 if (temp_str.lower() == \"quit()\" or temp_str.lower() == \"exit()\"):\n\
Chris Lattner24943d22010-06-08 16:52:24 +000096 self.loop_exit = True\n\
97 in_str = \"raise SystemExit \"\n\
98 return in_str\n\
99\n\
100 def my_raw_input (self, prompt):\n\
101 stream = sys.stdout\n\
102 stream.write (prompt)\n\
103 stream.flush ()\n\
104 try:\n\
105 line = sys.stdin.readline()\n\
106 except KeyboardInterrupt:\n\
107 line = \" \\n\"\n\
108 except (SystemExit, EOFError):\n\
109 line = \"quit()\\n\"\n\
110 if not line:\n\
111 raise EOFError\n\
112 if line[-1] == '\\n':\n\
113 line = line[:-1]\n\
114 return line\n\
115\n\
116 def read_py_command(self):\n\
117 # Read off a complete Python command.\n\
118 more = 0\n\
119 while 1:\n\
120 if more:\n\
121 prompt = sys.ps2\n\
122 else:\n\
123 prompt = sys.ps1\n\
124 line = self.my_raw_input(prompt)\n\
125 # Can be None if sys.stdin was redefined\n\
126 encoding = getattr(sys.stdin, \"encoding\", None)\n\
127 if encoding and not isinstance(line, unicode):\n\
128 line = line.decode(encoding)\n\
129 line = self.process_input (line)\n\
130 more = self.push(line)\n\
131 if not more:\n\
132 break\n\
133\n\
134def run_python_interpreter (dict):\n\
135 # Pass in the dictionary, for continuity from one session to the next.\n\
136 repl = SimpleREPL('>>> ', dict)\n\
137 repl.interact()\n";
138
139static int
140_check_and_flush (FILE *stream)
141{
142 int prev_fail = ferror (stream);
143 return fflush (stream) || prev_fail ? EOF : 0;
144}
145
Greg Clayton63094e02010-06-23 01:19:29 +0000146ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000147 ScriptInterpreter (eScriptLanguagePython),
148 m_compiled_module (NULL),
149 m_termios_valid (false)
150{
151
152 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
153 // Find the module that owns this code and use that path we get to
154 // set the PYTHONPATH appropriately.
155
156 FileSpec this_module (Host::GetModuleFileSpecForHostAddress ((void *)init_lldb));
157 std::string python_path;
158
159 if (this_module.GetDirectory())
160 {
161 // Append the directory that the module that loaded this code
162 // belongs to
163 python_path += this_module.GetDirectory().AsCString("");
164
165#if defined (__APPLE__)
166 // If we are running on MacOSX we might be in a framework and should
167 // add an appropriate path so Resource can be found in a bundle
168
169 if (::strstr(this_module.GetDirectory().AsCString(""), ".framework"))
170 {
171 python_path.append(1, ':');
172 python_path.append(this_module.GetDirectory().AsCString(""));
173 python_path.append("/Resources/Python");
174 }
175#endif
176 // The the PYTHONPATH environment variable so that Python can find
177 // our lldb.py module and our _lldb.so.
178 ::setenv ("PYTHONPATH", python_path.c_str(), 1);
179 }
180
181 Py_Initialize ();
182
183 PyObject *compiled_module = Py_CompileString (embedded_interpreter_string, "embedded_interpreter.py",
184 Py_file_input);
185
Eli Friedman3c90d992010-06-09 18:31:38 +0000186 m_compiled_module = static_cast<void*>(compiled_module);
Chris Lattner24943d22010-06-08 16:52:24 +0000187
Greg Clayton121f3312010-07-07 18:40:03 +0000188 // This function is in the C++ output file generated by SWIG after it is
189 // run on all of the headers in "lldb/API/SB*.h"
Chris Lattner24943d22010-06-08 16:52:24 +0000190 init_lldb ();
191
192 // Update the path python uses to search for modules to include the current directory.
193
194 int success = PyRun_SimpleString ("import sys");
195 success = PyRun_SimpleString ("sys.path.append ('.')");
196 if (success == 0)
197 {
198 // Import the Script Bridge module.
199 success = PyRun_SimpleString ("from lldb import *");
200 }
201
202 const char *pty_slave_name = GetScriptInterpreterPtyName ();
Greg Clayton63094e02010-06-23 01:19:29 +0000203 FILE *out_fh = interpreter.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000204
Eli Friedman3c90d992010-06-09 18:31:38 +0000205 PyObject *pmod = PyImport_ExecCodeModule(
206 const_cast<char*>("embedded_interpreter"),
207 static_cast<PyObject*>(m_compiled_module));
Chris Lattner24943d22010-06-08 16:52:24 +0000208 if (pmod != NULL)
209 {
210 PyRun_SimpleString ("ConsoleDict = locals()");
211 PyRun_SimpleString ("from embedded_interpreter import run_python_interpreter");
212 PyRun_SimpleString ("import sys");
213 PyRun_SimpleString ("from termios import *");
214 PyRun_SimpleString ("old_stdin = sys.stdin");
215
216 StreamString run_string;
217 run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name);
218 PyRun_SimpleString (run_string.GetData());
219 PyRun_SimpleString ("sys.stdin = new_stdin");
220
221 PyRun_SimpleString ("old_stdout = sys.stdout");
222
223 if (out_fh != NULL)
224 {
225 PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w",
226 _check_and_flush);
227 PyObject *sysmod = PyImport_AddModule ("sys");
228 PyObject *sysdict = PyModule_GetDict (sysmod);
229
230 if ((new_sysout != NULL)
231 && (sysmod != NULL)
232 && (sysdict != NULL))
233 {
234 PyDict_SetItemString (sysdict, "stdout", new_sysout);
235 }
236
237 if (PyErr_Occurred())
238 PyErr_Clear();
239 }
240
241 PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
242 PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
243 PyRun_SimpleString ("new_mode[6][VEOF] = 255");
244 PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
Caroline Tice558be582010-06-30 16:22:25 +0000245
246 run_string.Clear();
247 run_string.Printf ("debugger_unique_id = %d", interpreter.GetDebugger().GetID());
248 PyRun_SimpleString (run_string.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000249 }
250
251
252}
253
254ScriptInterpreterPython::~ScriptInterpreterPython ()
255{
256 PyRun_SimpleString ("sys.stdin = old_stdin");
257 PyRun_SimpleString ("sys.stdout = old_stdout");
258 Py_Finalize ();
259}
260
Johnny Chen60dde642010-07-30 22:33:14 +0000261bool
262ScriptInterpreterPython::ExecuteOneLine (CommandInterpreter &interpreter,
263 const char *command,
264 CommandReturnObject *result = 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000265{
Greg Clayton63094e02010-06-23 01:19:29 +0000266 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000267 {
Greg Clayton63094e02010-06-23 01:19:29 +0000268 int success;
269
270 success = PyRun_SimpleString (command);
Johnny Chen60dde642010-07-30 22:33:14 +0000271 if (success == 0)
272 return true;
273
274 // The one-liner failed. Append the error message.
275 if (result)
276 result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
277 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000278 }
Johnny Chen60dde642010-07-30 22:33:14 +0000279
280 if (result)
281 result->AppendError ("empty command passed to python\n");
282 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000283}
284
285
286
287size_t
288ScriptInterpreterPython::InputReaderCallback
289(
290 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000291 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000292 lldb::InputReaderAction notification,
293 const char *bytes,
294 size_t bytes_len
295)
296{
297 if (baton == NULL)
298 return 0;
299
Greg Clayton63094e02010-06-23 01:19:29 +0000300 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000301 switch (notification)
302 {
303 case eInputReaderActivate:
304 {
305 // Save terminal settings if we can
Greg Clayton63094e02010-06-23 01:19:29 +0000306 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
307 int input_fd = ::fileno (input_fh);
308 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000309 struct termios tmp_termios;
Greg Clayton63094e02010-06-23 01:19:29 +0000310 if (::tcgetattr (input_fd, &tmp_termios) == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000311 {
312 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000313 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000314 }
315 }
316 break;
317
318 case eInputReaderDeactivate:
319 break;
320
321 case eInputReaderReactivate:
322 break;
323
324 case eInputReaderGotToken:
325 if (bytes && bytes_len)
326 {
327 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000328 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000329 else
Greg Clayton63094e02010-06-23 01:19:29 +0000330 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000331 }
Greg Clayton63094e02010-06-23 01:19:29 +0000332 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 break;
334
335 case eInputReaderDone:
336 // Send a control D to the script interpreter
337 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
338 // Write a newline out to the reader output
339 //::fwrite ("\n", 1, 1, out_fh);
340 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000341 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000342 {
Greg Clayton63094e02010-06-23 01:19:29 +0000343 ::tcsetattr (::fileno (reader.GetDebugger().GetInputFileHandle()),
Chris Lattner24943d22010-06-08 16:52:24 +0000344 TCSANOW,
Greg Clayton63094e02010-06-23 01:19:29 +0000345 &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000346 }
347 break;
348 }
349
350 return bytes_len;
351}
352
353
354void
Greg Clayton63094e02010-06-23 01:19:29 +0000355ScriptInterpreterPython::ExecuteInterpreterLoop (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000356{
357 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
358
Greg Clayton63094e02010-06-23 01:19:29 +0000359 Debugger &debugger = interpreter.GetDebugger();
360 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000361 if (reader_sp)
362 {
363 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
364 this, // baton
365 eInputReaderGranularityLine, // token size, to pass to callback function
366 NULL, // end token
367 NULL, // prompt
368 true)); // echo input
369
370 if (error.Success())
371 {
Greg Clayton63094e02010-06-23 01:19:29 +0000372 debugger.PushInputReader (reader_sp);
373 ExecuteOneLine (interpreter, "run_python_interpreter(ConsoleDict)");
374 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000375 }
376 }
377}
378
379bool
380ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
381 ScriptInterpreter::ReturnType return_type,
382 void *ret_value)
383{
384 PyObject *py_return = NULL;
385 PyObject *mainmod = PyImport_AddModule ("__main__");
386 PyObject *globals = PyModule_GetDict (mainmod);
387 PyObject *locals = globals;
388 PyObject *py_error = NULL;
389 bool ret_success;
390 int success;
391
392 if (in_string != NULL)
393 {
394 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
395 if (py_return == NULL)
396 {
397 py_error = PyErr_Occurred ();
398 if (py_error != NULL)
399 PyErr_Clear ();
400
401 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
402 }
403
404 if (py_return != NULL)
405 {
406 switch (return_type)
407 {
408 case eCharPtr: // "char *"
409 {
410 const char format[3] = "s#";
411 success = PyArg_Parse (py_return, format, (char **) &ret_value);
412 break;
413 }
414 case eBool:
415 {
416 const char format[2] = "b";
417 success = PyArg_Parse (py_return, format, (bool *) ret_value);
418 break;
419 }
420 case eShortInt:
421 {
422 const char format[2] = "h";
423 success = PyArg_Parse (py_return, format, (short *) ret_value);
424 break;
425 }
426 case eShortIntUnsigned:
427 {
428 const char format[2] = "H";
429 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
430 break;
431 }
432 case eInt:
433 {
434 const char format[2] = "i";
435 success = PyArg_Parse (py_return, format, (int *) ret_value);
436 break;
437 }
438 case eIntUnsigned:
439 {
440 const char format[2] = "I";
441 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
442 break;
443 }
444 case eLongInt:
445 {
446 const char format[2] = "l";
447 success = PyArg_Parse (py_return, format, (long *) ret_value);
448 break;
449 }
450 case eLongIntUnsigned:
451 {
452 const char format[2] = "k";
453 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
454 break;
455 }
456 case eLongLong:
457 {
458 const char format[2] = "L";
459 success = PyArg_Parse (py_return, format, (long long *) ret_value);
460 break;
461 }
462 case eLongLongUnsigned:
463 {
464 const char format[2] = "K";
465 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
466 break;
467 }
468 case eFloat:
469 {
470 const char format[2] = "f";
471 success = PyArg_Parse (py_return, format, (float *) ret_value);
472 break;
473 }
474 case eDouble:
475 {
476 const char format[2] = "d";
477 success = PyArg_Parse (py_return, format, (double *) ret_value);
478 break;
479 }
480 case eChar:
481 {
482 const char format[2] = "c";
483 success = PyArg_Parse (py_return, format, (char *) ret_value);
484 break;
485 }
486 default:
487 {}
488 }
489 Py_DECREF (py_return);
490 if (success)
491 ret_success = true;
492 else
493 ret_success = false;
494 }
495 }
496
497 py_error = PyErr_Occurred();
498 if (py_error != NULL)
499 {
500 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
501 PyErr_Print ();
502 PyErr_Clear();
503 ret_success = false;
504 }
505
506 return ret_success;
507}
508
509bool
510ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
511{
512 bool success = false;
513 PyObject *py_return = NULL;
514 PyObject *mainmod = PyImport_AddModule ("__main__");
515 PyObject *globals = PyModule_GetDict (mainmod);
516 PyObject *locals = globals;
517 PyObject *py_error = NULL;
518
519 if (in_string != NULL)
520 {
521 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
522 if (compiled_node)
523 {
524 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
525 if (compiled_code)
526 {
527 py_return = PyEval_EvalCode (compiled_code, globals, locals);
528 if (py_return != NULL)
529 {
530 success = true;
531 Py_DECREF (py_return);
532 }
533 }
534 }
535 }
536
537 py_error = PyErr_Occurred ();
538 if (py_error != NULL)
539 {
540 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
541 PyErr_Print ();
542 PyErr_Clear();
543 success = false;
544 }
545
546 return success;
547}
548
549static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
550
551size_t
552ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
553(
554 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000555 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000556 lldb::InputReaderAction notification,
557 const char *bytes,
558 size_t bytes_len
559)
560{
561 static StringList commands_in_progress;
562
Greg Clayton63094e02010-06-23 01:19:29 +0000563 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000564 switch (notification)
565 {
566 case eInputReaderActivate:
567 {
568 commands_in_progress.Clear();
569 if (out_fh)
570 {
571 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000572 if (reader.GetPrompt())
573 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000574 }
575 }
576 break;
577
578 case eInputReaderDeactivate:
579 break;
580
581 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000582 if (reader.GetPrompt() && out_fh)
583 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000584 break;
585
586 case eInputReaderGotToken:
587 {
588 std::string temp_string (bytes, bytes_len);
589 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000590 if (out_fh && !reader.IsDone() && reader.GetPrompt())
591 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000592 }
593 break;
594
595 case eInputReaderDone:
596 {
597 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
598 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
599 data_ap->user_source.AppendList (commands_in_progress);
600 if (data_ap.get())
601 {
Greg Clayton63094e02010-06-23 01:19:29 +0000602 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000603 if (interpreter)
604 {
605 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
606 data_ap->script_source))
607 {
608 if (data_ap->script_source.GetSize() == 1)
609 {
610 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
611 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
612 }
613 }
614 }
615 else
616 {
617 // FIXME: Error processing.
618 }
619 }
620 }
621 break;
622
623 }
624
625 return bytes_len;
626}
627
628void
Greg Clayton63094e02010-06-23 01:19:29 +0000629ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (CommandInterpreter &interpreter,
630 BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000631 CommandReturnObject &result)
632{
Greg Clayton63094e02010-06-23 01:19:29 +0000633 Debugger &debugger = interpreter.GetDebugger();
634 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000635
636 if (reader_sp)
637 {
638 Error err = reader_sp->Initialize (
639 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
640 bp_options, // baton
641 eInputReaderGranularityLine, // token size, for feeding data to callback function
642 "DONE", // end token
643 "> ", // prompt
644 true); // echo input
645
646 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000647 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000648 else
649 {
650 result.AppendError (err.AsCString());
651 result.SetStatus (eReturnStatusFailed);
652 }
653 }
654 else
655 {
656 result.AppendError("out of memory");
657 result.SetStatus (eReturnStatusFailed);
658 }
659}
660
661bool
662ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
663{
664 // Convert StringList to one long, newline delimited, const char *.
665 std::string function_def_string;
666
667 int num_lines = function_def.GetSize();
668
669 for (int i = 0; i < num_lines; ++i)
670 {
671 function_def_string.append (function_def.GetStringAtIndex(i));
672 if (function_def_string.at (function_def_string.length() - 1) != '\n')
673 function_def_string.append ("\n");
674
675 }
676
677 return ExecuteMultipleLines (function_def_string.c_str());
678}
679
680bool
681ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
682{
683 static int num_created_functions = 0;
684
685 user_input.RemoveBlankLines ();
686 int num_lines = user_input.GetSize();
687 std::string last_function_call;
688
689 // Go through lines of input looking for any function definitions. For each function definition found,
690 // export the function definition to Python, create a potential function call for the function, and
691 // mark the lines of the function to be removed from the user input.
692
693 for (int i = 0; i < num_lines; ++i)
694 {
695 int function_start = i;
696 std::string current_str = user_input.GetStringAtIndex (i);
697 const char *current_line = current_str.c_str();
698 int len = 0;
699 if (current_line)
700 len = strlen (current_line);
701
702 // Check to see if the current line is the start of a Python function definition.
703 if (len > 4 && strncmp (current_line, "def ", 4) == 0)
704 {
705 // We've found the first line of a function. First, get the function name.
706
707 // Skip over the 'def '.
708 char *start = (char *) current_line + 4;
709
710 // Skip over white space.
711 while (start[0] == ' ' || start[0] == '\t')
712 ++start;
713
714 // Find the end of the function name.
715 char *end = start;
716 while (isalnum (end[0]) || end[0] == '_')
717 ++end;
718
719 int name_len = end - start;
720 std::string func_name = current_str.substr (4, name_len);
721
722 // Now to find the last line of the function. That will be the first line that does not begin with
723 // any white space (thanks to Python's indentation rules).
724 ++i;
725 bool found = false;
726 while (i < num_lines && !found)
727 {
728 std::string next_str = user_input.GetStringAtIndex (i);
729 const char *next_line = next_str.c_str();
730 if (next_line[0] != ' ' && next_line[0] != '\t')
731 found = true;
732 else
733 ++i;
734 }
735 if (found)
736 --i; // Make 'i' correspond to the last line of the function.
737 int function_end = i;
738
739 // Special case: All of user_input is one big function definition.
740 if ((function_start == 0) && (function_end == (num_lines - 1)))
741 {
742 ExportFunctionDefinitionToInterpreter (user_input);
743 last_function_call = func_name + " ()";
744 callback_data.AppendString (last_function_call.c_str());
745 return callback_data.GetSize() > 0;
746 }
747 else
748 {
749 // Make a copy of the function definition:
750 StringList new_function;
751 for (int k = function_start; k <= function_end; ++k)
752 {
753 new_function.AppendString (user_input.GetStringAtIndex (k));
754 // Mark the string to be deleted from user_input.
755 user_input.DeleteStringAtIndex (k);
756 user_input.InsertStringAtIndex (k, "<lldb_delete>");
757 }
758 ExportFunctionDefinitionToInterpreter (new_function);
759 last_function_call = func_name + " ()";
760 }
761 }
762 }
763
764 // Now instead of trying to really delete the marked lines from user_input, we will just copy all the
765 // unmarked lines into a new StringList.
766
767 StringList new_user_input;
768
769 for (int i = 0; i < num_lines; ++i)
770 {
771 std::string current_string = user_input.GetStringAtIndex (i);
772 if (current_string.compare (0, 13, "<lldb_delete>") == 0)
773 continue;
774
775 new_user_input.AppendString (current_string.c_str());
776 }
777
778 num_lines = new_user_input.GetSize();
779
780 if (num_lines > 0)
781 {
782 if (num_lines == 1
783 && strchr (new_user_input.GetStringAtIndex(0), '\n') == NULL)
784 {
785 // If there's only one line of input, and it doesn't contain any newline characters....
786 callback_data.AppendString (new_user_input.GetStringAtIndex (0));
787 }
788 else
789 {
790 // Create the new function name.
791 StreamString func_name;
792 func_name.Printf ("lldb_bp_callback_func_%d", num_created_functions);
793 //std::string func_name = "lldb_bp_callback_func_" + num_created_functions;
794 ++num_created_functions;
795
796 // Create the function call for the new function.
797 last_function_call = func_name.GetString() + " ()";
798
799 // Create the Python function definition line (which will have to be inserted at the beginning of
800 // the function).
801 std::string def_line = "def " + func_name.GetString() + " ():";
802
803
804 // Indent all lines an additional four spaces (as they are now being put inside a function definition).
805 for (int i = 0; i < num_lines; ++i)
806 {
807 const char *temp_cstring = new_user_input.GetStringAtIndex(i);
808 std::string temp2 = " ";
809 temp2.append(temp_cstring);
810 new_user_input.DeleteStringAtIndex (i);
811 new_user_input.InsertStringAtIndex (i, temp2.c_str());
812 }
813
814 // Insert the function definition line at the top of the new function.
815 new_user_input.InsertStringAtIndex (0, def_line.c_str());
816
817 ExportFunctionDefinitionToInterpreter (new_user_input);
818 callback_data.AppendString (last_function_call.c_str());
819 }
820 }
821 else
822 {
823 if (!last_function_call.empty())
824 callback_data.AppendString (last_function_call.c_str());
825 }
826
827 return callback_data.GetSize() > 0;
828}
829
830bool
831ScriptInterpreterPython::BreakpointCallbackFunction
832(
833 void *baton,
834 StoppointCallbackContext *context,
835 lldb::user_id_t break_id,
836 lldb::user_id_t break_loc_id
837)
838{
839 bool ret_value = true;
840 bool temp_bool;
841
842 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
843
844 const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
845
846 if (python_string != NULL)
847 {
Greg Clayton63094e02010-06-23 01:19:29 +0000848 bool success = context->exe_ctx.target->GetDebugger().
849 GetCommandInterpreter().
850 GetScriptInterpreter()->ExecuteOneLineWithReturn (python_string,
851 ScriptInterpreter::eBool,
852 (void *) &temp_bool);
Chris Lattner24943d22010-06-08 16:52:24 +0000853 if (success)
854 ret_value = temp_bool;
855 }
856
857 return ret_value;
858}