blob: ea8a11c2471e45f7c075000a235e8ae0661b6e25 [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
Greg Clayton63094e02010-06-23 01:19:29 +0000301 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
302 int input_fd = ::fileno (input_fh);
303 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000304 struct termios tmp_termios;
Greg Clayton63094e02010-06-23 01:19:29 +0000305 if (::tcgetattr (input_fd, &tmp_termios) == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000306 {
307 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000308 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000309 }
310 }
311 break;
312
313 case eInputReaderDeactivate:
314 break;
315
316 case eInputReaderReactivate:
317 break;
318
319 case eInputReaderGotToken:
320 if (bytes && bytes_len)
321 {
322 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000323 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000324 else
Greg Clayton63094e02010-06-23 01:19:29 +0000325 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000326 }
Greg Clayton63094e02010-06-23 01:19:29 +0000327 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000328 break;
329
330 case eInputReaderDone:
331 // Send a control D to the script interpreter
332 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
333 // Write a newline out to the reader output
334 //::fwrite ("\n", 1, 1, out_fh);
335 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000336 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000337 {
Greg Clayton63094e02010-06-23 01:19:29 +0000338 ::tcsetattr (::fileno (reader.GetDebugger().GetInputFileHandle()),
Chris Lattner24943d22010-06-08 16:52:24 +0000339 TCSANOW,
Greg Clayton63094e02010-06-23 01:19:29 +0000340 &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000341 }
342 break;
343 }
344
345 return bytes_len;
346}
347
348
349void
Greg Clayton63094e02010-06-23 01:19:29 +0000350ScriptInterpreterPython::ExecuteInterpreterLoop (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000351{
352 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
353
Greg Clayton63094e02010-06-23 01:19:29 +0000354 Debugger &debugger = interpreter.GetDebugger();
355 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000356 if (reader_sp)
357 {
358 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
359 this, // baton
360 eInputReaderGranularityLine, // token size, to pass to callback function
361 NULL, // end token
362 NULL, // prompt
363 true)); // echo input
364
365 if (error.Success())
366 {
Greg Clayton63094e02010-06-23 01:19:29 +0000367 debugger.PushInputReader (reader_sp);
368 ExecuteOneLine (interpreter, "run_python_interpreter(ConsoleDict)");
369 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000370 }
371 }
372}
373
374bool
375ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
376 ScriptInterpreter::ReturnType return_type,
377 void *ret_value)
378{
379 PyObject *py_return = NULL;
380 PyObject *mainmod = PyImport_AddModule ("__main__");
381 PyObject *globals = PyModule_GetDict (mainmod);
382 PyObject *locals = globals;
383 PyObject *py_error = NULL;
384 bool ret_success;
385 int success;
386
387 if (in_string != NULL)
388 {
389 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
390 if (py_return == NULL)
391 {
392 py_error = PyErr_Occurred ();
393 if (py_error != NULL)
394 PyErr_Clear ();
395
396 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
397 }
398
399 if (py_return != NULL)
400 {
401 switch (return_type)
402 {
403 case eCharPtr: // "char *"
404 {
405 const char format[3] = "s#";
406 success = PyArg_Parse (py_return, format, (char **) &ret_value);
407 break;
408 }
409 case eBool:
410 {
411 const char format[2] = "b";
412 success = PyArg_Parse (py_return, format, (bool *) ret_value);
413 break;
414 }
415 case eShortInt:
416 {
417 const char format[2] = "h";
418 success = PyArg_Parse (py_return, format, (short *) ret_value);
419 break;
420 }
421 case eShortIntUnsigned:
422 {
423 const char format[2] = "H";
424 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
425 break;
426 }
427 case eInt:
428 {
429 const char format[2] = "i";
430 success = PyArg_Parse (py_return, format, (int *) ret_value);
431 break;
432 }
433 case eIntUnsigned:
434 {
435 const char format[2] = "I";
436 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
437 break;
438 }
439 case eLongInt:
440 {
441 const char format[2] = "l";
442 success = PyArg_Parse (py_return, format, (long *) ret_value);
443 break;
444 }
445 case eLongIntUnsigned:
446 {
447 const char format[2] = "k";
448 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
449 break;
450 }
451 case eLongLong:
452 {
453 const char format[2] = "L";
454 success = PyArg_Parse (py_return, format, (long long *) ret_value);
455 break;
456 }
457 case eLongLongUnsigned:
458 {
459 const char format[2] = "K";
460 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
461 break;
462 }
463 case eFloat:
464 {
465 const char format[2] = "f";
466 success = PyArg_Parse (py_return, format, (float *) ret_value);
467 break;
468 }
469 case eDouble:
470 {
471 const char format[2] = "d";
472 success = PyArg_Parse (py_return, format, (double *) ret_value);
473 break;
474 }
475 case eChar:
476 {
477 const char format[2] = "c";
478 success = PyArg_Parse (py_return, format, (char *) ret_value);
479 break;
480 }
481 default:
482 {}
483 }
484 Py_DECREF (py_return);
485 if (success)
486 ret_success = true;
487 else
488 ret_success = false;
489 }
490 }
491
492 py_error = PyErr_Occurred();
493 if (py_error != NULL)
494 {
495 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
496 PyErr_Print ();
497 PyErr_Clear();
498 ret_success = false;
499 }
500
501 return ret_success;
502}
503
504bool
505ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
506{
507 bool success = false;
508 PyObject *py_return = NULL;
509 PyObject *mainmod = PyImport_AddModule ("__main__");
510 PyObject *globals = PyModule_GetDict (mainmod);
511 PyObject *locals = globals;
512 PyObject *py_error = NULL;
513
514 if (in_string != NULL)
515 {
516 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
517 if (compiled_node)
518 {
519 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
520 if (compiled_code)
521 {
522 py_return = PyEval_EvalCode (compiled_code, globals, locals);
523 if (py_return != NULL)
524 {
525 success = true;
526 Py_DECREF (py_return);
527 }
528 }
529 }
530 }
531
532 py_error = PyErr_Occurred ();
533 if (py_error != NULL)
534 {
535 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
536 PyErr_Print ();
537 PyErr_Clear();
538 success = false;
539 }
540
541 return success;
542}
543
544static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
545
546size_t
547ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
548(
549 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000550 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000551 lldb::InputReaderAction notification,
552 const char *bytes,
553 size_t bytes_len
554)
555{
556 static StringList commands_in_progress;
557
Greg Clayton63094e02010-06-23 01:19:29 +0000558 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000559 switch (notification)
560 {
561 case eInputReaderActivate:
562 {
563 commands_in_progress.Clear();
564 if (out_fh)
565 {
566 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000567 if (reader.GetPrompt())
568 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000569 }
570 }
571 break;
572
573 case eInputReaderDeactivate:
574 break;
575
576 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000577 if (reader.GetPrompt() && out_fh)
578 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000579 break;
580
581 case eInputReaderGotToken:
582 {
583 std::string temp_string (bytes, bytes_len);
584 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000585 if (out_fh && !reader.IsDone() && reader.GetPrompt())
586 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000587 }
588 break;
589
590 case eInputReaderDone:
591 {
592 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
593 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
594 data_ap->user_source.AppendList (commands_in_progress);
595 if (data_ap.get())
596 {
Greg Clayton63094e02010-06-23 01:19:29 +0000597 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000598 if (interpreter)
599 {
600 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
601 data_ap->script_source))
602 {
603 if (data_ap->script_source.GetSize() == 1)
604 {
605 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
606 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
607 }
608 }
609 }
610 else
611 {
612 // FIXME: Error processing.
613 }
614 }
615 }
616 break;
617
618 }
619
620 return bytes_len;
621}
622
623void
Greg Clayton63094e02010-06-23 01:19:29 +0000624ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (CommandInterpreter &interpreter,
625 BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000626 CommandReturnObject &result)
627{
Greg Clayton63094e02010-06-23 01:19:29 +0000628 Debugger &debugger = interpreter.GetDebugger();
629 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000630
631 if (reader_sp)
632 {
633 Error err = reader_sp->Initialize (
634 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
635 bp_options, // baton
636 eInputReaderGranularityLine, // token size, for feeding data to callback function
637 "DONE", // end token
638 "> ", // prompt
639 true); // echo input
640
641 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000642 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000643 else
644 {
645 result.AppendError (err.AsCString());
646 result.SetStatus (eReturnStatusFailed);
647 }
648 }
649 else
650 {
651 result.AppendError("out of memory");
652 result.SetStatus (eReturnStatusFailed);
653 }
654}
655
Johnny Chend1c2dca2010-09-10 18:21:10 +0000656// Set a Python one-liner as the callback for the breakpoint command.
657void
658ScriptInterpreterPython::SetBreakpointCommandCallback (CommandInterpreter &interpreter,
659 BreakpointOptions *bp_options,
660 const char *oneliner)
661{
662 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
663
664 // It's necessary to set both user_source and script_source to the oneliner.
665 // The former is used to generate callback description (as in breakpoint command list)
666 // while the latter is used for Python to interpret during the actual callback.
667 data_ap->user_source.AppendString (oneliner);
668 data_ap->script_source.AppendString (oneliner);
669
670 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
671 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
672
673 return;
674}
675
Chris Lattner24943d22010-06-08 16:52:24 +0000676bool
677ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
678{
679 // Convert StringList to one long, newline delimited, const char *.
680 std::string function_def_string;
681
682 int num_lines = function_def.GetSize();
683
684 for (int i = 0; i < num_lines; ++i)
685 {
686 function_def_string.append (function_def.GetStringAtIndex(i));
687 if (function_def_string.at (function_def_string.length() - 1) != '\n')
688 function_def_string.append ("\n");
689
690 }
691
692 return ExecuteMultipleLines (function_def_string.c_str());
693}
694
695bool
696ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
697{
698 static int num_created_functions = 0;
699
700 user_input.RemoveBlankLines ();
701 int num_lines = user_input.GetSize();
702 std::string last_function_call;
703
704 // Go through lines of input looking for any function definitions. For each function definition found,
705 // export the function definition to Python, create a potential function call for the function, and
706 // mark the lines of the function to be removed from the user input.
707
708 for (int i = 0; i < num_lines; ++i)
709 {
710 int function_start = i;
711 std::string current_str = user_input.GetStringAtIndex (i);
712 const char *current_line = current_str.c_str();
713 int len = 0;
714 if (current_line)
715 len = strlen (current_line);
716
717 // Check to see if the current line is the start of a Python function definition.
718 if (len > 4 && strncmp (current_line, "def ", 4) == 0)
719 {
720 // We've found the first line of a function. First, get the function name.
721
722 // Skip over the 'def '.
723 char *start = (char *) current_line + 4;
724
725 // Skip over white space.
726 while (start[0] == ' ' || start[0] == '\t')
727 ++start;
728
729 // Find the end of the function name.
730 char *end = start;
731 while (isalnum (end[0]) || end[0] == '_')
732 ++end;
733
734 int name_len = end - start;
735 std::string func_name = current_str.substr (4, name_len);
736
737 // Now to find the last line of the function. That will be the first line that does not begin with
738 // any white space (thanks to Python's indentation rules).
739 ++i;
740 bool found = false;
741 while (i < num_lines && !found)
742 {
743 std::string next_str = user_input.GetStringAtIndex (i);
744 const char *next_line = next_str.c_str();
745 if (next_line[0] != ' ' && next_line[0] != '\t')
746 found = true;
747 else
748 ++i;
749 }
750 if (found)
751 --i; // Make 'i' correspond to the last line of the function.
752 int function_end = i;
753
754 // Special case: All of user_input is one big function definition.
755 if ((function_start == 0) && (function_end == (num_lines - 1)))
756 {
757 ExportFunctionDefinitionToInterpreter (user_input);
758 last_function_call = func_name + " ()";
759 callback_data.AppendString (last_function_call.c_str());
760 return callback_data.GetSize() > 0;
761 }
762 else
763 {
764 // Make a copy of the function definition:
765 StringList new_function;
766 for (int k = function_start; k <= function_end; ++k)
767 {
768 new_function.AppendString (user_input.GetStringAtIndex (k));
769 // Mark the string to be deleted from user_input.
770 user_input.DeleteStringAtIndex (k);
771 user_input.InsertStringAtIndex (k, "<lldb_delete>");
772 }
773 ExportFunctionDefinitionToInterpreter (new_function);
774 last_function_call = func_name + " ()";
775 }
776 }
777 }
778
779 // Now instead of trying to really delete the marked lines from user_input, we will just copy all the
780 // unmarked lines into a new StringList.
781
782 StringList new_user_input;
783
784 for (int i = 0; i < num_lines; ++i)
785 {
786 std::string current_string = user_input.GetStringAtIndex (i);
787 if (current_string.compare (0, 13, "<lldb_delete>") == 0)
788 continue;
789
790 new_user_input.AppendString (current_string.c_str());
791 }
792
793 num_lines = new_user_input.GetSize();
794
795 if (num_lines > 0)
796 {
797 if (num_lines == 1
798 && strchr (new_user_input.GetStringAtIndex(0), '\n') == NULL)
799 {
800 // If there's only one line of input, and it doesn't contain any newline characters....
801 callback_data.AppendString (new_user_input.GetStringAtIndex (0));
802 }
803 else
804 {
805 // Create the new function name.
806 StreamString func_name;
807 func_name.Printf ("lldb_bp_callback_func_%d", num_created_functions);
808 //std::string func_name = "lldb_bp_callback_func_" + num_created_functions;
809 ++num_created_functions;
810
811 // Create the function call for the new function.
812 last_function_call = func_name.GetString() + " ()";
813
814 // Create the Python function definition line (which will have to be inserted at the beginning of
815 // the function).
816 std::string def_line = "def " + func_name.GetString() + " ():";
817
818
819 // Indent all lines an additional four spaces (as they are now being put inside a function definition).
820 for (int i = 0; i < num_lines; ++i)
821 {
822 const char *temp_cstring = new_user_input.GetStringAtIndex(i);
823 std::string temp2 = " ";
824 temp2.append(temp_cstring);
825 new_user_input.DeleteStringAtIndex (i);
826 new_user_input.InsertStringAtIndex (i, temp2.c_str());
827 }
828
829 // Insert the function definition line at the top of the new function.
830 new_user_input.InsertStringAtIndex (0, def_line.c_str());
831
832 ExportFunctionDefinitionToInterpreter (new_user_input);
833 callback_data.AppendString (last_function_call.c_str());
834 }
835 }
836 else
837 {
838 if (!last_function_call.empty())
839 callback_data.AppendString (last_function_call.c_str());
840 }
841
842 return callback_data.GetSize() > 0;
843}
844
845bool
846ScriptInterpreterPython::BreakpointCallbackFunction
847(
848 void *baton,
849 StoppointCallbackContext *context,
850 lldb::user_id_t break_id,
851 lldb::user_id_t break_loc_id
852)
853{
854 bool ret_value = true;
855 bool temp_bool;
856
857 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
858
859 const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
860
861 if (python_string != NULL)
862 {
Greg Clayton63094e02010-06-23 01:19:29 +0000863 bool success = context->exe_ctx.target->GetDebugger().
864 GetCommandInterpreter().
865 GetScriptInterpreter()->ExecuteOneLineWithReturn (python_string,
866 ScriptInterpreter::eBool,
867 (void *) &temp_bool);
Chris Lattner24943d22010-06-08 16:52:24 +0000868 if (success)
869 ret_value = temp_bool;
870 }
871
872 return ret_value;
873}