blob: b5ef735a8757d5e3993a5edbddd7e4ce30f382b3 [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) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000147 ScriptInterpreter (interpreter, eScriptLanguagePython),
Chris Lattner24943d22010-06-08 16:52:24 +0000148 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
Greg Clayton238c0a12010-09-18 01:14:36 +0000257ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result)
Chris Lattner24943d22010-06-08 16:52:24 +0000258{
Greg Clayton63094e02010-06-23 01:19:29 +0000259 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000260 {
Greg Clayton63094e02010-06-23 01:19:29 +0000261 int success;
262
263 success = PyRun_SimpleString (command);
Johnny Chen60dde642010-07-30 22:33:14 +0000264 if (success == 0)
265 return true;
266
267 // The one-liner failed. Append the error message.
268 if (result)
269 result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
270 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000271 }
Johnny Chen60dde642010-07-30 22:33:14 +0000272
273 if (result)
274 result->AppendError ("empty command passed to python\n");
275 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000276}
277
278
279
280size_t
281ScriptInterpreterPython::InputReaderCallback
282(
283 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000284 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000285 lldb::InputReaderAction notification,
286 const char *bytes,
287 size_t bytes_len
288)
289{
290 if (baton == NULL)
291 return 0;
292
Greg Clayton63094e02010-06-23 01:19:29 +0000293 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000294 switch (notification)
295 {
296 case eInputReaderActivate:
297 {
298 // Save terminal settings if we can
Caroline Ticec95c6d12010-09-14 22:49:06 +0000299 int input_fd;
Greg Clayton63094e02010-06-23 01:19:29 +0000300 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000301 if (input_fh != NULL)
302 input_fd = ::fileno (input_fh);
303 else
304 input_fd = STDIN_FILENO;
305
Greg Clayton63094e02010-06-23 01:19:29 +0000306 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000307 struct termios tmp_termios;
Greg Clayton63094e02010-06-23 01:19:29 +0000308 if (::tcgetattr (input_fd, &tmp_termios) == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000309 {
310 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000311 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000312 }
313 }
314 break;
315
316 case eInputReaderDeactivate:
317 break;
318
319 case eInputReaderReactivate:
320 break;
321
322 case eInputReaderGotToken:
323 if (bytes && bytes_len)
324 {
325 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000326 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000327 else
Greg Clayton63094e02010-06-23 01:19:29 +0000328 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000329 }
Greg Clayton63094e02010-06-23 01:19:29 +0000330 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000331 break;
332
333 case eInputReaderDone:
334 // Send a control D to the script interpreter
335 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
336 // Write a newline out to the reader output
337 //::fwrite ("\n", 1, 1, out_fh);
338 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000339 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000340 {
Caroline Ticec95c6d12010-09-14 22:49:06 +0000341 int input_fd;
342 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
343 if (input_fh != NULL)
344 input_fd = ::fileno (input_fh);
345 else
346 input_fd = STDIN_FILENO;
347
348 ::tcsetattr (input_fd, TCSANOW, &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000349 }
350 break;
351 }
352
353 return bytes_len;
354}
355
356
357void
Greg Clayton238c0a12010-09-18 01:14:36 +0000358ScriptInterpreterPython::ExecuteInterpreterLoop ()
Chris Lattner24943d22010-06-08 16:52:24 +0000359{
360 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
361
Greg Clayton238c0a12010-09-18 01:14:36 +0000362 Debugger &debugger = m_interpreter.GetDebugger();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000363
364 // At the moment, the only time the debugger does not have an input file handle is when this is called
365 // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
366 // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
367 // do it.
368
369 if (debugger.GetInputFileHandle() == NULL)
370 return;
371
Greg Clayton63094e02010-06-23 01:19:29 +0000372 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000373 if (reader_sp)
374 {
375 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
376 this, // baton
377 eInputReaderGranularityLine, // token size, to pass to callback function
378 NULL, // end token
379 NULL, // prompt
380 true)); // echo input
381
382 if (error.Success())
383 {
Greg Clayton63094e02010-06-23 01:19:29 +0000384 debugger.PushInputReader (reader_sp);
Greg Clayton238c0a12010-09-18 01:14:36 +0000385 ExecuteOneLine ("run_python_interpreter(ConsoleDict)", NULL);
Greg Clayton63094e02010-06-23 01:19:29 +0000386 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000387 }
388 }
389}
390
391bool
392ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
393 ScriptInterpreter::ReturnType return_type,
394 void *ret_value)
395{
396 PyObject *py_return = NULL;
397 PyObject *mainmod = PyImport_AddModule ("__main__");
398 PyObject *globals = PyModule_GetDict (mainmod);
399 PyObject *locals = globals;
400 PyObject *py_error = NULL;
401 bool ret_success;
402 int success;
403
404 if (in_string != NULL)
405 {
406 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
407 if (py_return == NULL)
408 {
409 py_error = PyErr_Occurred ();
410 if (py_error != NULL)
411 PyErr_Clear ();
412
413 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
414 }
415
416 if (py_return != NULL)
417 {
418 switch (return_type)
419 {
420 case eCharPtr: // "char *"
421 {
422 const char format[3] = "s#";
423 success = PyArg_Parse (py_return, format, (char **) &ret_value);
424 break;
425 }
426 case eBool:
427 {
428 const char format[2] = "b";
429 success = PyArg_Parse (py_return, format, (bool *) ret_value);
430 break;
431 }
432 case eShortInt:
433 {
434 const char format[2] = "h";
435 success = PyArg_Parse (py_return, format, (short *) ret_value);
436 break;
437 }
438 case eShortIntUnsigned:
439 {
440 const char format[2] = "H";
441 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
442 break;
443 }
444 case eInt:
445 {
446 const char format[2] = "i";
447 success = PyArg_Parse (py_return, format, (int *) ret_value);
448 break;
449 }
450 case eIntUnsigned:
451 {
452 const char format[2] = "I";
453 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
454 break;
455 }
456 case eLongInt:
457 {
458 const char format[2] = "l";
459 success = PyArg_Parse (py_return, format, (long *) ret_value);
460 break;
461 }
462 case eLongIntUnsigned:
463 {
464 const char format[2] = "k";
465 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
466 break;
467 }
468 case eLongLong:
469 {
470 const char format[2] = "L";
471 success = PyArg_Parse (py_return, format, (long long *) ret_value);
472 break;
473 }
474 case eLongLongUnsigned:
475 {
476 const char format[2] = "K";
477 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
478 break;
479 }
480 case eFloat:
481 {
482 const char format[2] = "f";
483 success = PyArg_Parse (py_return, format, (float *) ret_value);
484 break;
485 }
486 case eDouble:
487 {
488 const char format[2] = "d";
489 success = PyArg_Parse (py_return, format, (double *) ret_value);
490 break;
491 }
492 case eChar:
493 {
494 const char format[2] = "c";
495 success = PyArg_Parse (py_return, format, (char *) ret_value);
496 break;
497 }
498 default:
499 {}
500 }
501 Py_DECREF (py_return);
502 if (success)
503 ret_success = true;
504 else
505 ret_success = false;
506 }
507 }
508
509 py_error = PyErr_Occurred();
510 if (py_error != NULL)
511 {
512 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
513 PyErr_Print ();
514 PyErr_Clear();
515 ret_success = false;
516 }
517
518 return ret_success;
519}
520
521bool
522ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
523{
524 bool success = false;
525 PyObject *py_return = NULL;
526 PyObject *mainmod = PyImport_AddModule ("__main__");
527 PyObject *globals = PyModule_GetDict (mainmod);
528 PyObject *locals = globals;
529 PyObject *py_error = NULL;
530
531 if (in_string != NULL)
532 {
533 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
534 if (compiled_node)
535 {
536 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
537 if (compiled_code)
538 {
539 py_return = PyEval_EvalCode (compiled_code, globals, locals);
540 if (py_return != NULL)
541 {
542 success = true;
543 Py_DECREF (py_return);
544 }
545 }
546 }
547 }
548
549 py_error = PyErr_Occurred ();
550 if (py_error != NULL)
551 {
552 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
553 PyErr_Print ();
554 PyErr_Clear();
555 success = false;
556 }
557
558 return success;
559}
560
561static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
562
563size_t
564ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
565(
566 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000567 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000568 lldb::InputReaderAction notification,
569 const char *bytes,
570 size_t bytes_len
571)
572{
573 static StringList commands_in_progress;
574
Greg Clayton63094e02010-06-23 01:19:29 +0000575 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Caroline Ticec95c6d12010-09-14 22:49:06 +0000576 if (out_fh == NULL)
577 out_fh = stdout;
578
Chris Lattner24943d22010-06-08 16:52:24 +0000579 switch (notification)
580 {
581 case eInputReaderActivate:
582 {
583 commands_in_progress.Clear();
584 if (out_fh)
585 {
586 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000587 if (reader.GetPrompt())
588 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000589 }
590 }
591 break;
592
593 case eInputReaderDeactivate:
594 break;
595
596 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000597 if (reader.GetPrompt() && out_fh)
598 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000599 break;
600
601 case eInputReaderGotToken:
602 {
603 std::string temp_string (bytes, bytes_len);
604 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000605 if (out_fh && !reader.IsDone() && reader.GetPrompt())
606 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000607 }
608 break;
609
610 case eInputReaderDone:
611 {
612 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
613 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
614 data_ap->user_source.AppendList (commands_in_progress);
615 if (data_ap.get())
616 {
Greg Clayton63094e02010-06-23 01:19:29 +0000617 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000618 if (interpreter)
619 {
620 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
621 data_ap->script_source))
622 {
623 if (data_ap->script_source.GetSize() == 1)
624 {
625 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
626 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
627 }
628 }
Caroline Ticeb447e842010-09-21 19:25:28 +0000629 else
630 ::fprintf (out_fh, "Warning: No command attached to breakpoint.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000631 }
632 else
633 {
634 // FIXME: Error processing.
635 }
636 }
637 }
638 break;
639
640 }
641
642 return bytes_len;
643}
644
645void
Greg Clayton238c0a12010-09-18 01:14:36 +0000646ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000647 CommandReturnObject &result)
648{
Greg Clayton238c0a12010-09-18 01:14:36 +0000649 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton63094e02010-06-23 01:19:29 +0000650 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000651
652 if (reader_sp)
653 {
654 Error err = reader_sp->Initialize (
655 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
656 bp_options, // baton
657 eInputReaderGranularityLine, // token size, for feeding data to callback function
658 "DONE", // end token
659 "> ", // prompt
660 true); // echo input
661
662 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000663 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000664 else
665 {
666 result.AppendError (err.AsCString());
667 result.SetStatus (eReturnStatusFailed);
668 }
669 }
670 else
671 {
672 result.AppendError("out of memory");
673 result.SetStatus (eReturnStatusFailed);
674 }
675}
676
Johnny Chen3e0571b2010-09-11 00:23:59 +0000677// Set a Python one-liner as the callback for the breakpoint.
Johnny Chend1c2dca2010-09-10 18:21:10 +0000678void
Greg Clayton238c0a12010-09-18 01:14:36 +0000679ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
Johnny Chend1c2dca2010-09-10 18:21:10 +0000680 const char *oneliner)
681{
682 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
683
684 // It's necessary to set both user_source and script_source to the oneliner.
685 // The former is used to generate callback description (as in breakpoint command list)
686 // while the latter is used for Python to interpret during the actual callback.
687 data_ap->user_source.AppendString (oneliner);
688 data_ap->script_source.AppendString (oneliner);
689
690 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
691 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
692
693 return;
694}
695
Chris Lattner24943d22010-06-08 16:52:24 +0000696bool
697ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
698{
699 // Convert StringList to one long, newline delimited, const char *.
700 std::string function_def_string;
701
702 int num_lines = function_def.GetSize();
703
704 for (int i = 0; i < num_lines; ++i)
705 {
706 function_def_string.append (function_def.GetStringAtIndex(i));
707 if (function_def_string.at (function_def_string.length() - 1) != '\n')
708 function_def_string.append ("\n");
709
710 }
711
712 return ExecuteMultipleLines (function_def_string.c_str());
713}
714
715bool
716ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
717{
718 static int num_created_functions = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000719 user_input.RemoveBlankLines ();
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000720 int num_lines = user_input.GetSize ();
721 StreamString sstr;
Chris Lattner24943d22010-06-08 16:52:24 +0000722
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000723 // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
724 // frame and breakpoint location as parameters to the function.
Caroline Ticeb447e842010-09-21 19:25:28 +0000725
Caroline Ticeb447e842010-09-21 19:25:28 +0000726
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000727 sstr.Printf ("lldb_autogen_python_bp_callback_func_%d", num_created_functions);
728 ++num_created_functions;
729 std::string auto_generated_function_name = sstr.GetData();
Caroline Ticeb447e842010-09-21 19:25:28 +0000730
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000731 sstr.Clear();
Caroline Ticeb447e842010-09-21 19:25:28 +0000732 StringList auto_generated_function;
Caroline Ticeb447e842010-09-21 19:25:28 +0000733
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000734 // Create the function name & definition string.
735
736 sstr.Printf ("def %s (frame, bp_loc):", auto_generated_function_name.c_str());
737 auto_generated_function.AppendString (sstr.GetData());
738
739 // Wrap everything up inside the function, increasing the indentation.
Chris Lattner24943d22010-06-08 16:52:24 +0000740
741 for (int i = 0; i < num_lines; ++i)
742 {
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000743 sstr.Clear ();
744 sstr.Printf (" %s", user_input.GetStringAtIndex (i));
745 auto_generated_function.AppendString (sstr.GetData());
Caroline Ticeb447e842010-09-21 19:25:28 +0000746 }
Chris Lattner24943d22010-06-08 16:52:24 +0000747
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000748 // Verify that the results are valid Python.
Chris Lattner24943d22010-06-08 16:52:24 +0000749
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000750 if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
Caroline Ticeb447e842010-09-21 19:25:28 +0000751 {
Caroline Ticeb447e842010-09-21 19:25:28 +0000752 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000753 }
Caroline Tice59c5d5d2010-09-27 18:00:20 +0000754
755 // Store the name of the auto-generated function to be called.
756
757 callback_data.AppendString (auto_generated_function_name.c_str());
758 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000759}
760