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