blob: 39ae32a931afc0fcaec8a12f0c3fc5cf244b1302 [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.
Johnny Chen98bea862010-09-10 16:19:10 +0000199 success = PyRun_SimpleString ("import lldb");
Chris Lattner24943d22010-06-08 16:52:24 +0000200 }
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 *");
Chris Lattner24943d22010-06-08 16:52:24 +0000214
215 StreamString run_string;
216 run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name);
217 PyRun_SimpleString (run_string.GetData());
218 PyRun_SimpleString ("sys.stdin = new_stdin");
219
Chris Lattner24943d22010-06-08 16:52:24 +0000220 if (out_fh != NULL)
221 {
222 PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w",
223 _check_and_flush);
224 PyObject *sysmod = PyImport_AddModule ("sys");
225 PyObject *sysdict = PyModule_GetDict (sysmod);
226
227 if ((new_sysout != NULL)
228 && (sysmod != NULL)
229 && (sysdict != NULL))
230 {
231 PyDict_SetItemString (sysdict, "stdout", new_sysout);
232 }
233
234 if (PyErr_Occurred())
235 PyErr_Clear();
236 }
237
238 PyRun_SimpleString ("new_mode = tcgetattr(new_stdin)");
239 PyRun_SimpleString ("new_mode[3] = new_mode[3] | ECHO | ICANON");
240 PyRun_SimpleString ("new_mode[6][VEOF] = 255");
241 PyRun_SimpleString ("tcsetattr (new_stdin, TCSANOW, new_mode)");
Caroline Tice558be582010-06-30 16:22:25 +0000242
243 run_string.Clear();
Johnny Chen98bea862010-09-10 16:19:10 +0000244 run_string.Printf ("lldb.debugger_unique_id = %d", interpreter.GetDebugger().GetID());
Caroline Tice558be582010-06-30 16:22:25 +0000245 PyRun_SimpleString (run_string.GetData());
Chris Lattner24943d22010-06-08 16:52:24 +0000246 }
247
248
249}
250
251ScriptInterpreterPython::~ScriptInterpreterPython ()
252{
Chris Lattner24943d22010-06-08 16:52:24 +0000253 Py_Finalize ();
254}
255
Johnny Chen60dde642010-07-30 22:33:14 +0000256bool
257ScriptInterpreterPython::ExecuteOneLine (CommandInterpreter &interpreter,
258 const char *command,
259 CommandReturnObject *result = 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000260{
Greg Clayton63094e02010-06-23 01:19:29 +0000261 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000262 {
Greg Clayton63094e02010-06-23 01:19:29 +0000263 int success;
264
265 success = PyRun_SimpleString (command);
Johnny Chen60dde642010-07-30 22:33:14 +0000266 if (success == 0)
267 return true;
268
269 // The one-liner failed. Append the error message.
270 if (result)
271 result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
272 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000273 }
Johnny Chen60dde642010-07-30 22:33:14 +0000274
275 if (result)
276 result->AppendError ("empty command passed to python\n");
277 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000278}
279
280
281
282size_t
283ScriptInterpreterPython::InputReaderCallback
284(
285 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000286 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000287 lldb::InputReaderAction notification,
288 const char *bytes,
289 size_t bytes_len
290)
291{
292 if (baton == NULL)
293 return 0;
294
Greg Clayton63094e02010-06-23 01:19:29 +0000295 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000296 switch (notification)
297 {
298 case eInputReaderActivate:
299 {
300 // Save terminal settings if we can
Caroline Ticec95c6d12010-09-14 22:49:06 +0000301 int input_fd;
Greg Clayton63094e02010-06-23 01:19:29 +0000302 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000303 if (input_fh != NULL)
304 input_fd = ::fileno (input_fh);
305 else
306 input_fd = STDIN_FILENO;
307
Greg Clayton63094e02010-06-23 01:19:29 +0000308 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 {
Caroline Ticec95c6d12010-09-14 22:49:06 +0000343 int input_fd;
344 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
345 if (input_fh != NULL)
346 input_fd = ::fileno (input_fh);
347 else
348 input_fd = STDIN_FILENO;
349
350 ::tcsetattr (input_fd, TCSANOW, &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000351 }
352 break;
353 }
354
355 return bytes_len;
356}
357
358
359void
Greg Clayton63094e02010-06-23 01:19:29 +0000360ScriptInterpreterPython::ExecuteInterpreterLoop (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000361{
362 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
363
Greg Clayton63094e02010-06-23 01:19:29 +0000364 Debugger &debugger = interpreter.GetDebugger();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000365
366 // At the moment, the only time the debugger does not have an input file handle is when this is called
367 // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
368 // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
369 // do it.
370
371 if (debugger.GetInputFileHandle() == NULL)
372 return;
373
Greg Clayton63094e02010-06-23 01:19:29 +0000374 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000375 if (reader_sp)
376 {
377 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
378 this, // baton
379 eInputReaderGranularityLine, // token size, to pass to callback function
380 NULL, // end token
381 NULL, // prompt
382 true)); // echo input
383
384 if (error.Success())
385 {
Greg Clayton63094e02010-06-23 01:19:29 +0000386 debugger.PushInputReader (reader_sp);
387 ExecuteOneLine (interpreter, "run_python_interpreter(ConsoleDict)");
388 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000389 }
390 }
391}
392
393bool
394ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
395 ScriptInterpreter::ReturnType return_type,
396 void *ret_value)
397{
398 PyObject *py_return = NULL;
399 PyObject *mainmod = PyImport_AddModule ("__main__");
400 PyObject *globals = PyModule_GetDict (mainmod);
401 PyObject *locals = globals;
402 PyObject *py_error = NULL;
403 bool ret_success;
404 int success;
405
406 if (in_string != NULL)
407 {
408 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
409 if (py_return == NULL)
410 {
411 py_error = PyErr_Occurred ();
412 if (py_error != NULL)
413 PyErr_Clear ();
414
415 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
416 }
417
418 if (py_return != NULL)
419 {
420 switch (return_type)
421 {
422 case eCharPtr: // "char *"
423 {
424 const char format[3] = "s#";
425 success = PyArg_Parse (py_return, format, (char **) &ret_value);
426 break;
427 }
428 case eBool:
429 {
430 const char format[2] = "b";
431 success = PyArg_Parse (py_return, format, (bool *) ret_value);
432 break;
433 }
434 case eShortInt:
435 {
436 const char format[2] = "h";
437 success = PyArg_Parse (py_return, format, (short *) ret_value);
438 break;
439 }
440 case eShortIntUnsigned:
441 {
442 const char format[2] = "H";
443 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
444 break;
445 }
446 case eInt:
447 {
448 const char format[2] = "i";
449 success = PyArg_Parse (py_return, format, (int *) ret_value);
450 break;
451 }
452 case eIntUnsigned:
453 {
454 const char format[2] = "I";
455 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
456 break;
457 }
458 case eLongInt:
459 {
460 const char format[2] = "l";
461 success = PyArg_Parse (py_return, format, (long *) ret_value);
462 break;
463 }
464 case eLongIntUnsigned:
465 {
466 const char format[2] = "k";
467 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
468 break;
469 }
470 case eLongLong:
471 {
472 const char format[2] = "L";
473 success = PyArg_Parse (py_return, format, (long long *) ret_value);
474 break;
475 }
476 case eLongLongUnsigned:
477 {
478 const char format[2] = "K";
479 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
480 break;
481 }
482 case eFloat:
483 {
484 const char format[2] = "f";
485 success = PyArg_Parse (py_return, format, (float *) ret_value);
486 break;
487 }
488 case eDouble:
489 {
490 const char format[2] = "d";
491 success = PyArg_Parse (py_return, format, (double *) ret_value);
492 break;
493 }
494 case eChar:
495 {
496 const char format[2] = "c";
497 success = PyArg_Parse (py_return, format, (char *) ret_value);
498 break;
499 }
500 default:
501 {}
502 }
503 Py_DECREF (py_return);
504 if (success)
505 ret_success = true;
506 else
507 ret_success = false;
508 }
509 }
510
511 py_error = PyErr_Occurred();
512 if (py_error != NULL)
513 {
514 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
515 PyErr_Print ();
516 PyErr_Clear();
517 ret_success = false;
518 }
519
520 return ret_success;
521}
522
523bool
524ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
525{
526 bool success = false;
527 PyObject *py_return = NULL;
528 PyObject *mainmod = PyImport_AddModule ("__main__");
529 PyObject *globals = PyModule_GetDict (mainmod);
530 PyObject *locals = globals;
531 PyObject *py_error = NULL;
532
533 if (in_string != NULL)
534 {
535 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
536 if (compiled_node)
537 {
538 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
539 if (compiled_code)
540 {
541 py_return = PyEval_EvalCode (compiled_code, globals, locals);
542 if (py_return != NULL)
543 {
544 success = true;
545 Py_DECREF (py_return);
546 }
547 }
548 }
549 }
550
551 py_error = PyErr_Occurred ();
552 if (py_error != NULL)
553 {
554 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
555 PyErr_Print ();
556 PyErr_Clear();
557 success = false;
558 }
559
560 return success;
561}
562
563static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
564
565size_t
566ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
567(
568 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000569 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000570 lldb::InputReaderAction notification,
571 const char *bytes,
572 size_t bytes_len
573)
574{
575 static StringList commands_in_progress;
576
Greg Clayton63094e02010-06-23 01:19:29 +0000577 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000578 if (out_fh == NULL)
579 out_fh = stdout;
580
Chris Lattner24943d22010-06-08 16:52:24 +0000581 switch (notification)
582 {
583 case eInputReaderActivate:
584 {
585 commands_in_progress.Clear();
586 if (out_fh)
587 {
588 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000589 if (reader.GetPrompt())
590 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000591 }
592 }
593 break;
594
595 case eInputReaderDeactivate:
596 break;
597
598 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000599 if (reader.GetPrompt() && out_fh)
600 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000601 break;
602
603 case eInputReaderGotToken:
604 {
605 std::string temp_string (bytes, bytes_len);
606 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000607 if (out_fh && !reader.IsDone() && reader.GetPrompt())
608 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000609 }
610 break;
611
612 case eInputReaderDone:
613 {
614 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
615 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
616 data_ap->user_source.AppendList (commands_in_progress);
617 if (data_ap.get())
618 {
Greg Clayton63094e02010-06-23 01:19:29 +0000619 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000620 if (interpreter)
621 {
622 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
623 data_ap->script_source))
624 {
625 if (data_ap->script_source.GetSize() == 1)
626 {
627 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
628 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
629 }
630 }
631 }
632 else
633 {
634 // FIXME: Error processing.
635 }
636 }
637 }
638 break;
639
640 }
641
642 return bytes_len;
643}
644
645void
Greg Clayton63094e02010-06-23 01:19:29 +0000646ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (CommandInterpreter &interpreter,
647 BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000648 CommandReturnObject &result)
649{
Greg Clayton63094e02010-06-23 01:19:29 +0000650 Debugger &debugger = interpreter.GetDebugger();
651 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000652
653 if (reader_sp)
654 {
655 Error err = reader_sp->Initialize (
656 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
657 bp_options, // baton
658 eInputReaderGranularityLine, // token size, for feeding data to callback function
659 "DONE", // end token
660 "> ", // prompt
661 true); // echo input
662
663 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000664 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000665 else
666 {
667 result.AppendError (err.AsCString());
668 result.SetStatus (eReturnStatusFailed);
669 }
670 }
671 else
672 {
673 result.AppendError("out of memory");
674 result.SetStatus (eReturnStatusFailed);
675 }
676}
677
Johnny Chen3e0571b2010-09-11 00:23:59 +0000678// Set a Python one-liner as the callback for the breakpoint.
Johnny Chend1c2dca2010-09-10 18:21:10 +0000679void
680ScriptInterpreterPython::SetBreakpointCommandCallback (CommandInterpreter &interpreter,
681 BreakpointOptions *bp_options,
682 const char *oneliner)
683{
684 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
685
686 // It's necessary to set both user_source and script_source to the oneliner.
687 // The former is used to generate callback description (as in breakpoint command list)
688 // while the latter is used for Python to interpret during the actual callback.
689 data_ap->user_source.AppendString (oneliner);
690 data_ap->script_source.AppendString (oneliner);
691
692 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
693 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
694
695 return;
696}
697
Chris Lattner24943d22010-06-08 16:52:24 +0000698bool
699ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
700{
701 // Convert StringList to one long, newline delimited, const char *.
702 std::string function_def_string;
703
704 int num_lines = function_def.GetSize();
705
706 for (int i = 0; i < num_lines; ++i)
707 {
708 function_def_string.append (function_def.GetStringAtIndex(i));
709 if (function_def_string.at (function_def_string.length() - 1) != '\n')
710 function_def_string.append ("\n");
711
712 }
713
714 return ExecuteMultipleLines (function_def_string.c_str());
715}
716
717bool
718ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
719{
720 static int num_created_functions = 0;
721
722 user_input.RemoveBlankLines ();
723 int num_lines = user_input.GetSize();
724 std::string last_function_call;
725
726 // Go through lines of input looking for any function definitions. For each function definition found,
727 // export the function definition to Python, create a potential function call for the function, and
728 // mark the lines of the function to be removed from the user input.
729
730 for (int i = 0; i < num_lines; ++i)
731 {
732 int function_start = i;
733 std::string current_str = user_input.GetStringAtIndex (i);
734 const char *current_line = current_str.c_str();
735 int len = 0;
736 if (current_line)
737 len = strlen (current_line);
738
739 // Check to see if the current line is the start of a Python function definition.
740 if (len > 4 && strncmp (current_line, "def ", 4) == 0)
741 {
742 // We've found the first line of a function. First, get the function name.
743
744 // Skip over the 'def '.
745 char *start = (char *) current_line + 4;
746
747 // Skip over white space.
748 while (start[0] == ' ' || start[0] == '\t')
749 ++start;
750
751 // Find the end of the function name.
752 char *end = start;
753 while (isalnum (end[0]) || end[0] == '_')
754 ++end;
755
756 int name_len = end - start;
757 std::string func_name = current_str.substr (4, name_len);
758
759 // Now to find the last line of the function. That will be the first line that does not begin with
760 // any white space (thanks to Python's indentation rules).
761 ++i;
762 bool found = false;
763 while (i < num_lines && !found)
764 {
765 std::string next_str = user_input.GetStringAtIndex (i);
766 const char *next_line = next_str.c_str();
767 if (next_line[0] != ' ' && next_line[0] != '\t')
768 found = true;
769 else
770 ++i;
771 }
772 if (found)
773 --i; // Make 'i' correspond to the last line of the function.
774 int function_end = i;
775
776 // Special case: All of user_input is one big function definition.
777 if ((function_start == 0) && (function_end == (num_lines - 1)))
778 {
779 ExportFunctionDefinitionToInterpreter (user_input);
780 last_function_call = func_name + " ()";
781 callback_data.AppendString (last_function_call.c_str());
782 return callback_data.GetSize() > 0;
783 }
784 else
785 {
786 // Make a copy of the function definition:
787 StringList new_function;
788 for (int k = function_start; k <= function_end; ++k)
789 {
790 new_function.AppendString (user_input.GetStringAtIndex (k));
791 // Mark the string to be deleted from user_input.
792 user_input.DeleteStringAtIndex (k);
793 user_input.InsertStringAtIndex (k, "<lldb_delete>");
794 }
795 ExportFunctionDefinitionToInterpreter (new_function);
796 last_function_call = func_name + " ()";
797 }
798 }
799 }
800
801 // Now instead of trying to really delete the marked lines from user_input, we will just copy all the
802 // unmarked lines into a new StringList.
803
804 StringList new_user_input;
805
806 for (int i = 0; i < num_lines; ++i)
807 {
808 std::string current_string = user_input.GetStringAtIndex (i);
809 if (current_string.compare (0, 13, "<lldb_delete>") == 0)
810 continue;
811
812 new_user_input.AppendString (current_string.c_str());
813 }
814
815 num_lines = new_user_input.GetSize();
816
817 if (num_lines > 0)
818 {
819 if (num_lines == 1
820 && strchr (new_user_input.GetStringAtIndex(0), '\n') == NULL)
821 {
822 // If there's only one line of input, and it doesn't contain any newline characters....
823 callback_data.AppendString (new_user_input.GetStringAtIndex (0));
824 }
825 else
826 {
827 // Create the new function name.
828 StreamString func_name;
829 func_name.Printf ("lldb_bp_callback_func_%d", num_created_functions);
830 //std::string func_name = "lldb_bp_callback_func_" + num_created_functions;
831 ++num_created_functions;
832
833 // Create the function call for the new function.
834 last_function_call = func_name.GetString() + " ()";
835
836 // Create the Python function definition line (which will have to be inserted at the beginning of
837 // the function).
838 std::string def_line = "def " + func_name.GetString() + " ():";
839
840
841 // Indent all lines an additional four spaces (as they are now being put inside a function definition).
842 for (int i = 0; i < num_lines; ++i)
843 {
844 const char *temp_cstring = new_user_input.GetStringAtIndex(i);
845 std::string temp2 = " ";
846 temp2.append(temp_cstring);
847 new_user_input.DeleteStringAtIndex (i);
848 new_user_input.InsertStringAtIndex (i, temp2.c_str());
849 }
850
851 // Insert the function definition line at the top of the new function.
852 new_user_input.InsertStringAtIndex (0, def_line.c_str());
853
854 ExportFunctionDefinitionToInterpreter (new_user_input);
855 callback_data.AppendString (last_function_call.c_str());
856 }
857 }
858 else
859 {
860 if (!last_function_call.empty())
861 callback_data.AppendString (last_function_call.c_str());
862 }
863
864 return callback_data.GetSize() > 0;
865}
866
867bool
868ScriptInterpreterPython::BreakpointCallbackFunction
869(
870 void *baton,
871 StoppointCallbackContext *context,
872 lldb::user_id_t break_id,
873 lldb::user_id_t break_loc_id
874)
875{
876 bool ret_value = true;
877 bool temp_bool;
878
879 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
880
881 const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
882
883 if (python_string != NULL)
884 {
Greg Clayton63094e02010-06-23 01:19:29 +0000885 bool success = context->exe_ctx.target->GetDebugger().
886 GetCommandInterpreter().
887 GetScriptInterpreter()->ExecuteOneLineWithReturn (python_string,
888 ScriptInterpreter::eBool,
889 (void *) &temp_bool);
Chris Lattner24943d22010-06-08 16:52:24 +0000890 if (success)
891 ret_value = temp_bool;
892 }
893
894 return ret_value;
895}