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