blob: aac3dd814d9c3fc6ca056794a3168d1d3a067bfd [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
261void
Greg Clayton63094e02010-06-23 01:19:29 +0000262ScriptInterpreterPython::ExecuteOneLine (CommandInterpreter &interpreter, const char *command)
Chris Lattner24943d22010-06-08 16:52:24 +0000263{
Greg Clayton63094e02010-06-23 01:19:29 +0000264 if (command)
Chris Lattner24943d22010-06-08 16:52:24 +0000265 {
Greg Clayton63094e02010-06-23 01:19:29 +0000266 int success;
267
268 success = PyRun_SimpleString (command);
269 if (success != 0)
270 interpreter.GetDebugger().GetErrorStream().Printf ("error: python failed attempting to evaluate '%s'\n", command);
Chris Lattner24943d22010-06-08 16:52:24 +0000271 }
272}
273
274
275
276size_t
277ScriptInterpreterPython::InputReaderCallback
278(
279 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000280 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000281 lldb::InputReaderAction notification,
282 const char *bytes,
283 size_t bytes_len
284)
285{
286 if (baton == NULL)
287 return 0;
288
Greg Clayton63094e02010-06-23 01:19:29 +0000289 ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
Chris Lattner24943d22010-06-08 16:52:24 +0000290 switch (notification)
291 {
292 case eInputReaderActivate:
293 {
294 // Save terminal settings if we can
Greg Clayton63094e02010-06-23 01:19:29 +0000295 FILE *input_fh = reader.GetDebugger().GetInputFileHandle();
296 int input_fd = ::fileno (input_fh);
297 script_interpreter->m_termios_valid = ::tcgetattr (input_fd, &script_interpreter->m_termios) == 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000298 struct termios tmp_termios;
Greg Clayton63094e02010-06-23 01:19:29 +0000299 if (::tcgetattr (input_fd, &tmp_termios) == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000300 {
301 tmp_termios.c_cc[VEOF] = _POSIX_VDISABLE;
Greg Clayton63094e02010-06-23 01:19:29 +0000302 ::tcsetattr (input_fd, TCSANOW, &tmp_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000303 }
304 }
305 break;
306
307 case eInputReaderDeactivate:
308 break;
309
310 case eInputReaderReactivate:
311 break;
312
313 case eInputReaderGotToken:
314 if (bytes && bytes_len)
315 {
316 if ((int) bytes[0] == 4)
Greg Clayton63094e02010-06-23 01:19:29 +0000317 ::write (script_interpreter->GetMasterFileDescriptor(), "quit()", 6);
Chris Lattner24943d22010-06-08 16:52:24 +0000318 else
Greg Clayton63094e02010-06-23 01:19:29 +0000319 ::write (script_interpreter->GetMasterFileDescriptor(), bytes, bytes_len);
Chris Lattner24943d22010-06-08 16:52:24 +0000320 }
Greg Clayton63094e02010-06-23 01:19:29 +0000321 ::write (script_interpreter->GetMasterFileDescriptor(), "\n", 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000322 break;
323
324 case eInputReaderDone:
325 // Send a control D to the script interpreter
326 //::write (interpreter->GetMasterFileDescriptor(), "\nquit()\n", strlen("\nquit()\n"));
327 // Write a newline out to the reader output
328 //::fwrite ("\n", 1, 1, out_fh);
329 // Restore terminal settings if they were validly saved
Greg Clayton63094e02010-06-23 01:19:29 +0000330 if (script_interpreter->m_termios_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000331 {
Greg Clayton63094e02010-06-23 01:19:29 +0000332 ::tcsetattr (::fileno (reader.GetDebugger().GetInputFileHandle()),
Chris Lattner24943d22010-06-08 16:52:24 +0000333 TCSANOW,
Greg Clayton63094e02010-06-23 01:19:29 +0000334 &script_interpreter->m_termios);
Chris Lattner24943d22010-06-08 16:52:24 +0000335 }
336 break;
337 }
338
339 return bytes_len;
340}
341
342
343void
Greg Clayton63094e02010-06-23 01:19:29 +0000344ScriptInterpreterPython::ExecuteInterpreterLoop (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000345{
346 Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
347
Greg Clayton63094e02010-06-23 01:19:29 +0000348 Debugger &debugger = interpreter.GetDebugger();
349 InputReaderSP reader_sp (new InputReader(debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000350 if (reader_sp)
351 {
352 Error error (reader_sp->Initialize (ScriptInterpreterPython::InputReaderCallback,
353 this, // baton
354 eInputReaderGranularityLine, // token size, to pass to callback function
355 NULL, // end token
356 NULL, // prompt
357 true)); // echo input
358
359 if (error.Success())
360 {
Greg Clayton63094e02010-06-23 01:19:29 +0000361 debugger.PushInputReader (reader_sp);
362 ExecuteOneLine (interpreter, "run_python_interpreter(ConsoleDict)");
363 debugger.PopInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000364 }
365 }
366}
367
368bool
369ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
370 ScriptInterpreter::ReturnType return_type,
371 void *ret_value)
372{
373 PyObject *py_return = NULL;
374 PyObject *mainmod = PyImport_AddModule ("__main__");
375 PyObject *globals = PyModule_GetDict (mainmod);
376 PyObject *locals = globals;
377 PyObject *py_error = NULL;
378 bool ret_success;
379 int success;
380
381 if (in_string != NULL)
382 {
383 py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
384 if (py_return == NULL)
385 {
386 py_error = PyErr_Occurred ();
387 if (py_error != NULL)
388 PyErr_Clear ();
389
390 py_return = PyRun_String (in_string, Py_single_input, globals, locals);
391 }
392
393 if (py_return != NULL)
394 {
395 switch (return_type)
396 {
397 case eCharPtr: // "char *"
398 {
399 const char format[3] = "s#";
400 success = PyArg_Parse (py_return, format, (char **) &ret_value);
401 break;
402 }
403 case eBool:
404 {
405 const char format[2] = "b";
406 success = PyArg_Parse (py_return, format, (bool *) ret_value);
407 break;
408 }
409 case eShortInt:
410 {
411 const char format[2] = "h";
412 success = PyArg_Parse (py_return, format, (short *) ret_value);
413 break;
414 }
415 case eShortIntUnsigned:
416 {
417 const char format[2] = "H";
418 success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
419 break;
420 }
421 case eInt:
422 {
423 const char format[2] = "i";
424 success = PyArg_Parse (py_return, format, (int *) ret_value);
425 break;
426 }
427 case eIntUnsigned:
428 {
429 const char format[2] = "I";
430 success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
431 break;
432 }
433 case eLongInt:
434 {
435 const char format[2] = "l";
436 success = PyArg_Parse (py_return, format, (long *) ret_value);
437 break;
438 }
439 case eLongIntUnsigned:
440 {
441 const char format[2] = "k";
442 success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
443 break;
444 }
445 case eLongLong:
446 {
447 const char format[2] = "L";
448 success = PyArg_Parse (py_return, format, (long long *) ret_value);
449 break;
450 }
451 case eLongLongUnsigned:
452 {
453 const char format[2] = "K";
454 success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
455 break;
456 }
457 case eFloat:
458 {
459 const char format[2] = "f";
460 success = PyArg_Parse (py_return, format, (float *) ret_value);
461 break;
462 }
463 case eDouble:
464 {
465 const char format[2] = "d";
466 success = PyArg_Parse (py_return, format, (double *) ret_value);
467 break;
468 }
469 case eChar:
470 {
471 const char format[2] = "c";
472 success = PyArg_Parse (py_return, format, (char *) ret_value);
473 break;
474 }
475 default:
476 {}
477 }
478 Py_DECREF (py_return);
479 if (success)
480 ret_success = true;
481 else
482 ret_success = false;
483 }
484 }
485
486 py_error = PyErr_Occurred();
487 if (py_error != NULL)
488 {
489 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
490 PyErr_Print ();
491 PyErr_Clear();
492 ret_success = false;
493 }
494
495 return ret_success;
496}
497
498bool
499ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string)
500{
501 bool success = false;
502 PyObject *py_return = NULL;
503 PyObject *mainmod = PyImport_AddModule ("__main__");
504 PyObject *globals = PyModule_GetDict (mainmod);
505 PyObject *locals = globals;
506 PyObject *py_error = NULL;
507
508 if (in_string != NULL)
509 {
510 struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
511 if (compiled_node)
512 {
513 PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
514 if (compiled_code)
515 {
516 py_return = PyEval_EvalCode (compiled_code, globals, locals);
517 if (py_return != NULL)
518 {
519 success = true;
520 Py_DECREF (py_return);
521 }
522 }
523 }
524 }
525
526 py_error = PyErr_Occurred ();
527 if (py_error != NULL)
528 {
529 if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
530 PyErr_Print ();
531 PyErr_Clear();
532 success = false;
533 }
534
535 return success;
536}
537
538static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
539
540size_t
541ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
542(
543 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000544 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000545 lldb::InputReaderAction notification,
546 const char *bytes,
547 size_t bytes_len
548)
549{
550 static StringList commands_in_progress;
551
Greg Clayton63094e02010-06-23 01:19:29 +0000552 FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000553 switch (notification)
554 {
555 case eInputReaderActivate:
556 {
557 commands_in_progress.Clear();
558 if (out_fh)
559 {
560 ::fprintf (out_fh, "%s\n", g_reader_instructions);
Greg Clayton63094e02010-06-23 01:19:29 +0000561 if (reader.GetPrompt())
562 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000563 }
564 }
565 break;
566
567 case eInputReaderDeactivate:
568 break;
569
570 case eInputReaderReactivate:
Greg Clayton63094e02010-06-23 01:19:29 +0000571 if (reader.GetPrompt() && out_fh)
572 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000573 break;
574
575 case eInputReaderGotToken:
576 {
577 std::string temp_string (bytes, bytes_len);
578 commands_in_progress.AppendString (temp_string.c_str());
Greg Clayton63094e02010-06-23 01:19:29 +0000579 if (out_fh && !reader.IsDone() && reader.GetPrompt())
580 ::fprintf (out_fh, "%s", reader.GetPrompt());
Chris Lattner24943d22010-06-08 16:52:24 +0000581 }
582 break;
583
584 case eInputReaderDone:
585 {
586 BreakpointOptions *bp_options = (BreakpointOptions *)baton;
587 std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
588 data_ap->user_source.AppendList (commands_in_progress);
589 if (data_ap.get())
590 {
Greg Clayton63094e02010-06-23 01:19:29 +0000591 ScriptInterpreter *interpreter = reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
Chris Lattner24943d22010-06-08 16:52:24 +0000592 if (interpreter)
593 {
594 if (interpreter->GenerateBreakpointCommandCallbackData (data_ap->user_source,
595 data_ap->script_source))
596 {
597 if (data_ap->script_source.GetSize() == 1)
598 {
599 BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
600 bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
601 }
602 }
603 }
604 else
605 {
606 // FIXME: Error processing.
607 }
608 }
609 }
610 break;
611
612 }
613
614 return bytes_len;
615}
616
617void
Greg Clayton63094e02010-06-23 01:19:29 +0000618ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (CommandInterpreter &interpreter,
619 BreakpointOptions *bp_options,
Chris Lattner24943d22010-06-08 16:52:24 +0000620 CommandReturnObject &result)
621{
Greg Clayton63094e02010-06-23 01:19:29 +0000622 Debugger &debugger = interpreter.GetDebugger();
623 InputReaderSP reader_sp (new InputReader (debugger));
Chris Lattner24943d22010-06-08 16:52:24 +0000624
625 if (reader_sp)
626 {
627 Error err = reader_sp->Initialize (
628 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback,
629 bp_options, // baton
630 eInputReaderGranularityLine, // token size, for feeding data to callback function
631 "DONE", // end token
632 "> ", // prompt
633 true); // echo input
634
635 if (err.Success())
Greg Clayton63094e02010-06-23 01:19:29 +0000636 debugger.PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000637 else
638 {
639 result.AppendError (err.AsCString());
640 result.SetStatus (eReturnStatusFailed);
641 }
642 }
643 else
644 {
645 result.AppendError("out of memory");
646 result.SetStatus (eReturnStatusFailed);
647 }
648}
649
650bool
651ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
652{
653 // Convert StringList to one long, newline delimited, const char *.
654 std::string function_def_string;
655
656 int num_lines = function_def.GetSize();
657
658 for (int i = 0; i < num_lines; ++i)
659 {
660 function_def_string.append (function_def.GetStringAtIndex(i));
661 if (function_def_string.at (function_def_string.length() - 1) != '\n')
662 function_def_string.append ("\n");
663
664 }
665
666 return ExecuteMultipleLines (function_def_string.c_str());
667}
668
669bool
670ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, StringList &callback_data)
671{
672 static int num_created_functions = 0;
673
674 user_input.RemoveBlankLines ();
675 int num_lines = user_input.GetSize();
676 std::string last_function_call;
677
678 // Go through lines of input looking for any function definitions. For each function definition found,
679 // export the function definition to Python, create a potential function call for the function, and
680 // mark the lines of the function to be removed from the user input.
681
682 for (int i = 0; i < num_lines; ++i)
683 {
684 int function_start = i;
685 std::string current_str = user_input.GetStringAtIndex (i);
686 const char *current_line = current_str.c_str();
687 int len = 0;
688 if (current_line)
689 len = strlen (current_line);
690
691 // Check to see if the current line is the start of a Python function definition.
692 if (len > 4 && strncmp (current_line, "def ", 4) == 0)
693 {
694 // We've found the first line of a function. First, get the function name.
695
696 // Skip over the 'def '.
697 char *start = (char *) current_line + 4;
698
699 // Skip over white space.
700 while (start[0] == ' ' || start[0] == '\t')
701 ++start;
702
703 // Find the end of the function name.
704 char *end = start;
705 while (isalnum (end[0]) || end[0] == '_')
706 ++end;
707
708 int name_len = end - start;
709 std::string func_name = current_str.substr (4, name_len);
710
711 // Now to find the last line of the function. That will be the first line that does not begin with
712 // any white space (thanks to Python's indentation rules).
713 ++i;
714 bool found = false;
715 while (i < num_lines && !found)
716 {
717 std::string next_str = user_input.GetStringAtIndex (i);
718 const char *next_line = next_str.c_str();
719 if (next_line[0] != ' ' && next_line[0] != '\t')
720 found = true;
721 else
722 ++i;
723 }
724 if (found)
725 --i; // Make 'i' correspond to the last line of the function.
726 int function_end = i;
727
728 // Special case: All of user_input is one big function definition.
729 if ((function_start == 0) && (function_end == (num_lines - 1)))
730 {
731 ExportFunctionDefinitionToInterpreter (user_input);
732 last_function_call = func_name + " ()";
733 callback_data.AppendString (last_function_call.c_str());
734 return callback_data.GetSize() > 0;
735 }
736 else
737 {
738 // Make a copy of the function definition:
739 StringList new_function;
740 for (int k = function_start; k <= function_end; ++k)
741 {
742 new_function.AppendString (user_input.GetStringAtIndex (k));
743 // Mark the string to be deleted from user_input.
744 user_input.DeleteStringAtIndex (k);
745 user_input.InsertStringAtIndex (k, "<lldb_delete>");
746 }
747 ExportFunctionDefinitionToInterpreter (new_function);
748 last_function_call = func_name + " ()";
749 }
750 }
751 }
752
753 // Now instead of trying to really delete the marked lines from user_input, we will just copy all the
754 // unmarked lines into a new StringList.
755
756 StringList new_user_input;
757
758 for (int i = 0; i < num_lines; ++i)
759 {
760 std::string current_string = user_input.GetStringAtIndex (i);
761 if (current_string.compare (0, 13, "<lldb_delete>") == 0)
762 continue;
763
764 new_user_input.AppendString (current_string.c_str());
765 }
766
767 num_lines = new_user_input.GetSize();
768
769 if (num_lines > 0)
770 {
771 if (num_lines == 1
772 && strchr (new_user_input.GetStringAtIndex(0), '\n') == NULL)
773 {
774 // If there's only one line of input, and it doesn't contain any newline characters....
775 callback_data.AppendString (new_user_input.GetStringAtIndex (0));
776 }
777 else
778 {
779 // Create the new function name.
780 StreamString func_name;
781 func_name.Printf ("lldb_bp_callback_func_%d", num_created_functions);
782 //std::string func_name = "lldb_bp_callback_func_" + num_created_functions;
783 ++num_created_functions;
784
785 // Create the function call for the new function.
786 last_function_call = func_name.GetString() + " ()";
787
788 // Create the Python function definition line (which will have to be inserted at the beginning of
789 // the function).
790 std::string def_line = "def " + func_name.GetString() + " ():";
791
792
793 // Indent all lines an additional four spaces (as they are now being put inside a function definition).
794 for (int i = 0; i < num_lines; ++i)
795 {
796 const char *temp_cstring = new_user_input.GetStringAtIndex(i);
797 std::string temp2 = " ";
798 temp2.append(temp_cstring);
799 new_user_input.DeleteStringAtIndex (i);
800 new_user_input.InsertStringAtIndex (i, temp2.c_str());
801 }
802
803 // Insert the function definition line at the top of the new function.
804 new_user_input.InsertStringAtIndex (0, def_line.c_str());
805
806 ExportFunctionDefinitionToInterpreter (new_user_input);
807 callback_data.AppendString (last_function_call.c_str());
808 }
809 }
810 else
811 {
812 if (!last_function_call.empty())
813 callback_data.AppendString (last_function_call.c_str());
814 }
815
816 return callback_data.GetSize() > 0;
817}
818
819bool
820ScriptInterpreterPython::BreakpointCallbackFunction
821(
822 void *baton,
823 StoppointCallbackContext *context,
824 lldb::user_id_t break_id,
825 lldb::user_id_t break_loc_id
826)
827{
828 bool ret_value = true;
829 bool temp_bool;
830
831 BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
832
833 const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
834
835 if (python_string != NULL)
836 {
Greg Clayton63094e02010-06-23 01:19:29 +0000837 bool success = context->exe_ctx.target->GetDebugger().
838 GetCommandInterpreter().
839 GetScriptInterpreter()->ExecuteOneLineWithReturn (python_string,
840 ScriptInterpreter::eBool,
841 (void *) &temp_bool);
Chris Lattner24943d22010-06-08 16:52:24 +0000842 if (success)
843 ret_value = temp_bool;
844 }
845
846 return ret_value;
847}