Add SWIG Python interface files for SBDebugger, SBCompileUnit, and SBEvent.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@135432 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/scripts/Python/interface/SBCompileUnit.i b/scripts/Python/interface/SBCompileUnit.i
new file mode 100644
index 0000000..8a2e885
--- /dev/null
+++ b/scripts/Python/interface/SBCompileUnit.i
@@ -0,0 +1,70 @@
+//===-- SWIG Interface for SBCompileUnit ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"Represents a compilation unit, or compiled source file.
+
+SBCompileUnit supports line entry iteration. For example,
+
+    for lineEntry in compileUnit:
+        print 'line entry: %s:%d' % (str(lineEntry.GetFileSpec()),
+                                    lineEntry.GetLine())
+        print 'start addr: %s' % str(lineEntry.GetStartAddress())
+        print 'end   addr: %s' % str(lineEntry.GetEndAddress())
+
+produces:
+
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:20
+start addr: a.out[0x100000d98]
+end   addr: a.out[0x100000da3]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:21
+start addr: a.out[0x100000da3]
+end   addr: a.out[0x100000da9]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:22
+start addr: a.out[0x100000da9]
+end   addr: a.out[0x100000db6]
+line entry: /Volumes/data/lldb/svn/trunk/test/python_api/symbol-context/main.c:23
+start addr: a.out[0x100000db6]
+end   addr: a.out[0x100000dbc]
+...
+") SBCompileUnit;
+class SBCompileUnit
+{
+public:
+
+    SBCompileUnit ();
+
+    SBCompileUnit (const lldb::SBCompileUnit &rhs);
+
+    ~SBCompileUnit ();
+
+    bool
+    IsValid () const;
+
+    lldb::SBFileSpec
+    GetFileSpec () const;
+
+    uint32_t
+    GetNumLineEntries () const;
+
+    lldb::SBLineEntry
+    GetLineEntryAtIndex (uint32_t idx) const;
+
+    uint32_t
+    FindLineEntryIndex (uint32_t start_idx,
+                        uint32_t line,
+                        lldb::SBFileSpec *inline_file_spec) const;
+
+    bool
+    GetDescription (lldb::SBStream &description);
+};
+
+} // namespace lldb
diff --git a/scripts/Python/interface/SBDebugger.i b/scripts/Python/interface/SBDebugger.i
new file mode 100644
index 0000000..4339572
--- /dev/null
+++ b/scripts/Python/interface/SBDebugger.i
@@ -0,0 +1,310 @@
+//===-- SWIG Interface for SBDebugger ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"SBDebugger is the primordial object that creates SBTargets and provides
+access to them.  It also manages the overall debugging experiences.
+
+For example (from example/disasm.py),
+
+import lldb
+import os
+import sys
+
+def disassemble_instructions (insts):
+    for i in insts:
+        print i
+
+...
+
+# Create a new debugger instance
+debugger = lldb.SBDebugger.Create()
+
+# When we step or continue, don't return from the function until the process 
+# stops. We do this by setting the async mode to false.
+debugger.SetAsync (False)
+
+# Create a target from a file and arch
+print 'Creating a target for \'%s\'' % exe
+
+target = debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT)
+
+if target:
+    # If the target is valid set a breakpoint at main
+    main_bp = target.BreakpointCreateByName (fname, target.GetExecutable().GetFilename());
+
+    print main_bp
+
+    # Launch the process. Since we specified synchronous mode, we won't return
+    # from this function until we hit the breakpoint at main
+    process = target.LaunchSimple (None, None, os.getcwd())
+    
+    # Make sure the launch went ok
+    if process:
+        # Print some simple process info
+        state = process.GetState ()
+        print process
+        if state == lldb.eStateStopped:
+            # Get the first thread
+            thread = process.GetThreadAtIndex (0)
+            if thread:
+                # Print some simple thread info
+                print thread
+                # Get the first frame
+                frame = thread.GetFrameAtIndex (0)
+                if frame:
+                    # Print some simple frame info
+                    print frame
+                    function = frame.GetFunction()
+                    # See if we have debug info (a function)
+                    if function:
+                        # We do have a function, print some info for the function
+                        print function
+                        # Now get all instructions for this function and print them
+                        insts = function.GetInstructions(target)
+                        disassemble_instructions (insts)
+                    else:
+                        # See if we have a symbol in the symbol table for where we stopped
+                        symbol = frame.GetSymbol();
+                        if symbol:
+                            # We do have a symbol, print some info for the symbol
+                            print symbol
+                            # Now get all instructions for this symbol and print them
+                            insts = symbol.GetInstructions(target)
+                            disassemble_instructions (insts)
+
+                    registerList = frame.GetRegisters()
+                    print 'Frame registers (size of register set = %d):' % registerList.GetSize()
+                    for value in registerList:
+                        #print value
+                        print '%s (number of children = %d):' % (value.GetName(), value.GetNumChildren())
+                        for child in value:
+                            print 'Name: ', child.GetName(), ' Value: ', child.GetValue(frame)
+
+            print 'Hit the breakpoint at main, enter to continue and wait for program to exit or \'Ctrl-D\'/\'quit\' to terminate the program'
+            next = sys.stdin.readline()
+            if not next or next.rstrip('\n') == 'quit':
+                print 'Terminating the inferior process...'
+                process.Kill()
+            else:
+                # Now continue to the program exit
+                process.Continue()
+                # When we return from the above function we will hopefully be at the
+                # program exit. Print out some process info
+                print process
+        elif state == lldb.eStateExited:
+            print 'Didn\'t hit the breakpoint at main, program has exited...'
+        else:
+            print 'Unexpected process state: %s, killing process...' % debugger.StateAsCString (state)
+            process.Kill()
+") SBDebugger;
+class SBDebugger
+{
+public:
+
+    static void
+    Initialize();
+    
+    static void
+    Terminate();
+    
+    static lldb::SBDebugger
+    Create();
+
+    static void
+    Destroy (lldb::SBDebugger &debugger);
+
+    SBDebugger();
+
+    SBDebugger(const lldb::SBDebugger &rhs);
+
+    ~SBDebugger();
+
+    bool
+    IsValid() const;
+
+    void
+    Clear ();
+
+    void
+    SetAsync (bool b);
+
+    void
+    SkipLLDBInitFiles (bool b);
+
+    void
+    SetInputFileHandle (FILE *f, bool transfer_ownership);
+
+    void
+    SetOutputFileHandle (FILE *f, bool transfer_ownership);
+
+    void
+    SetErrorFileHandle (FILE *f, bool transfer_ownership);
+
+    FILE *
+    GetInputFileHandle ();
+
+    FILE *
+    GetOutputFileHandle ();
+
+    FILE *
+    GetErrorFileHandle ();
+
+    lldb::SBCommandInterpreter
+    GetCommandInterpreter ();
+
+    void
+    HandleCommand (const char *command);
+
+    lldb::SBListener
+    GetListener ();
+
+    void
+    HandleProcessEvent (const lldb::SBProcess &process,
+                        const lldb::SBEvent &event,
+                        FILE *out,
+                        FILE *err);
+
+    lldb::SBTarget
+    CreateTargetWithFileAndTargetTriple (const char *filename,
+                                         const char *target_triple);
+
+    lldb::SBTarget
+    CreateTargetWithFileAndArch (const char *filename,
+                                 const char *archname);
+
+    lldb::SBTarget
+    CreateTarget (const char *filename);
+
+    %feature("docstring",
+    "Return true if target is deleted from the target list of the debugger."
+    ) DeleteTarget;
+    bool
+    DeleteTarget (lldb::SBTarget &target);
+
+    lldb::SBTarget
+    GetTargetAtIndex (uint32_t idx);
+
+    lldb::SBTarget
+    FindTargetWithProcessID (pid_t pid);
+
+    lldb::SBTarget
+    FindTargetWithFileAndArch (const char *filename,
+                               const char *arch);
+
+    uint32_t
+    GetNumTargets ();
+
+    lldb::SBTarget
+    GetSelectedTarget ();
+
+    lldb::SBSourceManager &
+    GetSourceManager ();
+
+    // REMOVE: just for a quick fix, need to expose platforms through
+    // SBPlatform from this class.
+    lldb::SBError
+    SetCurrentPlatform (const char *platform_name);
+    
+    bool
+    SetCurrentPlatformSDKRoot (const char *sysroot);
+
+    // FIXME: Once we get the set show stuff in place, the driver won't need
+    // an interface to the Set/Get UseExternalEditor.
+    bool
+    SetUseExternalEditor (bool input);
+    
+    bool 
+    GetUseExternalEditor ();
+
+    static bool
+    GetDefaultArchitecture (char *arch_name, size_t arch_name_len);
+
+    static bool
+    SetDefaultArchitecture (const char *arch_name);
+
+    lldb::ScriptLanguage
+    GetScriptingLanguage (const char *script_language_name);
+
+    static const char *
+    GetVersionString ();
+
+    static const char *
+    StateAsCString (lldb::StateType state);
+
+    static bool
+    StateIsRunningState (lldb::StateType state);
+
+    static bool
+    StateIsStoppedState (lldb::StateType state);
+
+    void
+    DispatchInput (void *baton, const void *data, size_t data_len);
+
+    void
+    DispatchInputInterrupt ();
+
+    void
+    DispatchInputEndOfFile ();
+    
+    void
+    PushInputReader (lldb::SBInputReader &reader);
+
+    void
+    NotifyTopInputReader (lldb::InputReaderAction notification);
+
+    bool
+    InputReaderIsTopReader (const lldb::SBInputReader &reader);
+
+    const char *
+    GetInstanceName  ();
+
+    static SBDebugger
+    FindDebuggerWithID (int id);
+
+    static lldb::SBError
+    SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name);
+
+    static lldb::SBStringList
+    GetInternalVariableValue (const char *var_name, const char *debugger_instance_name);
+
+    bool
+    GetDescription (lldb::SBStream &description);
+
+    uint32_t
+    GetTerminalWidth () const;
+
+    void
+    SetTerminalWidth (uint32_t term_width);
+
+    lldb::user_id_t
+    GetID ();
+    
+    const char *
+    GetPrompt() const;
+
+    void
+    SetPrompt (const char *prompt);
+        
+    lldb::ScriptLanguage 
+    GetScriptLanguage() const;
+
+    void
+    SetScriptLanguage (lldb::ScriptLanguage script_lang);
+
+    bool
+    GetCloseInputOnEOF () const;
+    
+    void
+    SetCloseInputOnEOF (bool b);
+}; // class SBDebugger
+
+} // namespace lldb
diff --git a/scripts/Python/interface/SBEvent.i b/scripts/Python/interface/SBEvent.i
new file mode 100644
index 0000000..66963ea
--- /dev/null
+++ b/scripts/Python/interface/SBEvent.i
@@ -0,0 +1,150 @@
+//===-- SWIG Interface for SBEvent ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class SBBroadcaster;
+
+%feature("docstring",
+"API clients can register to receive events.
+
+For example, check out the following output:
+
+Try wait for event...
+Event description: 0x103d0bb70 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = running}
+Event data flavor: Process::ProcessEventData
+Process state: running
+
+Try wait for event...
+Event description: 0x103a700a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = stopped}
+Event data flavor: Process::ProcessEventData
+Process state: stopped
+
+Try wait for event...
+Event description: 0x103d0d4a0 Event: broadcaster = 0x1009c8410, type = 0x00000001, data = { process = 0x1009c8400 (pid = 21528), state = exited}
+Event data flavor: Process::ProcessEventData
+Process state: exited
+
+Try wait for event...
+timeout occurred waiting for event...
+
+from test/python_api/event/TestEventspy:
+
+    def do_listen_for_and_print_event(self):
+        '''Create a listener and use SBEvent API to print the events received.'''
+        exe = os.path.join(os.getcwd(), 'a.out')
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # Now create a breakpoint on main.c by name 'c'.
+        breakpoint = target.BreakpointCreateByName('c', 'a.out')
+
+        # Now launch the process, and do not stop at the entry point.
+        process = target.LaunchSimple(None, None, os.getcwd())
+        self.assertTrue(process.GetState() == lldb.eStateStopped,
+                        PROCESS_STOPPED)
+
+        # Get a handle on the process's broadcaster.
+        broadcaster = process.GetBroadcaster()
+
+        # Create an empty event object.
+        event = lldb.SBEvent()
+
+        # Create a listener object and register with the broadcaster.
+        listener = lldb.SBListener('my listener')
+        rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
+        self.assertTrue(rc, 'AddListener successfully retruns')
+
+        traceOn = self.TraceOn()
+        if traceOn:
+            lldbutil.print_stacktraces(process)
+
+        # Create MyListeningThread class to wait for any kind of event.
+        import threading
+        class MyListeningThread(threading.Thread):
+            def run(self):
+                count = 0
+                # Let's only try at most 4 times to retrieve any kind of event.
+                # After that, the thread exits.
+                while not count > 3:
+                    if traceOn:
+                        print 'Try wait for event...'
+                    if listener.WaitForEventForBroadcasterWithType(5,
+                                                                   broadcaster,
+                                                                   lldb.SBProcess.eBroadcastBitStateChanged,
+                                                                   event):
+                        if traceOn:
+                            desc = lldbutil.get_description(event)
+                            print 'Event description:', desc
+                            print 'Event data flavor:', event.GetDataFlavor()
+                            print 'Process state:', lldbutil.state_type_to_str(process.GetState())
+                            print
+                    else:
+                        if traceOn:
+                            print 'timeout occurred waiting for event...'
+                    count = count + 1
+                return
+
+        # Let's start the listening thread to retrieve the events.
+        my_thread = MyListeningThread()
+        my_thread.start()
+
+        # Use Python API to continue the process.  The listening thread should be
+        # able to receive the state changed events.
+        process.Continue()
+
+        # Use Python API to kill the process.  The listening thread should be
+        # able to receive the state changed event, too.
+        process.Kill()
+
+        # Wait until the 'MyListeningThread' terminates.
+        my_thread.join()
+") SBEvent;
+class SBEvent
+{
+public:
+    SBEvent();
+
+    SBEvent (const lldb::SBEvent &rhs);
+    
+    %feature("autodoc",
+    "__init__(self, int type, str data) -> SBEvent (make an event that contains a C string)"
+    ) SBEvent;
+    SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len);
+
+    ~SBEvent();
+
+    bool
+    IsValid() const;
+
+    const char *
+    GetDataFlavor ();
+
+    uint32_t
+    GetType () const;
+
+    lldb::SBBroadcaster
+    GetBroadcaster () const;
+
+    bool
+    BroadcasterMatchesRef (const lldb::SBBroadcaster &broadcaster);
+
+    void
+    Clear();
+
+    static const char *
+    GetCStringFromEvent (const lldb::SBEvent &event);
+
+    bool
+    GetDescription (lldb::SBStream &description) const;
+};
+
+} // namespace lldb