forked from OSchip/llvm-project
Merging the iohandler branch back into main.
The many many benefits include: 1 - Input/Output/Error streams are now handled as real streams not a push style input 2 - auto completion in python embedded interpreter 3 - multi-line input for "script" and "expression" commands now allow you to edit previous/next lines using up and down arrow keys and this makes multi-line input actually a viable thing to use 4 - it is now possible to use curses to drive LLDB (please try the "gui" command) We will need to deal with and fix any buildbot failures and tests and arise now that input/output and error are correctly hooked up in all cases. llvm-svn: 200263
This commit is contained in:
parent
f1cb16e481
commit
44d937820b
|
@ -254,7 +254,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
|||
find_library(DEBUG_SYMBOLS_LIBRARY DebugSymbols PATHS "/System/Library/PrivateFrameworks")
|
||||
|
||||
set(LIBXML2_INCLUDE_DIR "/usr/include/libxml2")
|
||||
list(APPEND system_libs xml2)
|
||||
list(APPEND system_libs xml2 ncurses panel)
|
||||
list(APPEND system_libs ${CARBON_LIBRARY} ${FOUNDATION_LIBRARY}
|
||||
${CORE_FOUNDATION_LIBRARY} ${CORE_SERVICES_LIBRARY} ${SECURITY_LIBRARY}
|
||||
${DEBUG_SYMBOLS_LIBRARY})
|
||||
|
@ -262,7 +262,11 @@ endif()
|
|||
|
||||
# On FreeBSD, link libexecinfo because libc is missing backtrace()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
list(APPEND system_libs execinfo)
|
||||
list(APPEND system_libs execinfo ncurses panel)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
list(APPEND system_libs ncurses panel)
|
||||
endif()
|
||||
|
||||
#add_subdirectory(include)
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBHostOS.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBInstruction.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
#include "lldb/API/SBLineEntry.h"
|
||||
|
|
|
@ -122,6 +122,36 @@ public:
|
|||
|
||||
SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL); // Access using SBDebugger::GetCommandInterpreter();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Return true if the command interpreter is the active IO handler.
|
||||
///
|
||||
/// This indicates that any input coming into the debugger handles will
|
||||
/// go to the command interpreter and will result in LLDB command line
|
||||
/// commands being executed.
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
IsActive ();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Get the string that needs to be written to the debugger stdin file
|
||||
/// handle when a control character is typed.
|
||||
///
|
||||
/// Some GUI programs will intercept "control + char" sequences and want
|
||||
/// to have them do what normally would happen when using a real
|
||||
/// terminal, so this function allows GUI programs to emulate this
|
||||
/// functionality.
|
||||
///
|
||||
/// @param[in] ch
|
||||
/// The character that was typed along with the control key
|
||||
///
|
||||
/// @return
|
||||
/// The string that should be written into the file handle that is
|
||||
/// feeding the input stream for the debugger, or NULL if there is
|
||||
/// no string for this control key.
|
||||
//----------------------------------------------------------------------
|
||||
const char *
|
||||
GetIOHandlerControlSequence(char ch);
|
||||
|
||||
protected:
|
||||
|
||||
lldb_private::CommandInterpreter &
|
||||
|
|
|
@ -17,6 +17,16 @@
|
|||
|
||||
namespace lldb {
|
||||
|
||||
|
||||
class SBInputReader
|
||||
{
|
||||
public:
|
||||
SBInputReader();
|
||||
~SBInputReader();
|
||||
SBError Initialize(lldb::SBDebugger&, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool);
|
||||
void SetIsDone(bool);
|
||||
bool IsActive() const;
|
||||
};
|
||||
class SBDebugger
|
||||
{
|
||||
public:
|
||||
|
@ -231,12 +241,6 @@ public:
|
|||
void
|
||||
PushInputReader (lldb::SBInputReader &reader);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::SBInputReader &reader);
|
||||
|
||||
const char *
|
||||
GetInstanceName ();
|
||||
|
||||
|
@ -313,6 +317,10 @@ public:
|
|||
GetSyntheticForType (SBTypeNameSpecifier);
|
||||
#endif
|
||||
|
||||
void
|
||||
RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread);
|
||||
|
||||
private:
|
||||
|
||||
friend class SBCommandInterpreter;
|
||||
|
|
|
@ -48,7 +48,6 @@ class SBFileSpecList;
|
|||
class SBFrame;
|
||||
class SBFunction;
|
||||
class SBHostOS;
|
||||
class SBInputReader;
|
||||
class SBInstruction;
|
||||
class SBInstructionList;
|
||||
class SBLineEntry;
|
||||
|
|
|
@ -71,7 +71,6 @@ protected:
|
|||
friend class SBDebugger;
|
||||
friend class SBCommunication;
|
||||
friend class SBHostOS;
|
||||
friend class SBInputReader;
|
||||
friend class SBPlatform;
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
//===-- SBInputReader.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBInputReader_h_
|
||||
#define LLDB_SBInputReader_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBInputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
SBInputReader *reader,
|
||||
InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
SBInputReader ();
|
||||
|
||||
SBInputReader (const lldb::InputReaderSP &reader_sp);
|
||||
|
||||
SBInputReader (const lldb::SBInputReader &rhs);
|
||||
|
||||
~SBInputReader ();
|
||||
|
||||
|
||||
SBError
|
||||
Initialize (SBDebugger &debugger,
|
||||
Callback callback,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
const lldb::SBInputReader &
|
||||
operator = (const lldb::SBInputReader &rhs);
|
||||
|
||||
bool
|
||||
IsActive () const;
|
||||
|
||||
bool
|
||||
IsDone () const;
|
||||
|
||||
void
|
||||
SetIsDone (bool value);
|
||||
|
||||
InputReaderGranularity
|
||||
GetGranularity ();
|
||||
|
||||
protected:
|
||||
friend class SBDebugger;
|
||||
|
||||
lldb_private::InputReader *
|
||||
operator->() const;
|
||||
|
||||
lldb::InputReaderSP &
|
||||
operator *();
|
||||
|
||||
const lldb::InputReaderSP &
|
||||
operator *() const;
|
||||
|
||||
lldb_private::InputReader *
|
||||
get() const;
|
||||
|
||||
lldb_private::InputReader &
|
||||
ref() const;
|
||||
|
||||
private:
|
||||
|
||||
static size_t
|
||||
PrivateCallback (void *baton,
|
||||
lldb_private::InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
lldb::InputReaderSP m_opaque_sp;
|
||||
Callback m_callback_function;
|
||||
void *m_callback_baton;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBInputReader_h_
|
|
@ -19,9 +19,8 @@
|
|||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/Communication.h"
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/Listener.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/SourceManager.h"
|
||||
#include "lldb/Core/UserID.h"
|
||||
#include "lldb/Core/UserSettingsController.h"
|
||||
|
@ -91,23 +90,25 @@ public:
|
|||
void
|
||||
SetAsyncExecution (bool async);
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetInputFile ()
|
||||
{
|
||||
return m_input_file.GetFile();
|
||||
return m_input_file_sp;
|
||||
}
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetOutputFile ()
|
||||
{
|
||||
return m_output_file.GetFile();
|
||||
return m_output_file_sp;
|
||||
}
|
||||
|
||||
File &
|
||||
lldb::StreamFileSP
|
||||
GetErrorFile ()
|
||||
{
|
||||
return m_error_file.GetFile();
|
||||
return m_error_file_sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SetInputFileHandle (FILE *fh, bool tranfer_ownership);
|
||||
|
@ -124,18 +125,6 @@ public:
|
|||
void
|
||||
RestoreInputTerminalState();
|
||||
|
||||
Stream&
|
||||
GetOutputStream ()
|
||||
{
|
||||
return m_output_file;
|
||||
}
|
||||
|
||||
Stream&
|
||||
GetErrorStream ()
|
||||
{
|
||||
return m_error_file;
|
||||
}
|
||||
|
||||
lldb::StreamSP
|
||||
GetAsyncOutputStream ();
|
||||
|
||||
|
@ -200,24 +189,38 @@ public:
|
|||
void
|
||||
DispatchInputEndOfFile ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// If any of the streams are not set, set them to the in/out/err
|
||||
// stream of the top most input reader to ensure they at least have
|
||||
// something
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
DispatchInput (const char *bytes, size_t bytes_len);
|
||||
AdoptTopIOHandlerFilesIfInvalid (lldb::StreamFileSP &in,
|
||||
lldb::StreamFileSP &out,
|
||||
lldb::StreamFileSP &err);
|
||||
|
||||
void
|
||||
WriteToDefaultReader (const char *bytes, size_t bytes_len);
|
||||
|
||||
void
|
||||
PushInputReader (const lldb::InputReaderSP& reader_sp);
|
||||
PushIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
bool
|
||||
PopInputReader (const lldb::InputReaderSP& reader_sp);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp);
|
||||
PopIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
// Synchronously run an input reader until it is done
|
||||
void
|
||||
RunIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
bool
|
||||
IsTopIOHandler (const lldb::IOHandlerSP& reader_sp);
|
||||
|
||||
ConstString
|
||||
GetTopIOHandlerControlSequence(char ch);
|
||||
|
||||
bool
|
||||
HideTopIOHandler();
|
||||
|
||||
void
|
||||
RefreshTopIOHandler();
|
||||
|
||||
static lldb::DebuggerSP
|
||||
FindDebuggerWithID (lldb::user_id_t id);
|
||||
|
||||
|
@ -240,7 +243,7 @@ public:
|
|||
|
||||
|
||||
void
|
||||
CleanUpInputReaders ();
|
||||
ClearIOHandlers ();
|
||||
|
||||
static int
|
||||
TestDebuggerRefCount ();
|
||||
|
@ -338,29 +341,65 @@ public:
|
|||
bool
|
||||
LoadPlugin (const FileSpec& spec, Error& error);
|
||||
|
||||
void
|
||||
ExecuteIOHanders();
|
||||
|
||||
bool
|
||||
IsForwardingEvents ();
|
||||
|
||||
void
|
||||
EnableForwardEvents (const lldb::ListenerSP &listener_sp);
|
||||
|
||||
void
|
||||
CancelForwardEvents (const lldb::ListenerSP &listener_sp);
|
||||
protected:
|
||||
|
||||
static void
|
||||
DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len);
|
||||
|
||||
lldb::InputReaderSP
|
||||
GetCurrentInputReader ();
|
||||
|
||||
void
|
||||
ActivateInputReader (const lldb::InputReaderSP &reader_sp);
|
||||
friend class CommandInterpreter;
|
||||
|
||||
bool
|
||||
CheckIfTopInputReaderIsDone ();
|
||||
StartEventHandlerThread();
|
||||
|
||||
void
|
||||
StopEventHandlerThread();
|
||||
|
||||
static lldb::thread_result_t
|
||||
EventHandlerThread (lldb::thread_arg_t arg);
|
||||
|
||||
bool
|
||||
StartIOHandlerThread();
|
||||
|
||||
void
|
||||
StopIOHandlerThread();
|
||||
|
||||
static lldb::thread_result_t
|
||||
IOHandlerThread (lldb::thread_arg_t arg);
|
||||
|
||||
void
|
||||
DefaultEventHandler();
|
||||
|
||||
void
|
||||
HandleBreakpointEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
void
|
||||
HandleProcessEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
void
|
||||
HandleThreadEvent (const lldb::EventSP &event_sp);
|
||||
|
||||
size_t
|
||||
GetProcessSTDOUT (Process *process, Stream *stream);
|
||||
|
||||
size_t
|
||||
GetProcessSTDERR (Process *process, Stream *stream);
|
||||
|
||||
SourceManager::SourceFileCache &
|
||||
GetSourceFileCache ()
|
||||
{
|
||||
return m_source_file_cache;
|
||||
}
|
||||
Communication m_input_comm;
|
||||
StreamFile m_input_file;
|
||||
StreamFile m_output_file;
|
||||
StreamFile m_error_file;
|
||||
lldb::StreamFileSP m_input_file_sp;
|
||||
lldb::StreamFileSP m_output_file_sp;
|
||||
lldb::StreamFileSP m_error_file_sp;
|
||||
TerminalState m_terminal_state;
|
||||
TargetList m_target_list;
|
||||
PlatformList m_platform_list;
|
||||
|
@ -370,8 +409,7 @@ protected:
|
|||
// source file cache.
|
||||
std::unique_ptr<CommandInterpreter> m_command_interpreter_ap;
|
||||
|
||||
InputReaderStack m_input_reader_stack;
|
||||
std::string m_input_reader_data;
|
||||
IOHandlerStack m_input_reader_stack;
|
||||
typedef std::map<std::string, lldb::StreamWP> LogStreamMap;
|
||||
LogStreamMap m_log_streams;
|
||||
lldb::StreamSP m_log_callback_stream_sp;
|
||||
|
@ -379,7 +417,10 @@ protected:
|
|||
static LoadPluginCallbackType g_load_plugin_callback;
|
||||
typedef std::vector<lldb::DynamicLibrarySP> LoadedPluginsList;
|
||||
LoadedPluginsList m_loaded_plugins;
|
||||
|
||||
lldb::thread_t m_event_handler_thread;
|
||||
lldb::thread_t m_io_handler_thread;
|
||||
lldb::ListenerSP m_forward_listener_sp;
|
||||
bool m_event_handler_thread_alive;
|
||||
void
|
||||
InstanceInitialize ();
|
||||
|
||||
|
|
|
@ -175,6 +175,9 @@ public:
|
|||
uint32_t
|
||||
GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target);
|
||||
|
||||
uint32_t
|
||||
GetIndexOfInstructionAtAddress (const Address &addr);
|
||||
|
||||
void
|
||||
Clear();
|
||||
|
||||
|
|
|
@ -0,0 +1,611 @@
|
|||
//===-- IOHandler.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_IOHandler_h_
|
||||
#define liblldb_IOHandler_h_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Core/ValueObjectList.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace curses
|
||||
{
|
||||
class Application;
|
||||
typedef std::unique_ptr<Application> ApplicationAP;
|
||||
}
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandler (Debugger &debugger);
|
||||
|
||||
IOHandler (Debugger &debugger,
|
||||
const lldb::StreamFileSP &input_sp,
|
||||
const lldb::StreamFileSP &output_sp,
|
||||
const lldb::StreamFileSP &error_sp);
|
||||
|
||||
virtual
|
||||
~IOHandler ();
|
||||
|
||||
// Each IOHandler gets to run until it is done. It should read data
|
||||
// from the "in" and place output into "out" and "err and return
|
||||
// when done.
|
||||
virtual void
|
||||
Run () = 0;
|
||||
|
||||
// Hide any characters that have been displayed so far so async
|
||||
// output can be displayed. Refresh() will be called after the
|
||||
// output has been displayed.
|
||||
virtual void
|
||||
Hide () = 0;
|
||||
|
||||
// Called when the async output has been received in order to update
|
||||
// the input reader (refresh the prompt and redisplay any current
|
||||
// line(s) that are being edited
|
||||
virtual void
|
||||
Refresh () = 0;
|
||||
|
||||
virtual void
|
||||
Interrupt () = 0;
|
||||
|
||||
virtual void
|
||||
GotEOF() = 0;
|
||||
|
||||
virtual bool
|
||||
IsActive ()
|
||||
{
|
||||
return m_active && !m_done;
|
||||
}
|
||||
|
||||
virtual void
|
||||
SetIsDone (bool b)
|
||||
{
|
||||
m_done = b;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetIsDone ()
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
virtual void
|
||||
Activate ()
|
||||
{
|
||||
m_active = true;
|
||||
}
|
||||
|
||||
virtual void
|
||||
Deactivate ()
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetPrompt ()
|
||||
{
|
||||
// Prompt support isn't mandatory
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
SetPrompt (const char *prompt)
|
||||
{
|
||||
// Prompt support isn't mandatory
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
int
|
||||
GetInputFD();
|
||||
|
||||
int
|
||||
GetOutputFD();
|
||||
|
||||
int
|
||||
GetErrorFD();
|
||||
|
||||
FILE *
|
||||
GetInputFILE();
|
||||
|
||||
FILE *
|
||||
GetOutputFILE();
|
||||
|
||||
FILE *
|
||||
GetErrorFILE();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetInputStreamFile();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetOutputStreamFile();
|
||||
|
||||
lldb::StreamFileSP &
|
||||
GetErrorStreamFile();
|
||||
|
||||
Debugger &
|
||||
GetDebugger()
|
||||
{
|
||||
return m_debugger;
|
||||
}
|
||||
|
||||
void *
|
||||
GetUserData ()
|
||||
{
|
||||
return m_user_data;
|
||||
}
|
||||
|
||||
void
|
||||
SetUserData (void *user_data)
|
||||
{
|
||||
m_user_data = user_data;
|
||||
}
|
||||
|
||||
protected:
|
||||
Debugger &m_debugger;
|
||||
lldb::StreamFileSP m_input_sp;
|
||||
lldb::StreamFileSP m_output_sp;
|
||||
lldb::StreamFileSP m_error_sp;
|
||||
void *m_user_data;
|
||||
bool m_done;
|
||||
bool m_active;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (IOHandler);
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// A delegate class for use with IOHandler subclasses.
|
||||
///
|
||||
/// The IOHandler delegate is designed to be mixed into classes so
|
||||
/// they can use an IOHandler subclass to fetch input and notify the
|
||||
/// object that inherits from this delegate class when a token is
|
||||
/// received.
|
||||
//------------------------------------------------------------------
|
||||
class IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
enum class Completion {
|
||||
None,
|
||||
LLDBCommand,
|
||||
Expression
|
||||
};
|
||||
|
||||
IOHandlerDelegate (Completion completion = Completion::None) :
|
||||
m_completion(completion),
|
||||
m_io_handler_done (false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~IOHandlerDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual int
|
||||
IOHandlerComplete (IOHandler &io_handler,
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called when a line or lines have been retrieved.
|
||||
///
|
||||
/// This funtion can handle the current line and possibly call
|
||||
/// IOHandler::SetIsDone(true) when the IO handler is done like when
|
||||
/// "quit" is entered as a command, of when an empty line is
|
||||
/// received. It is up to the delegate to determine when a line
|
||||
/// should cause a IOHandler to exit.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Called when a line in \a lines has been updated when doing
|
||||
/// multi-line input.
|
||||
///
|
||||
/// @return
|
||||
/// Return an enumeration to indicate the status of the current
|
||||
/// line:
|
||||
/// Success - The line is good and should be added to the
|
||||
/// multiple lines
|
||||
/// Error - There is an error with the current line and it
|
||||
/// need to be re-edited before it is acceptable
|
||||
/// Done - The lines collection is complete and ready to be
|
||||
/// returned.
|
||||
//------------------------------------------------------------------
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
return LineStatus::Done; // Stop getting lines on the first line that is updated
|
||||
// subclasses should do something more intelligent here.
|
||||
// This function will not be called on IOHandler objects
|
||||
// that are getting single lines.
|
||||
}
|
||||
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
protected:
|
||||
Completion m_completion; // Support for common builtin completions
|
||||
bool m_io_handler_done;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// IOHandlerDelegateMultiline
|
||||
//
|
||||
// A IOHandlerDelegate that handles terminating multi-line input when
|
||||
// the last line is equal to "end_line" which is specified in the
|
||||
// constructor.
|
||||
//----------------------------------------------------------------------
|
||||
class IOHandlerDelegateMultiline :
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
IOHandlerDelegateMultiline (const char *end_line,
|
||||
Completion completion = Completion::None) :
|
||||
IOHandlerDelegate (completion),
|
||||
m_end_line((end_line && end_line[0]) ? end_line : "")
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~IOHandlerDelegateMultiline ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
if (ch == 'd')
|
||||
return ConstString (m_end_line + "\n");
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
if (line_idx == UINT32_MAX)
|
||||
{
|
||||
// Remove the last empty line from "lines" so it doesn't appear
|
||||
// in our final expression and return true to indicate we are done
|
||||
// getting lines
|
||||
lines.PopBack();
|
||||
return LineStatus::Done;
|
||||
}
|
||||
else if (line_idx + 1 == lines.GetSize())
|
||||
{
|
||||
// The last line was edited, if this line is empty, then we are done
|
||||
// getting our multiple lines.
|
||||
if (lines[line_idx] == m_end_line)
|
||||
return LineStatus::Done;
|
||||
}
|
||||
return LineStatus::Success;
|
||||
}
|
||||
protected:
|
||||
const std::string m_end_line;
|
||||
};
|
||||
|
||||
|
||||
class IOHandlerEditline : public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerEditline (Debugger &debugger,
|
||||
const char *editline_name, // Used for saving history files
|
||||
const char *prompt,
|
||||
bool multi_line,
|
||||
IOHandlerDelegate &delegate);
|
||||
|
||||
IOHandlerEditline (Debugger &debugger,
|
||||
const lldb::StreamFileSP &input_sp,
|
||||
const lldb::StreamFileSP &output_sp,
|
||||
const lldb::StreamFileSP &error_sp,
|
||||
const char *editline_name, // Used for saving history files
|
||||
const char *prompt,
|
||||
bool multi_line,
|
||||
IOHandlerDelegate &delegate);
|
||||
|
||||
virtual
|
||||
~IOHandlerEditline ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
|
||||
virtual void
|
||||
Activate ()
|
||||
{
|
||||
IOHandler::Activate();
|
||||
m_delegate.IOHandlerActivated(*this);
|
||||
}
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
return m_delegate.GetControlSequence (ch);
|
||||
}
|
||||
|
||||
virtual const char *
|
||||
GetPrompt ();
|
||||
|
||||
virtual bool
|
||||
SetPrompt (const char *prompt);
|
||||
|
||||
bool
|
||||
GetLine (std::string &line);
|
||||
|
||||
bool
|
||||
GetLines (StringList &lines);
|
||||
|
||||
private:
|
||||
static LineStatus
|
||||
LineCompletedCallback (Editline *editline,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error,
|
||||
void *baton);
|
||||
|
||||
static int AutoCompleteCallback (const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches,
|
||||
void *baton);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Editline> m_editline_ap;
|
||||
IOHandlerDelegate &m_delegate;
|
||||
std::string m_prompt;
|
||||
bool m_multi_line;
|
||||
bool m_interactive;
|
||||
|
||||
};
|
||||
|
||||
class IOHandlerConfirm :
|
||||
public IOHandlerEditline,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
IOHandlerConfirm (Debugger &debugger,
|
||||
const char *prompt,
|
||||
bool default_response);
|
||||
|
||||
virtual
|
||||
~IOHandlerConfirm ();
|
||||
|
||||
bool
|
||||
GetResponse () const
|
||||
{
|
||||
return m_user_response;
|
||||
}
|
||||
|
||||
virtual int
|
||||
IOHandlerComplete (IOHandler &io_handler,
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches);
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
|
||||
|
||||
protected:
|
||||
const bool m_default_response;
|
||||
bool m_user_response;
|
||||
};
|
||||
|
||||
class IOHandlerCursesGUI :
|
||||
public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerCursesGUI (Debugger &debugger);
|
||||
|
||||
virtual
|
||||
~IOHandlerCursesGUI ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
|
||||
virtual void
|
||||
Activate ();
|
||||
|
||||
virtual void
|
||||
Deactivate ();
|
||||
|
||||
protected:
|
||||
curses::ApplicationAP m_app_ap;
|
||||
};
|
||||
|
||||
class IOHandlerCursesValueObjectList :
|
||||
public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list);
|
||||
|
||||
virtual
|
||||
~IOHandlerCursesValueObjectList ();
|
||||
|
||||
virtual void
|
||||
Run ();
|
||||
|
||||
virtual void
|
||||
Hide ();
|
||||
|
||||
virtual void
|
||||
Refresh ();
|
||||
|
||||
virtual void
|
||||
Interrupt ();
|
||||
|
||||
virtual void
|
||||
GotEOF();
|
||||
protected:
|
||||
ValueObjectList m_valobj_list;
|
||||
};
|
||||
|
||||
class IOHandlerStack
|
||||
{
|
||||
public:
|
||||
|
||||
IOHandlerStack () :
|
||||
m_stack(),
|
||||
m_mutex(Mutex::eMutexTypeRecursive),
|
||||
m_top (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~IOHandlerStack ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
GetSize () const
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
return m_stack.size();
|
||||
}
|
||||
|
||||
void
|
||||
Push (const lldb::IOHandlerSP& sp)
|
||||
{
|
||||
if (sp)
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
m_stack.push (sp);
|
||||
// Set m_top the non-locking IsTop() call
|
||||
m_top = sp.get();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IsEmpty () const
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
return m_stack.empty();
|
||||
}
|
||||
|
||||
lldb::IOHandlerSP
|
||||
Top ()
|
||||
{
|
||||
lldb::IOHandlerSP sp;
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
if (!m_stack.empty())
|
||||
sp = m_stack.top();
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
void
|
||||
Pop ()
|
||||
{
|
||||
Mutex::Locker locker (m_mutex);
|
||||
if (!m_stack.empty())
|
||||
m_stack.pop();
|
||||
// Set m_top the non-locking IsTop() call
|
||||
if (m_stack.empty())
|
||||
m_top = NULL;
|
||||
else
|
||||
m_top = m_stack.top().get();
|
||||
}
|
||||
|
||||
Mutex &
|
||||
GetMutex()
|
||||
{
|
||||
return m_mutex;
|
||||
}
|
||||
|
||||
bool
|
||||
IsTop (const lldb::IOHandlerSP &io_handler_sp) const
|
||||
{
|
||||
return m_top == io_handler_sp.get();
|
||||
}
|
||||
|
||||
ConstString
|
||||
GetTopIOHandlerControlSequence (char ch)
|
||||
{
|
||||
if (m_top)
|
||||
return m_top->GetControlSequence(ch);
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::stack<lldb::IOHandlerSP> m_stack;
|
||||
mutable Mutex m_mutex;
|
||||
IOHandler *m_top;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (IOHandlerStack);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_IOHandler_h_
|
|
@ -1,274 +0,0 @@
|
|||
//===-- InputReader.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReader_h_
|
||||
#define liblldb_InputReader_h_
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Host/Predicate.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
struct HandlerData
|
||||
{
|
||||
InputReader& reader;
|
||||
const char *bytes;
|
||||
size_t bytes_len;
|
||||
void* baton;
|
||||
|
||||
HandlerData(InputReader& r,
|
||||
const char* b,
|
||||
size_t l,
|
||||
void* t) :
|
||||
reader(r),
|
||||
bytes(b),
|
||||
bytes_len(l),
|
||||
baton(t)
|
||||
{
|
||||
}
|
||||
|
||||
lldb::StreamSP
|
||||
GetOutStream();
|
||||
|
||||
bool
|
||||
GetBatchMode();
|
||||
};
|
||||
|
||||
struct InitializationParameters
|
||||
{
|
||||
private:
|
||||
void* m_baton;
|
||||
lldb::InputReaderGranularity m_token_size;
|
||||
char* m_end_token;
|
||||
char* m_prompt;
|
||||
bool m_echo;
|
||||
bool m_save_user_input;
|
||||
public:
|
||||
InitializationParameters() :
|
||||
m_baton(NULL),
|
||||
m_token_size(lldb::eInputReaderGranularityLine),
|
||||
m_echo(true),
|
||||
m_save_user_input(false)
|
||||
{
|
||||
SetEndToken("DONE");
|
||||
SetPrompt("> ");
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetEcho(bool e)
|
||||
{
|
||||
m_echo = e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetSaveUserInput(bool s)
|
||||
{
|
||||
m_save_user_input = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetBaton(void* b)
|
||||
{
|
||||
m_baton = b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetGranularity(lldb::InputReaderGranularity g)
|
||||
{
|
||||
m_token_size = g;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetEndToken(const char* e)
|
||||
{
|
||||
m_end_token = new char[strlen(e)+1];
|
||||
::strcpy(m_end_token,e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetPrompt(const char* p)
|
||||
{
|
||||
m_prompt = new char[strlen(p)+1];
|
||||
::strcpy(m_prompt,p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend class InputReaderEZ;
|
||||
|
||||
};
|
||||
|
||||
InputReader (Debugger &debugger);
|
||||
|
||||
virtual
|
||||
~InputReader ();
|
||||
|
||||
virtual Error
|
||||
Initialize (Callback callback,
|
||||
void *baton,
|
||||
lldb::InputReaderGranularity token_size,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
virtual Error Initialize(void* baton,
|
||||
lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
|
||||
const char* end_token = "DONE",
|
||||
const char *prompt = "> ",
|
||||
bool echo = true)
|
||||
{
|
||||
return Error("unimplemented");
|
||||
}
|
||||
|
||||
virtual Error
|
||||
Initialize(InitializationParameters& params)
|
||||
{
|
||||
return Error("unimplemented");
|
||||
}
|
||||
|
||||
// to use these handlers instead of the Callback function, you must subclass
|
||||
// InputReaderEZ, and redefine the handlers for the events you care about
|
||||
virtual void
|
||||
ActivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DeactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
ReactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
AsynchronousOutputWrittenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
GotTokenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
InterruptHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
EOFHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DoneHandler(HandlerData&) {}
|
||||
|
||||
bool
|
||||
IsDone () const
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
void
|
||||
SetIsDone (bool b)
|
||||
{
|
||||
m_done = b;
|
||||
}
|
||||
|
||||
lldb::InputReaderGranularity
|
||||
GetGranularity () const
|
||||
{
|
||||
return m_granularity;
|
||||
}
|
||||
|
||||
bool
|
||||
GetEcho () const
|
||||
{
|
||||
return m_echo;
|
||||
}
|
||||
|
||||
StringList&
|
||||
GetUserInput()
|
||||
{
|
||||
return m_user_input;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subclasses _can_ override this function to get input as it comes in
|
||||
// without any granularity
|
||||
virtual size_t
|
||||
HandleRawBytes (const char *bytes, size_t bytes_len);
|
||||
|
||||
Debugger &
|
||||
GetDebugger()
|
||||
{
|
||||
return m_debugger;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive () const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
const char *
|
||||
GetPrompt () const;
|
||||
|
||||
void
|
||||
RefreshPrompt();
|
||||
|
||||
// If you want to read from an input reader synchronously, then just initialize the
|
||||
// reader and then call WaitOnReaderIsDone, which will return when the reader is popped.
|
||||
void
|
||||
WaitOnReaderIsDone ();
|
||||
|
||||
static const char *
|
||||
GranularityAsCString (lldb::InputReaderGranularity granularity);
|
||||
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
void
|
||||
Notify (lldb::InputReaderAction notification);
|
||||
|
||||
Debugger &m_debugger;
|
||||
Callback m_callback;
|
||||
void *m_callback_baton;
|
||||
std::string m_end_token;
|
||||
std::string m_prompt;
|
||||
lldb::InputReaderGranularity m_granularity;
|
||||
bool m_done;
|
||||
bool m_echo;
|
||||
bool m_active;
|
||||
Predicate<bool> m_reader_done;
|
||||
StringList m_user_input;
|
||||
bool m_save_user_input;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReader);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_InputReader_h_
|
|
@ -1,87 +0,0 @@
|
|||
//===-- InputReaderEZ.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReaderEZ_h_
|
||||
#define liblldb_InputReaderEZ_h_
|
||||
|
||||
#include "lldb/Core/InputReader.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReaderEZ : public InputReader
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
static size_t Callback_Impl(void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
public:
|
||||
|
||||
InputReaderEZ (Debugger &debugger) :
|
||||
InputReader(debugger)
|
||||
{}
|
||||
|
||||
virtual
|
||||
~InputReaderEZ ();
|
||||
|
||||
using InputReader::Initialize;
|
||||
virtual Error
|
||||
Initialize(void* baton,
|
||||
lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
|
||||
const char* end_token = "DONE",
|
||||
const char *prompt = "> ",
|
||||
bool echo = true);
|
||||
|
||||
virtual Error
|
||||
Initialize(InitializationParameters& params);
|
||||
|
||||
virtual void
|
||||
ActivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DeactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
ReactivateHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
AsynchronousOutputWrittenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
GotTokenHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
InterruptHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
EOFHandler(HandlerData&) {}
|
||||
|
||||
virtual void
|
||||
DoneHandler(HandlerData&) {}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return m_save_user_input;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReaderEZ);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #ifndef liblldb_InputReaderEZ_h_
|
|
@ -1,58 +0,0 @@
|
|||
//===-- InputReaderStack.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_InputReaderStack_h_
|
||||
#define liblldb_InputReaderStack_h_
|
||||
|
||||
#include <stack>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class InputReaderStack
|
||||
{
|
||||
public:
|
||||
|
||||
InputReaderStack ();
|
||||
|
||||
~InputReaderStack ();
|
||||
|
||||
size_t
|
||||
GetSize () const;
|
||||
|
||||
void
|
||||
Push (const lldb::InputReaderSP& reader_sp);
|
||||
|
||||
bool
|
||||
IsEmpty () const;
|
||||
|
||||
lldb::InputReaderSP
|
||||
Top ();
|
||||
|
||||
void
|
||||
Pop ();
|
||||
|
||||
Mutex &
|
||||
GetStackMutex ();
|
||||
|
||||
protected:
|
||||
|
||||
std::stack<lldb::InputReaderSP> m_input_readers;
|
||||
mutable Mutex m_input_readers_mutex;
|
||||
|
||||
private:
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReaderStack);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_InputReaderStack_h_
|
|
@ -70,6 +70,15 @@ public:
|
|||
return m_source_map_mod_id;
|
||||
}
|
||||
|
||||
const char *
|
||||
PeekLineData (uint32_t line);
|
||||
|
||||
uint32_t
|
||||
GetLineLength (uint32_t line, bool include_newline_chars);
|
||||
|
||||
uint32_t
|
||||
GetNumLines ();
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
|
@ -167,11 +176,11 @@ public:
|
|||
uint32_t start_line,
|
||||
uint32_t end_line,
|
||||
std::vector<uint32_t> &match_lines);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
FileSP
|
||||
GetFile (const FileSpec &file_spec);
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from SourceManager can see and modify these
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <string>
|
||||
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
|
@ -35,7 +34,7 @@ public:
|
|||
private:
|
||||
Broadcaster &m_broadcaster;
|
||||
uint32_t m_broadcast_event_type;
|
||||
StreamString m_accumulated_data;
|
||||
std::string m_accumulated_data;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -33,6 +33,9 @@ public:
|
|||
void
|
||||
AppendString (const std::string &s);
|
||||
|
||||
void
|
||||
AppendString (std::string &&s);
|
||||
|
||||
void
|
||||
AppendString (const char *str);
|
||||
|
||||
|
@ -51,6 +54,34 @@ public:
|
|||
size_t
|
||||
GetSize () const;
|
||||
|
||||
void
|
||||
SetSize (size_t n)
|
||||
{
|
||||
m_strings.resize(n);
|
||||
}
|
||||
|
||||
size_t
|
||||
GetMaxStringLength () const;
|
||||
|
||||
std::string &
|
||||
operator [](size_t idx)
|
||||
{
|
||||
// No bounds checking, verify "idx" is good prior to calling this function
|
||||
return m_strings[idx];
|
||||
}
|
||||
|
||||
const std::string &
|
||||
operator [](size_t idx) const
|
||||
{
|
||||
// No bounds checking, verify "idx" is good prior to calling this function
|
||||
return m_strings[idx];
|
||||
}
|
||||
|
||||
void
|
||||
PopBack ()
|
||||
{
|
||||
m_strings.pop_back();
|
||||
}
|
||||
const char *
|
||||
GetStringAtIndex (size_t idx) const;
|
||||
|
||||
|
@ -63,6 +94,12 @@ public:
|
|||
void
|
||||
LongestCommonPrefix (std::string &common_prefix);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t idx, const std::string &str);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t idx, std::string &&str);
|
||||
|
||||
void
|
||||
InsertStringAtIndex (size_t id, const char *str);
|
||||
|
||||
|
@ -72,12 +109,15 @@ public:
|
|||
void
|
||||
RemoveBlankLines ();
|
||||
|
||||
size_t
|
||||
SplitIntoLines (const std::string &lines);
|
||||
|
||||
size_t
|
||||
SplitIntoLines (const char *lines, size_t len);
|
||||
|
||||
std::string
|
||||
CopyList(const char* item_preamble = NULL,
|
||||
const char* items_sep = "\n");
|
||||
const char* items_sep = "\n") const;
|
||||
|
||||
StringList&
|
||||
operator << (const char* str);
|
||||
|
|
|
@ -75,6 +75,12 @@ public:
|
|||
void
|
||||
Swap (ValueObjectList &value_object_list);
|
||||
|
||||
void
|
||||
Clear ()
|
||||
{
|
||||
m_value_objects.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::vector<lldb::ValueObjectSP> collection;
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
//===-- Editline.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Editline_h_
|
||||
#define liblldb_Editline_h_
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef _WIN32
|
||||
#include "ELWrapper.h"
|
||||
#else
|
||||
#include <histedit.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lldb/Host/Condition.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Editline Editline.h "lldb/Host/Editline.h"
|
||||
/// @brief A class that encapsulates editline functionality.
|
||||
//----------------------------------------------------------------------
|
||||
class Editline
|
||||
{
|
||||
public:
|
||||
typedef LineStatus (*LineCompletedCallbackType) (
|
||||
Editline *editline,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error,
|
||||
void *baton);
|
||||
|
||||
typedef int (*CompleteCallbackType) (
|
||||
const char *current_line,
|
||||
const char *cursor,
|
||||
const char *last_char,
|
||||
int skip_first_n_matches,
|
||||
int max_matches,
|
||||
StringList &matches,
|
||||
void *baton);
|
||||
|
||||
typedef int (*GetCharCallbackType) (
|
||||
::EditLine *,
|
||||
char *c);
|
||||
|
||||
Editline(const char *prog, // Used for the history file and for editrc program name
|
||||
const char *prompt,
|
||||
FILE *fin,
|
||||
FILE *fout,
|
||||
FILE *ferr);
|
||||
|
||||
~Editline();
|
||||
|
||||
Error
|
||||
GetLine (std::string &line);
|
||||
|
||||
Error
|
||||
GetLines (const std::string &end_line, StringList &lines);
|
||||
|
||||
bool
|
||||
LoadHistory ();
|
||||
|
||||
bool
|
||||
SaveHistory ();
|
||||
|
||||
FILE *
|
||||
GetInputFile ();
|
||||
|
||||
FILE *
|
||||
GetOutputFile ();
|
||||
|
||||
FILE *
|
||||
GetErrorFile ();
|
||||
|
||||
bool
|
||||
GettingLine () const
|
||||
{
|
||||
return m_getting_line;
|
||||
}
|
||||
|
||||
void
|
||||
Hide ();
|
||||
|
||||
void
|
||||
Refresh();
|
||||
|
||||
void
|
||||
Interrupt ();
|
||||
|
||||
void
|
||||
SetAutoCompleteCallback (CompleteCallbackType callback,
|
||||
void *baton)
|
||||
{
|
||||
m_completion_callback = callback;
|
||||
m_completion_callback_baton = baton;
|
||||
}
|
||||
|
||||
void
|
||||
SetLineCompleteCallback (LineCompletedCallbackType callback,
|
||||
void *baton)
|
||||
{
|
||||
m_line_complete_callback = callback;
|
||||
m_line_complete_callback_baton = baton;
|
||||
}
|
||||
|
||||
size_t
|
||||
Push (const char *bytes, size_t len);
|
||||
|
||||
// Cache bytes and use them for input without using a FILE. Calling this function
|
||||
// will set the getc callback in the editline
|
||||
size_t
|
||||
SetInputBuffer (const char *c, size_t len);
|
||||
|
||||
static int
|
||||
GetCharFromInputFileCallback (::EditLine *e, char *c);
|
||||
|
||||
void
|
||||
SetGetCharCallback (GetCharCallbackType callback);
|
||||
|
||||
const char *
|
||||
GetPrompt();
|
||||
|
||||
void
|
||||
SetPrompt (const char *p);
|
||||
|
||||
private:
|
||||
|
||||
Error
|
||||
PrivateGetLine(std::string &line);
|
||||
|
||||
FileSpec
|
||||
GetHistoryFile();
|
||||
|
||||
unsigned char
|
||||
HandleCompletion (int ch);
|
||||
|
||||
int
|
||||
GetChar (char *c);
|
||||
|
||||
|
||||
static unsigned char
|
||||
CallbackEditPrevLine (::EditLine *e, int ch);
|
||||
|
||||
static unsigned char
|
||||
CallbackEditNextLine (::EditLine *e, int ch);
|
||||
|
||||
static unsigned char
|
||||
CallbackComplete (::EditLine *e, int ch);
|
||||
|
||||
static const char *
|
||||
GetPromptCallback (::EditLine *e);
|
||||
|
||||
static Editline *
|
||||
GetClientData (::EditLine *e);
|
||||
|
||||
static FILE *
|
||||
GetFilePointer (::EditLine *e, int fd);
|
||||
|
||||
static int
|
||||
GetCharInputBufferCallback (::EditLine *e, char *c);
|
||||
|
||||
enum class Command
|
||||
{
|
||||
None = 0,
|
||||
EditPrevLine,
|
||||
EditNextLine,
|
||||
};
|
||||
::EditLine *m_editline;
|
||||
::History *m_history;
|
||||
::HistEvent m_history_event;
|
||||
std::string m_program;
|
||||
std::string m_prompt;
|
||||
std::string m_lines_prompt;
|
||||
std::string m_getc_buffer;
|
||||
Mutex m_getc_mutex;
|
||||
Condition m_getc_cond;
|
||||
CompleteCallbackType m_completion_callback;
|
||||
void *m_completion_callback_baton;
|
||||
// Mutex m_gets_mutex; // Make sure only one thread
|
||||
LineCompletedCallbackType m_line_complete_callback;
|
||||
void *m_line_complete_callback_baton;
|
||||
Command m_lines_command;
|
||||
uint32_t m_lines_curr_line;
|
||||
uint32_t m_lines_max_line;
|
||||
bool m_prompt_with_line_numbers;
|
||||
bool m_getting_line;
|
||||
bool m_got_eof; // Set to true when we detect EOF
|
||||
bool m_interrupted;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Editline);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // #if defined(__cplusplus)
|
||||
#endif // liblldb_Host_h_
|
|
@ -51,7 +51,8 @@ public:
|
|||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (false)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,7 +60,8 @@ public:
|
|||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (fh),
|
||||
m_options (0),
|
||||
m_owned (transfer_ownership)
|
||||
m_own_stream (transfer_ownership),
|
||||
m_own_descriptor (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -111,13 +113,15 @@ public:
|
|||
uint32_t options,
|
||||
uint32_t permissions = lldb::eFilePermissionsFileDefault);
|
||||
|
||||
File (int fd, bool tranfer_ownership) :
|
||||
File (int fd, bool transfer_ownership) :
|
||||
m_descriptor (fd),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (tranfer_ownership)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (transfer_ownership)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
|
@ -476,6 +480,12 @@ public:
|
|||
size_t
|
||||
PrintfVarArg(const char *format, va_list args);
|
||||
|
||||
|
||||
void
|
||||
SetOptions (uint32_t options)
|
||||
{
|
||||
m_options = options;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
|
@ -497,7 +507,8 @@ protected:
|
|||
int m_descriptor;
|
||||
FILE *m_stream;
|
||||
uint32_t m_options;
|
||||
bool m_owned;
|
||||
bool m_own_stream;
|
||||
bool m_own_descriptor;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Interpreter/CommandHistory.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
|
@ -29,7 +30,8 @@ namespace lldb_private {
|
|||
|
||||
class CommandInterpreter :
|
||||
public Broadcaster,
|
||||
public Properties
|
||||
public Properties,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, OptionArgVectorSP> OptionArgMap;
|
||||
|
@ -305,7 +307,8 @@ public:
|
|||
ExecutionContext
|
||||
GetExecutionContext()
|
||||
{
|
||||
return m_exe_ctx_ref.Lock();
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
return m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -317,20 +320,12 @@ public:
|
|||
const char *
|
||||
ProcessEmbeddedScriptCommands (const char *arg);
|
||||
|
||||
const char *
|
||||
GetPrompt ();
|
||||
|
||||
void
|
||||
SetPrompt (const char *);
|
||||
UpdatePrompt (const char *);
|
||||
|
||||
bool Confirm (const char *message, bool default_answer);
|
||||
|
||||
static size_t
|
||||
GetConfirmationInputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction action,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
bool
|
||||
Confirm (const char *message,
|
||||
bool default_answer);
|
||||
|
||||
void
|
||||
LoadCommandDictionary ();
|
||||
|
@ -395,8 +390,12 @@ public:
|
|||
bool
|
||||
GetBatchCommandMode () { return m_batch_command_mode; }
|
||||
|
||||
void
|
||||
SetBatchCommandMode (bool value) { m_batch_command_mode = value; }
|
||||
bool
|
||||
SetBatchCommandMode (bool value) {
|
||||
const bool old_value = m_batch_command_mode;
|
||||
m_batch_command_mode = value;
|
||||
return old_value;
|
||||
}
|
||||
|
||||
void
|
||||
ChildrenTruncated ()
|
||||
|
@ -435,6 +434,25 @@ public:
|
|||
return m_command_history;
|
||||
}
|
||||
|
||||
bool
|
||||
IsActive ();
|
||||
|
||||
void
|
||||
RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread);
|
||||
|
||||
void
|
||||
GetLLDBCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton);
|
||||
|
||||
void
|
||||
GetPythonCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Properties
|
||||
//------------------------------------------------------------------
|
||||
|
@ -450,12 +468,31 @@ public:
|
|||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// IOHandlerDelegate functions
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler,
|
||||
std::string &line);
|
||||
|
||||
virtual ConstString
|
||||
GetControlSequence (char ch)
|
||||
{
|
||||
if (ch == 'd')
|
||||
return ConstString("quit\n");
|
||||
return ConstString();
|
||||
}
|
||||
|
||||
size_t
|
||||
GetProcessOutput ();
|
||||
|
||||
void
|
||||
SetSynchronous (bool value);
|
||||
|
||||
lldb::CommandObjectSP
|
||||
GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Error
|
||||
|
@ -473,6 +510,7 @@ private:
|
|||
CommandHistory m_command_history;
|
||||
std::string m_repeat_command; // Stores the command that will be executed for an empty command string.
|
||||
std::unique_ptr<ScriptInterpreter> m_script_interpreter_ap;
|
||||
lldb::IOHandlerSP m_command_io_handler_sp;
|
||||
char m_comment_char;
|
||||
bool m_batch_command_mode;
|
||||
ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace lldb_private {
|
|||
{
|
||||
}
|
||||
|
||||
PythonObject (PyObject* py_obj) :
|
||||
explicit PythonObject (PyObject* py_obj) :
|
||||
m_py_obj(NULL)
|
||||
{
|
||||
Reset (py_obj);
|
||||
|
@ -43,7 +43,7 @@ namespace lldb_private {
|
|||
Reset (rhs.m_py_obj);
|
||||
}
|
||||
|
||||
PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
explicit PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
|
||||
virtual
|
||||
~PythonObject ()
|
||||
|
@ -51,18 +51,10 @@ namespace lldb_private {
|
|||
Reset (NULL);
|
||||
}
|
||||
|
||||
const PythonObject &
|
||||
operator = (const PythonObject &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
Reset (rhs.m_py_obj);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
Reset (const PythonObject &object)
|
||||
{
|
||||
return Reset(object.GetPythonObject());
|
||||
return Reset(object.get());
|
||||
}
|
||||
|
||||
virtual bool
|
||||
|
@ -90,11 +82,11 @@ namespace lldb_private {
|
|||
Dump (Stream &strm) const;
|
||||
|
||||
PyObject*
|
||||
GetPythonObject () const
|
||||
get () const
|
||||
{
|
||||
return m_py_obj;
|
||||
}
|
||||
|
||||
|
||||
PythonString
|
||||
Repr ();
|
||||
|
||||
|
@ -159,7 +151,7 @@ namespace lldb_private {
|
|||
{
|
||||
public:
|
||||
|
||||
PythonList ();
|
||||
PythonList (bool create_empty);
|
||||
PythonList (PyObject* py_obj);
|
||||
PythonList (const PythonObject &object);
|
||||
PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
|
@ -186,7 +178,7 @@ namespace lldb_private {
|
|||
{
|
||||
public:
|
||||
|
||||
PythonDictionary ();
|
||||
explicit PythonDictionary (bool create_empty);
|
||||
PythonDictionary (PyObject* object);
|
||||
PythonDictionary (const PythonObject &object);
|
||||
PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp);
|
||||
|
@ -220,6 +212,9 @@ namespace lldb_private {
|
|||
PythonObject
|
||||
GetValueAtPosition (uint32_t pos) const;
|
||||
|
||||
void
|
||||
SetItemForKey (const PythonString &key, PyObject *value);
|
||||
|
||||
void
|
||||
SetItemForKey (const PythonString &key, const PythonObject& value);
|
||||
};
|
||||
|
|
|
@ -245,11 +245,13 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions())
|
||||
{
|
||||
return true;
|
||||
Error error;
|
||||
error.SetErrorString("not implemented");
|
||||
return error;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
|
|
|
@ -19,16 +19,21 @@
|
|||
|
||||
#include "lldb/lldb-python.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Interpreter/PythonDataObjects.h"
|
||||
#include "lldb/Host/Terminal.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ScriptInterpreterPython : public ScriptInterpreter
|
||||
class ScriptInterpreterPython :
|
||||
public ScriptInterpreter,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
|
||||
friend class IOHandlerPythonInterpreter;
|
||||
|
||||
ScriptInterpreterPython (CommandInterpreter &interpreter);
|
||||
|
||||
~ScriptInterpreterPython ();
|
||||
|
@ -47,7 +52,7 @@ public:
|
|||
void *ret_value,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions());
|
||||
|
||||
bool
|
||||
lldb_private::Error
|
||||
ExecuteMultipleLines (const char *in_string,
|
||||
const ExecuteScriptOptions &options = ExecuteScriptOptions());
|
||||
|
||||
|
@ -134,20 +139,20 @@ public:
|
|||
bool
|
||||
GenerateWatchpointCommandCallbackData (StringList &input, std::string& output);
|
||||
|
||||
static size_t
|
||||
GenerateBreakpointOptionsCommandCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
static size_t
|
||||
GenerateWatchpointOptionsCommandCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
// static size_t
|
||||
// GenerateBreakpointOptionsCommandCallback (void *baton,
|
||||
// InputReader &reader,
|
||||
// lldb::InputReaderAction notification,
|
||||
// const char *bytes,
|
||||
// size_t bytes_len);
|
||||
//
|
||||
// static size_t
|
||||
// GenerateWatchpointOptionsCommandCallback (void *baton,
|
||||
// InputReader &reader,
|
||||
// lldb::InputReaderAction notification,
|
||||
// const char *bytes,
|
||||
// size_t bytes_len);
|
||||
|
||||
static bool
|
||||
BreakpointCallbackFunction (void *baton,
|
||||
StoppointCallbackContext *context,
|
||||
|
@ -238,9 +243,6 @@ public:
|
|||
virtual void
|
||||
ResetOutputFileHandle (FILE *new_fh);
|
||||
|
||||
static lldb::thread_result_t
|
||||
RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton);
|
||||
|
||||
static void
|
||||
InitializePrivate ();
|
||||
|
||||
|
@ -266,10 +268,29 @@ public:
|
|||
SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
|
||||
SWIGPython_GetDynamicSetting swig_plugin_get);
|
||||
|
||||
const char *
|
||||
GetDictionaryName ()
|
||||
{
|
||||
return m_dictionary_name.c_str();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// IOHandlerDelegate
|
||||
//----------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler);
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data);
|
||||
|
||||
protected:
|
||||
|
||||
bool
|
||||
EnterSession (bool init_lldb_globals);
|
||||
EnterSession (bool init_lldb_globals,
|
||||
FILE *in,
|
||||
FILE *out,
|
||||
FILE *err);
|
||||
|
||||
void
|
||||
LeaveSession ();
|
||||
|
@ -279,8 +300,6 @@ protected:
|
|||
|
||||
void
|
||||
RestoreTerminalState ();
|
||||
|
||||
private:
|
||||
|
||||
class SynchronicityHandler
|
||||
{
|
||||
|
@ -322,7 +341,7 @@ private:
|
|||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
|
||||
};
|
||||
|
||||
public:
|
||||
class Locker : public ScriptInterpreterLocker
|
||||
{
|
||||
public:
|
||||
|
@ -344,7 +363,9 @@ private:
|
|||
Locker (ScriptInterpreterPython *py_interpreter = NULL,
|
||||
uint16_t on_entry = AcquireLock | InitSession,
|
||||
uint16_t on_leave = FreeLock | TearDownSession,
|
||||
FILE* wait_msg_handle = NULL);
|
||||
FILE *in = NULL,
|
||||
FILE *out = NULL,
|
||||
FILE *err = NULL);
|
||||
|
||||
~Locker ();
|
||||
|
||||
|
@ -354,7 +375,7 @@ private:
|
|||
DoAcquireLock ();
|
||||
|
||||
bool
|
||||
DoInitSession (bool init_lldb_globals);
|
||||
DoInitSession (bool init_lldb_globals, FILE *in, FILE *out, FILE *err);
|
||||
|
||||
bool
|
||||
DoFreeLock ();
|
||||
|
@ -367,59 +388,40 @@ private:
|
|||
|
||||
bool m_teardown_session;
|
||||
ScriptInterpreterPython *m_python_interpreter;
|
||||
FILE* m_tmp_fh;
|
||||
// FILE* m_tmp_fh;
|
||||
PyGILState_STATE m_GILState;
|
||||
};
|
||||
|
||||
class PythonInputReaderManager
|
||||
{
|
||||
public:
|
||||
PythonInputReaderManager (ScriptInterpreterPython *interpreter);
|
||||
|
||||
explicit operator bool()
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
~PythonInputReaderManager();
|
||||
|
||||
private:
|
||||
|
||||
static size_t
|
||||
InputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
static lldb::thread_result_t
|
||||
RunPythonInputReader (lldb::thread_arg_t baton);
|
||||
|
||||
ScriptInterpreterPython *m_interpreter;
|
||||
lldb::DebuggerSP m_debugger_sp;
|
||||
lldb::InputReaderSP m_reader_sp;
|
||||
bool m_error;
|
||||
private:
|
||||
|
||||
enum ActiveIOHandler {
|
||||
eIOHandlerNone,
|
||||
eIOHandlerBreakpoint,
|
||||
eIOHandlerWatchpoint
|
||||
};
|
||||
PythonObject &
|
||||
GetMainModule ();
|
||||
|
||||
PythonDictionary &
|
||||
GetSessionDictionary ();
|
||||
|
||||
PythonDictionary &
|
||||
GetSysModuleDictionary ();
|
||||
|
||||
static size_t
|
||||
InputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
|
||||
lldb_utility::PseudoTerminal m_embedded_thread_pty;
|
||||
lldb_utility::PseudoTerminal m_embedded_python_pty;
|
||||
lldb::InputReaderSP m_embedded_thread_input_reader_sp;
|
||||
lldb::InputReaderSP m_embedded_python_input_reader_sp;
|
||||
FILE *m_dbg_stdout;
|
||||
PyObject *m_new_sysout;
|
||||
PyObject *m_old_sysout;
|
||||
PyObject *m_old_syserr;
|
||||
PyObject *m_run_one_line;
|
||||
bool
|
||||
GetEmbeddedInterpreterModuleObjects ();
|
||||
|
||||
PythonObject m_saved_stdin;
|
||||
PythonObject m_saved_stdout;
|
||||
PythonObject m_saved_stderr;
|
||||
PythonObject m_main_module;
|
||||
PythonObject m_lldb_module;
|
||||
PythonDictionary m_session_dict;
|
||||
PythonDictionary m_sys_module_dict;
|
||||
PythonObject m_run_one_line_function;
|
||||
PythonObject m_run_one_line_str_global;
|
||||
std::string m_dictionary_name;
|
||||
TerminalState m_terminal_state;
|
||||
ActiveIOHandler m_active_io_handler;
|
||||
bool m_session_is_active;
|
||||
bool m_pty_slave_is_open;
|
||||
bool m_valid_session;
|
||||
|
|
|
@ -608,6 +608,17 @@ public:
|
|||
size_t
|
||||
MemorySize () const;
|
||||
|
||||
lldb::DisassemblerSP
|
||||
GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache);
|
||||
|
||||
bool
|
||||
GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm);
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
|
|
|
@ -291,6 +291,17 @@ public:
|
|||
virtual void
|
||||
DumpSymbolContext (Stream *s);
|
||||
|
||||
lldb::DisassemblerSP
|
||||
GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache);
|
||||
|
||||
bool
|
||||
GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm);
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t m_uid; // User ID (usually the original symbol table index)
|
||||
|
|
|
@ -298,7 +298,7 @@ public:
|
|||
/// any valid weak references in this object.
|
||||
//------------------------------------------------------------------
|
||||
ExecutionContext
|
||||
Lock () const;
|
||||
Lock (bool thread_and_frame_only_if_stopped) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns true if this object has a weak reference to a thread.
|
||||
|
@ -402,7 +402,7 @@ public:
|
|||
ExecutionContext (const lldb::ThreadWP &thread_wp);
|
||||
ExecutionContext (const lldb::StackFrameWP &frame_wp);
|
||||
ExecutionContext (const ExecutionContextRef &exe_ctx_ref);
|
||||
ExecutionContext (const ExecutionContextRef *exe_ctx_ref);
|
||||
ExecutionContext (const ExecutionContextRef *exe_ctx_ref, bool thread_and_frame_only_if_stopped = false);
|
||||
|
||||
// These two variants take in a locker, and grab the target, lock the API mutex into locker, then
|
||||
// fill in the rest of the shared pointers.
|
||||
|
|
|
@ -535,7 +535,8 @@ public:
|
|||
m_resume_count (0),
|
||||
m_monitor_callback (NULL),
|
||||
m_monitor_callback_baton (NULL),
|
||||
m_monitor_signals (false)
|
||||
m_monitor_signals (false),
|
||||
m_hijack_listener_sp ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -554,7 +555,8 @@ public:
|
|||
m_resume_count (0),
|
||||
m_monitor_callback (NULL),
|
||||
m_monitor_callback_baton (NULL),
|
||||
m_monitor_signals (false)
|
||||
m_monitor_signals (false),
|
||||
m_hijack_listener_sp ()
|
||||
{
|
||||
if (stdin_path)
|
||||
{
|
||||
|
@ -781,6 +783,7 @@ public:
|
|||
m_flags.Clear();
|
||||
m_file_actions.clear();
|
||||
m_resume_count = 0;
|
||||
m_hijack_listener_sp.reset();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -831,6 +834,19 @@ public:
|
|||
{
|
||||
return m_pty;
|
||||
}
|
||||
|
||||
lldb::ListenerSP
|
||||
GetHijackListener () const
|
||||
{
|
||||
return m_hijack_listener_sp;
|
||||
}
|
||||
|
||||
void
|
||||
SetHijackListener (const lldb::ListenerSP &listener_sp)
|
||||
{
|
||||
m_hijack_listener_sp = listener_sp;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
std::string m_working_dir;
|
||||
|
@ -843,7 +859,7 @@ protected:
|
|||
Host::MonitorChildProcessCallback m_monitor_callback;
|
||||
void *m_monitor_callback_baton;
|
||||
bool m_monitor_signals;
|
||||
|
||||
lldb::ListenerSP m_hijack_listener_sp;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -876,6 +892,7 @@ public:
|
|||
ProcessInfo::operator= (launch_info);
|
||||
SetProcessPluginName (launch_info.GetProcessPluginName());
|
||||
SetResumeCount (launch_info.GetResumeCount());
|
||||
SetHijackListener(launch_info.GetHijackListener());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -965,7 +982,22 @@ public:
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
lldb::ListenerSP
|
||||
GetHijackListener () const
|
||||
{
|
||||
return m_hijack_listener_sp;
|
||||
}
|
||||
|
||||
void
|
||||
SetHijackListener (const lldb::ListenerSP &listener_sp)
|
||||
{
|
||||
m_hijack_listener_sp = listener_sp;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
lldb::ListenerSP m_hijack_listener_sp;
|
||||
std::string m_plugin_name;
|
||||
uint32_t m_resume_count; // How many times do we resume after launching
|
||||
bool m_wait_for_launch;
|
||||
|
@ -1379,10 +1411,11 @@ class Process :
|
|||
public ExecutionContextScope,
|
||||
public PluginInterface
|
||||
{
|
||||
friend class ThreadList;
|
||||
friend class ClangFunction; // For WaitForStateChangeEventsPrivate
|
||||
friend class ProcessEventData;
|
||||
friend class StopInfo;
|
||||
friend class ClangFunction; // For WaitForStateChangeEventsPrivate
|
||||
friend class ProcessEventData;
|
||||
friend class StopInfo;
|
||||
friend class Target;
|
||||
friend class ThreadList;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -3376,10 +3409,15 @@ public:
|
|||
// is set to the event which triggered the stop. If wait_always = false,
|
||||
// and the process is already stopped, this function returns immediately.
|
||||
lldb::StateType
|
||||
WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL, bool wait_always = true);
|
||||
WaitForProcessToStop (const TimeValue *timeout,
|
||||
lldb::EventSP *event_sp_ptr = NULL,
|
||||
bool wait_always = true,
|
||||
Listener *hijack_listener = NULL);
|
||||
|
||||
lldb::StateType
|
||||
WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp);
|
||||
WaitForStateChangedEvents (const TimeValue *timeout,
|
||||
lldb::EventSP &event_sp,
|
||||
Listener *hijack_listener); // Pass NULL to use builtin listener
|
||||
|
||||
Event *
|
||||
PeekAtStateChangedEvents ();
|
||||
|
@ -3546,6 +3584,12 @@ public:
|
|||
void
|
||||
SetSTDIOFileDescriptor (int file_descriptor);
|
||||
|
||||
void
|
||||
WatchForSTDIN (IOHandler &io_handler);
|
||||
|
||||
void
|
||||
CancelWatchForSTDIN (bool exited);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Add a permanent region of memory that should never be read or
|
||||
// written to. This can be used to ensure that memory reads or writes
|
||||
|
@ -3738,7 +3782,7 @@ protected:
|
|||
std::unique_ptr<SystemRuntime> m_system_runtime_ap;
|
||||
UnixSignals m_unix_signals; /// This is the current signal set for this process.
|
||||
lldb::ABISP m_abi_sp;
|
||||
lldb::InputReaderSP m_process_input_reader;
|
||||
lldb::IOHandlerSP m_process_input_reader;
|
||||
Communication m_stdio_communication;
|
||||
Mutex m_stdio_communication_mutex;
|
||||
std::string m_stdout_data;
|
||||
|
@ -3835,21 +3879,14 @@ protected:
|
|||
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
void
|
||||
PushProcessInputReader ();
|
||||
PushProcessIOHandler ();
|
||||
|
||||
void
|
||||
PopProcessInputReader ();
|
||||
PopProcessIOHandler ();
|
||||
|
||||
void
|
||||
ResetProcessInputReader ();
|
||||
|
||||
static size_t
|
||||
ProcessInputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
ResetProcessIOHandler ();
|
||||
|
||||
Error
|
||||
HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp);
|
||||
|
||||
|
|
|
@ -1172,7 +1172,7 @@ public:
|
|||
std::unique_ptr<ThreadSpec> m_thread_spec_ap;
|
||||
bool m_active;
|
||||
|
||||
// Use AddStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
|
||||
// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands,
|
||||
// and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.)
|
||||
StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid);
|
||||
friend class Target;
|
||||
|
@ -1181,8 +1181,8 @@ public:
|
|||
|
||||
// Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook.
|
||||
// Returns the id of the new hook.
|
||||
lldb::user_id_t
|
||||
AddStopHook (StopHookSP &new_hook);
|
||||
StopHookSP
|
||||
CreateStopHook ();
|
||||
|
||||
void
|
||||
RunStopHooks ();
|
||||
|
|
|
@ -412,6 +412,55 @@ public:
|
|||
void
|
||||
DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping into.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @param[in] source_step
|
||||
/// If true and the frame has debug info, then do a source level
|
||||
/// step in, else do a single instruction step in.
|
||||
///
|
||||
/// @param[in] avoid_code_without_debug_info
|
||||
/// If \a true, then avoid stepping into code that doesn't have
|
||||
/// debug info, else step into any code regardless of wether it
|
||||
/// has debug info.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepIn (bool source_step,
|
||||
bool avoid_code_without_debug_info);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping over.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @param[in] source_step
|
||||
/// If true and the frame has debug info, then do a source level
|
||||
/// step over, else do a single instruction step over.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepOver (bool source_step);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default implementation for stepping out.
|
||||
///
|
||||
/// This function is designed to be used by commands where the
|
||||
/// process is publicly stopped.
|
||||
///
|
||||
/// @return
|
||||
/// An error that describes anything that went wrong
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
StepOut ();
|
||||
//------------------------------------------------------------------
|
||||
/// Retrieves the per-thread data area.
|
||||
/// Most OSs maintain a per-thread pointer (e.g. the FS register on
|
||||
|
|
|
@ -82,6 +82,7 @@ class Disassembler;
|
|||
struct DumpValueObjectOptions;
|
||||
class DynamicLibrary;
|
||||
class DynamicLoader;
|
||||
class Editline;
|
||||
class EmulateInstruction;
|
||||
class Error;
|
||||
class EvaluateExpressionOptions;
|
||||
|
@ -102,9 +103,9 @@ class FuncUnwinders;
|
|||
class Function;
|
||||
class FunctionInfo;
|
||||
class InlineFunctionInfo;
|
||||
class InputReader;
|
||||
class Instruction;
|
||||
class InstructionList;
|
||||
class IOHandler;
|
||||
class IRExecutionUnit;
|
||||
class LanguageRuntime;
|
||||
class SystemRuntime;
|
||||
|
@ -302,8 +303,8 @@ namespace lldb {
|
|||
typedef std::shared_ptr<lldb_private::Function> FunctionSP;
|
||||
typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP;
|
||||
typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP;
|
||||
typedef std::shared_ptr<lldb_private::InputReader> InputReaderSP;
|
||||
typedef std::shared_ptr<lldb_private::Instruction> InstructionSP;
|
||||
typedef std::shared_ptr<lldb_private::IOHandler> IOHandlerSP;
|
||||
typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP;
|
||||
typedef std::shared_ptr<lldb_private::SystemRuntime> SystemRuntimeSP;
|
||||
typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
|
||||
|
@ -358,6 +359,7 @@ namespace lldb {
|
|||
typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP;
|
||||
typedef std::shared_ptr<lldb_private::Stream> StreamSP;
|
||||
typedef std::weak_ptr<lldb_private::Stream> StreamWP;
|
||||
typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
|
||||
typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP;
|
||||
typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP;
|
||||
|
|
|
@ -253,6 +253,15 @@ typedef enum MemoryModuleLoadLevel {
|
|||
} MemoryModuleLoadLevel;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Result enums for when reading multiple lines from IOHandlers
|
||||
//----------------------------------------------------------------------
|
||||
enum class LineStatus {
|
||||
Success, // The line that was just edited if good and should be added to the lines
|
||||
Error, // There is an error with the current line and it needs to be re-edited before it can be accepted
|
||||
Done // Lines are complete
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD))
|
|||
# Don't allow unresolved symbols.
|
||||
LLVMLibsOptions += -Wl,--no-undefined
|
||||
# Link in python
|
||||
LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt
|
||||
LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt -ledit -lncurses -lpanel
|
||||
LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT)
|
||||
endif
|
||||
|
||||
|
|
|
@ -51,9 +51,14 @@
|
|||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
|
||||
260157C71885F52500F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
|
||||
260157C81885F53100F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
|
||||
2606EDDE184E68940034641B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 260C876910F538E700BB2B04 /* Foundation.framework */; };
|
||||
2606EDDF184E68A10034641B /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
|
||||
260A248E15D06C50009981B0 /* OptionValues.h in Headers */ = {isa = PBXBuildFile; fileRef = 260A248D15D06C4F009981B0 /* OptionValues.h */; };
|
||||
260A63171861008E00FECF8E /* IOHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 260A63161861008E00FECF8E /* IOHandler.h */; };
|
||||
260A63191861009E00FECF8E /* IOHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260A63181861009E00FECF8E /* IOHandler.cpp */; };
|
||||
260CC62E15D04377002BF2E0 /* OptionValueArgs.h in Headers */ = {isa = PBXBuildFile; fileRef = 260CC62115D04377002BF2E0 /* OptionValueArgs.h */; };
|
||||
260CC62F15D04377002BF2E0 /* OptionValueArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 260CC62215D04377002BF2E0 /* OptionValueArray.h */; };
|
||||
260CC63015D04377002BF2E0 /* OptionValueBoolean.h in Headers */ = {isa = PBXBuildFile; fileRef = 260CC62315D04377002BF2E0 /* OptionValueBoolean.h */; };
|
||||
|
@ -113,7 +118,6 @@
|
|||
265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */; };
|
||||
265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A613D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp */; };
|
||||
2660AAB914622483003A9694 /* LLDBWrapPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A4EEB511682AAC007A372A /* LLDBWrapPython.cpp */; };
|
||||
2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 2663E378152BD1890091EC22 /* ReadWriteLock.h */; };
|
||||
26651A18133BF9E0005B64B7 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26651A17133BF9DF005B64B7 /* Opcode.cpp */; };
|
||||
266603CA1345B5A8004DA8B6 /* ConnectionSharedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266603C91345B5A8004DA8B6 /* ConnectionSharedMemory.cpp */; };
|
||||
2668020E115FD12C008E1FE4 /* lldb-defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7C2510F1B3BC00F91463 /* lldb-defines.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
|
@ -156,9 +160,12 @@
|
|||
26680337116005F1008E1FE4 /* SBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */; };
|
||||
2668035C11601108008E1FE4 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
|
||||
266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266DFE9613FD656E00D0C574 /* OperatingSystem.cpp */; };
|
||||
2670F8121862B44A006B332C /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2670F8111862B44A006B332C /* libncurses.dylib */; };
|
||||
2671A0D013482601003A87BB /* ConnectionMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */; };
|
||||
26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
|
||||
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
|
||||
26780C611867C33D00234593 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2670F8111862B44A006B332C /* libncurses.dylib */; };
|
||||
26780C651867C34500234593 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2670F8111862B44A006B332C /* libncurses.dylib */; };
|
||||
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
|
||||
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
|
||||
268648C416531BF800F04704 /* com.apple.debugserver.posix.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C116531BF800F04704 /* com.apple.debugserver.posix.plist */; };
|
||||
|
@ -218,7 +225,6 @@
|
|||
2689003C13353E0400698AC0 /* Error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7810F1B85900F91463 /* Error.cpp */; };
|
||||
2689003D13353E0400698AC0 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7910F1B85900F91463 /* Event.cpp */; };
|
||||
2689003E13353E0400698AC0 /* FileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7B10F1B85900F91463 /* FileSpecList.cpp */; };
|
||||
2689003F13353E0400698AC0 /* InputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB5118A027A00D753A0 /* InputReader.cpp */; };
|
||||
2689004013353E0400698AC0 /* Language.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7D10F1B85900F91463 /* Language.cpp */; };
|
||||
2689004113353E0400698AC0 /* Listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7E10F1B85900F91463 /* Listener.cpp */; };
|
||||
2689004213353E0400698AC0 /* Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7F10F1B85900F91463 /* Log.cpp */; };
|
||||
|
@ -451,6 +457,13 @@
|
|||
26C72C961243229A0068DC16 /* SBStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C72C951243229A0068DC16 /* SBStream.cpp */; };
|
||||
26CA97A1172B1FD5005DC71B /* RegisterContextThreadMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CA979F172B1FD5005DC71B /* RegisterContextThreadMemory.cpp */; };
|
||||
26CA97A2172B1FD5005DC71B /* RegisterContextThreadMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 26CA97A0172B1FD5005DC71B /* RegisterContextThreadMemory.h */; };
|
||||
26CEB5EF18761CB2008F575A /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32A10F3DFDD009D5894 /* libedit.dylib */; };
|
||||
26CEB5F218762056008F575A /* CommandObjectGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CEB5F018762056008F575A /* CommandObjectGUI.cpp */; };
|
||||
26CEB5F318762056008F575A /* CommandObjectGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 26CEB5F118762056008F575A /* CommandObjectGUI.h */; };
|
||||
26CFDCA11861638D000E63E5 /* Editline.h in Headers */ = {isa = PBXBuildFile; fileRef = 26CFDCA01861638D000E63E5 /* Editline.h */; };
|
||||
26CFDCA3186163A4000E63E5 /* Editline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26CFDCA2186163A4000E63E5 /* Editline.cpp */; };
|
||||
26CFDCA71861646C000E63E5 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32A10F3DFDD009D5894 /* libedit.dylib */; };
|
||||
26CFDCA818616473000E63E5 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32A10F3DFDD009D5894 /* libedit.dylib */; };
|
||||
26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1803C16CEBFD300EDFB5B /* KQueue.cpp */; };
|
||||
26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1804016CEDF0700EDFB5B /* TimeSpecTimeout.cpp */; };
|
||||
26D1804516CEE12500EDFB5B /* KQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D1804416CEE12500EDFB5B /* KQueue.h */; };
|
||||
|
@ -491,8 +504,6 @@
|
|||
26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26ED3D6C13C563810017D45E /* OptionGroupVariable.cpp */; };
|
||||
26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F4A21A13FBA31A0064B613 /* ThreadMemory.cpp */; };
|
||||
26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27310F3D9E4009D5894 /* Driver.cpp */; };
|
||||
26F5C27810F3D9E4009D5894 /* IOChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27510F3D9E4009D5894 /* IOChannel.cpp */; };
|
||||
26F5C32C10F3DFDD009D5894 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32A10F3DFDD009D5894 /* libedit.dylib */; };
|
||||
26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */; };
|
||||
26F73062139D8FDB00FD51C7 /* History.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F73061139D8FDB00FD51C7 /* History.cpp */; };
|
||||
26FFC19914FC072100087D58 /* AuxVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19314FC072100087D58 /* AuxVector.cpp */; };
|
||||
|
@ -529,7 +540,6 @@
|
|||
4CF3D80C15AF4DC800845BF3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; };
|
||||
4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
|
||||
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; };
|
||||
94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* ValueObjectCast.cpp */; };
|
||||
94145431175E63B500284436 /* lldb-versioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /* lldb-versioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
|
@ -595,10 +605,7 @@
|
|||
9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3576A7116E9AB700E8ED2F /* SBHostOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; };
|
||||
9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */; };
|
||||
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */; };
|
||||
9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; };
|
||||
9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AA69DAE118A023300D753A0 /* SBInputReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */; };
|
||||
9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC7038D117674EB0086C050 /* SBInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9AC70390117675270086C050 /* SBInstructionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC7038F117675270086C050 /* SBInstructionList.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9AC703AF117675410086C050 /* SBInstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC703AE117675410086C050 /* SBInstruction.cpp */; };
|
||||
|
@ -796,6 +803,7 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
260157C41885F4FF00F875CF /* libpanel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpanel.dylib; path = ../../../../../../../usr/lib/libpanel.dylib; sourceTree = "<group>"; };
|
||||
260223E7115F06D500A601A2 /* SBCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBCommunication.h; path = include/lldb/API/SBCommunication.h; sourceTree = "<group>"; };
|
||||
260223E8115F06E500A601A2 /* SBCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBCommunication.cpp; path = source/API/SBCommunication.cpp; sourceTree = "<group>"; };
|
||||
26022531115F27FA00A601A2 /* SBFileSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpec.h; path = include/lldb/API/SBFileSpec.h; sourceTree = "<group>"; };
|
||||
|
@ -804,6 +812,8 @@
|
|||
260A63111860FDB600FECF8E /* Queue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Queue.h; path = include/lldb/Target/Queue.h; sourceTree = "<group>"; };
|
||||
260A63121860FDBD00FECF8E /* QueueItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = QueueItem.h; path = include/lldb/Target/QueueItem.h; sourceTree = "<group>"; };
|
||||
260A63131860FDC700FECF8E /* QueueList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = QueueList.h; path = include/lldb/Target/QueueList.h; sourceTree = "<group>"; };
|
||||
260A63161861008E00FECF8E /* IOHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOHandler.h; path = include/lldb/Core/IOHandler.h; sourceTree = "<group>"; };
|
||||
260A63181861009E00FECF8E /* IOHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOHandler.cpp; path = source/Core/IOHandler.cpp; sourceTree = "<group>"; };
|
||||
260C6EA013011578005E16B0 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = include/lldb/Host/File.h; sourceTree = "<group>"; };
|
||||
260C6EA213011581005E16B0 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = "<group>"; };
|
||||
260C847110F50EFC00BB2B04 /* ThreadPlanBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanBase.cpp; path = source/Target/ThreadPlanBase.cpp; sourceTree = "<group>"; };
|
||||
|
@ -923,7 +933,6 @@
|
|||
2611FEFE142D83060017FEA3 /* SBFrame.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBFrame.i; sourceTree = "<group>"; };
|
||||
2611FEFF142D83060017FEA3 /* SBFunction.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBFunction.i; sourceTree = "<group>"; };
|
||||
2611FF00142D83060017FEA3 /* SBHostOS.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBHostOS.i; sourceTree = "<group>"; };
|
||||
2611FF01142D83060017FEA3 /* SBInputReader.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBInputReader.i; sourceTree = "<group>"; };
|
||||
2611FF02142D83060017FEA3 /* SBInstruction.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBInstruction.i; sourceTree = "<group>"; };
|
||||
2611FF03142D83060017FEA3 /* SBInstructionList.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBInstructionList.i; sourceTree = "<group>"; };
|
||||
2611FF04142D83060017FEA3 /* SBLineEntry.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBLineEntry.i; sourceTree = "<group>"; };
|
||||
|
@ -1026,7 +1035,6 @@
|
|||
2660D9F611922A1300958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = source/Utility/StringExtractor.cpp; sourceTree = "<group>"; };
|
||||
2660D9F711922A1300958FBD /* StringExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = source/Utility/StringExtractor.h; sourceTree = "<group>"; };
|
||||
2660D9FE11922A7F00958FBD /* ThreadPlanStepUntil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepUntil.cpp; path = source/Target/ThreadPlanStepUntil.cpp; sourceTree = "<group>"; };
|
||||
2663E378152BD1890091EC22 /* ReadWriteLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ReadWriteLock.h; path = include/lldb/Host/ReadWriteLock.h; sourceTree = "<group>"; };
|
||||
26651A14133BEC76005B64B7 /* lldb-public.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-public.h"; path = "include/lldb/lldb-public.h"; sourceTree = "<group>"; };
|
||||
26651A15133BF9CC005B64B7 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Opcode.h; path = include/lldb/Core/Opcode.h; sourceTree = "<group>"; };
|
||||
26651A17133BF9DF005B64B7 /* Opcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Opcode.cpp; path = source/Core/Opcode.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1048,6 +1056,7 @@
|
|||
266DFE9613FD656E00D0C574 /* OperatingSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OperatingSystem.cpp; path = source/Target/OperatingSystem.cpp; sourceTree = "<group>"; };
|
||||
266DFE9813FD658300D0C574 /* OperatingSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OperatingSystem.h; path = include/lldb/Target/OperatingSystem.h; sourceTree = "<group>"; };
|
||||
266F5CBB12FC846200DFCE33 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Config.h; path = include/lldb/Host/Config.h; sourceTree = "<group>"; };
|
||||
2670F8111862B44A006B332C /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = "<absolute>"; };
|
||||
2671A0CD134825F6003A87BB /* ConnectionMachPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConnectionMachPort.h; path = include/lldb/Core/ConnectionMachPort.h; sourceTree = "<group>"; };
|
||||
2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConnectionMachPort.cpp; path = source/Core/ConnectionMachPort.cpp; sourceTree = "<group>"; };
|
||||
2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||
|
@ -1408,7 +1417,11 @@
|
|||
26C81CA511335651004BDC5A /* UUID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UUID.cpp; path = source/Core/UUID.cpp; sourceTree = "<group>"; };
|
||||
26CA979F172B1FD5005DC71B /* RegisterContextThreadMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextThreadMemory.cpp; path = Utility/RegisterContextThreadMemory.cpp; sourceTree = "<group>"; };
|
||||
26CA97A0172B1FD5005DC71B /* RegisterContextThreadMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextThreadMemory.h; path = Utility/RegisterContextThreadMemory.h; sourceTree = "<group>"; };
|
||||
26CEB5F018762056008F575A /* CommandObjectGUI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectGUI.cpp; path = source/Commands/CommandObjectGUI.cpp; sourceTree = "<group>"; };
|
||||
26CEB5F118762056008F575A /* CommandObjectGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectGUI.h; path = source/Commands/CommandObjectGUI.h; sourceTree = "<group>"; };
|
||||
26CF992414428766001E4138 /* AnsiTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnsiTerminal.h; path = include/lldb/Utility/AnsiTerminal.h; sourceTree = "<group>"; };
|
||||
26CFDCA01861638D000E63E5 /* Editline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Editline.h; path = include/lldb/Host/Editline.h; sourceTree = "<group>"; };
|
||||
26CFDCA2186163A4000E63E5 /* Editline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Editline.cpp; sourceTree = "<group>"; };
|
||||
26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverAddress.h; path = include/lldb/Breakpoint/BreakpointResolverAddress.h; sourceTree = "<group>"; };
|
||||
26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverFileLine.h; path = include/lldb/Breakpoint/BreakpointResolverFileLine.h; sourceTree = "<group>"; };
|
||||
26D0DD5210FE554D00271C65 /* BreakpointResolverName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverName.h; path = include/lldb/Breakpoint/BreakpointResolverName.h; sourceTree = "<group>"; };
|
||||
|
@ -1482,8 +1495,6 @@
|
|||
26F5C27210F3D9E4009D5894 /* lldb-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "lldb-Info.plist"; path = "tools/driver/lldb-Info.plist"; sourceTree = "<group>"; };
|
||||
26F5C27310F3D9E4009D5894 /* Driver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Driver.cpp; path = tools/driver/Driver.cpp; sourceTree = "<group>"; };
|
||||
26F5C27410F3D9E4009D5894 /* Driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Driver.h; path = tools/driver/Driver.h; sourceTree = "<group>"; };
|
||||
26F5C27510F3D9E4009D5894 /* IOChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IOChannel.cpp; path = tools/driver/IOChannel.cpp; sourceTree = "<group>"; };
|
||||
26F5C27610F3D9E4009D5894 /* IOChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IOChannel.h; path = tools/driver/IOChannel.h; sourceTree = "<group>"; };
|
||||
26F5C32410F3DF23009D5894 /* libpython.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpython.dylib; path = /usr/lib/libpython.dylib; sourceTree = "<absolute>"; };
|
||||
26F5C32A10F3DFDD009D5894 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; };
|
||||
26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libtermcap.dylib; path = /usr/lib/libtermcap.dylib; sourceTree = "<absolute>"; };
|
||||
|
@ -1620,8 +1631,6 @@
|
|||
69A01E201236C5D400C660B5 /* TimeValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimeValue.cpp; sourceTree = "<group>"; };
|
||||
94005E0313F438DF001EF42D /* python-wrapper.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-wrapper.swig"; sourceTree = "<group>"; };
|
||||
94005E0513F45A1B001EF42D /* embedded_interpreter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = embedded_interpreter.py; path = source/Interpreter/embedded_interpreter.py; sourceTree = "<group>"; };
|
||||
94031A9B13CF484600DCFF3C /* InputReaderEZ.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InputReaderEZ.h; path = include/lldb/Core/InputReaderEZ.h; sourceTree = "<group>"; };
|
||||
94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderEZ.cpp; path = source/Core/InputReaderEZ.cpp; sourceTree = "<group>"; };
|
||||
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = "<group>"; };
|
||||
94094C68163B6CCC0083A547 /* ValueObjectCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectCast.h; path = include/lldb/Core/ValueObjectCast.h; sourceTree = "<group>"; };
|
||||
94094C69163B6CD90083A547 /* ValueObjectCast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectCast.cpp; path = source/Core/ValueObjectCast.cpp; sourceTree = "<group>"; };
|
||||
|
@ -1761,12 +1770,6 @@
|
|||
9A9831081125FC5800A56CB0 /* SBTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBTarget.h; path = include/lldb/API/SBTarget.h; sourceTree = "<group>"; };
|
||||
9A9831091125FC5800A56CB0 /* SBThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBThread.cpp; path = source/API/SBThread.cpp; sourceTree = "<group>"; };
|
||||
9A98310A1125FC5800A56CB0 /* SBThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBThread.h; path = include/lldb/API/SBThread.h; sourceTree = "<group>"; };
|
||||
9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReaderStack.cpp; path = source/Core/InputReaderStack.cpp; sourceTree = "<group>"; };
|
||||
9A9E1F0013980943005AC039 /* InputReaderStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputReaderStack.h; path = include/lldb/Core/InputReaderStack.h; sourceTree = "<group>"; };
|
||||
9AA69DAE118A023300D753A0 /* SBInputReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBInputReader.h; path = include/lldb/API/SBInputReader.h; sourceTree = "<group>"; };
|
||||
9AA69DB0118A024600D753A0 /* SBInputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBInputReader.cpp; path = source/API/SBInputReader.cpp; sourceTree = "<group>"; };
|
||||
9AA69DB5118A027A00D753A0 /* InputReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputReader.cpp; path = source/Core/InputReader.cpp; sourceTree = "<group>"; };
|
||||
9AA69DBB118A029E00D753A0 /* InputReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputReader.h; path = include/lldb/Core/InputReader.h; sourceTree = "<group>"; };
|
||||
9AC7033D11752C4C0086C050 /* AddressResolverFileLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddressResolverFileLine.h; path = include/lldb/Core/AddressResolverFileLine.h; sourceTree = "<group>"; };
|
||||
9AC7033E11752C540086C050 /* AddressResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddressResolver.h; path = include/lldb/Core/AddressResolver.h; sourceTree = "<group>"; };
|
||||
9AC7033F11752C590086C050 /* AddressResolverName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddressResolverName.h; path = include/lldb/Core/AddressResolverName.h; sourceTree = "<group>"; };
|
||||
|
@ -1862,6 +1865,9 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
260157C81885F53100F875CF /* libpanel.dylib in Frameworks */,
|
||||
2670F8121862B44A006B332C /* libncurses.dylib in Frameworks */,
|
||||
26CEB5EF18761CB2008F575A /* libedit.dylib in Frameworks */,
|
||||
26D55235159A7DB100708D8D /* libxml2.dylib in Frameworks */,
|
||||
268901161335BBC300698AC0 /* liblldb-core.a in Frameworks */,
|
||||
2668022F115FD19D008E1FE4 /* CoreFoundation.framework in Frameworks */,
|
||||
|
@ -1881,6 +1887,9 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
260157C71885F52500F875CF /* libpanel.dylib in Frameworks */,
|
||||
26780C651867C34500234593 /* libncurses.dylib in Frameworks */,
|
||||
26CFDCA71861646C000E63E5 /* libedit.dylib in Frameworks */,
|
||||
26D6F3FA183E888800194858 /* liblldb-core.a in Frameworks */,
|
||||
2606EDDE184E68940034641B /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
|
@ -1890,6 +1899,9 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */,
|
||||
26780C611867C33D00234593 /* libncurses.dylib in Frameworks */,
|
||||
26CFDCA818616473000E63E5 /* libedit.dylib in Frameworks */,
|
||||
2606EDDF184E68A10034641B /* liblldb-core.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1898,7 +1910,6 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
26F5C32C10F3DFDD009D5894 /* libedit.dylib in Frameworks */,
|
||||
26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */,
|
||||
2668035C11601108008E1FE4 /* LLDB.framework in Frameworks */,
|
||||
);
|
||||
|
@ -1925,6 +1936,7 @@
|
|||
08FB7794FE84155DC02AAC07 /* lldb */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
260157C41885F4FF00F875CF /* libpanel.dylib */,
|
||||
26F5C32810F3DF7D009D5894 /* Libraries */,
|
||||
264E8576159BE51A00E9D7A2 /* Resources */,
|
||||
08FB7795FE84155DC02AAC07 /* Source */,
|
||||
|
@ -2213,7 +2225,6 @@
|
|||
4CE4F676162CE1E100F75CB3 /* SBExpressionOptions.i */,
|
||||
2611FEFF142D83060017FEA3 /* SBFunction.i */,
|
||||
2611FF00142D83060017FEA3 /* SBHostOS.i */,
|
||||
2611FF01142D83060017FEA3 /* SBInputReader.i */,
|
||||
2611FF02142D83060017FEA3 /* SBInstruction.i */,
|
||||
2611FF03142D83060017FEA3 /* SBInstructionList.i */,
|
||||
2611FF04142D83060017FEA3 /* SBLineEntry.i */,
|
||||
|
@ -2309,8 +2320,6 @@
|
|||
26DE205C1161901400A093E2 /* SBFunction.cpp */,
|
||||
9A3576A7116E9AB700E8ED2F /* SBHostOS.h */,
|
||||
9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */,
|
||||
9AA69DAE118A023300D753A0 /* SBInputReader.h */,
|
||||
9AA69DB0118A024600D753A0 /* SBInputReader.cpp */,
|
||||
9AC7038D117674EB0086C050 /* SBInstruction.h */,
|
||||
9AC703AE117675410086C050 /* SBInstruction.cpp */,
|
||||
9AC7038F117675270086C050 /* SBInstructionList.h */,
|
||||
|
@ -2716,12 +2725,8 @@
|
|||
26BC7D6410F1B77400F91463 /* Flags.h */,
|
||||
26F7305F139D8FC900FD51C7 /* History.h */,
|
||||
26F73061139D8FDB00FD51C7 /* History.cpp */,
|
||||
9AA69DBB118A029E00D753A0 /* InputReader.h */,
|
||||
9AA69DB5118A027A00D753A0 /* InputReader.cpp */,
|
||||
94031A9B13CF484600DCFF3C /* InputReaderEZ.h */,
|
||||
94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */,
|
||||
9A9E1F0013980943005AC039 /* InputReaderStack.h */,
|
||||
9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */,
|
||||
260A63161861008E00FECF8E /* IOHandler.h */,
|
||||
260A63181861009E00FECF8E /* IOHandler.cpp */,
|
||||
26BC7D6510F1B77400F91463 /* IOStreamMacros.h */,
|
||||
26BC7D6610F1B77400F91463 /* Language.h */,
|
||||
26BC7E7D10F1B85900F91463 /* Language.cpp */,
|
||||
|
@ -2954,6 +2959,8 @@
|
|||
26BC7E3110F1B84700F91463 /* CommandObjectExpression.cpp */,
|
||||
2672D8471189055500FF4019 /* CommandObjectFrame.h */,
|
||||
2672D8461189055500FF4019 /* CommandObjectFrame.cpp */,
|
||||
26CEB5F118762056008F575A /* CommandObjectGUI.h */,
|
||||
26CEB5F018762056008F575A /* CommandObjectGUI.cpp */,
|
||||
26BC7D1A10F1B76300F91463 /* CommandObjectHelp.h */,
|
||||
26BC7E3310F1B84700F91463 /* CommandObjectHelp.cpp */,
|
||||
264AD83911095BBD00E0B039 /* CommandObjectLog.h */,
|
||||
|
@ -3048,6 +3055,7 @@
|
|||
26BC7DD210F1B7D500F91463 /* Condition.h */,
|
||||
266F5CBB12FC846200DFCE33 /* Config.h */,
|
||||
9456F2231616645A00656F91 /* DynamicLibrary.h */,
|
||||
26CFDCA01861638D000E63E5 /* Editline.h */,
|
||||
26BC7DD310F1B7D500F91463 /* Endian.h */,
|
||||
260C6EA013011578005E16B0 /* File.h */,
|
||||
26FA4315130103F400E71120 /* FileSpec.h */,
|
||||
|
@ -3055,7 +3063,6 @@
|
|||
26BC7DD510F1B7D500F91463 /* Mutex.h */,
|
||||
A36FF33D17D8E98800244D40 /* OptionParser.h */,
|
||||
26BC7DD610F1B7D500F91463 /* Predicate.h */,
|
||||
2663E378152BD1890091EC22 /* ReadWriteLock.h */,
|
||||
26D7E45B13D5E2F9007FD12B /* SocketAddress.h */,
|
||||
26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */,
|
||||
2689B0A4113EE3CD00A4AEDB /* Symbols.h */,
|
||||
|
@ -3411,8 +3418,6 @@
|
|||
26F5C27210F3D9E4009D5894 /* lldb-Info.plist */,
|
||||
26F5C27410F3D9E4009D5894 /* Driver.h */,
|
||||
26F5C27310F3D9E4009D5894 /* Driver.cpp */,
|
||||
26F5C27610F3D9E4009D5894 /* IOChannel.h */,
|
||||
26F5C27510F3D9E4009D5894 /* IOChannel.cpp */,
|
||||
);
|
||||
name = Driver;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3425,6 +3430,7 @@
|
|||
260C876910F538E700BB2B04 /* Foundation.framework */,
|
||||
26F5C32A10F3DFDD009D5894 /* libedit.dylib */,
|
||||
2689FFCA13353D7A00698AC0 /* liblldb-core.a */,
|
||||
2670F8111862B44A006B332C /* libncurses.dylib */,
|
||||
26F5C37410F3F61B009D5894 /* libobjc.dylib */,
|
||||
26F5C32410F3DF23009D5894 /* libpython.dylib */,
|
||||
26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */,
|
||||
|
@ -3538,6 +3544,7 @@
|
|||
children = (
|
||||
AF37E10917C861F20061E18E /* ProcessRunLock.cpp */,
|
||||
9456F2211616644B00656F91 /* DynamicLibrary.cpp */,
|
||||
26CFDCA2186163A4000E63E5 /* Editline.cpp */,
|
||||
260C6EA213011581005E16B0 /* File.cpp */,
|
||||
26FA43171301048600E71120 /* FileSpec.cpp */,
|
||||
69A01E1B1236C5D400C660B5 /* Condition.cpp */,
|
||||
|
@ -3667,7 +3674,6 @@
|
|||
26680225115FD13D008E1FE4 /* SBFrame.h in Headers */,
|
||||
26DE205311618FAC00A093E2 /* SBFunction.h in Headers */,
|
||||
9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */,
|
||||
9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */,
|
||||
9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */,
|
||||
9AC70390117675270086C050 /* SBInstructionList.h in Headers */,
|
||||
26DE205911618FE700A093E2 /* SBLineEntry.h in Headers */,
|
||||
|
@ -3719,7 +3725,6 @@
|
|||
2694E9A514FC0BBD0076DE67 /* PlatformLinux.h in Headers */,
|
||||
26AB54121832DC3400EADFF3 /* RegisterCheckpoint.h in Headers */,
|
||||
26AB92131819D74600E63F3E /* DWARFDataExtractor.h in Headers */,
|
||||
2663E379152BD1890091EC22 /* ReadWriteLock.h in Headers */,
|
||||
945759681534941F005A9070 /* PlatformPOSIX.h in Headers */,
|
||||
26B1EFAF154638AF00E2DAC7 /* DWARFDeclContext.h in Headers */,
|
||||
260CC62E15D04377002BF2E0 /* OptionValueArgs.h in Headers */,
|
||||
|
@ -3729,7 +3734,9 @@
|
|||
260CC63215D04377002BF2E0 /* OptionValueDictionary.h in Headers */,
|
||||
262173A118395D3800C52091 /* SectionLoadHistory.h in Headers */,
|
||||
260CC63315D04377002BF2E0 /* OptionValueEnumeration.h in Headers */,
|
||||
260A63171861008E00FECF8E /* IOHandler.h in Headers */,
|
||||
260CC63415D04377002BF2E0 /* OptionValueFileSpec.h in Headers */,
|
||||
26CFDCA11861638D000E63E5 /* Editline.h in Headers */,
|
||||
AF9B8F34182DB52900DA866F /* SystemRuntimeMacOSX.h in Headers */,
|
||||
26D1804716CEE12C00EDFB5B /* TimeSpecTimeout.h in Headers */,
|
||||
260CC63515D04377002BF2E0 /* OptionValueFileSpecList.h in Headers */,
|
||||
|
@ -3752,6 +3759,7 @@
|
|||
947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */,
|
||||
262ED0051631FA2800879631 /* OptionGroupString.h in Headers */,
|
||||
944372DD171F6B4300E57C32 /* RegisterContextDummy.h in Headers */,
|
||||
26CEB5F318762056008F575A /* CommandObjectGUI.h in Headers */,
|
||||
AF061F8B182C980000B6A19C /* HistoryThread.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -4118,7 +4126,6 @@
|
|||
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */,
|
||||
9AC703AF117675410086C050 /* SBInstruction.cpp in Sources */,
|
||||
9AC703B1117675490086C050 /* SBInstructionList.cpp in Sources */,
|
||||
9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */,
|
||||
268F9D55123AA16600B91E9B /* SBSymbolContextList.cpp in Sources */,
|
||||
26C72C961243229A0068DC16 /* SBStream.cpp in Sources */,
|
||||
9443B122140C18C40013457C /* SBData.cpp in Sources */,
|
||||
|
@ -4208,7 +4215,6 @@
|
|||
2689003C13353E0400698AC0 /* Error.cpp in Sources */,
|
||||
2689003D13353E0400698AC0 /* Event.cpp in Sources */,
|
||||
2689003E13353E0400698AC0 /* FileSpecList.cpp in Sources */,
|
||||
2689003F13353E0400698AC0 /* InputReader.cpp in Sources */,
|
||||
2689004013353E0400698AC0 /* Language.cpp in Sources */,
|
||||
2689004113353E0400698AC0 /* Listener.cpp in Sources */,
|
||||
2689004213353E0400698AC0 /* Log.cpp in Sources */,
|
||||
|
@ -4278,6 +4284,7 @@
|
|||
2689007C13353E1A00698AC0 /* Symbols.cpp in Sources */,
|
||||
2689007D13353E2200698AC0 /* Args.cpp in Sources */,
|
||||
2689007F13353E2200698AC0 /* CommandCompletions.cpp in Sources */,
|
||||
26CEB5F218762056008F575A /* CommandObjectGUI.cpp in Sources */,
|
||||
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */,
|
||||
AF9B8F33182DB52900DA866F /* SystemRuntimeMacOSX.cpp in Sources */,
|
||||
2689008113353E2200698AC0 /* CommandObject.cpp in Sources */,
|
||||
|
@ -4288,6 +4295,7 @@
|
|||
2689008713353E2200698AC0 /* ScriptInterpreter.cpp in Sources */,
|
||||
2689008813353E2200698AC0 /* ScriptInterpreterNone.cpp in Sources */,
|
||||
2689008913353E2200698AC0 /* ScriptInterpreterPython.cpp in Sources */,
|
||||
260A63191861009E00FECF8E /* IOHandler.cpp in Sources */,
|
||||
2689008D13353E4200698AC0 /* DynamicLoaderMacOSXDYLD.cpp in Sources */,
|
||||
2689008E13353E4200698AC0 /* DynamicLoaderStatic.cpp in Sources */,
|
||||
2689009613353E4200698AC0 /* ObjectContainerBSDArchive.cpp in Sources */,
|
||||
|
@ -4441,7 +4449,6 @@
|
|||
26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */,
|
||||
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */,
|
||||
2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */,
|
||||
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */,
|
||||
B28058A1139988B0002D96D0 /* InferiorCallPOSIX.cpp in Sources */,
|
||||
26F73062139D8FDB00FD51C7 /* History.cpp in Sources */,
|
||||
4CCA644D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp in Sources */,
|
||||
|
@ -4453,7 +4460,6 @@
|
|||
9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */,
|
||||
49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */,
|
||||
26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */,
|
||||
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */,
|
||||
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */,
|
||||
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */,
|
||||
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */,
|
||||
|
@ -4475,6 +4481,7 @@
|
|||
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */,
|
||||
949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */,
|
||||
B27318421416AC12006039C8 /* WatchpointList.cpp in Sources */,
|
||||
26CFDCA3186163A4000E63E5 /* Editline.cpp in Sources */,
|
||||
26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */,
|
||||
B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */,
|
||||
49A71FE7141FFA5C00D59478 /* IRInterpreter.cpp in Sources */,
|
||||
|
@ -4563,7 +4570,6 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */,
|
||||
26F5C27810F3D9E4009D5894 /* IOChannel.cpp in Sources */,
|
||||
9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -99,7 +99,6 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\
|
|||
" ${SRC_ROOT}/include/lldb/API/SBFrame.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBFunction.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBHostOS.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBInputReader.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBInstruction.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBInstructionList.h"\
|
||||
" ${SRC_ROOT}/include/lldb/API/SBLineEntry.h"\
|
||||
|
@ -147,7 +146,6 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\
|
|||
" ${SRC_ROOT}/scripts/Python/interface/SBFrame.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBFunction.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBHostOS.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBInputReader.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBInstruction.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBInstructionList.i"\
|
||||
" ${SRC_ROOT}/scripts/Python/interface/SBLineEntry.i"\
|
||||
|
|
|
@ -78,6 +78,9 @@ public:
|
|||
bool
|
||||
IsValid() const;
|
||||
|
||||
const char *
|
||||
GetIOHandlerControlSequence(char ch);
|
||||
|
||||
bool
|
||||
CommandExists (const char *cmd);
|
||||
|
||||
|
@ -120,6 +123,10 @@ public:
|
|||
int match_start_point,
|
||||
int max_return_elements,
|
||||
lldb::SBStringList &matches);
|
||||
|
||||
bool
|
||||
IsActive ();
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
|
|
@ -292,15 +292,6 @@ public:
|
|||
void
|
||||
DispatchInputEndOfFile ();
|
||||
|
||||
void
|
||||
PushInputReader (lldb::SBInputReader &reader);
|
||||
|
||||
void
|
||||
NotifyTopInputReader (lldb::InputReaderAction notification);
|
||||
|
||||
bool
|
||||
InputReaderIsTopReader (const lldb::SBInputReader &reader);
|
||||
|
||||
const char *
|
||||
GetInstanceName ();
|
||||
|
||||
|
@ -372,7 +363,11 @@ public:
|
|||
|
||||
lldb::SBTypeSynthetic
|
||||
GetSyntheticForType (lldb::SBTypeNameSpecifier);
|
||||
|
||||
|
||||
void
|
||||
RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread);
|
||||
|
||||
}; // class SBDebugger
|
||||
|
||||
} // namespace lldb
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
//===-- SWIG Interface for SBInputREader ------------------------*- 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 SBInputReader
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t (*Callback) (void *baton,
|
||||
SBInputReader *reader,
|
||||
InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
SBInputReader ();
|
||||
|
||||
SBInputReader (const lldb::SBInputReader &rhs);
|
||||
|
||||
~SBInputReader ();
|
||||
|
||||
SBError
|
||||
Initialize (SBDebugger &debugger,
|
||||
Callback callback,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo);
|
||||
|
||||
bool
|
||||
IsValid () const;
|
||||
|
||||
bool
|
||||
IsActive () const;
|
||||
|
||||
bool
|
||||
IsDone () const;
|
||||
|
||||
void
|
||||
SetIsDone (bool value);
|
||||
|
||||
InputReaderGranularity
|
||||
GetGranularity ();
|
||||
};
|
||||
|
||||
} // namespace lldb
|
|
@ -777,15 +777,6 @@
|
|||
// Py_XDECREF($self->GetCallbackBaton());
|
||||
// }
|
||||
// }
|
||||
// %extend lldb::SBInputReader {
|
||||
// // FIXME: m_callback_function is private and we have no other
|
||||
// // way to access it.
|
||||
// PyObject *lldb::SBInputReader::__del__ (){
|
||||
// // Only call Py_XDECREF if we have a Python object (or NULL)
|
||||
// if (LLDBSwigPythonCallSBInputReaderCallback == $self->m_callback_function)
|
||||
// Py_XDECREF($self->m_callback_baton);
|
||||
// }
|
||||
// }
|
||||
|
||||
%pythoncode %{
|
||||
|
||||
|
|
|
@ -112,10 +112,3 @@ SBTypeToSWIGWrapper (lldb::SBCommandReturnObject* cmd_ret_obj_sb)
|
|||
{
|
||||
return SWIG_NewPointerObj((void *) cmd_ret_obj_sb, SWIGTYPE_p_lldb__SBCommandReturnObject, 0);
|
||||
}
|
||||
|
||||
template <>
|
||||
PyObject*
|
||||
SBTypeToSWIGWrapper (lldb::SBInputReader* input_reader_sb)
|
||||
{
|
||||
return SWIG_NewPointerObj((void *) input_reader_sb, SWIGTYPE_p_lldb__SBInputReader, 0);
|
||||
}
|
||||
|
|
|
@ -355,28 +355,6 @@
|
|||
free($1);
|
||||
}
|
||||
|
||||
// For lldb::SBInputReader::Callback
|
||||
%typemap(in) (lldb::SBInputReader::Callback callback, void *callback_baton) {
|
||||
if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
|
||||
PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME (filcab): We can't currently check if our callback is already
|
||||
// LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
|
||||
// baton) nor can we just remove all traces of a callback, if we want to
|
||||
// revert to a file logging mechanism.
|
||||
|
||||
// Don't lose the callback reference
|
||||
Py_INCREF($input);
|
||||
$1 = LLDBSwigPythonCallSBInputReaderCallback;
|
||||
$2 = $input;
|
||||
}
|
||||
|
||||
%typemap(typecheck) (lldb::SBInputReader::Callback callback, void *baton) {
|
||||
$1 = $input == Py_None;
|
||||
$1 = $1 || PyCallable_Check(reinterpret_cast<PyObject*>($input));
|
||||
}
|
||||
|
||||
// For Log::LogOutputCallback
|
||||
%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
|
||||
|
|
|
@ -929,10 +929,6 @@ LLDBSwigPythonCallModuleInit
|
|||
|
||||
%runtime %{
|
||||
// Forward declaration to be inserted at the start of LLDBWrapPython.h
|
||||
// I used runtime as a hack to make SWIG place it where it's needed.
|
||||
// This is needed to use LLDBSwigPythonCallSBInputReaderCallback in the
|
||||
// typemaps and in the extensions (SBInputReader.__del__()).
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
|
||||
|
@ -952,13 +948,6 @@ LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t
|
||||
LLDBSwigPythonCallSBInputReaderCallback(void *baton,
|
||||
lldb::SBInputReader *reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char*bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -967,47 +956,7 @@ void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
|
|||
%}
|
||||
|
||||
%wrapper %{
|
||||
// For the InputReader Callback functions
|
||||
SWIGEXPORT size_t
|
||||
LLDBSwigPythonCallSBInputReaderCallback(void *baton,
|
||||
lldb::SBInputReader *reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char*bytes,
|
||||
size_t bytes_len) {
|
||||
if (baton != Py_None) {
|
||||
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
|
||||
|
||||
PyObject *py_InputReader = SBTypeToSWIGWrapper(reader);
|
||||
PyObject *py_Notification = PyInt_FromLong(notification);
|
||||
PyObject *py_Bytes = PyBytes_FromStringAndSize(bytes, bytes_len);
|
||||
|
||||
PyObject *tuple = PyTuple_Pack(3, py_InputReader, py_Notification, py_Bytes);
|
||||
PyObject *res = PyObject_Call(reinterpret_cast<PyObject*>(baton), tuple, NULL);
|
||||
Py_XDECREF(tuple);
|
||||
Py_XDECREF(py_InputReader);
|
||||
Py_XDECREF(py_Notification);
|
||||
Py_XDECREF(py_Bytes);
|
||||
|
||||
if (res == NULL) {
|
||||
PyObject *exc = PyErr_Occurred();
|
||||
if (exc) {
|
||||
::puts("\nErroring out at LLDBSwigPythonCallSBInputReaderCallback");
|
||||
PyErr_Print();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t result = 0;
|
||||
// If the callback misbehaves and returns Py_None, assume it returned 0
|
||||
if (res != Py_None)
|
||||
result = static_cast<size_t>(PyInt_AsSsize_t(res));
|
||||
|
||||
Py_XDECREF(res);
|
||||
SWIG_PYTHON_THREAD_END_BLOCK;
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// For the LogOutputCallback functions
|
||||
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
|
||||
|
|
|
@ -72,7 +72,6 @@ import os
|
|||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBFunction.h"
|
||||
#include "lldb/API/SBHostOS.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBInstruction.h"
|
||||
#include "lldb/API/SBInstructionList.h"
|
||||
#include "lldb/API/SBLineEntry.h"
|
||||
|
@ -139,7 +138,6 @@ import os
|
|||
%include "./Python/interface/SBFrame.i"
|
||||
%include "./Python/interface/SBFunction.i"
|
||||
%include "./Python/interface/SBHostOS.i"
|
||||
%include "./Python/interface/SBInputReader.i"
|
||||
%include "./Python/interface/SBInstruction.i"
|
||||
%include "./Python/interface/SBInstructionList.i"
|
||||
%include "./Python/interface/SBLineEntry.i"
|
||||
|
|
|
@ -21,7 +21,6 @@ add_lldb_library(lldbAPI
|
|||
SBFrame.cpp
|
||||
SBFunction.cpp
|
||||
SBHostOS.cpp
|
||||
SBInputReader.cpp
|
||||
SBInstruction.cpp
|
||||
SBInstructionList.cpp
|
||||
SBLineEntry.cpp
|
||||
|
|
|
@ -107,6 +107,22 @@ SBCommandInterpreter::AliasExists (const char *cmd)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SBCommandInterpreter::IsActive ()
|
||||
{
|
||||
if (m_opaque_ptr)
|
||||
return m_opaque_ptr->IsActive ();
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *
|
||||
SBCommandInterpreter::GetIOHandlerControlSequence(char ch)
|
||||
{
|
||||
if (m_opaque_ptr)
|
||||
return m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence (ch).GetCString();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lldb::ReturnStatus
|
||||
SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBSourceManager.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
|
@ -37,6 +36,7 @@
|
|||
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/DataFormatters/DataVisualization.h"
|
||||
#include "lldb/Host/DynamicLibrary.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
|
@ -49,6 +49,29 @@ using namespace lldb;
|
|||
using namespace lldb_private;
|
||||
|
||||
|
||||
SBInputReader::SBInputReader()
|
||||
{
|
||||
}
|
||||
SBInputReader::~SBInputReader()
|
||||
{
|
||||
}
|
||||
|
||||
SBError
|
||||
SBInputReader::Initialize(lldb::SBDebugger& sb_debugger, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool)
|
||||
{
|
||||
return SBError();
|
||||
}
|
||||
|
||||
void
|
||||
SBInputReader::SetIsDone(bool)
|
||||
{
|
||||
}
|
||||
bool
|
||||
SBInputReader::IsActive() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static lldb::DynamicLibrarySP
|
||||
LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error)
|
||||
{
|
||||
|
@ -111,7 +134,7 @@ SBDebugger::Clear ()
|
|||
log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get());
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->CleanUpInputReaders ();
|
||||
m_opaque_sp->ClearIOHandlers ();
|
||||
|
||||
m_opaque_sp.reset();
|
||||
}
|
||||
|
@ -309,7 +332,11 @@ FILE *
|
|||
SBDebugger::GetInputFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetInputFile().GetStream();
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -317,7 +344,11 @@ FILE *
|
|||
SBDebugger::GetOutputFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetOutputFile().GetStream();
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -325,7 +356,12 @@ FILE *
|
|||
SBDebugger::GetErrorFileHandle ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetErrorFile().GetStream();
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
StreamFileSP stream_file_sp (m_opaque_sp->GetErrorFile());
|
||||
if (stream_file_sp)
|
||||
return stream_file_sp->GetFile().GetStream();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -885,17 +921,17 @@ SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len)
|
|||
void
|
||||
SBDebugger::DispatchInput (const void *data, size_t data_len)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
|
||||
m_opaque_sp.get(),
|
||||
(int) data_len,
|
||||
(const char *) data,
|
||||
(uint64_t)data_len);
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->DispatchInput ((const char *) data, data_len);
|
||||
// Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
//
|
||||
// if (log)
|
||||
// log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
|
||||
// m_opaque_sp.get(),
|
||||
// (int) data_len,
|
||||
// (const char *) data,
|
||||
// (uint64_t)data_len);
|
||||
//
|
||||
// if (m_opaque_sp)
|
||||
// m_opaque_sp->DispatchInput ((const char *) data, data_len);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -911,54 +947,18 @@ SBDebugger::DispatchInputEndOfFile ()
|
|||
if (m_opaque_sp)
|
||||
m_opaque_sp->DispatchInputEndOfFile ();
|
||||
}
|
||||
|
||||
bool
|
||||
SBDebugger::InputReaderIsTopReader (const lldb::SBInputReader &reader)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::InputReaderIsTopReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
|
||||
|
||||
if (m_opaque_sp && reader.IsValid())
|
||||
{
|
||||
InputReaderSP reader_sp (*reader);
|
||||
return m_opaque_sp->InputReaderIsTopReader (reader_sp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SBDebugger::PushInputReader (SBInputReader &reader)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
|
||||
|
||||
if (m_opaque_sp && reader.IsValid())
|
||||
{
|
||||
TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
|
||||
Mutex::Locker api_locker;
|
||||
if (target_sp)
|
||||
api_locker.Lock(target_sp->GetAPIMutex());
|
||||
InputReaderSP reader_sp(*reader);
|
||||
m_opaque_sp->PushInputReader (reader_sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SBDebugger::NotifyTopInputReader (InputReaderAction notification)
|
||||
SBDebugger::RunCommandInterpreter (bool auto_handle_events,
|
||||
bool spawn_thread)
|
||||
{
|
||||
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification);
|
||||
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->NotifyTopInputReader (notification);
|
||||
m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, spawn_thread);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1050,7 +1050,7 @@ SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger
|
|||
if (!value_str.empty())
|
||||
{
|
||||
StringList string_list;
|
||||
string_list.SplitIntoLines(value_str.c_str(), value_str.size());
|
||||
string_list.SplitIntoLines(value_str);
|
||||
return SBStringList(&string_list);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
//===-- SBInputReader.cpp ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBInputReader.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
SBInputReader::SBInputReader () :
|
||||
m_opaque_sp (),
|
||||
m_callback_function (NULL),
|
||||
m_callback_baton (NULL)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
SBInputReader::SBInputReader (const lldb::InputReaderSP &reader_sp) :
|
||||
m_opaque_sp (reader_sp)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBInputReader::SBInputReader (reader_sp=%p) => SBInputReader(%p)", reader_sp.get(),
|
||||
m_opaque_sp.get());
|
||||
}
|
||||
|
||||
SBInputReader::SBInputReader (const SBInputReader &rhs) :
|
||||
m_opaque_sp (rhs.m_opaque_sp)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf("SBInputReader::SBInputReader (rhs.sp=%p) => SBInputReader(%p)",
|
||||
rhs.m_opaque_sp.get(), m_opaque_sp.get());
|
||||
}
|
||||
|
||||
SBInputReader::~SBInputReader ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
SBInputReader::PrivateCallback
|
||||
(
|
||||
void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len
|
||||
)
|
||||
{
|
||||
SBInputReader *sb_reader = (SBInputReader *)baton;
|
||||
return sb_reader->m_callback_function (sb_reader->m_callback_baton,
|
||||
sb_reader,
|
||||
notification,
|
||||
bytes,
|
||||
bytes_len);
|
||||
}
|
||||
|
||||
SBError
|
||||
SBInputReader::Initialize
|
||||
(
|
||||
SBDebugger &debugger,
|
||||
Callback callback_function,
|
||||
void *callback_baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo
|
||||
)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
if (log)
|
||||
log->Printf("SBInputReader(%p)::Initialize (SBDebugger(%p), callback_function=%p, callback_baton=%p, "
|
||||
"granularity=%s, end_token=\"%s\", prompt=\"%s\", echo=%i)",
|
||||
m_opaque_sp.get(),
|
||||
debugger.get(),
|
||||
callback_function,
|
||||
callback_baton,
|
||||
InputReader::GranularityAsCString (granularity), end_token, prompt,
|
||||
echo);
|
||||
|
||||
SBError sb_error;
|
||||
m_opaque_sp.reset (new InputReader (debugger.ref()));
|
||||
|
||||
m_callback_function = callback_function;
|
||||
m_callback_baton = callback_baton;
|
||||
|
||||
if (m_opaque_sp)
|
||||
{
|
||||
sb_error.SetError (m_opaque_sp->Initialize (SBInputReader::PrivateCallback,
|
||||
this,
|
||||
granularity,
|
||||
end_token,
|
||||
prompt,
|
||||
echo));
|
||||
}
|
||||
|
||||
if (sb_error.Fail())
|
||||
{
|
||||
m_opaque_sp.reset ();
|
||||
m_callback_function = NULL;
|
||||
m_callback_baton = NULL;
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
SBStream sstr;
|
||||
sb_error.GetDescription (sstr);
|
||||
log->Printf ("SBInputReader(%p)::Initialize (...) => SBError(%p): %s", m_opaque_sp.get(),
|
||||
sb_error.get(), sstr.GetData());
|
||||
}
|
||||
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsValid () const
|
||||
{
|
||||
return (m_opaque_sp.get() != NULL);
|
||||
}
|
||||
|
||||
const SBInputReader &
|
||||
SBInputReader::operator = (const SBInputReader &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
m_opaque_sp = rhs.m_opaque_sp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InputReader *
|
||||
SBInputReader::operator->() const
|
||||
{
|
||||
return m_opaque_sp.get();
|
||||
}
|
||||
|
||||
lldb::InputReaderSP &
|
||||
SBInputReader::operator *()
|
||||
{
|
||||
return m_opaque_sp;
|
||||
}
|
||||
|
||||
const lldb::InputReaderSP &
|
||||
SBInputReader::operator *() const
|
||||
{
|
||||
return m_opaque_sp;
|
||||
}
|
||||
|
||||
InputReader *
|
||||
SBInputReader::get() const
|
||||
{
|
||||
return m_opaque_sp.get();
|
||||
}
|
||||
|
||||
InputReader &
|
||||
SBInputReader::ref() const
|
||||
{
|
||||
assert (m_opaque_sp.get());
|
||||
return *m_opaque_sp;
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsDone () const
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->IsDone();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SBInputReader::SetIsDone (bool value)
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
m_opaque_sp->SetIsDone (value);
|
||||
}
|
||||
|
||||
bool
|
||||
SBInputReader::IsActive () const
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
bool ret_value = false;
|
||||
if (m_opaque_sp)
|
||||
ret_value = m_opaque_sp->IsActive();
|
||||
|
||||
if (log)
|
||||
log->Printf ("SBInputReader(%p)::IsActive () => %i", m_opaque_sp.get(), ret_value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
InputReaderGranularity
|
||||
SBInputReader::GetGranularity ()
|
||||
{
|
||||
if (m_opaque_sp)
|
||||
return m_opaque_sp->GetGranularity();
|
||||
else
|
||||
return eInputReaderGranularityInvalid;
|
||||
}
|
|
@ -10,6 +10,7 @@ add_lldb_library(lldbCommands
|
|||
CommandObjectDisassemble.cpp
|
||||
CommandObjectExpression.cpp
|
||||
CommandObjectFrame.cpp
|
||||
CommandObjectGUI.cpp
|
||||
CommandObjectHelp.cpp
|
||||
CommandObjectLog.cpp
|
||||
CommandObjectMemory.cpp
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "CommandObjectBreakpointCommand.h"
|
||||
#include "CommandObjectBreakpoint.h"
|
||||
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -34,7 +35,9 @@ using namespace lldb_private;
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
class CommandObjectBreakpointCommandAdd : public CommandObjectParsed
|
||||
class CommandObjectBreakpointCommandAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -43,6 +46,7 @@ public:
|
|||
"add",
|
||||
"Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.",
|
||||
NULL),
|
||||
IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
|
||||
m_options (interpreter)
|
||||
{
|
||||
SetHelpLong (
|
||||
|
@ -207,40 +211,45 @@ one command per line.\n" );
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString(g_reader_instructions);
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
|
||||
{
|
||||
io_handler.SetIsDone(true);
|
||||
|
||||
BreakpointOptions *bp_options = (BreakpointOptions *) io_handler.GetUserData();
|
||||
if (bp_options)
|
||||
{
|
||||
std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
|
||||
if (data_ap.get())
|
||||
{
|
||||
data_ap->user_source.SplitIntoLines (line.c_str(), line.size());
|
||||
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
|
||||
bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
|
||||
CommandReturnObject &result)
|
||||
{
|
||||
InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
|
||||
std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
|
||||
if (reader_sp && data_ap.get())
|
||||
{
|
||||
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
|
||||
bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp);
|
||||
|
||||
Error err (reader_sp->Initialize (CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback,
|
||||
bp_options, // baton
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
"DONE", // end token
|
||||
"> ", // prompt
|
||||
true)); // echo input
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
|
||||
m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
bp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
}
|
||||
|
||||
/// Set a one-liner as the callback for the breakpoint.
|
||||
|
@ -262,93 +271,6 @@ one command per line.\n" );
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
static size_t
|
||||
GenerateBreakpointCommandCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_reader_instructions);
|
||||
if (reader.GetPrompt())
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderReactivate:
|
||||
if (reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
if (bytes && bytes_len && baton)
|
||||
{
|
||||
BreakpointOptions *bp_options = (BreakpointOptions *) baton;
|
||||
if (bp_options)
|
||||
{
|
||||
Baton *bp_options_baton = bp_options->GetBaton();
|
||||
if (bp_options_baton)
|
||||
((BreakpointOptions::CommandData *)bp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len);
|
||||
}
|
||||
}
|
||||
if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
{
|
||||
// Finish, and cancel the breakpoint command.
|
||||
reader.SetIsDone (true);
|
||||
BreakpointOptions *bp_options = (BreakpointOptions *) baton;
|
||||
if (bp_options)
|
||||
{
|
||||
Baton *bp_options_baton = bp_options->GetBaton ();
|
||||
if (bp_options_baton)
|
||||
{
|
||||
((BreakpointOptions::CommandData *) bp_options_baton->m_data)->user_source.Clear();
|
||||
((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.clear();
|
||||
}
|
||||
}
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No command attached to breakpoint.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
static bool
|
||||
BreakpointOptionsCallbackFunction (void *baton,
|
||||
|
@ -623,7 +545,7 @@ private:
|
|||
};
|
||||
|
||||
const char *
|
||||
CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.";
|
||||
CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n";
|
||||
|
||||
// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
|
||||
// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include "lldb/lldb-types.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
|
||||
// Project includes
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/InputReaderEZ.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Interpreter/CommandHistory.h"
|
||||
|
@ -379,7 +378,8 @@ protected:
|
|||
{
|
||||
const char *filename = command.GetArgumentAtIndex(0);
|
||||
|
||||
result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
|
||||
if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
|
||||
result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
|
||||
|
||||
FileSpec cmd_file (filename, true);
|
||||
ExecutionContext *exe_ctx = NULL; // Just use the default context.
|
||||
|
@ -423,7 +423,7 @@ CommandObjectCommandsSource::CommandOptions::g_option_table[] =
|
|||
|
||||
static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"You must define a Python function with this signature:\n"
|
||||
"def my_command_impl(debugger, args, result, internal_dict):";
|
||||
"def my_command_impl(debugger, args, result, internal_dict):\n";
|
||||
|
||||
|
||||
class CommandObjectCommandsAlias : public CommandObjectRaw
|
||||
|
@ -856,7 +856,9 @@ protected:
|
|||
//-------------------------------------------------------------------------
|
||||
#pragma mark CommandObjectCommandsAddRegex
|
||||
|
||||
class CommandObjectCommandsAddRegex : public CommandObjectParsed
|
||||
class CommandObjectCommandsAddRegex :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
|
||||
|
@ -864,6 +866,7 @@ public:
|
|||
"command regex",
|
||||
"Allow the user to create a regular expression command.",
|
||||
"command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
|
||||
IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
|
||||
m_options (interpreter)
|
||||
{
|
||||
SetHelpLong(
|
||||
|
@ -899,6 +902,97 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
|
||||
{
|
||||
io_handler.SetIsDone(true);
|
||||
if (m_regex_cmd_ap.get())
|
||||
{
|
||||
StringList lines;
|
||||
if (lines.SplitIntoLines (data))
|
||||
{
|
||||
const size_t num_lines = lines.GetSize();
|
||||
bool check_only = false;
|
||||
for (size_t i=0; i<num_lines; ++i)
|
||||
{
|
||||
printf ("regex[%zu] = %s\n", i, lines[i].c_str());
|
||||
llvm::StringRef bytes_strref (lines[i]);
|
||||
Error error = AppendRegexSubstitution (bytes_strref, check_only);
|
||||
if (error.Fail())
|
||||
{
|
||||
if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
|
||||
{
|
||||
StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
|
||||
out_stream->Printf("error: %s\n", error.AsCString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_regex_cmd_ap->HasRegexEntries())
|
||||
{
|
||||
CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
|
||||
m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
if (line_idx == UINT32_MAX)
|
||||
{
|
||||
// Return true to indicate we are done getting lines (this
|
||||
// is a "fake" line - the real terminating blank line was
|
||||
// removed during a previous call with the code below)
|
||||
error.Clear();
|
||||
return LineStatus::Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t num_lines = lines.GetSize();
|
||||
if (line_idx + 1 == num_lines)
|
||||
{
|
||||
// The last line was edited, if this line is empty, then we are done
|
||||
// getting our multiple lines.
|
||||
if (lines[line_idx].empty())
|
||||
{
|
||||
// Remove the last empty line from "lines" so it doesn't appear
|
||||
// in our final expression and return true to indicate we are done
|
||||
// getting lines
|
||||
lines.PopBack();
|
||||
return LineStatus::Done;
|
||||
}
|
||||
}
|
||||
// Check the current line to make sure it is formatted correctly
|
||||
bool check_only = true;
|
||||
llvm::StringRef regex_sed(lines[line_idx]);
|
||||
error = AppendRegexSubstitution (regex_sed, check_only);
|
||||
if (error.Fail())
|
||||
{
|
||||
return LineStatus::Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LineStatus::Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DoExecute (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
|
@ -920,21 +1014,18 @@ protected:
|
|||
|
||||
if (argc == 1)
|
||||
{
|
||||
InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
|
||||
if (reader_sp)
|
||||
Debugger &debugger = m_interpreter.GetDebugger();
|
||||
const bool multiple_lines = true; // Get multiple lines
|
||||
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
|
||||
"lldb", // Name of input reader for history
|
||||
"\033[K> ", // Prompt and clear line
|
||||
multiple_lines,
|
||||
*this));
|
||||
|
||||
if (io_handler_sp)
|
||||
{
|
||||
error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
|
||||
this, // baton
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
NULL, // end token
|
||||
"> ", // prompt
|
||||
true); // echo input
|
||||
if (error.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
return true;
|
||||
}
|
||||
debugger.PushIOHandler(io_handler_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -942,7 +1033,8 @@ protected:
|
|||
for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
|
||||
{
|
||||
llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
|
||||
error = AppendRegexSubstitution (arg_strref);
|
||||
bool check_only = false;
|
||||
error = AppendRegexSubstitution (arg_strref, check_only);
|
||||
if (error.Fail())
|
||||
break;
|
||||
}
|
||||
|
@ -963,7 +1055,7 @@ protected:
|
|||
}
|
||||
|
||||
Error
|
||||
AppendRegexSubstitution (const llvm::StringRef ®ex_sed)
|
||||
AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only)
|
||||
{
|
||||
Error error;
|
||||
|
||||
|
@ -1053,10 +1145,14 @@ protected:
|
|||
regex_sed.data());
|
||||
return error;
|
||||
}
|
||||
std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
|
||||
std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
|
||||
m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
|
||||
subst.c_str());
|
||||
|
||||
if (check_only == false)
|
||||
{
|
||||
std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
|
||||
std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
|
||||
m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
|
||||
subst.c_str());
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1073,89 +1169,6 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
InputReaderDidCancel()
|
||||
{
|
||||
m_regex_cmd_ap.reset();
|
||||
}
|
||||
|
||||
static size_t
|
||||
InputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
{
|
||||
CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
|
||||
bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (!batch_mode)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
|
||||
out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
case eInputReaderReactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
|
||||
--bytes_len;
|
||||
if (bytes_len == 0)
|
||||
reader.SetIsDone(true);
|
||||
else if (bytes)
|
||||
{
|
||||
llvm::StringRef bytes_strref (bytes, bytes_len);
|
||||
Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
|
||||
if (error.Fail())
|
||||
{
|
||||
if (!batch_mode)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
out_stream->Printf("error: %s\n", error.AsCString());
|
||||
out_stream->Flush();
|
||||
}
|
||||
add_regex_cmd->InputReaderDidCancel ();
|
||||
reader.SetIsDone (true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
{
|
||||
reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
out_stream->PutCString("Regular expression command creations was cancelled.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
add_regex_cmd->InputReaderDidCancel ();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
add_regex_cmd->AddRegexCommandToInterpreter();
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
|
||||
|
||||
|
@ -1526,7 +1539,9 @@ CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
|
|||
// CommandObjectCommandsScriptAdd
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class CommandObjectCommandsScriptAdd : public CommandObjectParsed
|
||||
class CommandObjectCommandsScriptAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
|
||||
|
@ -1534,6 +1549,7 @@ public:
|
|||
"command script add",
|
||||
"Add a scripted function as an LLDB command.",
|
||||
NULL),
|
||||
IOHandlerDelegateMultiline ("DONE"),
|
||||
m_options (interpreter)
|
||||
{
|
||||
CommandArgumentEntry arg1;
|
||||
|
@ -1567,7 +1583,7 @@ protected:
|
|||
public:
|
||||
|
||||
CommandOptions (CommandInterpreter &interpreter) :
|
||||
Options (interpreter)
|
||||
Options (interpreter)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1586,7 +1602,7 @@ protected:
|
|||
m_funct_name = std::string(option_arg);
|
||||
break;
|
||||
case 's':
|
||||
m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
|
||||
m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
|
||||
if (!error.Success())
|
||||
error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
|
||||
break;
|
||||
|
@ -1602,7 +1618,7 @@ protected:
|
|||
OptionParsingStarting ()
|
||||
{
|
||||
m_funct_name = "";
|
||||
m_synchronous = eScriptedCommandSynchronicitySynchronous;
|
||||
m_synchronicity = eScriptedCommandSynchronicitySynchronous;
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
|
@ -1618,128 +1634,81 @@ protected:
|
|||
// Instance variables to hold the values for command options.
|
||||
|
||||
std::string m_funct_name;
|
||||
ScriptedCommandSynchronicity m_synchronous;
|
||||
ScriptedCommandSynchronicity m_synchronicity;
|
||||
};
|
||||
|
||||
private:
|
||||
class PythonAliasReader : public InputReaderEZ
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
private:
|
||||
CommandInterpreter& m_interpreter;
|
||||
std::string m_cmd_name;
|
||||
ScriptedCommandSynchronicity m_synchronous;
|
||||
StringList m_user_input;
|
||||
DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
|
||||
public:
|
||||
PythonAliasReader(Debugger& debugger,
|
||||
CommandInterpreter& interpreter,
|
||||
std::string cmd_name,
|
||||
ScriptedCommandSynchronicity synch) :
|
||||
InputReaderEZ(debugger),
|
||||
m_interpreter(interpreter),
|
||||
m_cmd_name(cmd_name),
|
||||
m_synchronous(synch),
|
||||
m_user_input()
|
||||
{}
|
||||
|
||||
virtual
|
||||
~PythonAliasReader()
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString(g_python_command_instructions);
|
||||
output_sp->Flush();
|
||||
}
|
||||
|
||||
virtual void ActivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_python_command_instructions);
|
||||
if (data.reader.GetPrompt())
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ReactivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void GotTokenHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.bytes && data.bytes_len)
|
||||
{
|
||||
m_user_input.AppendString(data.bytes, data.bytes_len);
|
||||
}
|
||||
if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void InterruptHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
data.reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No script attached.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void EOFHandler(HandlerData& data)
|
||||
{
|
||||
data.reader.SetIsDone (true);
|
||||
}
|
||||
virtual void DoneHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
|
||||
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
if (!interpreter)
|
||||
{
|
||||
out_stream->Printf ("Script interpreter missing: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
std::string funct_name_str;
|
||||
if (!interpreter->GenerateScriptAliasFunction (m_user_input,
|
||||
funct_name_str))
|
||||
{
|
||||
out_stream->Printf ("Unable to create function: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
if (funct_name_str.empty())
|
||||
{
|
||||
out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
// everything should be fine now, let's add this alias
|
||||
|
||||
CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
|
||||
m_cmd_name,
|
||||
funct_name_str.c_str(),
|
||||
m_synchronous));
|
||||
|
||||
if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
|
||||
{
|
||||
out_stream->Printf ("Unable to add selected command: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
|
||||
{
|
||||
StreamFileSP error_sp = io_handler.GetErrorStreamFile();
|
||||
|
||||
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
|
||||
if (interpreter)
|
||||
{
|
||||
|
||||
StringList lines;
|
||||
lines.SplitIntoLines(data);
|
||||
if (lines.GetSize() > 0)
|
||||
{
|
||||
std::string funct_name_str;
|
||||
if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
|
||||
{
|
||||
if (funct_name_str.empty())
|
||||
{
|
||||
error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything should be fine now, let's add this alias
|
||||
|
||||
CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
|
||||
m_cmd_name,
|
||||
funct_name_str.c_str(),
|
||||
m_synchronicity));
|
||||
|
||||
if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
|
||||
{
|
||||
error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: unable to create function, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: empty function, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
|
||||
io_handler.SetIsDone(true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
bool
|
||||
DoExecute (Args& command, CommandReturnObject &result)
|
||||
|
@ -1761,45 +1730,24 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string cmd_name = command.GetArgumentAtIndex(0);
|
||||
// Store the command name and synchronicity in case we get multi-line input
|
||||
m_cmd_name = command.GetArgumentAtIndex(0);
|
||||
m_synchronicity = m_options.m_synchronicity;
|
||||
|
||||
if (m_options.m_funct_name.empty())
|
||||
{
|
||||
InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
|
||||
m_interpreter,
|
||||
cmd_name,
|
||||
m_options.m_synchronous));
|
||||
|
||||
if (reader_sp)
|
||||
{
|
||||
|
||||
InputReaderEZ::InitializationParameters ipr;
|
||||
|
||||
Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" ")));
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
|
||||
cmd_name,
|
||||
m_cmd_name,
|
||||
m_options.m_funct_name,
|
||||
m_options.m_synchronous));
|
||||
if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
|
||||
m_synchronicity));
|
||||
if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
|
||||
{
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
|
@ -1815,6 +1763,8 @@ protected:
|
|||
}
|
||||
|
||||
CommandOptions m_options;
|
||||
std::string m_cmd_name;
|
||||
ScriptedCommandSynchronicity m_synchronicity;
|
||||
};
|
||||
|
||||
static OptionEnumValueElement g_script_synchro_type[] =
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
// Project includes
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
#include "lldb/DataFormatters/ValueObjectPrinter.h"
|
||||
#include "lldb/Expression/ClangExpressionVariable.h"
|
||||
|
@ -197,6 +196,7 @@ CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interprete
|
|||
"Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
|
||||
NULL,
|
||||
eFlagProcessMustBePaused | eFlagTryTargetAPILock),
|
||||
IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
|
||||
m_option_group (interpreter),
|
||||
m_format_options (eFormatDefault),
|
||||
m_command_options (),
|
||||
|
@ -254,87 +254,6 @@ CommandObjectExpression::GetOptions ()
|
|||
return &m_option_group;
|
||||
}
|
||||
|
||||
size_t
|
||||
CommandObjectExpression::MultiLineExpressionCallback
|
||||
(
|
||||
void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len
|
||||
)
|
||||
{
|
||||
CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
|
||||
bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (!batch_mode)
|
||||
{
|
||||
StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
|
||||
if (async_strm_sp)
|
||||
{
|
||||
async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
|
||||
async_strm_sp->Flush();
|
||||
}
|
||||
}
|
||||
// Fall through
|
||||
case eInputReaderReactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
++cmd_object_expr->m_expr_line_count;
|
||||
if (bytes && bytes_len)
|
||||
{
|
||||
cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
|
||||
}
|
||||
|
||||
if (bytes_len == 0)
|
||||
reader.SetIsDone(true);
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
cmd_object_expr->m_expr_lines.clear();
|
||||
reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
|
||||
if (async_strm_sp)
|
||||
{
|
||||
async_strm_sp->PutCString("Expression evaluation cancelled.\n");
|
||||
async_strm_sp->Flush();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
if (cmd_object_expr->m_expr_lines.size() > 0)
|
||||
{
|
||||
StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
|
||||
cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
|
||||
output_stream.get(),
|
||||
error_stream.get());
|
||||
output_stream->Flush();
|
||||
error_stream->Flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectExpression::EvaluateExpression
|
||||
(
|
||||
|
@ -445,6 +364,60 @@ CommandObjectExpression::EvaluateExpression
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CommandObjectExpression::IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
|
||||
{
|
||||
io_handler.SetIsDone(true);
|
||||
// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
|
||||
// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
StreamFileSP error_sp(io_handler.GetErrorStreamFile());
|
||||
|
||||
EvaluateExpression (line.c_str(),
|
||||
output_sp.get(),
|
||||
error_sp.get());
|
||||
if (output_sp)
|
||||
output_sp->Flush();
|
||||
if (error_sp)
|
||||
error_sp->Flush();
|
||||
}
|
||||
|
||||
LineStatus
|
||||
CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error)
|
||||
{
|
||||
if (line_idx == UINT32_MAX)
|
||||
{
|
||||
// Remove the last line from "lines" so it doesn't appear
|
||||
// in our final expression
|
||||
lines.PopBack();
|
||||
error.Clear();
|
||||
return LineStatus::Done;
|
||||
}
|
||||
else if (line_idx + 1 == lines.GetSize())
|
||||
{
|
||||
// The last line was edited, if this line is empty, then we are done
|
||||
// getting our multiple lines.
|
||||
if (lines[line_idx].empty())
|
||||
return LineStatus::Done;
|
||||
}
|
||||
return LineStatus::Success;
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectExpression::DoExecute
|
||||
(
|
||||
|
@ -461,31 +434,14 @@ CommandObjectExpression::DoExecute
|
|||
m_expr_lines.clear();
|
||||
m_expr_line_count = 0;
|
||||
|
||||
InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
|
||||
if (reader_sp)
|
||||
{
|
||||
Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
|
||||
this, // baton
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
NULL, // end token
|
||||
NULL, // prompt
|
||||
true)); // echo input
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
Debugger &debugger = GetCommandInterpreter().GetDebugger();
|
||||
const bool multiple_lines = true; // Get multiple lines
|
||||
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
|
||||
"lldb-expr", // Name of input reader for history
|
||||
NULL, // No prompt
|
||||
multiple_lines,
|
||||
*this));
|
||||
debugger.PushIOHandler(io_handler_sp);
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
#include "lldb/Interpreter/OptionGroupFormat.h"
|
||||
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
|
||||
|
@ -21,7 +22,9 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
class CommandObjectExpression : public CommandObjectRaw
|
||||
class CommandObjectExpression :
|
||||
public CommandObjectRaw,
|
||||
public IOHandlerDelegate
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -71,17 +74,26 @@ public:
|
|||
GetOptions ();
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// IOHandler::Delegate functions
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler);
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler,
|
||||
std::string &line);
|
||||
|
||||
virtual LineStatus
|
||||
IOHandlerLinesUpdated (IOHandler &io_handler,
|
||||
StringList &lines,
|
||||
uint32_t line_idx,
|
||||
Error &error);
|
||||
virtual bool
|
||||
DoExecute (const char *command,
|
||||
CommandReturnObject &result);
|
||||
|
||||
static size_t
|
||||
MultiLineExpressionCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
bool
|
||||
EvaluateExpression (const char *expr,
|
||||
Stream *output_stream,
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//===-- CommandObjectGUI.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/lldb-python.h"
|
||||
|
||||
#include "CommandObjectGUI.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CommandObjectGUI
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
CommandObjectGUI::CommandObjectGUI (CommandInterpreter &interpreter) :
|
||||
CommandObjectParsed (interpreter, "gui", "Switch into the curses based GUI mode.", "gui")
|
||||
{
|
||||
}
|
||||
|
||||
CommandObjectGUI::~CommandObjectGUI ()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectGUI::DoExecute (Args& args, CommandReturnObject &result)
|
||||
{
|
||||
if (args.GetArgumentCount() == 0)
|
||||
{
|
||||
Debugger &debugger = m_interpreter.GetDebugger();
|
||||
IOHandlerSP io_handler_sp (new IOHandlerCursesGUI (debugger));
|
||||
if (io_handler_sp)
|
||||
debugger.PushIOHandler(io_handler_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("the gui command takes no arguments.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
//===-- CommandObjectGUI.h --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_CommandObjectGUI_h_
|
||||
#define liblldb_CommandObjectGUI_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CommandObjectGUI
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class CommandObjectGUI : public CommandObjectParsed
|
||||
{
|
||||
public:
|
||||
|
||||
CommandObjectGUI (CommandInterpreter &interpreter);
|
||||
|
||||
virtual
|
||||
~CommandObjectGUI ();
|
||||
|
||||
protected:
|
||||
virtual bool
|
||||
DoExecute (Args& args,
|
||||
CommandReturnObject &result);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_CommandObjectGUI_h_
|
|
@ -532,37 +532,36 @@ protected:
|
|||
|
||||
if (error.Success())
|
||||
{
|
||||
ListenerSP listener_sp (new Listener("lldb.CommandObjectProcessAttach.DoExecute.attach.hijack"));
|
||||
m_options.attach_info.SetHijackListener(listener_sp);
|
||||
process->HijackProcessEvents(listener_sp.get());
|
||||
error = process->Attach (m_options.attach_info);
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
result.SetStatus (eReturnStatusSuccessContinuingNoResult);
|
||||
StateType state = process->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
|
||||
|
||||
process->RestoreProcessEvents();
|
||||
|
||||
result.SetDidChangeProcessState (true);
|
||||
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
|
||||
process->Destroy();
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("attach failed: %s\n", error.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
// If we're synchronous, wait for the stopped event and report that.
|
||||
// Otherwise just return.
|
||||
// FIXME: in the async case it will now be possible to get to the command
|
||||
// interpreter with a state eStateAttaching. Make sure we handle that correctly.
|
||||
StateType state = process->WaitForProcessToStop (NULL);
|
||||
|
||||
result.SetDidChangeProcessState (true);
|
||||
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("attach failed: process did not stop (no such process or permission problem?)");
|
||||
process->Destroy();
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1087,7 +1086,7 @@ protected:
|
|||
|
||||
if (process)
|
||||
{
|
||||
error = process->ConnectRemote (&process->GetTarget().GetDebugger().GetOutputStream(), remote_url);
|
||||
error = process->ConnectRemote (process->GetTarget().GetDebugger().GetOutputFile().get(), remote_url);
|
||||
|
||||
if (error.Fail())
|
||||
{
|
||||
|
|
|
@ -92,7 +92,8 @@ CommandObjectQuit::DoExecute (Args& command, CommandReturnObject &result)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
m_interpreter.BroadcastEvent (CommandInterpreter::eBroadcastBitQuitCommandReceived);
|
||||
const uint32_t event_type = CommandInterpreter::eBroadcastBitQuitCommandReceived;
|
||||
m_interpreter.BroadcastEvent (event_type);
|
||||
result.SetStatus (eReturnStatusQuit);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
// Project includes
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/ModuleSpec.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
|
@ -4759,7 +4759,9 @@ private:
|
|||
// CommandObjectTargetStopHookAdd
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class CommandObjectTargetStopHookAdd : public CommandObjectParsed
|
||||
class CommandObjectTargetStopHookAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -4926,9 +4928,10 @@ public:
|
|||
|
||||
CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
|
||||
CommandObjectParsed (interpreter,
|
||||
"target stop-hook add ",
|
||||
"target stop-hook add",
|
||||
"Add a hook to be executed when the target stops.",
|
||||
"target stop-hook add"),
|
||||
IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand),
|
||||
m_options (interpreter)
|
||||
{
|
||||
}
|
||||
|
@ -4937,102 +4940,61 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
static size_t
|
||||
ReadCommandsCallbackFunction (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
|
||||
static bool got_interrupted;
|
||||
bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
|
||||
if (reader.GetPrompt())
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
got_interrupted = false;
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderReactivate:
|
||||
if (reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
got_interrupted = false;
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
if (bytes && bytes_len && baton)
|
||||
{
|
||||
StringList *commands = new_stop_hook->GetCommandPointer();
|
||||
if (commands)
|
||||
{
|
||||
commands->AppendString (bytes, bytes_len);
|
||||
}
|
||||
}
|
||||
if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
{
|
||||
// Finish, and cancel the stop hook.
|
||||
new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Stop hook cancelled.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
|
||||
reader.SetIsDone (true);
|
||||
}
|
||||
got_interrupted = true;
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
if (!got_interrupted && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Stop hook #%" PRIu64 " added.\n", new_stop_hook->GetID());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n");
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
|
||||
{
|
||||
if (m_stop_hook_sp)
|
||||
{
|
||||
if (line.empty())
|
||||
{
|
||||
StreamFileSP error_sp(io_handler.GetErrorStreamFile());
|
||||
if (error_sp)
|
||||
{
|
||||
error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID());
|
||||
error_sp->Flush();
|
||||
}
|
||||
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
|
||||
if (target)
|
||||
target->RemoveStopHookByID(m_stop_hook_sp->GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID());
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
m_stop_hook_sp.reset();
|
||||
}
|
||||
io_handler.SetIsDone(true);
|
||||
}
|
||||
|
||||
bool
|
||||
DoExecute (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
m_stop_hook_sp.reset();
|
||||
|
||||
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
|
||||
if (target)
|
||||
{
|
||||
Target::StopHookSP new_hook_sp;
|
||||
target->AddStopHook (new_hook_sp);
|
||||
Target::StopHookSP new_hook_sp = target->CreateStopHook();
|
||||
|
||||
// First step, make the specifier.
|
||||
std::unique_ptr<SymbolContextSpecifier> specifier_ap;
|
||||
|
@ -5105,31 +5067,12 @@ protected:
|
|||
}
|
||||
else
|
||||
{
|
||||
// Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
|
||||
// the new stop hook's command string.
|
||||
InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
|
||||
if (!reader_sp)
|
||||
{
|
||||
result.AppendError("out of memory\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
target->RemoveStopHookByID (new_hook_sp->GetID());
|
||||
return false;
|
||||
}
|
||||
|
||||
Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
|
||||
new_hook_sp.get(), // baton
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
"DONE", // end token
|
||||
"> ", // prompt
|
||||
true)); // echo input
|
||||
if (!err.Success())
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
target->RemoveStopHookByID (new_hook_sp->GetID());
|
||||
return false;
|
||||
}
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
m_stop_hook_sp = new_hook_sp;
|
||||
m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
|
||||
}
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
|
@ -5143,6 +5086,7 @@ protected:
|
|||
}
|
||||
private:
|
||||
CommandOptions m_options;
|
||||
Target::StopHookSP m_stop_hook_sp;
|
||||
};
|
||||
|
||||
OptionDefinition
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReaderEZ.h"
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Core/RegularExpression.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
|
@ -42,7 +42,6 @@ public:
|
|||
TypeSummaryImpl::Flags m_flags;
|
||||
|
||||
StringList m_target_types;
|
||||
StringList m_user_source;
|
||||
|
||||
bool m_regex;
|
||||
|
||||
|
@ -74,7 +73,6 @@ public:
|
|||
bool m_skip_references;
|
||||
bool m_cascade;
|
||||
bool m_regex;
|
||||
StringList m_user_source;
|
||||
StringList m_target_types;
|
||||
|
||||
std::string m_category;
|
||||
|
@ -88,7 +86,6 @@ public:
|
|||
m_skip_references(sref),
|
||||
m_cascade(casc),
|
||||
m_regex(regx),
|
||||
m_user_source(),
|
||||
m_target_types(),
|
||||
m_category(catg)
|
||||
{
|
||||
|
@ -100,7 +97,9 @@ public:
|
|||
|
||||
|
||||
|
||||
class CommandObjectTypeSummaryAdd : public CommandObjectParsed
|
||||
class CommandObjectTypeSummaryAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
|
||||
private:
|
||||
|
@ -153,10 +152,6 @@ private:
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
void
|
||||
CollectPythonScript(ScriptAddOptions *options,
|
||||
CommandReturnObject &result);
|
||||
|
||||
bool
|
||||
Execute_ScriptSummary (Args& command, CommandReturnObject &result);
|
||||
|
||||
|
@ -178,6 +173,146 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"def function (valobj,internal_dict):\n"
|
||||
" \"\"\"valobj: an SBValue which you want to provide a summary for\n"
|
||||
" internal_dict: an LLDB support object not to be used\"\"\"";
|
||||
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString(g_summary_addreader_instructions);
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
|
||||
{
|
||||
StreamFileSP error_sp = io_handler.GetErrorStreamFile();
|
||||
|
||||
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
|
||||
if (interpreter)
|
||||
{
|
||||
StringList lines;
|
||||
lines.SplitIntoLines(data);
|
||||
if (lines.GetSize() > 0)
|
||||
{
|
||||
ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
|
||||
if (options_ptr)
|
||||
{
|
||||
ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
|
||||
|
||||
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
|
||||
if (interpreter)
|
||||
{
|
||||
std::string funct_name_str;
|
||||
if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
|
||||
{
|
||||
if (funct_name_str.empty())
|
||||
{
|
||||
error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
// now I have a valid function name, let's add this as script for every type in the list
|
||||
|
||||
TypeSummaryImplSP script_format;
|
||||
script_format.reset(new ScriptSummaryFormat(options->m_flags,
|
||||
funct_name_str.c_str(),
|
||||
lines.CopyList(" ").c_str()));
|
||||
|
||||
Error error;
|
||||
|
||||
for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
|
||||
{
|
||||
const char *type_name = options->m_target_types.GetStringAtIndex(i);
|
||||
CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
|
||||
script_format,
|
||||
(options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
error_sp->Printf ("error: %s", error.AsCString());
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (options->m_name)
|
||||
{
|
||||
CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
|
||||
script_format,
|
||||
CommandObjectTypeSummaryAdd::eNamedSummary,
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
|
||||
script_format,
|
||||
CommandObjectTypeSummaryAdd::eNamedSummary,
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
error_sp->Printf ("error: %s", error.AsCString());
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: %s", error.AsCString());
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error.AsCString())
|
||||
{
|
||||
error_sp->Printf ("error: %s", error.AsCString());
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: unable to generate a function.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: no script interpreter.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: empty function, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
|
||||
io_handler.SetIsDone(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
AddSummary(ConstString type_name,
|
||||
lldb::TypeSummaryImplSP entry,
|
||||
|
@ -190,7 +325,19 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
class CommandObjectTypeSynthAdd : public CommandObjectParsed
|
||||
static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"You must define a Python class with these methods:\n"
|
||||
" def __init__(self, valobj, dict):\n"
|
||||
" def num_children(self):\n"
|
||||
" def get_child_at_index(self, index):\n"
|
||||
" def get_child_index(self, name):\n"
|
||||
" def update(self):\n"
|
||||
" '''Optional'''\n"
|
||||
"class synthProvider:\n";
|
||||
|
||||
class CommandObjectTypeSynthAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
|
||||
private:
|
||||
|
@ -200,7 +347,7 @@ private:
|
|||
public:
|
||||
|
||||
CommandOptions (CommandInterpreter &interpreter) :
|
||||
Options (interpreter)
|
||||
Options (interpreter)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -296,9 +443,6 @@ private:
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
void
|
||||
CollectPythonScript (SynthAddOptions *options,
|
||||
CommandReturnObject &result);
|
||||
bool
|
||||
Execute_HandwritePython (Args& command, CommandReturnObject &result);
|
||||
|
||||
|
@ -307,8 +451,137 @@ private:
|
|||
|
||||
protected:
|
||||
bool
|
||||
DoExecute (Args& command, CommandReturnObject &result);
|
||||
DoExecute (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
if (m_options.handwrite_python)
|
||||
return Execute_HandwritePython(command, result);
|
||||
else if (m_options.is_class_based)
|
||||
return Execute_PythonClass(command, result);
|
||||
else
|
||||
{
|
||||
result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString(g_synth_addreader_instructions);
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
|
||||
{
|
||||
StreamFileSP error_sp = io_handler.GetErrorStreamFile();
|
||||
|
||||
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
|
||||
if (interpreter)
|
||||
{
|
||||
StringList lines;
|
||||
lines.SplitIntoLines(data);
|
||||
if (lines.GetSize() > 0)
|
||||
{
|
||||
SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
|
||||
if (options_ptr)
|
||||
{
|
||||
SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
|
||||
|
||||
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
|
||||
if (interpreter)
|
||||
{
|
||||
std::string class_name_str;
|
||||
if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
|
||||
{
|
||||
if (class_name_str.empty())
|
||||
{
|
||||
error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything should be fine now, let's add the synth provider class
|
||||
|
||||
SyntheticChildrenSP synth_provider;
|
||||
synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
|
||||
SetSkipPointers(options->m_skip_pointers).
|
||||
SetSkipReferences(options->m_skip_references),
|
||||
class_name_str.c_str()));
|
||||
|
||||
|
||||
lldb::TypeCategoryImplSP category;
|
||||
DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
|
||||
|
||||
Error error;
|
||||
|
||||
for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
|
||||
{
|
||||
const char *type_name = options->m_target_types.GetStringAtIndex(i);
|
||||
ConstString const_type_name(type_name);
|
||||
if (const_type_name)
|
||||
{
|
||||
if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
|
||||
synth_provider,
|
||||
options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
|
||||
options->m_category,
|
||||
&error))
|
||||
{
|
||||
error_sp->Printf("error: %s\n", error.AsCString());
|
||||
error_sp->Flush();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: invalid type name.\n");
|
||||
error_sp->Flush();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: unable to generate a class.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: no script interpreter.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: internal synchronization data missing.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: empty function, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
|
||||
error_sp->Flush();
|
||||
}
|
||||
|
||||
io_handler.SetIsDone(true);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
enum SynthFormatType
|
||||
|
@ -1102,176 +1375,6 @@ CommandObjectTypeFormatList::CommandOptions::g_option_table[] =
|
|||
// CommandObjectTypeSummaryAdd
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"def function (valobj,internal_dict):\n"
|
||||
" \"\"\"valobj: an SBValue which you want to provide a summary for\n"
|
||||
" internal_dict: an LLDB support object not to be used\"\"\"";
|
||||
|
||||
class TypeScriptAddInputReader : public InputReaderEZ
|
||||
{
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader);
|
||||
public:
|
||||
TypeScriptAddInputReader(Debugger& debugger) :
|
||||
InputReaderEZ(debugger)
|
||||
{}
|
||||
|
||||
virtual
|
||||
~TypeScriptAddInputReader()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ActivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_summary_addreader_instructions);
|
||||
if (data.reader.GetPrompt())
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ReactivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
if (data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void GotTokenHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
if (data.bytes && data.bytes_len && data.baton)
|
||||
{
|
||||
((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
|
||||
}
|
||||
if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void InterruptHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
data.reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No command attached to breakpoint.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void EOFHandler(HandlerData& data)
|
||||
{
|
||||
data.reader.SetIsDone (true);
|
||||
}
|
||||
virtual void DoneHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream();
|
||||
ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton);
|
||||
if (!options_ptr)
|
||||
{
|
||||
out_stream->Printf ("internal synchronization information missing or invalid.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
|
||||
|
||||
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
if (!interpreter)
|
||||
{
|
||||
out_stream->Printf ("no script interpreter.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
std::string funct_name_str;
|
||||
if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
|
||||
funct_name_str))
|
||||
{
|
||||
out_stream->Printf ("unable to generate a function.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
if (funct_name_str.empty())
|
||||
{
|
||||
out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
// now I have a valid function name, let's add this as script for every type in the list
|
||||
|
||||
TypeSummaryImplSP script_format;
|
||||
script_format.reset(new ScriptSummaryFormat(options->m_flags,
|
||||
funct_name_str.c_str(),
|
||||
options->m_user_source.CopyList(" ").c_str()));
|
||||
|
||||
Error error;
|
||||
|
||||
for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
|
||||
{
|
||||
const char *type_name = options->m_target_types.GetStringAtIndex(i);
|
||||
CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
|
||||
script_format,
|
||||
(options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
out_stream->Printf ("%s", error.AsCString());
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (options->m_name)
|
||||
{
|
||||
CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
|
||||
script_format,
|
||||
CommandObjectTypeSummaryAdd::eNamedSummary,
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
|
||||
script_format,
|
||||
CommandObjectTypeSummaryAdd::eNamedSummary,
|
||||
options->m_category,
|
||||
&error);
|
||||
if (error.Fail())
|
||||
{
|
||||
out_stream->Printf ("%s", error.AsCString());
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_stream->Printf ("%s", error.AsCString());
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (error.AsCString())
|
||||
{
|
||||
out_stream->PutCString (error.AsCString());
|
||||
out_stream->Flush();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef LLDB_DISABLE_PYTHON
|
||||
|
||||
Error
|
||||
|
@ -1352,35 +1455,9 @@ CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
|
|||
m_category = "default";
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
void
|
||||
CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
|
||||
CommandReturnObject &result)
|
||||
{
|
||||
InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
|
||||
if (reader_sp && options)
|
||||
{
|
||||
|
||||
InputReaderEZ::InitializationParameters ipr;
|
||||
|
||||
Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
|
||||
|
@ -1406,7 +1483,7 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
|
||||
std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
|
||||
|
||||
script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
|
||||
funct_name,
|
||||
|
@ -1445,14 +1522,15 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string code = " " + m_options.m_python_script;
|
||||
std::string code = " " + m_options.m_python_script;
|
||||
|
||||
script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
|
||||
funct_name_str.c_str(),
|
||||
code.c_str()));
|
||||
}
|
||||
else // use an InputReader to grab Python code from the user
|
||||
{
|
||||
else
|
||||
{
|
||||
// Use an IOHandler to grab Python code from the user
|
||||
ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
|
||||
m_options.m_regex,
|
||||
m_options.m_name,
|
||||
|
@ -1471,7 +1549,12 @@ CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturn
|
|||
}
|
||||
}
|
||||
|
||||
CollectPythonScript(options,result);
|
||||
m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
result.SetStatus(eReturnStatusSuccessFinishNoResult);
|
||||
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
|
@ -1603,6 +1686,7 @@ CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &in
|
|||
"type summary add",
|
||||
"Add a new summary style for a type.",
|
||||
NULL),
|
||||
IOHandlerDelegateMultiline ("DONE"),
|
||||
m_options (interpreter)
|
||||
{
|
||||
CommandArgumentEntry type_arg;
|
||||
|
@ -3647,193 +3731,6 @@ CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
|
|||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// TypeSynthAddInputReader
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"You must define a Python class with these methods:\n"
|
||||
" def __init__(self, valobj, dict):\n"
|
||||
" def num_children(self):\n"
|
||||
" def get_child_at_index(self, index):\n"
|
||||
" def get_child_index(self, name):\n"
|
||||
"Optionally, you can also define a method:\n"
|
||||
" def update(self):\n"
|
||||
"if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n"
|
||||
"class synthProvider:";
|
||||
|
||||
class TypeSynthAddInputReader : public InputReaderEZ
|
||||
{
|
||||
public:
|
||||
TypeSynthAddInputReader(Debugger& debugger) :
|
||||
InputReaderEZ(debugger)
|
||||
{}
|
||||
|
||||
virtual
|
||||
~TypeSynthAddInputReader()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ActivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_synth_addreader_instructions);
|
||||
if (data.reader.GetPrompt())
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ReactivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void GotTokenHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.bytes && data.bytes_len && data.baton)
|
||||
{
|
||||
((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
|
||||
}
|
||||
if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void InterruptHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
data.reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No command attached to breakpoint.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void EOFHandler(HandlerData& data)
|
||||
{
|
||||
data.reader.SetIsDone (true);
|
||||
}
|
||||
virtual void DoneHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
|
||||
if (!options_ptr)
|
||||
{
|
||||
out_stream->Printf ("internal synchronization data missing.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
|
||||
|
||||
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
if (!interpreter)
|
||||
{
|
||||
out_stream->Printf ("no script interpreter.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
std::string class_name_str;
|
||||
if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
|
||||
class_name_str))
|
||||
{
|
||||
out_stream->Printf ("unable to generate a class.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
if (class_name_str.empty())
|
||||
{
|
||||
out_stream->Printf ("unable to obtain a proper name for the class.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// everything should be fine now, let's add the synth provider class
|
||||
|
||||
SyntheticChildrenSP synth_provider;
|
||||
synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
|
||||
SetSkipPointers(options->m_skip_pointers).
|
||||
SetSkipReferences(options->m_skip_references),
|
||||
class_name_str.c_str()));
|
||||
|
||||
|
||||
lldb::TypeCategoryImplSP category;
|
||||
DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
|
||||
|
||||
Error error;
|
||||
|
||||
for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
|
||||
{
|
||||
const char *type_name = options->m_target_types.GetStringAtIndex(i);
|
||||
ConstString typeCS(type_name);
|
||||
if (typeCS)
|
||||
{
|
||||
if (!CommandObjectTypeSynthAdd::AddSynth(typeCS,
|
||||
synth_provider,
|
||||
options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
|
||||
options->m_category,
|
||||
&error))
|
||||
{
|
||||
out_stream->Printf("%s\n", error.AsCString());
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_stream->Printf ("invalid type name.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader);
|
||||
};
|
||||
|
||||
void
|
||||
CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options,
|
||||
CommandReturnObject &result)
|
||||
{
|
||||
InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
|
||||
if (reader_sp && options)
|
||||
{
|
||||
|
||||
InputReaderEZ::InitializationParameters ipr;
|
||||
|
||||
Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
|
@ -3858,7 +3755,11 @@ CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturn
|
|||
}
|
||||
}
|
||||
|
||||
CollectPythonScript(options,result);
|
||||
m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
result.SetStatus(eReturnStatusSuccessFinishNoResult);
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
|
@ -3937,6 +3838,7 @@ CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interp
|
|||
"type synthetic add",
|
||||
"Add a new synthetic provider for a type.",
|
||||
NULL),
|
||||
IOHandlerDelegateMultiline ("DONE"),
|
||||
m_options (interpreter)
|
||||
{
|
||||
CommandArgumentEntry type_arg;
|
||||
|
@ -4006,21 +3908,6 @@ CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CommandObjectTypeSynthAdd::DoExecute (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
if (m_options.handwrite_python)
|
||||
return Execute_HandwritePython(command, result);
|
||||
else if (m_options.is_class_based)
|
||||
return Execute_PythonClass(command, result);
|
||||
else
|
||||
{
|
||||
result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
OptionDefinition
|
||||
CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "CommandObjectWatchpointCommand.h"
|
||||
#include "CommandObjectWatchpoint.h"
|
||||
|
||||
#include "lldb/Core/IOHandler.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
@ -34,7 +35,9 @@ using namespace lldb_private;
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
class CommandObjectWatchpointCommandAdd : public CommandObjectParsed
|
||||
class CommandObjectWatchpointCommandAdd :
|
||||
public CommandObjectParsed,
|
||||
public IOHandlerDelegateMultiline
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -43,6 +46,7 @@ public:
|
|||
"add",
|
||||
"Add a set of commands to a watchpoint, to be executed whenever the watchpoint is hit.",
|
||||
NULL),
|
||||
IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
|
||||
m_options (interpreter)
|
||||
{
|
||||
SetHelpLong (
|
||||
|
@ -185,40 +189,45 @@ but do NOT enter more than one command per line. \n" );
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
virtual void
|
||||
IOHandlerActivated (IOHandler &io_handler)
|
||||
{
|
||||
StreamFileSP output_sp(io_handler.GetOutputStreamFile());
|
||||
if (output_sp)
|
||||
{
|
||||
output_sp->PutCString("Enter your debugger command(s). Type 'DONE' to end.\n");
|
||||
output_sp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
|
||||
{
|
||||
io_handler.SetIsDone(true);
|
||||
|
||||
// The WatchpointOptions object is owned by the watchpoint or watchpoint location
|
||||
WatchpointOptions *wp_options = (WatchpointOptions *) io_handler.GetUserData();
|
||||
if (wp_options)
|
||||
{
|
||||
std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
|
||||
if (data_ap.get())
|
||||
{
|
||||
data_ap->user_source.SplitIntoLines(line);
|
||||
BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
|
||||
wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
|
||||
CommandReturnObject &result)
|
||||
{
|
||||
InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
|
||||
std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
|
||||
if (reader_sp && data_ap.get())
|
||||
{
|
||||
BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
|
||||
wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
|
||||
|
||||
Error err (reader_sp->Initialize (CommandObjectWatchpointCommandAdd::GenerateWatchpointCommandCallback,
|
||||
wp_options, // callback_data
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
"DONE", // end token
|
||||
"> ", // prompt
|
||||
true)); // echo input
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
|
||||
m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt
|
||||
*this, // IOHandlerDelegate
|
||||
true, // Run IOHandler in async mode
|
||||
wp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
|
||||
}
|
||||
|
||||
/// Set a one-liner as the callback for the watchpoint.
|
||||
|
@ -240,93 +249,6 @@ but do NOT enter more than one command per line. \n" );
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
static size_t
|
||||
GenerateWatchpointCommandCallback (void *callback_data,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
{
|
||||
StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
|
||||
bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_reader_instructions);
|
||||
if (reader.GetPrompt())
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderReactivate:
|
||||
if (reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
if (bytes && bytes_len && callback_data)
|
||||
{
|
||||
WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
|
||||
if (wp_options)
|
||||
{
|
||||
Baton *wp_options_baton = wp_options->GetBaton();
|
||||
if (wp_options_baton)
|
||||
((WatchpointOptions::CommandData *)wp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len);
|
||||
}
|
||||
}
|
||||
if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
{
|
||||
// Finish, and cancel the watchpoint command.
|
||||
reader.SetIsDone (true);
|
||||
WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
|
||||
if (wp_options)
|
||||
{
|
||||
Baton *wp_options_baton = wp_options->GetBaton ();
|
||||
if (wp_options_baton)
|
||||
{
|
||||
((WatchpointOptions::CommandData *) wp_options_baton->m_data)->user_source.Clear();
|
||||
((WatchpointOptions::CommandData *) wp_options_baton->m_data)->script_source.clear();
|
||||
}
|
||||
}
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No command attached to watchpoint.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
static bool
|
||||
WatchpointOptionsCallbackFunction (void *baton,
|
||||
|
@ -579,12 +501,8 @@ protected:
|
|||
|
||||
private:
|
||||
CommandOptions m_options;
|
||||
static const char *g_reader_instructions;
|
||||
|
||||
};
|
||||
|
||||
const char *
|
||||
CommandObjectWatchpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.";
|
||||
|
||||
// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
|
||||
// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
#include "lldb/lldb-types.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||
|
||||
|
||||
|
|
|
@ -323,8 +323,10 @@ Broadcaster::RestoreBroadcaster ()
|
|||
listener->m_name.c_str(),
|
||||
listener);
|
||||
}
|
||||
m_hijacking_listeners.pop_back();
|
||||
m_hijacking_masks.pop_back();
|
||||
if (!m_hijacking_listeners.empty())
|
||||
m_hijacking_listeners.pop_back();
|
||||
if (!m_hijacking_masks.empty())
|
||||
m_hijacking_masks.pop_back();
|
||||
}
|
||||
|
||||
ConstString &
|
||||
|
|
|
@ -28,9 +28,7 @@ add_lldb_library(lldbCore
|
|||
FileLineResolver.cpp
|
||||
FileSpecList.cpp
|
||||
History.cpp
|
||||
InputReader.cpp
|
||||
InputReaderEZ.cpp
|
||||
InputReaderStack.cpp
|
||||
IOHandler.cpp
|
||||
Language.cpp
|
||||
Listener.cpp
|
||||
Log.cpp
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1045,10 +1045,8 @@ InstructionList::GetIndexOfNextBranchInstruction(uint32_t start) const
|
|||
}
|
||||
|
||||
uint32_t
|
||||
InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
|
||||
InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
|
||||
{
|
||||
Address address;
|
||||
address.SetLoadAddress(load_addr, &target);
|
||||
size_t num_instructions = m_instructions.size();
|
||||
uint32_t index = UINT32_MAX;
|
||||
for (size_t i = 0; i < num_instructions; i++)
|
||||
|
@ -1062,6 +1060,15 @@ InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Tar
|
|||
return index;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
|
||||
{
|
||||
Address address;
|
||||
address.SetLoadAddress(load_addr, &target);
|
||||
return GetIndexOfInstructionAtAddress(address);
|
||||
}
|
||||
|
||||
size_t
|
||||
Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
|
||||
const AddressRange &range,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,387 +0,0 @@
|
|||
//===-- InputReader.cpp -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/lldb-python.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
InputReader::InputReader (Debugger &debugger) :
|
||||
m_debugger (debugger),
|
||||
m_callback (NULL),
|
||||
m_callback_baton (NULL),
|
||||
m_end_token (),
|
||||
m_granularity (eInputReaderGranularityInvalid),
|
||||
m_done (true),
|
||||
m_echo (true),
|
||||
m_active (false),
|
||||
m_reader_done (false),
|
||||
m_user_input(),
|
||||
m_save_user_input(false)
|
||||
{
|
||||
}
|
||||
|
||||
InputReader::~InputReader ()
|
||||
{
|
||||
}
|
||||
|
||||
Error
|
||||
InputReader::Initialize
|
||||
(
|
||||
Callback callback,
|
||||
void *baton,
|
||||
lldb::InputReaderGranularity granularity,
|
||||
const char *end_token,
|
||||
const char *prompt,
|
||||
bool echo
|
||||
)
|
||||
{
|
||||
Error err;
|
||||
m_callback = callback;
|
||||
m_callback_baton = baton,
|
||||
m_granularity = granularity;
|
||||
if (end_token != NULL)
|
||||
m_end_token = end_token;
|
||||
if (prompt != NULL)
|
||||
m_prompt = prompt;
|
||||
m_done = true;
|
||||
m_echo = echo;
|
||||
|
||||
if (m_granularity == eInputReaderGranularityInvalid)
|
||||
{
|
||||
err.SetErrorString ("Invalid read token size: Reader must be initialized with a token size other than 'eInputReaderGranularityInvalid'.");
|
||||
}
|
||||
else
|
||||
if (end_token != NULL && granularity != eInputReaderGranularityInvalid)
|
||||
{
|
||||
if (granularity == eInputReaderGranularityByte)
|
||||
{
|
||||
// Check to see if end_token is longer than one byte.
|
||||
|
||||
if (strlen (end_token) > 1)
|
||||
{
|
||||
err.SetErrorString ("Invalid end token: End token cannot be larger than specified token size (byte).");
|
||||
}
|
||||
}
|
||||
else if (granularity == eInputReaderGranularityWord)
|
||||
{
|
||||
// Check to see if m_end_token contains any white space (i.e. is multiple words).
|
||||
|
||||
const char *white_space = " \t\n";
|
||||
size_t pos = m_end_token.find_first_of (white_space);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
err.SetErrorString ("Invalid end token: End token cannot be larger than specified token size (word).");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check to see if m_end_token contains any newlines; cannot handle multi-line end tokens.
|
||||
|
||||
size_t pos = m_end_token.find_first_of ('\n');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
err.SetErrorString ("Invalid end token: End token cannot contain a newline.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_done = err.Fail();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
size_t
|
||||
InputReader::HandleRawBytes (const char *bytes, size_t bytes_len)
|
||||
{
|
||||
const char *end_token = NULL;
|
||||
|
||||
if (m_end_token.empty() == false)
|
||||
{
|
||||
end_token = ::strstr (bytes, m_end_token.c_str());
|
||||
if (end_token >= bytes + bytes_len)
|
||||
end_token = NULL;
|
||||
}
|
||||
|
||||
const char *p = bytes;
|
||||
const char *end = bytes + bytes_len;
|
||||
|
||||
switch (m_granularity)
|
||||
{
|
||||
case eInputReaderGranularityInvalid:
|
||||
break;
|
||||
|
||||
case eInputReaderGranularityByte:
|
||||
while (p < end)
|
||||
{
|
||||
if (end_token == p)
|
||||
{
|
||||
p += m_end_token.size();
|
||||
SetIsDone(true);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_callback (m_callback_baton, *this, eInputReaderGotToken, p, 1) == 0)
|
||||
break;
|
||||
++p;
|
||||
if (IsDone())
|
||||
break;
|
||||
}
|
||||
// Return how many bytes were handled.
|
||||
return p - bytes;
|
||||
break;
|
||||
|
||||
|
||||
case eInputReaderGranularityWord:
|
||||
{
|
||||
char quote = '\0';
|
||||
const char *word_start = NULL;
|
||||
bool send_word = false;
|
||||
for (; p < end; ++p, send_word = false)
|
||||
{
|
||||
if (end_token && end_token == p)
|
||||
{
|
||||
m_end_token.size();
|
||||
SetIsDone(true);
|
||||
break;
|
||||
}
|
||||
|
||||
const char ch = *p;
|
||||
if (isspace(ch) && (!quote || (quote == ch && p[-1] != '\\')))
|
||||
{
|
||||
// We have a space character or the terminating quote
|
||||
send_word = word_start != NULL;
|
||||
quote = '\0';
|
||||
}
|
||||
else if (quote)
|
||||
{
|
||||
// We are in the middle of a quoted character
|
||||
continue;
|
||||
}
|
||||
else if (ch == '"' || ch == '\'' || ch == '`')
|
||||
quote = ch;
|
||||
else if (word_start == NULL)
|
||||
{
|
||||
// We have the first character in a word
|
||||
word_start = p;
|
||||
}
|
||||
|
||||
if (send_word)
|
||||
{
|
||||
const size_t word_len = p - word_start;
|
||||
size_t bytes_handled = m_callback (m_callback_baton,
|
||||
*this,
|
||||
eInputReaderGotToken,
|
||||
word_start,
|
||||
word_len);
|
||||
|
||||
if (bytes_handled != word_len)
|
||||
return word_start - bytes + bytes_handled;
|
||||
|
||||
if (IsDone())
|
||||
return p - bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case eInputReaderGranularityLine:
|
||||
{
|
||||
const char *line_start = bytes;
|
||||
const char *end_line = NULL;
|
||||
while (p < end)
|
||||
{
|
||||
const char ch = *p;
|
||||
if (ch == '\n' || ch == '\r')
|
||||
{
|
||||
size_t line_length = p - line_start;
|
||||
// Now skip the newline character
|
||||
++p;
|
||||
// Skip a complete DOS newline if we run into one
|
||||
if (ch == 0xd && p < end && *p == 0xa)
|
||||
++p;
|
||||
|
||||
if (line_start <= end_token && end_token < line_start + line_length)
|
||||
{
|
||||
SetIsDone(true);
|
||||
m_callback (m_callback_baton,
|
||||
*this,
|
||||
eInputReaderGotToken,
|
||||
line_start,
|
||||
end_token - line_start);
|
||||
|
||||
return p - bytes;
|
||||
}
|
||||
|
||||
size_t bytes_handled = m_callback (m_callback_baton,
|
||||
*this,
|
||||
eInputReaderGotToken,
|
||||
line_start,
|
||||
line_length);
|
||||
|
||||
end_line = p;
|
||||
|
||||
if (bytes_handled != line_length)
|
||||
{
|
||||
// The input reader wasn't able to handle all the data
|
||||
return line_start - bytes + bytes_handled;
|
||||
}
|
||||
|
||||
|
||||
if (IsDone())
|
||||
return p - bytes;
|
||||
|
||||
line_start = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_line)
|
||||
return end_line - bytes;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case eInputReaderGranularityAll:
|
||||
{
|
||||
// Nothing should be handle unless we see our end token
|
||||
if (end_token)
|
||||
{
|
||||
size_t length = end_token - bytes;
|
||||
size_t bytes_handled = m_callback (m_callback_baton,
|
||||
*this,
|
||||
eInputReaderGotToken,
|
||||
bytes,
|
||||
length);
|
||||
m_done = true;
|
||||
|
||||
p += bytes_handled + m_end_token.size();
|
||||
|
||||
// Consume any white space, such as newlines, beyond the end token
|
||||
|
||||
while (p < end && isspace(*p))
|
||||
++p;
|
||||
|
||||
if (bytes_handled != length)
|
||||
return bytes_handled;
|
||||
else
|
||||
{
|
||||
return p - bytes;
|
||||
//return bytes_handled + m_end_token.size();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
InputReader::GetPrompt () const
|
||||
{
|
||||
if (!m_prompt.empty())
|
||||
return m_prompt.c_str();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
InputReader::RefreshPrompt ()
|
||||
{
|
||||
if (m_debugger.GetCommandInterpreter().GetBatchCommandMode())
|
||||
return;
|
||||
|
||||
if (!m_prompt.empty())
|
||||
{
|
||||
File &out_file = m_debugger.GetOutputFile();
|
||||
if (out_file.IsValid())
|
||||
{
|
||||
out_file.Printf ("%s", m_prompt.c_str());
|
||||
out_file.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InputReader::Notify (InputReaderAction notification)
|
||||
{
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
case eInputReaderReactivate:
|
||||
m_active = true;
|
||||
m_reader_done.SetValue(false, eBroadcastAlways);
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
case eInputReaderDone:
|
||||
m_active = false;
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
case eInputReaderEndOfFile:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
return; // We don't notify the tokens here, it is done in HandleRawBytes
|
||||
}
|
||||
if (m_callback)
|
||||
m_callback (m_callback_baton, *this, notification, NULL, 0);
|
||||
if (notification == eInputReaderDone)
|
||||
m_reader_done.SetValue(true, eBroadcastAlways);
|
||||
}
|
||||
|
||||
void
|
||||
InputReader::WaitOnReaderIsDone ()
|
||||
{
|
||||
m_reader_done.WaitForValueEqualTo (true);
|
||||
}
|
||||
|
||||
const char *
|
||||
InputReader::GranularityAsCString (lldb::InputReaderGranularity granularity)
|
||||
{
|
||||
switch (granularity)
|
||||
{
|
||||
case eInputReaderGranularityInvalid: return "invalid";
|
||||
case eInputReaderGranularityByte: return "byte";
|
||||
case eInputReaderGranularityWord: return "word";
|
||||
case eInputReaderGranularityLine: return "line";
|
||||
case eInputReaderGranularityAll: return "all";
|
||||
}
|
||||
|
||||
static char unknown_state_string[64];
|
||||
snprintf(unknown_state_string, sizeof (unknown_state_string), "InputReaderGranularity = %i", granularity);
|
||||
return unknown_state_string;
|
||||
}
|
||||
|
||||
bool
|
||||
InputReader::HandlerData::GetBatchMode()
|
||||
{
|
||||
return reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
|
||||
}
|
||||
|
||||
lldb::StreamSP
|
||||
InputReader::HandlerData::GetOutStream()
|
||||
{
|
||||
return reader.GetDebugger().GetAsyncOutputStream();
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
//===-- InputReaderEZ.cpp ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/InputReaderEZ.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
size_t
|
||||
InputReaderEZ::Callback_Impl(void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
|
||||
{
|
||||
HandlerData hand_data(reader,
|
||||
bytes,
|
||||
bytes_len,
|
||||
baton);
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
reader.ActivateHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderDeactivate:
|
||||
reader.DeactivateHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderReactivate:
|
||||
reader.ReactivateHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
reader.AsynchronousOutputWrittenHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderGotToken:
|
||||
{
|
||||
if (reader.GetSaveUserInput())
|
||||
reader.GetUserInput().AppendString(bytes, bytes_len);
|
||||
reader.GotTokenHandler(hand_data);
|
||||
}
|
||||
break;
|
||||
case eInputReaderInterrupt:
|
||||
reader.InterruptHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderEndOfFile:
|
||||
reader.EOFHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderDone:
|
||||
reader.DoneHandler(hand_data);
|
||||
break;
|
||||
}
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
Error
|
||||
InputReaderEZ::Initialize(void* baton,
|
||||
lldb::InputReaderGranularity token_size,
|
||||
const char* end_token,
|
||||
const char *prompt,
|
||||
bool echo)
|
||||
{
|
||||
return InputReader::Initialize(Callback_Impl,
|
||||
baton,
|
||||
token_size,
|
||||
end_token,
|
||||
prompt,
|
||||
echo);
|
||||
}
|
||||
|
||||
Error
|
||||
InputReaderEZ::Initialize(InitializationParameters& params)
|
||||
{
|
||||
Error ret = Initialize(params.m_baton,
|
||||
params.m_token_size,
|
||||
params.m_end_token,
|
||||
params.m_prompt,
|
||||
params.m_echo);
|
||||
m_save_user_input = params.m_save_user_input;
|
||||
return ret;
|
||||
}
|
||||
|
||||
InputReaderEZ::~InputReaderEZ ()
|
||||
{
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
//===-- InputReaderStack.cpp ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/InputReaderStack.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
InputReaderStack::InputReaderStack () :
|
||||
m_input_readers (),
|
||||
m_input_readers_mutex (Mutex::eMutexTypeRecursive)
|
||||
{
|
||||
}
|
||||
|
||||
InputReaderStack::~InputReaderStack ()
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
InputReaderStack::GetSize () const
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
return m_input_readers.size();
|
||||
}
|
||||
|
||||
void
|
||||
InputReaderStack::Push (const lldb::InputReaderSP& reader_sp)
|
||||
{
|
||||
if (reader_sp)
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
m_input_readers.push (reader_sp);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InputReaderStack::IsEmpty () const
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
return m_input_readers.empty();
|
||||
}
|
||||
|
||||
InputReaderSP
|
||||
InputReaderStack::Top ()
|
||||
{
|
||||
InputReaderSP input_reader_sp;
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
input_reader_sp = m_input_readers.top();
|
||||
}
|
||||
|
||||
return input_reader_sp;
|
||||
}
|
||||
|
||||
void
|
||||
InputReaderStack::Pop ()
|
||||
{
|
||||
Mutex::Locker locker (m_input_readers_mutex);
|
||||
if (!m_input_readers.empty())
|
||||
m_input_readers.pop();
|
||||
}
|
||||
|
||||
Mutex &
|
||||
InputReaderStack::GetStackMutex ()
|
||||
{
|
||||
return m_input_readers_mutex;
|
||||
}
|
|
@ -432,6 +432,56 @@ SourceManager::File::GetLineOffset (uint32_t line)
|
|||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SourceManager::File::GetNumLines ()
|
||||
{
|
||||
CalculateLineOffsets();
|
||||
return m_offsets.size();
|
||||
}
|
||||
|
||||
const char *
|
||||
SourceManager::File::PeekLineData (uint32_t line)
|
||||
{
|
||||
if (!LineIsValid(line))
|
||||
return NULL;
|
||||
|
||||
size_t line_offset = GetLineOffset (line);
|
||||
if (line_offset < m_data_sp->GetByteSize())
|
||||
return (const char *)m_data_sp->GetBytes() + line_offset;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SourceManager::File::GetLineLength (uint32_t line, bool include_newline_chars)
|
||||
{
|
||||
if (!LineIsValid(line))
|
||||
return false;
|
||||
|
||||
size_t start_offset = GetLineOffset (line);
|
||||
size_t end_offset = GetLineOffset (line + 1);
|
||||
if (end_offset == UINT32_MAX)
|
||||
end_offset = m_data_sp->GetByteSize();
|
||||
|
||||
if (end_offset > start_offset)
|
||||
{
|
||||
uint32_t length = end_offset - start_offset;
|
||||
if (include_newline_chars == false)
|
||||
{
|
||||
const char *line_start = (const char *)m_data_sp->GetBytes() + start_offset;
|
||||
while (length > 0)
|
||||
{
|
||||
const char last_char = line_start[length-1];
|
||||
if ((last_char == '\r') || (last_char == '\n'))
|
||||
--length;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
SourceManager::File::LineIsValid (uint32_t line)
|
||||
{
|
||||
|
|
|
@ -28,25 +28,26 @@ StreamAsynchronousIO::StreamAsynchronousIO (Broadcaster &broadcaster, uint32_t b
|
|||
|
||||
StreamAsynchronousIO::~StreamAsynchronousIO ()
|
||||
{
|
||||
// Flush when we destroy to make sure we display the data
|
||||
Flush();
|
||||
}
|
||||
|
||||
void
|
||||
StreamAsynchronousIO::Flush ()
|
||||
{
|
||||
if (m_accumulated_data.GetSize() > 0)
|
||||
if (!m_accumulated_data.empty())
|
||||
{
|
||||
std::unique_ptr<EventDataBytes> data_bytes_ap (new EventDataBytes);
|
||||
// Let's swap the bytes to avoid LARGE string copies.
|
||||
data_bytes_ap->SwapBytes (m_accumulated_data.GetString());
|
||||
data_bytes_ap->SwapBytes (m_accumulated_data);
|
||||
EventSP new_event_sp (new Event (m_broadcast_event_type, data_bytes_ap.release()));
|
||||
m_broadcaster.BroadcastEvent (new_event_sp);
|
||||
m_accumulated_data.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
StreamAsynchronousIO::Write (const void *s, size_t length)
|
||||
{
|
||||
m_accumulated_data.Write (s, length);
|
||||
m_accumulated_data.append ((const char *)s, length);
|
||||
return length;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,12 @@ StringList::AppendString (const std::string &s)
|
|||
m_strings.push_back (s);
|
||||
}
|
||||
|
||||
void
|
||||
StringList::AppendString (std::string &&s)
|
||||
{
|
||||
m_strings.push_back (s);
|
||||
}
|
||||
|
||||
void
|
||||
StringList::AppendString (const char *str, size_t str_len)
|
||||
{
|
||||
|
@ -93,6 +99,20 @@ StringList::GetSize () const
|
|||
return m_strings.size();
|
||||
}
|
||||
|
||||
size_t
|
||||
StringList::GetMaxStringLength () const
|
||||
{
|
||||
size_t max_length = 0;
|
||||
for (const auto &s : m_strings)
|
||||
{
|
||||
const size_t len = s.size();
|
||||
if (max_length < len)
|
||||
max_length = len;
|
||||
}
|
||||
return max_length;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
StringList::GetStringAtIndex (size_t idx) const
|
||||
{
|
||||
|
@ -126,37 +146,39 @@ StringList::Clear ()
|
|||
void
|
||||
StringList::LongestCommonPrefix (std::string &common_prefix)
|
||||
{
|
||||
//arg_sstr_collection::iterator pos, end = m_args.end();
|
||||
size_t pos = 0;
|
||||
size_t end = m_strings.size();
|
||||
const size_t num_strings = m_strings.size();
|
||||
|
||||
if (pos == end)
|
||||
common_prefix.clear();
|
||||
else
|
||||
common_prefix = m_strings[pos];
|
||||
|
||||
for (++pos; pos != end; ++pos)
|
||||
if (num_strings == 0)
|
||||
{
|
||||
size_t new_size = strlen (m_strings[pos].c_str());
|
||||
common_prefix.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
common_prefix = m_strings.front();
|
||||
|
||||
// First trim common_prefix if it is longer than the current element:
|
||||
if (common_prefix.size() > new_size)
|
||||
common_prefix.erase (new_size);
|
||||
|
||||
// Then trim it at the first disparity:
|
||||
|
||||
for (size_t i = 0; i < common_prefix.size(); i++)
|
||||
for (size_t idx = 1; idx < num_strings; ++idx)
|
||||
{
|
||||
if (m_strings[pos][i] != common_prefix[i])
|
||||
{
|
||||
common_prefix.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string &curr_string = m_strings[idx];
|
||||
size_t new_size = curr_string.size();
|
||||
|
||||
// If we've emptied the common prefix, we're done.
|
||||
if (common_prefix.empty())
|
||||
break;
|
||||
// First trim common_prefix if it is longer than the current element:
|
||||
if (common_prefix.size() > new_size)
|
||||
common_prefix.erase (new_size);
|
||||
|
||||
// Then trim it at the first disparity:
|
||||
for (size_t i = 0; i < common_prefix.size(); i++)
|
||||
{
|
||||
if (curr_string[i] != common_prefix[i])
|
||||
{
|
||||
common_prefix.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've emptied the common prefix, we're done.
|
||||
if (common_prefix.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,6 +194,24 @@ StringList::InsertStringAtIndex (size_t idx, const char *str)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
StringList::InsertStringAtIndex (size_t idx, const std::string &str)
|
||||
{
|
||||
if (idx < m_strings.size())
|
||||
m_strings.insert (m_strings.begin() + idx, str);
|
||||
else
|
||||
m_strings.push_back (str);
|
||||
}
|
||||
|
||||
void
|
||||
StringList::InsertStringAtIndex (size_t idx, std::string &&str)
|
||||
{
|
||||
if (idx < m_strings.size())
|
||||
m_strings.insert (m_strings.begin() + idx, str);
|
||||
else
|
||||
m_strings.push_back (str);
|
||||
}
|
||||
|
||||
void
|
||||
StringList::DeleteStringAtIndex (size_t idx)
|
||||
{
|
||||
|
@ -179,6 +219,12 @@ StringList::DeleteStringAtIndex (size_t idx)
|
|||
m_strings.erase (m_strings.begin() + idx);
|
||||
}
|
||||
|
||||
size_t
|
||||
StringList::SplitIntoLines (const std::string &lines)
|
||||
{
|
||||
return SplitIntoLines (lines.c_str(), lines.size());
|
||||
}
|
||||
|
||||
size_t
|
||||
StringList::SplitIntoLines (const char *lines, size_t len)
|
||||
{
|
||||
|
@ -231,8 +277,7 @@ StringList::RemoveBlankLines ()
|
|||
}
|
||||
|
||||
std::string
|
||||
StringList::CopyList(const char* item_preamble,
|
||||
const char* items_sep)
|
||||
StringList::CopyList(const char* item_preamble, const char* items_sep) const
|
||||
{
|
||||
StreamString strm;
|
||||
for (size_t i = 0; i < GetSize(); i++)
|
||||
|
|
|
@ -3721,7 +3721,8 @@ ValueObject::EvaluationPoint::SyncWithProcessState()
|
|||
{
|
||||
|
||||
// Start with the target, if it is NULL, then we're obviously not going to get any further:
|
||||
ExecutionContext exe_ctx(m_exe_ctx_ref.Lock());
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
ExecutionContext exe_ctx(m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
|
||||
|
||||
if (exe_ctx.GetTargetPtr() == NULL)
|
||||
return false;
|
||||
|
|
|
@ -206,7 +206,8 @@ ValueObjectChild::UpdateValue ()
|
|||
|
||||
if (m_error.Success())
|
||||
{
|
||||
ExecutionContext exe_ctx (GetExecutionContextRef().Lock());
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
|
||||
if (GetClangType().GetTypeInfo() & ClangASTType::eTypeHasValue)
|
||||
m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
|
||||
else
|
||||
|
|
|
@ -84,7 +84,8 @@ lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtInde
|
|||
stream.Printf("[%zu]",idx);
|
||||
DataExtractor data;
|
||||
val_hash.first->GetData(data);
|
||||
ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock();
|
||||
const bool thread_and_frame_only_if_stopped = true;
|
||||
ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
|
||||
return val_hash.first->CreateValueObjectFromData(stream.GetData(),
|
||||
data,
|
||||
exe_ctx,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Disassembler.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Expression/ClangASTSource.h"
|
||||
#include "lldb/Expression/ClangExpression.h"
|
||||
|
@ -505,7 +506,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
|
|||
Stream *error_stream = NULL;
|
||||
Target *target = exe_ctx.GetTargetPtr();
|
||||
if (target)
|
||||
error_stream = &target->GetDebugger().GetErrorStream();
|
||||
error_stream = target->GetDebugger().GetErrorFile().get();
|
||||
|
||||
IRForTarget ir_for_target(decl_map,
|
||||
m_expr.NeedsVariableResolution(),
|
||||
|
|
|
@ -3,6 +3,7 @@ set(LLVM_NO_RTTI 1)
|
|||
add_lldb_library(lldbHostCommon
|
||||
Condition.cpp
|
||||
DynamicLibrary.cpp
|
||||
Editline.cpp
|
||||
File.cpp
|
||||
FileSpec.cpp
|
||||
Host.cpp
|
||||
|
|
|
@ -0,0 +1,671 @@
|
|||
//===-- Editline.cpp --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "lldb/Host/Editline.h"
|
||||
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
static const char k_prompt_escape_char = '\1';
|
||||
|
||||
Editline::Editline (const char *prog, // prog can't be NULL
|
||||
const char *prompt, // can be NULL for no prompt
|
||||
FILE *fin,
|
||||
FILE *fout,
|
||||
FILE *ferr) :
|
||||
m_editline (NULL),
|
||||
m_history (NULL),
|
||||
m_history_event (),
|
||||
m_program (),
|
||||
m_prompt (),
|
||||
m_lines_prompt (),
|
||||
m_getc_buffer (),
|
||||
m_getc_mutex (Mutex::eMutexTypeNormal),
|
||||
m_getc_cond (),
|
||||
// m_gets_mutex (Mutex::eMutexTypeNormal),
|
||||
m_completion_callback (NULL),
|
||||
m_completion_callback_baton (NULL),
|
||||
m_line_complete_callback (NULL),
|
||||
m_line_complete_callback_baton (NULL),
|
||||
m_lines_command (Command::None),
|
||||
m_lines_curr_line (0),
|
||||
m_lines_max_line (0),
|
||||
m_prompt_with_line_numbers (false),
|
||||
m_getting_line (false),
|
||||
m_got_eof (false),
|
||||
m_interrupted (false)
|
||||
{
|
||||
if (prog && prog[0])
|
||||
{
|
||||
m_program = prog;
|
||||
m_editline = ::el_init(prog, fin, fout, ferr);
|
||||
m_history = ::history_init();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_editline = ::el_init("lldb-tmp", fin, fout, ferr);
|
||||
}
|
||||
if (prompt && prompt[0])
|
||||
SetPrompt (prompt);
|
||||
|
||||
//::el_set (m_editline, EL_BIND, "^[[A", NULL); // Print binding for up arrow key
|
||||
//::el_set (m_editline, EL_BIND, "^[[B", NULL); // Print binding for up down key
|
||||
|
||||
assert (m_editline);
|
||||
::el_set (m_editline, EL_CLIENTDATA, this);
|
||||
::el_set (m_editline, EL_PROMPT_ESC, GetPromptCallback, k_prompt_escape_char);
|
||||
::el_set (m_editline, EL_EDITOR, "emacs");
|
||||
if (m_history)
|
||||
{
|
||||
::el_set (m_editline, EL_HIST, history, m_history);
|
||||
}
|
||||
::el_set (m_editline, EL_ADDFN, "lldb-complete", "Editline completion function", Editline::CallbackComplete);
|
||||
::el_set (m_editline, EL_ADDFN, "lldb-edit-prev-line", "Editline edit prev line", Editline::CallbackEditPrevLine);
|
||||
::el_set (m_editline, EL_ADDFN, "lldb-edit-next-line", "Editline edit next line", Editline::CallbackEditNextLine);
|
||||
|
||||
::el_set (m_editline, EL_BIND, "^r", "em-inc-search-prev", NULL); // Cycle through backwards search, entering string
|
||||
::el_set (m_editline, EL_BIND, "^w", "ed-delete-prev-word", NULL); // Delete previous word, behave like bash does.
|
||||
::el_set (m_editline, EL_BIND, "\033[3~", "ed-delete-next-char", NULL); // Fix the delete key.
|
||||
::el_set (m_editline, EL_BIND, "\t", "lldb-complete", NULL); // Bind TAB to be autocompelte
|
||||
|
||||
// Source $PWD/.editrc then $HOME/.editrc
|
||||
::el_source (m_editline, NULL);
|
||||
|
||||
if (m_history)
|
||||
{
|
||||
::history (m_history, &m_history_event, H_SETSIZE, 800);
|
||||
::history (m_history, &m_history_event, H_SETUNIQUE, 1);
|
||||
}
|
||||
|
||||
// Always read through our callback function so we don't read
|
||||
// stuff we aren't supposed to. This also stops the extra echoing
|
||||
// that can happen when you have more input than editline can handle
|
||||
// at once.
|
||||
SetGetCharCallback(GetCharFromInputFileCallback);
|
||||
|
||||
LoadHistory();
|
||||
}
|
||||
|
||||
Editline::~Editline()
|
||||
{
|
||||
SaveHistory();
|
||||
|
||||
if (m_history)
|
||||
{
|
||||
::history_end (m_history);
|
||||
m_history = NULL;
|
||||
}
|
||||
|
||||
// Disable edit mode to stop the terminal from flushing all input
|
||||
// during the call to el_end() since we expect to have multiple editline
|
||||
// instances in this program.
|
||||
::el_set (m_editline, EL_EDITMODE, 0);
|
||||
|
||||
::el_end(m_editline);
|
||||
m_editline = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Editline::SetGetCharCallback (GetCharCallbackType callback)
|
||||
{
|
||||
::el_set (m_editline, EL_GETCFN, callback);
|
||||
}
|
||||
|
||||
FileSpec
|
||||
Editline::GetHistoryFile()
|
||||
{
|
||||
char history_path[PATH_MAX];
|
||||
::snprintf (history_path, sizeof(history_path), "~/.%s-history", m_program.c_str());
|
||||
return FileSpec(history_path, true);
|
||||
}
|
||||
|
||||
bool
|
||||
Editline::LoadHistory ()
|
||||
{
|
||||
if (m_history)
|
||||
{
|
||||
FileSpec history_file(GetHistoryFile());
|
||||
if (history_file.Exists())
|
||||
::history (m_history, &m_history_event, H_LOAD, history_file.GetPath().c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Editline::SaveHistory ()
|
||||
{
|
||||
if (m_history)
|
||||
{
|
||||
std::string history_path = GetHistoryFile().GetPath();
|
||||
::history (m_history, &m_history_event, H_SAVE, history_path.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Error
|
||||
Editline::PrivateGetLine(std::string &line)
|
||||
{
|
||||
Error error;
|
||||
if (m_interrupted)
|
||||
{
|
||||
error.SetErrorString("interrupted");
|
||||
return error;
|
||||
}
|
||||
|
||||
line.clear();
|
||||
if (m_editline != NULL)
|
||||
{
|
||||
int line_len = 0;
|
||||
const char *line_cstr = NULL;
|
||||
// Call el_gets to prompt the user and read the user's input.
|
||||
// {
|
||||
// // Make sure we know when we are in el_gets() by using a mutex
|
||||
// Mutex::Locker locker (m_gets_mutex);
|
||||
line_cstr = ::el_gets (m_editline, &line_len);
|
||||
// }
|
||||
|
||||
static int save_errno = (line_len < 0) ? errno : 0;
|
||||
|
||||
if (save_errno != 0)
|
||||
{
|
||||
error.SetError(save_errno, eErrorTypePOSIX);
|
||||
}
|
||||
else if (line_cstr)
|
||||
{
|
||||
// Decrement the length so we don't have newline characters in "line" for when
|
||||
// we assign the cstr into the std::string
|
||||
while (line_len > 0 &&
|
||||
(line_cstr[line_len - 1] == '\n' ||
|
||||
line_cstr[line_len - 1] == '\r'))
|
||||
--line_len;
|
||||
|
||||
if (line_len > 0)
|
||||
{
|
||||
// We didn't strip the newlines, we just adjusted the length, and
|
||||
// we want to add the history item with the newlines
|
||||
if (m_history)
|
||||
::history (m_history, &m_history_event, H_ENTER, line_cstr);
|
||||
|
||||
// Copy the part of the c string that we want (removing the newline chars)
|
||||
line.assign(line_cstr, line_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString("the EditLine instance has been deleted");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
Error
|
||||
Editline::GetLine(std::string &line)
|
||||
{
|
||||
Error error;
|
||||
line.clear();
|
||||
|
||||
// Set arrow key bindings for up and down arrows for single line
|
||||
// mode where up and down arrows do prev/next history
|
||||
::el_set (m_editline, EL_BIND, "^[[A", "ed-prev-history", NULL); // Map up arrow
|
||||
::el_set (m_editline, EL_BIND, "^[[B", "ed-next-history", NULL); // Map down arrow
|
||||
m_interrupted = false;
|
||||
|
||||
if (!m_got_eof)
|
||||
{
|
||||
if (m_getting_line)
|
||||
{
|
||||
error.SetErrorString("already getting a line");
|
||||
return error;
|
||||
}
|
||||
if (m_lines_curr_line > 0)
|
||||
{
|
||||
error.SetErrorString("already getting lines");
|
||||
return error;
|
||||
}
|
||||
m_getting_line = true;
|
||||
error = PrivateGetLine(line);
|
||||
m_getting_line = false;
|
||||
}
|
||||
|
||||
if (m_got_eof && line.empty())
|
||||
{
|
||||
// Only set the error if we didn't get an error back from PrivateGetLine()
|
||||
if (error.Success())
|
||||
error.SetErrorString("end of file");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
size_t
|
||||
Editline::Push (const char *bytes, size_t len)
|
||||
{
|
||||
if (m_editline)
|
||||
{
|
||||
// Must NULL terminate the string for el_push() so we stick it
|
||||
// into a std::string first
|
||||
::el_push(m_editline, std::string (bytes, len).c_str());
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Error
|
||||
Editline::GetLines(const std::string &end_line, StringList &lines)
|
||||
{
|
||||
Error error;
|
||||
if (m_getting_line)
|
||||
{
|
||||
error.SetErrorString("already getting a line");
|
||||
return error;
|
||||
}
|
||||
if (m_lines_curr_line > 0)
|
||||
{
|
||||
error.SetErrorString("already getting lines");
|
||||
return error;
|
||||
}
|
||||
|
||||
// Set arrow key bindings for up and down arrows for multiple line
|
||||
// mode where up and down arrows do edit prev/next line
|
||||
::el_set (m_editline, EL_BIND, "^[[A", "lldb-edit-prev-line", NULL); // Map up arrow
|
||||
::el_set (m_editline, EL_BIND, "^[[B", "lldb-edit-next-line", NULL); // Map down arrow
|
||||
::el_set (m_editline, EL_BIND, "^b", "ed-prev-history", NULL);
|
||||
::el_set (m_editline, EL_BIND, "^n", "ed-next-history", NULL);
|
||||
m_interrupted = false;
|
||||
|
||||
LineStatus line_status = LineStatus::Success;
|
||||
|
||||
lines.Clear();
|
||||
|
||||
FILE *out_file = GetOutputFile();
|
||||
FILE *err_file = GetErrorFile();
|
||||
m_lines_curr_line = 1;
|
||||
while (line_status != LineStatus::Done)
|
||||
{
|
||||
const uint32_t line_idx = m_lines_curr_line-1;
|
||||
if (line_idx >= lines.GetSize())
|
||||
lines.SetSize(m_lines_curr_line);
|
||||
m_lines_max_line = lines.GetSize();
|
||||
m_lines_command = Command::None;
|
||||
assert(line_idx < m_lines_max_line);
|
||||
std::string &line = lines[line_idx];
|
||||
error = PrivateGetLine(line);
|
||||
if (error.Fail())
|
||||
{
|
||||
line_status = LineStatus::Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_lines_command)
|
||||
{
|
||||
case Command::None:
|
||||
if (m_line_complete_callback)
|
||||
{
|
||||
line_status = m_line_complete_callback (this,
|
||||
lines,
|
||||
line_idx,
|
||||
error,
|
||||
m_line_complete_callback_baton);
|
||||
}
|
||||
else if (line == end_line)
|
||||
{
|
||||
line_status = LineStatus::Done;
|
||||
}
|
||||
|
||||
if (line_status == LineStatus::Success)
|
||||
{
|
||||
++m_lines_curr_line;
|
||||
// If we already have content for the next line because
|
||||
// we were editing previous lines, then populate the line
|
||||
// with the appropriate contents
|
||||
if (line_idx+1 < lines.GetSize() && !lines[line_idx+1].empty())
|
||||
::el_push (m_editline, lines[line_idx+1].c_str());
|
||||
}
|
||||
else if (line_status == LineStatus::Error)
|
||||
{
|
||||
// Clear to end of line ("ESC[K"), then print the error,
|
||||
// then go to the next line ("\n") and then move cursor up
|
||||
// two lines ("ESC[2A").
|
||||
fprintf (err_file, "\033[Kerror: %s\n\033[2A", error.AsCString());
|
||||
}
|
||||
break;
|
||||
case Command::EditPrevLine:
|
||||
if (m_lines_curr_line > 1)
|
||||
{
|
||||
//::fprintf (out_file, "\033[1A\033[%uD\033[2K", (uint32_t)(m_lines_prompt.size() + lines[line_idx].size())); // Make cursor go up a line and clear that line
|
||||
::fprintf (out_file, "\033[1A\033[1000D\033[2K");
|
||||
if (!lines[line_idx-1].empty())
|
||||
::el_push (m_editline, lines[line_idx-1].c_str());
|
||||
--m_lines_curr_line;
|
||||
}
|
||||
break;
|
||||
case Command::EditNextLine:
|
||||
// Allow the down arrow to create a new line
|
||||
++m_lines_curr_line;
|
||||
//::fprintf (out_file, "\033[1B\033[%uD\033[2K", (uint32_t)(m_lines_prompt.size() + lines[line_idx].size()));
|
||||
::fprintf (out_file, "\033[1B\033[1000D\033[2K");
|
||||
if (line_idx+1 < lines.GetSize() && !lines[line_idx+1].empty())
|
||||
::el_push (m_editline, lines[line_idx+1].c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_lines_curr_line = 0;
|
||||
m_lines_command = Command::None;
|
||||
|
||||
// If we have a callback, call it one more time to let the
|
||||
// user know the lines are complete
|
||||
if (m_line_complete_callback)
|
||||
m_line_complete_callback (this,
|
||||
lines,
|
||||
UINT32_MAX,
|
||||
error,
|
||||
m_line_complete_callback_baton);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
Editline::HandleCompletion (int ch)
|
||||
{
|
||||
if (m_completion_callback == NULL)
|
||||
return CC_ERROR;
|
||||
|
||||
const LineInfo *line_info = ::el_line(m_editline);
|
||||
StringList completions;
|
||||
int page_size = 40;
|
||||
|
||||
const int num_completions = m_completion_callback (line_info->buffer,
|
||||
line_info->cursor,
|
||||
line_info->lastchar,
|
||||
0, // Don't skip any matches (start at match zero)
|
||||
-1, // Get all the matches
|
||||
completions,
|
||||
m_completion_callback_baton);
|
||||
|
||||
FILE *out_file = GetOutputFile();
|
||||
|
||||
// if (num_completions == -1)
|
||||
// {
|
||||
// ::el_insertstr (m_editline, m_completion_key);
|
||||
// return CC_REDISPLAY;
|
||||
// }
|
||||
// else
|
||||
if (num_completions == -2)
|
||||
{
|
||||
// Replace the entire line with the first string...
|
||||
::el_deletestr (m_editline, line_info->cursor - line_info->buffer);
|
||||
::el_insertstr (m_editline, completions.GetStringAtIndex(0));
|
||||
return CC_REDISPLAY;
|
||||
}
|
||||
|
||||
// If we get a longer match display that first.
|
||||
const char *completion_str = completions.GetStringAtIndex(0);
|
||||
if (completion_str != NULL && *completion_str != '\0')
|
||||
{
|
||||
el_insertstr (m_editline, completion_str);
|
||||
return CC_REDISPLAY;
|
||||
}
|
||||
|
||||
if (num_completions > 1)
|
||||
{
|
||||
int num_elements = num_completions + 1;
|
||||
::fprintf (out_file, "\nAvailable completions:");
|
||||
if (num_completions < page_size)
|
||||
{
|
||||
for (int i = 1; i < num_elements; i++)
|
||||
{
|
||||
completion_str = completions.GetStringAtIndex(i);
|
||||
::fprintf (out_file, "\n\t%s", completion_str);
|
||||
}
|
||||
::fprintf (out_file, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
int cur_pos = 1;
|
||||
char reply;
|
||||
int got_char;
|
||||
while (cur_pos < num_elements)
|
||||
{
|
||||
int endpoint = cur_pos + page_size;
|
||||
if (endpoint > num_elements)
|
||||
endpoint = num_elements;
|
||||
for (; cur_pos < endpoint; cur_pos++)
|
||||
{
|
||||
completion_str = completions.GetStringAtIndex(cur_pos);
|
||||
::fprintf (out_file, "\n\t%s", completion_str);
|
||||
}
|
||||
|
||||
if (cur_pos >= num_elements)
|
||||
{
|
||||
::fprintf (out_file, "\n");
|
||||
break;
|
||||
}
|
||||
|
||||
::fprintf (out_file, "\nMore (Y/n/a): ");
|
||||
reply = 'n';
|
||||
got_char = el_getc(m_editline, &reply);
|
||||
if (got_char == -1 || reply == 'n')
|
||||
break;
|
||||
if (reply == 'a')
|
||||
page_size = num_elements - cur_pos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (num_completions == 0)
|
||||
return CC_REFRESH_BEEP;
|
||||
else
|
||||
return CC_REDISPLAY;
|
||||
}
|
||||
|
||||
Editline *
|
||||
Editline::GetClientData (::EditLine *e)
|
||||
{
|
||||
Editline *editline = NULL;
|
||||
if (e && ::el_get(e, EL_CLIENTDATA, &editline) == 0)
|
||||
return editline;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *
|
||||
Editline::GetInputFile ()
|
||||
{
|
||||
return GetFilePointer (m_editline, 0);
|
||||
}
|
||||
|
||||
FILE *
|
||||
Editline::GetOutputFile ()
|
||||
{
|
||||
return GetFilePointer (m_editline, 1);
|
||||
}
|
||||
|
||||
FILE *
|
||||
Editline::GetErrorFile ()
|
||||
{
|
||||
return GetFilePointer (m_editline, 2);
|
||||
}
|
||||
|
||||
const char *
|
||||
Editline::GetPrompt()
|
||||
{
|
||||
if (m_prompt_with_line_numbers && m_lines_curr_line > 0)
|
||||
{
|
||||
StreamString strm;
|
||||
strm.Printf("%3u: ", m_lines_curr_line);
|
||||
m_lines_prompt = std::move(strm.GetString());
|
||||
return m_lines_prompt.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_prompt.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Editline::SetPrompt (const char *p)
|
||||
{
|
||||
if (p && p[0])
|
||||
m_prompt = p;
|
||||
else
|
||||
m_prompt.clear();
|
||||
size_t start_pos = 0;
|
||||
size_t escape_pos;
|
||||
while ((escape_pos = m_prompt.find('\033', start_pos)) != std::string::npos)
|
||||
{
|
||||
m_prompt.insert(escape_pos, 1, k_prompt_escape_char);
|
||||
start_pos += 2;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *
|
||||
Editline::GetFilePointer (::EditLine *e, int fd)
|
||||
{
|
||||
FILE *file_ptr = NULL;
|
||||
if (e && ::el_get(e, EL_GETFP, fd, &file_ptr) == 0)
|
||||
return file_ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
Editline::CallbackEditPrevLine (::EditLine *e, int ch)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline->m_lines_curr_line > 1)
|
||||
{
|
||||
editline->m_lines_command = Command::EditPrevLine;
|
||||
return CC_NEWLINE;
|
||||
}
|
||||
return CC_ERROR;
|
||||
}
|
||||
unsigned char
|
||||
Editline::CallbackEditNextLine (::EditLine *e, int ch)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline->m_lines_curr_line < editline->m_lines_max_line)
|
||||
{
|
||||
editline->m_lines_command = Command::EditNextLine;
|
||||
return CC_NEWLINE;
|
||||
}
|
||||
return CC_ERROR;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
Editline::CallbackComplete (::EditLine *e, int ch)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline)
|
||||
return editline->HandleCompletion (ch);
|
||||
return CC_ERROR;
|
||||
}
|
||||
|
||||
const char *
|
||||
Editline::GetPromptCallback (::EditLine *e)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline)
|
||||
return editline->GetPrompt();
|
||||
return "";
|
||||
}
|
||||
|
||||
size_t
|
||||
Editline::SetInputBuffer (const char *c, size_t len)
|
||||
{
|
||||
if (c && len > 0)
|
||||
{
|
||||
Mutex::Locker locker(m_getc_mutex);
|
||||
SetGetCharCallback(GetCharInputBufferCallback);
|
||||
m_getc_buffer.append(c, len);
|
||||
m_getc_cond.Broadcast();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
Editline::GetChar (char *c)
|
||||
{
|
||||
Mutex::Locker locker(m_getc_mutex);
|
||||
if (m_getc_buffer.empty())
|
||||
m_getc_cond.Wait(m_getc_mutex);
|
||||
if (m_getc_buffer.empty())
|
||||
return 0;
|
||||
*c = m_getc_buffer[0];
|
||||
m_getc_buffer.erase(0,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
Editline::GetCharInputBufferCallback (EditLine *e, char *c)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline)
|
||||
return editline->GetChar(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Editline::GetCharFromInputFileCallback (EditLine *e, char *c)
|
||||
{
|
||||
Editline *editline = GetClientData (e);
|
||||
if (editline && editline->m_got_eof == false)
|
||||
{
|
||||
char ch = ::fgetc(editline->GetInputFile());
|
||||
if (ch == '\x04' || ch == EOF)
|
||||
{
|
||||
editline->m_got_eof = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*c = ch;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Editline::Hide ()
|
||||
{
|
||||
FILE *out_file = GetOutputFile();
|
||||
if (out_file)
|
||||
{
|
||||
const LineInfo *line_info = ::el_line(m_editline);
|
||||
if (line_info)
|
||||
::fprintf (out_file, "\033[%uD\033[K", (uint32_t)(strlen(GetPrompt()) + line_info->cursor - line_info->buffer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Editline::Refresh()
|
||||
{
|
||||
::el_set (m_editline, EL_REFRESH);
|
||||
}
|
||||
|
||||
void
|
||||
Editline::Interrupt ()
|
||||
{
|
||||
m_interrupted = true;
|
||||
if (m_getting_line || m_lines_curr_line > 0)
|
||||
el_insertstr(m_editline, "\n"); // True to force the line to complete itself so we get exit from el_gets()
|
||||
}
|
|
@ -76,8 +76,9 @@ FILE * File::kInvalidStream = NULL;
|
|||
File::File(const char *path, uint32_t options, uint32_t permissions) :
|
||||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (false)
|
||||
m_options (),
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (false)
|
||||
{
|
||||
Open (path, options, permissions);
|
||||
}
|
||||
|
@ -88,7 +89,8 @@ File::File (const FileSpec& filespec,
|
|||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (false)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (false)
|
||||
{
|
||||
if (filespec)
|
||||
{
|
||||
|
@ -100,7 +102,8 @@ File::File (const File &rhs) :
|
|||
m_descriptor (kInvalidDescriptor),
|
||||
m_stream (kInvalidStream),
|
||||
m_options (0),
|
||||
m_owned (false)
|
||||
m_own_stream (false),
|
||||
m_own_descriptor (false)
|
||||
{
|
||||
Duplicate (rhs);
|
||||
}
|
||||
|
@ -141,7 +144,7 @@ File::SetDescriptor (int fd, bool transfer_ownership)
|
|||
if (IsValid())
|
||||
Close();
|
||||
m_descriptor = fd;
|
||||
m_owned = transfer_ownership;
|
||||
m_own_descriptor = transfer_ownership;
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,10 +158,31 @@ File::GetStream ()
|
|||
const char *mode = GetStreamOpenModeFromOptions (m_options);
|
||||
if (mode)
|
||||
{
|
||||
if (!m_own_descriptor)
|
||||
{
|
||||
// We must duplicate the file descriptor if we don't own it because
|
||||
// when you call fdopen, the stream will own the fd
|
||||
#ifdef _WIN32
|
||||
m_descriptor = ::_dup(GetDescriptor());
|
||||
#else
|
||||
m_descriptor = ::fcntl(GetDescriptor(), F_DUPFD);
|
||||
#endif
|
||||
m_own_descriptor = true;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
m_stream = ::fdopen (m_descriptor, mode);
|
||||
} while (m_stream == NULL && errno == EINTR);
|
||||
|
||||
// If we got a stream, then we own the stream and should no
|
||||
// longer own the descriptor because fclose() will close it for us
|
||||
|
||||
if (m_stream)
|
||||
{
|
||||
m_own_stream = true;
|
||||
m_own_descriptor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +196,7 @@ File::SetStream (FILE *fh, bool transfer_ownership)
|
|||
if (IsValid())
|
||||
Close();
|
||||
m_stream = fh;
|
||||
m_owned = transfer_ownership;
|
||||
m_own_stream = transfer_ownership;
|
||||
}
|
||||
|
||||
Error
|
||||
|
@ -194,7 +218,7 @@ File::Duplicate (const File &rhs)
|
|||
else
|
||||
{
|
||||
m_options = rhs.m_options;
|
||||
m_owned = true;
|
||||
m_own_descriptor = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -272,7 +296,10 @@ File::Open (const char *path, uint32_t options, uint32_t permissions)
|
|||
if (!DescriptorIsValid())
|
||||
error.SetErrorToErrno();
|
||||
else
|
||||
m_owned = true;
|
||||
{
|
||||
m_own_descriptor = true;
|
||||
m_options = options;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -328,27 +355,22 @@ Error
|
|||
File::Close ()
|
||||
{
|
||||
Error error;
|
||||
if (IsValid ())
|
||||
if (StreamIsValid() && m_own_stream)
|
||||
{
|
||||
if (m_owned)
|
||||
{
|
||||
if (StreamIsValid())
|
||||
{
|
||||
if (::fclose (m_stream) == EOF)
|
||||
error.SetErrorToErrno();
|
||||
}
|
||||
|
||||
if (DescriptorIsValid())
|
||||
{
|
||||
if (::close (m_descriptor) != 0)
|
||||
error.SetErrorToErrno();
|
||||
}
|
||||
}
|
||||
m_descriptor = kInvalidDescriptor;
|
||||
m_stream = kInvalidStream;
|
||||
m_options = 0;
|
||||
m_owned = false;
|
||||
if (::fclose (m_stream) == EOF)
|
||||
error.SetErrorToErrno();
|
||||
}
|
||||
|
||||
if (DescriptorIsValid() && m_own_descriptor)
|
||||
{
|
||||
if (::close (m_descriptor) != 0)
|
||||
error.SetErrorToErrno();
|
||||
}
|
||||
m_descriptor = kInvalidDescriptor;
|
||||
m_stream = kInvalidStream;
|
||||
m_options = 0;
|
||||
m_own_stream = false;
|
||||
m_own_descriptor = false;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../Commands/CommandObjectDisassemble.h"
|
||||
#include "../Commands/CommandObjectExpression.h"
|
||||
#include "../Commands/CommandObjectFrame.h"
|
||||
#include "../Commands/CommandObjectGUI.h"
|
||||
#include "../Commands/CommandObjectHelp.h"
|
||||
#include "../Commands/CommandObjectLog.h"
|
||||
#include "../Commands/CommandObjectMemory.h"
|
||||
|
@ -42,11 +43,12 @@
|
|||
|
||||
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
|
||||
#include "lldb/Host/Editline.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
|
@ -99,11 +101,13 @@ CommandInterpreter::CommandInterpreter
|
|||
) :
|
||||
Broadcaster (&debugger, "lldb.command-interpreter"),
|
||||
Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
|
||||
IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand),
|
||||
m_debugger (debugger),
|
||||
m_synchronous_execution (synchronous_execution),
|
||||
m_skip_lldbinit_files (false),
|
||||
m_skip_app_init_files (false),
|
||||
m_script_interpreter_ap (),
|
||||
m_command_io_handler_sp (),
|
||||
m_comment_char ('#'),
|
||||
m_batch_command_mode (false),
|
||||
m_truncation_warning(eNoTruncation),
|
||||
|
@ -376,6 +380,7 @@ CommandInterpreter::LoadCommandDictionary ()
|
|||
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
|
||||
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
|
||||
m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
|
||||
m_command_dict["gui"] = CommandObjectSP (new CommandObjectGUI (*this));
|
||||
m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this));
|
||||
m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this));
|
||||
m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this));
|
||||
|
@ -2093,96 +2098,15 @@ CommandInterpreter::~CommandInterpreter ()
|
|||
{
|
||||
}
|
||||
|
||||
const char *
|
||||
CommandInterpreter::GetPrompt ()
|
||||
{
|
||||
return m_debugger.GetPrompt();
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::SetPrompt (const char *new_prompt)
|
||||
CommandInterpreter::UpdatePrompt (const char *new_prompt)
|
||||
{
|
||||
m_debugger.SetPrompt (new_prompt);
|
||||
EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
|
||||
BroadcastEvent (prompt_change_event_sp);
|
||||
if (m_command_io_handler_sp)
|
||||
m_command_io_handler_sp->SetPrompt(new_prompt);
|
||||
}
|
||||
|
||||
size_t
|
||||
CommandInterpreter::GetConfirmationInputReaderCallback
|
||||
(
|
||||
void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction action,
|
||||
const char *bytes,
|
||||
size_t bytes_len
|
||||
)
|
||||
{
|
||||
File &out_file = reader.GetDebugger().GetOutputFile();
|
||||
bool *response_ptr = (bool *) baton;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
if (out_file.IsValid())
|
||||
{
|
||||
if (reader.GetPrompt())
|
||||
{
|
||||
out_file.Printf ("%s", reader.GetPrompt());
|
||||
out_file.Flush ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderReactivate:
|
||||
if (out_file.IsValid() && reader.GetPrompt())
|
||||
{
|
||||
out_file.Printf ("%s", reader.GetPrompt());
|
||||
out_file.Flush ();
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
if (bytes_len == 0)
|
||||
{
|
||||
reader.SetIsDone(true);
|
||||
}
|
||||
else if (bytes[0] == 'y' || bytes[0] == 'Y')
|
||||
{
|
||||
*response_ptr = true;
|
||||
reader.SetIsDone(true);
|
||||
}
|
||||
else if (bytes[0] == 'n' || bytes[0] == 'N')
|
||||
{
|
||||
*response_ptr = false;
|
||||
reader.SetIsDone(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (out_file.IsValid() && !reader.IsDone() && reader.GetPrompt())
|
||||
{
|
||||
out_file.Printf ("Please answer \"y\" or \"n\".\n%s", reader.GetPrompt());
|
||||
out_file.Flush ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
case eInputReaderEndOfFile:
|
||||
*response_ptr = false; // Assume ^C or ^D means cancel the proposed action
|
||||
reader.SetIsDone (true);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
break;
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
CommandInterpreter::Confirm (const char *message, bool default_answer)
|
||||
|
@ -2190,31 +2114,13 @@ CommandInterpreter::Confirm (const char *message, bool default_answer)
|
|||
// Check AutoConfirm first:
|
||||
if (m_debugger.GetAutoConfirm())
|
||||
return default_answer;
|
||||
|
||||
InputReaderSP reader_sp (new InputReader(GetDebugger()));
|
||||
bool response = default_answer;
|
||||
if (reader_sp)
|
||||
{
|
||||
std::string prompt(message);
|
||||
prompt.append(": [");
|
||||
if (default_answer)
|
||||
prompt.append ("Y/n] ");
|
||||
else
|
||||
prompt.append ("y/N] ");
|
||||
|
||||
Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback,
|
||||
&response, // baton
|
||||
eInputReaderGranularityLine, // token size, to pass to callback function
|
||||
NULL, // end token
|
||||
prompt.c_str(), // prompt
|
||||
true)); // echo input
|
||||
if (err.Success())
|
||||
{
|
||||
GetDebugger().PushInputReader (reader_sp);
|
||||
}
|
||||
reader_sp->WaitOnReaderIsDone();
|
||||
}
|
||||
return response;
|
||||
|
||||
IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger,
|
||||
message,
|
||||
default_answer);
|
||||
IOHandlerSP io_handler_sp (confirm);
|
||||
m_debugger.RunIOHandler (io_handler_sp);
|
||||
return confirm->GetResponse();
|
||||
}
|
||||
|
||||
OptionArgVectorSP
|
||||
|
@ -2490,7 +2396,9 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
|
|||
bool echo_commands = false;
|
||||
bool print_results = false;
|
||||
|
||||
const bool saved_batch = SetBatchCommandMode (true);
|
||||
HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, eLazyBoolNo, result);
|
||||
SetBatchCommandMode (saved_batch);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2553,8 +2461,8 @@ CommandInterpreter::HandleCommands (const StringList &commands,
|
|||
if (echo_commands)
|
||||
{
|
||||
result.AppendMessageWithFormat ("%s %s\n",
|
||||
GetPrompt(),
|
||||
cmd);
|
||||
m_debugger.GetPrompt(),
|
||||
cmd);
|
||||
}
|
||||
|
||||
CommandReturnObject tmp_result;
|
||||
|
@ -2650,6 +2558,33 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
|
|||
{
|
||||
if (cmd_file.Exists())
|
||||
{
|
||||
StreamFileSP input_file_sp (new StreamFile());
|
||||
|
||||
std::string cmd_file_path = cmd_file.GetPath();
|
||||
Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead);
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
Debugger &debugger = GetDebugger();
|
||||
|
||||
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
|
||||
input_file_sp,
|
||||
debugger.GetOutputFile(),
|
||||
debugger.GetErrorFile(),
|
||||
NULL, // Pass in NULL for "editline_name" so no history is saved, or written
|
||||
m_debugger.GetPrompt(),
|
||||
false, // Not multi-line
|
||||
*this));
|
||||
m_debugger.RunIOHandler(io_handler_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool success;
|
||||
StringList commands;
|
||||
success = commands.ReadFileLines(cmd_file);
|
||||
|
@ -2662,6 +2597,7 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file,
|
|||
m_command_source_depth++;
|
||||
HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, add_to_history, result);
|
||||
m_command_source_depth--;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2901,7 +2837,6 @@ CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
|
||||
{
|
||||
|
@ -2915,3 +2850,160 @@ CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
|
|||
m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CommandInterpreter::GetProcessOutput ()
|
||||
{
|
||||
// The process has stuff waiting for stderr; get it and write it out to the appropriate place.
|
||||
char stdio_buffer[1024];
|
||||
size_t len;
|
||||
size_t total_bytes = 0;
|
||||
Error error;
|
||||
TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
|
||||
if (target_sp)
|
||||
{
|
||||
ProcessSP process_sp (target_sp->GetProcessSP());
|
||||
if (process_sp)
|
||||
{
|
||||
while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
|
||||
{
|
||||
size_t bytes_written = len;
|
||||
m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written);
|
||||
total_bytes += len;
|
||||
}
|
||||
while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
|
||||
{
|
||||
size_t bytes_written = len;
|
||||
m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written);
|
||||
total_bytes += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total_bytes;
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
|
||||
{
|
||||
lldb_private::CommandReturnObject result;
|
||||
HandleCommand(line.c_str(), eLazyBoolCalculate, result);
|
||||
|
||||
// Display any STDOUT/STDERR _prior_ to emitting the command result text
|
||||
GetProcessOutput ();
|
||||
|
||||
// Now emit the command output text from the command we just executed
|
||||
const char *output = result.GetOutputData();
|
||||
if (output && output[0])
|
||||
io_handler.GetOutputStreamFile()->PutCString(output);
|
||||
|
||||
// Now emit the command error text from the command we just executed
|
||||
const char *error = result.GetErrorData();
|
||||
if (error && error[0])
|
||||
io_handler.GetErrorStreamFile()->PutCString(error);
|
||||
|
||||
switch (result.GetStatus())
|
||||
{
|
||||
case eReturnStatusInvalid:
|
||||
case eReturnStatusSuccessFinishNoResult:
|
||||
case eReturnStatusSuccessFinishResult:
|
||||
case eReturnStatusSuccessContinuingNoResult:
|
||||
case eReturnStatusSuccessContinuingResult:
|
||||
case eReturnStatusStarted:
|
||||
case eReturnStatusFailed:
|
||||
break;
|
||||
|
||||
case eReturnStatusQuit:
|
||||
io_handler.SetIsDone(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton)
|
||||
{
|
||||
Debugger &debugger = GetDebugger();
|
||||
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
|
||||
"lldb", // Name of input reader for history
|
||||
prompt, // Prompt
|
||||
true, // Get multiple lines
|
||||
delegate)); // IOHandlerDelegate
|
||||
|
||||
if (io_handler_sp)
|
||||
{
|
||||
io_handler_sp->SetUserData (baton);
|
||||
if (asynchronously)
|
||||
debugger.PushIOHandler(io_handler_sp);
|
||||
else
|
||||
debugger.RunIOHandler(io_handler_sp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
|
||||
IOHandlerDelegate &delegate,
|
||||
bool asynchronously,
|
||||
void *baton)
|
||||
{
|
||||
Debugger &debugger = GetDebugger();
|
||||
IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
|
||||
"lldb-python", // Name of input reader for history
|
||||
prompt, // Prompt
|
||||
true, // Get multiple lines
|
||||
delegate)); // IOHandlerDelegate
|
||||
|
||||
if (io_handler_sp)
|
||||
{
|
||||
io_handler_sp->SetUserData (baton);
|
||||
if (asynchronously)
|
||||
debugger.PushIOHandler(io_handler_sp);
|
||||
else
|
||||
debugger.RunIOHandler(io_handler_sp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
CommandInterpreter::IsActive ()
|
||||
{
|
||||
return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
|
||||
}
|
||||
|
||||
void
|
||||
CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
|
||||
bool spawn_thread)
|
||||
{
|
||||
const bool multiple_lines = false; // Only get one line at a time
|
||||
if (!m_command_io_handler_sp)
|
||||
m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
|
||||
m_debugger.GetInputFile(),
|
||||
m_debugger.GetOutputFile(),
|
||||
m_debugger.GetErrorFile(),
|
||||
"lldb",
|
||||
m_debugger.GetPrompt(),
|
||||
multiple_lines,
|
||||
*this));
|
||||
m_debugger.PushIOHandler(m_command_io_handler_sp);
|
||||
|
||||
if (auto_handle_events)
|
||||
m_debugger.StartEventHandlerThread();
|
||||
|
||||
if (spawn_thread)
|
||||
{
|
||||
m_debugger.StartIOHandlerThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_debugger.ExecuteIOHanders();
|
||||
|
||||
if (auto_handle_events)
|
||||
m_debugger.StopEventHandlerThread();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ PythonString::PythonString (PyObject *py_obj) :
|
|||
PythonString::PythonString (const PythonObject &object) :
|
||||
PythonObject()
|
||||
{
|
||||
Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a string
|
||||
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a string
|
||||
}
|
||||
|
||||
PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
|
||||
|
@ -166,7 +166,7 @@ PythonInteger::PythonInteger (PyObject *py_obj) :
|
|||
PythonInteger::PythonInteger (const PythonObject &object) :
|
||||
PythonObject()
|
||||
{
|
||||
Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a integer type
|
||||
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a integer type
|
||||
}
|
||||
|
||||
PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
|
||||
|
@ -223,8 +223,8 @@ PythonInteger::SetInteger (int64_t value)
|
|||
// PythonList
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PythonList::PythonList () :
|
||||
PythonObject(PyList_New(0))
|
||||
PythonList::PythonList (bool create_empty) :
|
||||
PythonObject(create_empty ? PyList_New(0) : NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ PythonList::PythonList (PyObject *py_obj) :
|
|||
PythonList::PythonList (const PythonObject &object) :
|
||||
PythonObject()
|
||||
{
|
||||
Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a list
|
||||
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a list
|
||||
}
|
||||
|
||||
PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
|
||||
|
@ -280,29 +280,29 @@ PythonList::GetItemAtIndex (uint32_t index)
|
|||
{
|
||||
if (m_py_obj)
|
||||
return PythonObject(PyList_GetItem(m_py_obj, index));
|
||||
return NULL;
|
||||
return PythonObject();
|
||||
}
|
||||
|
||||
void
|
||||
PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
|
||||
{
|
||||
if (m_py_obj && object)
|
||||
PyList_SetItem(m_py_obj, index, object.GetPythonObject());
|
||||
PyList_SetItem(m_py_obj, index, object.get());
|
||||
}
|
||||
|
||||
void
|
||||
PythonList::AppendItem (const PythonObject &object)
|
||||
{
|
||||
if (m_py_obj && object)
|
||||
PyList_Append(m_py_obj, object.GetPythonObject());
|
||||
PyList_Append(m_py_obj, object.get());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// PythonDictionary
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PythonDictionary::PythonDictionary () :
|
||||
PythonObject(PyDict_New())
|
||||
PythonDictionary::PythonDictionary (bool create_empty) :
|
||||
PythonObject(create_empty ? PyDict_New() : NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ PythonDictionary::PythonDictionary (PyObject *py_obj) :
|
|||
PythonDictionary::PythonDictionary (const PythonObject &object) :
|
||||
PythonObject()
|
||||
{
|
||||
Reset(object.GetPythonObject()); // Use "Reset()" to ensure that py_obj is a dictionary
|
||||
Reset(object.get()); // Use "Reset()" to ensure that py_obj is a dictionary
|
||||
}
|
||||
|
||||
PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
|
||||
|
@ -356,7 +356,7 @@ PythonDictionary::GetItemForKey (const char *key) const
|
|||
PythonString python_key(key);
|
||||
return GetItemForKey(python_key);
|
||||
}
|
||||
return NULL;
|
||||
return PythonObject();
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,7 +364,7 @@ PythonObject
|
|||
PythonDictionary::GetItemForKey (const PythonString &key) const
|
||||
{
|
||||
if (m_py_obj && key)
|
||||
return PythonObject(PyDict_GetItem(m_py_obj, key.GetPythonObject()));
|
||||
return PythonObject(PyDict_GetItem(m_py_obj, key.get()));
|
||||
return PythonObject();
|
||||
}
|
||||
|
||||
|
@ -374,7 +374,7 @@ PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fa
|
|||
{
|
||||
if (m_py_obj && key)
|
||||
{
|
||||
PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
|
||||
PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
|
||||
if (py_obj && PyString_Check(py_obj))
|
||||
return PyString_AsString(py_obj);
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_
|
|||
{
|
||||
if (m_py_obj && key)
|
||||
{
|
||||
PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
|
||||
PyObject *py_obj = PyDict_GetItem(m_py_obj, key.get());
|
||||
if (py_obj)
|
||||
{
|
||||
if (PyInt_Check(py_obj))
|
||||
|
@ -404,7 +404,7 @@ PythonDictionary::GetKeys () const
|
|||
{
|
||||
if (m_py_obj)
|
||||
return PythonList(PyDict_Keys(m_py_obj));
|
||||
return PythonList();
|
||||
return PythonList(true);
|
||||
}
|
||||
|
||||
PythonString
|
||||
|
@ -431,7 +431,7 @@ PythonDictionary::GetValueAtPosition (uint32_t pos) const
|
|||
Py_ssize_t pos_iter = 0;
|
||||
|
||||
if (!m_py_obj)
|
||||
return NULL;
|
||||
return PythonObject();
|
||||
|
||||
while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
|
||||
if (pos-- == 0)
|
||||
|
@ -440,11 +440,18 @@ PythonDictionary::GetValueAtPosition (uint32_t pos) const
|
|||
return PythonObject();
|
||||
}
|
||||
|
||||
void
|
||||
PythonDictionary::SetItemForKey (const PythonString &key, PyObject *value)
|
||||
{
|
||||
if (m_py_obj && key && value)
|
||||
PyDict_SetItem(m_py_obj, key.get(), value);
|
||||
}
|
||||
|
||||
void
|
||||
PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
|
||||
{
|
||||
if (m_py_obj && key && value)
|
||||
PyDict_SetItem(m_py_obj, key.GetPythonObject(), value.GetPythonObject());
|
||||
PyDict_SetItem(m_py_obj, key.get(), value.get());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "lldb/Interpreter/ScriptInterpreterNone.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
|
@ -30,14 +31,14 @@ ScriptInterpreterNone::~ScriptInterpreterNone ()
|
|||
bool
|
||||
ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, const ExecuteScriptOptions&)
|
||||
{
|
||||
m_interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n");
|
||||
m_interpreter.GetDebugger().GetErrorFile()->PutCString ("error: there is no embedded script interpreter in this mode.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ScriptInterpreterNone::ExecuteInterpreterLoop ()
|
||||
{
|
||||
m_interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n");
|
||||
m_interpreter.GetDebugger().GetErrorFile()->PutCString ("error: there is no embedded script interpreter in this mode.\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,103 +1,108 @@
|
|||
import readline
|
||||
import __builtin__
|
||||
import code
|
||||
import lldb
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
class SimpleREPL(code.InteractiveConsole):
|
||||
def __init__(self, prompt, dict):
|
||||
code.InteractiveConsole.__init__(self,dict)
|
||||
self.prompt = prompt
|
||||
self.loop_exit = False
|
||||
self.dict = dict
|
||||
try:
|
||||
import readline
|
||||
import rlcompleter
|
||||
except ImportError:
|
||||
have_readline = False
|
||||
else:
|
||||
have_readline = True
|
||||
if 'libedit' in readline.__doc__:
|
||||
readline.parse_and_bind('bind ^I rl_complete')
|
||||
else:
|
||||
readline.parse_and_bind('tab: complete')
|
||||
|
||||
def interact(self):
|
||||
try:
|
||||
sys.ps1
|
||||
except AttributeError:
|
||||
sys.ps1 = ">>> "
|
||||
try:
|
||||
sys.ps2
|
||||
except AttributeError:
|
||||
sys.ps2 = "... "
|
||||
g_builtin_override_called = False
|
||||
|
||||
while not self.loop_exit:
|
||||
try:
|
||||
self.read_py_command()
|
||||
except (SystemExit, EOFError):
|
||||
# EOF while in Python just breaks out to top level.
|
||||
self.write('\n')
|
||||
self.loop_exit = True
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
self.write("\nKeyboardInterrupt\n")
|
||||
self.resetbuffer()
|
||||
more = 0
|
||||
except:
|
||||
traceback.print_exc()
|
||||
class LLDBQuitter(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
def __repr__(self):
|
||||
self()
|
||||
def __call__(self, code=None):
|
||||
global g_builtin_override_called
|
||||
g_builtin_override_called = True
|
||||
raise SystemExit(-1)
|
||||
|
||||
def process_input (self, in_str):
|
||||
# Canonicalize the format of the input string
|
||||
temp_str = in_str
|
||||
temp_str.strip(' \t')
|
||||
words = temp_str.split()
|
||||
temp_str = ('').join(words)
|
||||
def setquit():
|
||||
'''Redefine builtin functions 'quit()' and 'exit()' to print a message and raise an EOFError exception.'''
|
||||
# This function will be called prior to each interactive
|
||||
# interpreter loop or each single line, so we set the global
|
||||
# g_builtin_override_called to False so we know if a SystemExit
|
||||
# is thrown, we can catch it and tell the difference between
|
||||
# a call to "quit()" or "exit()" and something like
|
||||
# "sys.exit(123)"
|
||||
global g_builtin_override_called
|
||||
g_builtin_override_called = False
|
||||
__builtin__.quit = LLDBQuitter('quit')
|
||||
__builtin__.exit = LLDBQuitter('exit')
|
||||
|
||||
# Check the input string to see if it was the quit
|
||||
# command. If so, intercept it, so that it doesn't
|
||||
# close stdin on us!
|
||||
if (temp_str.lower() == "quit()" or temp_str.lower() == "exit()"):
|
||||
self.loop_exit = True
|
||||
in_str = "raise SystemExit "
|
||||
return in_str
|
||||
# When running one line, we might place the string to run in this string
|
||||
# in case it would be hard to correctly escape a string's contents
|
||||
|
||||
def my_raw_input (self, prompt):
|
||||
stream = sys.stdout
|
||||
stream.write (prompt)
|
||||
stream.flush ()
|
||||
try:
|
||||
line = sys.stdin.readline()
|
||||
except KeyboardInterrupt:
|
||||
line = " \n"
|
||||
except (SystemExit, EOFError):
|
||||
line = "quit()\n"
|
||||
if not line:
|
||||
raise EOFError
|
||||
if line[-1] == '\n':
|
||||
line = line[:-1]
|
||||
return line
|
||||
g_run_one_line_str = None
|
||||
|
||||
def read_py_command(self):
|
||||
# Read off a complete Python command.
|
||||
more = 0
|
||||
while 1:
|
||||
if more:
|
||||
prompt = sys.ps2
|
||||
else:
|
||||
prompt = sys.ps1
|
||||
line = self.my_raw_input(prompt)
|
||||
# Can be None if sys.stdin was redefined
|
||||
encoding = getattr(sys.stdin, "encoding", None)
|
||||
if encoding and not isinstance(line, unicode):
|
||||
line = line.decode(encoding)
|
||||
line = self.process_input (line)
|
||||
more = self.push(line)
|
||||
if not more:
|
||||
break
|
||||
|
||||
def one_line (self, input):
|
||||
line = self.process_input (input)
|
||||
more = self.push(line)
|
||||
if more:
|
||||
self.write ("Input not a complete line.\n")
|
||||
self.resetbuffer()
|
||||
more = 0
|
||||
def get_terminal_size(fd):
|
||||
try:
|
||||
import fcntl, termios, struct
|
||||
hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
|
||||
except:
|
||||
hw = (0,0)
|
||||
return hw
|
||||
|
||||
def run_python_interpreter (dict):
|
||||
# Pass in the dictionary, for continuity from one session to the next.
|
||||
repl = SimpleREPL('>>> ', dict)
|
||||
repl.interact()
|
||||
def readfunc_stdio(prompt):
|
||||
sys.stdout.write(prompt)
|
||||
return sys.stdin.readline()
|
||||
|
||||
def run_one_line (dict, input_string):
|
||||
repl = SimpleREPL ('', dict)
|
||||
repl.one_line (input_string)
|
||||
def run_python_interpreter (local_dict):
|
||||
# Pass in the dictionary, for continuity from one session to the next.
|
||||
setquit()
|
||||
try:
|
||||
fd = sys.stdin.fileno();
|
||||
interacted = False
|
||||
if get_terminal_size(fd)[1] == 0:
|
||||
try:
|
||||
import termios
|
||||
old = termios.tcgetattr(fd)
|
||||
if old[3] & termios.ECHO:
|
||||
# Need to turn off echoing and restore
|
||||
new = termios.tcgetattr(fd)
|
||||
new[3] = new[3] & ~termios.ECHO
|
||||
try:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, new)
|
||||
interacted = True
|
||||
code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", readfunc=readfunc_stdio, local=local_dict)
|
||||
finally:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old)
|
||||
except:
|
||||
pass
|
||||
# Don't need to turn off echoing
|
||||
if not interacted:
|
||||
code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", readfunc=readfunc_stdio, local=local_dict)
|
||||
else:
|
||||
# We have a real interactive terminal
|
||||
code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", local=local_dict)
|
||||
except SystemExit as e:
|
||||
global g_builtin_override_called
|
||||
if not g_builtin_override_called:
|
||||
print 'Script exited with %s' %(e)
|
||||
|
||||
def run_one_line (local_dict, input_string):
|
||||
global g_run_one_line_str
|
||||
setquit()
|
||||
try:
|
||||
repl = code.InteractiveConsole(local_dict);
|
||||
if input_string:
|
||||
repl.runsource (input_string)
|
||||
elif g_run_one_line_str:
|
||||
repl.runsource (g_run_one_line_str)
|
||||
|
||||
except SystemExit as e:
|
||||
global g_builtin_override_called
|
||||
if not g_builtin_override_called:
|
||||
print 'Script exited with %s' %(e)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Host/Symbols.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
|
@ -717,7 +718,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
|
|||
{
|
||||
if (m_uuid != exe_module->GetUUID())
|
||||
{
|
||||
Stream *s = &process->GetTarget().GetDebugger().GetOutputStream();
|
||||
Stream *s = process->GetTarget().GetDebugger().GetOutputFile().get();
|
||||
if (s)
|
||||
{
|
||||
s->Printf ("warning: Host-side kernel file has Mach-O UUID of %s but remote kernel has a UUID of %s -- a mismatched kernel file will result in a poor debugger experience.\n",
|
||||
|
@ -765,7 +766,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *p
|
|||
|
||||
if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
|
||||
{
|
||||
Stream *s = &target.GetDebugger().GetOutputStream();
|
||||
Stream *s = target.GetDebugger().GetOutputFile().get();
|
||||
if (s)
|
||||
{
|
||||
s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
|
||||
|
@ -834,7 +835,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *p
|
|||
|
||||
if (IsKernel() && !m_module_sp)
|
||||
{
|
||||
Stream *s = &target.GetDebugger().GetOutputStream();
|
||||
Stream *s = target.GetDebugger().GetOutputFile().get();
|
||||
if (s)
|
||||
{
|
||||
s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
|
||||
|
@ -867,7 +868,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *p
|
|||
|
||||
if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
|
||||
{
|
||||
Stream *s = &target.GetDebugger().GetOutputStream();
|
||||
Stream *s = target.GetDebugger().GetOutputFile().get();
|
||||
if (s)
|
||||
{
|
||||
s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
|
||||
|
@ -945,7 +946,7 @@ DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *p
|
|||
|
||||
if (is_loaded && m_module_sp && IsKernel())
|
||||
{
|
||||
Stream *s = &target.GetDebugger().GetOutputStream();
|
||||
Stream *s = target.GetDebugger().GetOutputFile().get();
|
||||
if (s)
|
||||
{
|
||||
ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
|
||||
|
@ -1248,7 +1249,7 @@ DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
|
|||
if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
|
||||
return true;
|
||||
|
||||
Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
|
||||
Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
|
||||
if (s && load_kexts)
|
||||
{
|
||||
if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/Expression/ClangExpression.h"
|
||||
#include "lldb/Expression/ClangFunction.h"
|
||||
|
@ -664,7 +665,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
|
|||
// step through any method dispatches. Warn to that effect and get out of here.
|
||||
if (process_sp->CanJIT())
|
||||
{
|
||||
process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\""
|
||||
process_sp->GetTarget().GetDebugger().GetErrorFile()->Printf ("Could not find implementation lookup function \"%s\""
|
||||
" step in through ObjC method dispatch will not work.\n",
|
||||
get_impl_name.AsCString());
|
||||
}
|
||||
|
|
|
@ -812,7 +812,12 @@ PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
|
|||
process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
|
||||
|
||||
if (process_sp)
|
||||
{
|
||||
ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack"));
|
||||
attach_info.SetHijackListener(listener_sp);
|
||||
process_sp->HijackProcessEvents(listener_sp.get());
|
||||
error = process_sp->Attach (attach_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Core/ThreadSafeValue.h"
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/ConnectionFileDescriptor.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/ModuleSpec.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
|
@ -1073,27 +1072,6 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process
|
|||
return error;
|
||||
}
|
||||
|
||||
size_t
|
||||
ProcessGDBRemote::AttachInputReaderCallback
|
||||
(
|
||||
void *baton,
|
||||
InputReader *reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len
|
||||
)
|
||||
{
|
||||
if (notification == eInputReaderGotToken)
|
||||
{
|
||||
ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
|
||||
if (gdb_process->m_waiting_for_attach)
|
||||
gdb_process->m_waiting_for_attach = false;
|
||||
reader->SetIsDone(true);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Error
|
||||
ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Core/ThreadSafeValue.h"
|
||||
|
@ -378,13 +377,6 @@ protected:
|
|||
GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
|
||||
std::string &dispatch_queue_name);
|
||||
|
||||
static size_t
|
||||
AttachInputReaderCallback (void *baton,
|
||||
lldb_private::InputReader *reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len);
|
||||
|
||||
lldb_private::DynamicLoader *
|
||||
GetDynamicLoader ();
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
#include "lldb/Core/Stream.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Symbol/Function.h"
|
||||
#include "lldb/Core/Disassembler.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
|
@ -404,6 +405,43 @@ Function::CalculateSymbolContextFunction ()
|
|||
return this;
|
||||
}
|
||||
|
||||
lldb::DisassemblerSP
|
||||
Function::GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache)
|
||||
{
|
||||
ModuleSP module_sp (GetAddressRange().GetBaseAddress().GetModule());
|
||||
if (module_sp)
|
||||
{
|
||||
const bool prefer_file_cache = false;
|
||||
return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
|
||||
NULL,
|
||||
flavor,
|
||||
exe_ctx,
|
||||
GetAddressRange(),
|
||||
prefer_file_cache);
|
||||
}
|
||||
return lldb::DisassemblerSP();
|
||||
}
|
||||
|
||||
bool
|
||||
Function::GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm)
|
||||
{
|
||||
lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
|
||||
if (disassembler_sp)
|
||||
{
|
||||
const bool show_address = true;
|
||||
const bool show_bytes = false;
|
||||
disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//Symbol *
|
||||
//Function::CalculateSymbolContextSymbol ()
|
||||
//{
|
||||
|
|
|
@ -580,3 +580,40 @@ Symbol::ResolveReExportedSymbol (Target &target)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
lldb::DisassemblerSP
|
||||
Symbol::GetInstructions (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache)
|
||||
{
|
||||
ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule());
|
||||
if (module_sp)
|
||||
{
|
||||
const bool prefer_file_cache = false;
|
||||
return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
|
||||
NULL,
|
||||
flavor,
|
||||
exe_ctx,
|
||||
m_addr_range,
|
||||
prefer_file_cache);
|
||||
}
|
||||
return lldb::DisassemblerSP();
|
||||
}
|
||||
|
||||
bool
|
||||
Symbol::GetDisassembly (const ExecutionContext &exe_ctx,
|
||||
const char *flavor,
|
||||
bool prefer_file_cache,
|
||||
Stream &strm)
|
||||
{
|
||||
lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
|
||||
if (disassembler_sp)
|
||||
{
|
||||
const bool show_address = true;
|
||||
const bool show_bytes = false;
|
||||
disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref) :
|
|||
{
|
||||
}
|
||||
|
||||
ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr) :
|
||||
ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, bool thread_and_frame_only_if_stopped) :
|
||||
m_target_sp (),
|
||||
m_process_sp (),
|
||||
m_thread_sp (),
|
||||
|
@ -164,8 +164,11 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr)
|
|||
{
|
||||
m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
|
||||
m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
|
||||
m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
|
||||
m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
|
||||
if (!thread_and_frame_only_if_stopped || (m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true)))
|
||||
{
|
||||
m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
|
||||
m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -824,9 +827,9 @@ ExecutionContextRef::GetFrameSP () const
|
|||
}
|
||||
|
||||
ExecutionContext
|
||||
ExecutionContextRef::Lock () const
|
||||
ExecutionContextRef::Lock (bool thread_and_frame_only_if_stopped) const
|
||||
{
|
||||
return ExecutionContext(this);
|
||||
return ExecutionContext(this, thread_and_frame_only_if_stopped);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1039,6 +1039,8 @@ Platform::DebugProcess (ProcessLaunchInfo &launch_info,
|
|||
process_sp = Attach (attach_info, debugger, target, listener, error);
|
||||
if (process_sp)
|
||||
{
|
||||
launch_info.SetHijackListener(attach_info.GetHijackListener());
|
||||
|
||||
// Since we attached to the process, it will think it needs to detach
|
||||
// if the process object just goes away without an explicit call to
|
||||
// Process::Kill() or Process::Detach(), so let it know to kill the
|
||||
|
|
|
@ -18,15 +18,16 @@
|
|||
#include "lldb/Core/Event.h"
|
||||
#include "lldb/Core/ConnectionFileDescriptor.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Expression/ClangUserExpression.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Host/Terminal.h"
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/DynamicLoader.h"
|
||||
#include "lldb/Target/OperatingSystem.h"
|
||||
|
@ -1244,7 +1245,7 @@ Process::GetNextEvent (EventSP &event_sp)
|
|||
|
||||
|
||||
StateType
|
||||
Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr, bool wait_always)
|
||||
Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr, bool wait_always, Listener *hijack_listener)
|
||||
{
|
||||
// We can't just wait for a "stopped" event, because the stopped event may have restarted the target.
|
||||
// We have to actually check each event, and in the case of a stopped event check the restarted flag
|
||||
|
@ -1273,7 +1274,7 @@ Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp
|
|||
while (state != eStateInvalid)
|
||||
{
|
||||
EventSP event_sp;
|
||||
state = WaitForStateChangedEvents (timeout, event_sp);
|
||||
state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);
|
||||
if (event_sp_ptr && event_sp)
|
||||
*event_sp_ptr = event_sp;
|
||||
|
||||
|
@ -1283,12 +1284,22 @@ Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp
|
|||
case eStateDetached:
|
||||
case eStateExited:
|
||||
case eStateUnloaded:
|
||||
// We need to toggle the run lock as this won't get done in
|
||||
// SetPublicState() if the process is hijacked.
|
||||
if (hijack_listener)
|
||||
m_public_run_lock.SetStopped();
|
||||
return state;
|
||||
case eStateStopped:
|
||||
if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
|
||||
continue;
|
||||
else
|
||||
{
|
||||
// We need to toggle the run lock as this won't get done in
|
||||
// SetPublicState() if the process is hijacked.
|
||||
if (hijack_listener)
|
||||
m_public_run_lock.SetStopped();
|
||||
return state;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
@ -1301,7 +1312,8 @@ StateType
|
|||
Process::WaitForState
|
||||
(
|
||||
const TimeValue *timeout,
|
||||
const StateType *match_states, const uint32_t num_match_states
|
||||
const StateType *match_states,
|
||||
const uint32_t num_match_states
|
||||
)
|
||||
{
|
||||
EventSP event_sp;
|
||||
|
@ -1314,7 +1326,7 @@ Process::WaitForState
|
|||
if (state == eStateDetached || state == eStateExited)
|
||||
return state;
|
||||
|
||||
state = WaitForStateChangedEvents (timeout, event_sp);
|
||||
state = WaitForStateChangedEvents (timeout, event_sp, NULL);
|
||||
|
||||
for (i=0; i<num_match_states; ++i)
|
||||
{
|
||||
|
@ -1360,18 +1372,22 @@ Process::RestorePrivateProcessEvents ()
|
|||
}
|
||||
|
||||
StateType
|
||||
Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
|
||||
Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
|
||||
|
||||
if (log)
|
||||
log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
|
||||
|
||||
Listener *listener = hijack_listener;
|
||||
if (listener == NULL)
|
||||
listener = &m_listener;
|
||||
|
||||
StateType state = eStateInvalid;
|
||||
if (m_listener.WaitForEventForBroadcasterWithType (timeout,
|
||||
this,
|
||||
eBroadcastBitStateChanged | eBroadcastBitInterrupt,
|
||||
event_sp))
|
||||
if (listener->WaitForEventForBroadcasterWithType (timeout,
|
||||
this,
|
||||
eBroadcastBitStateChanged | eBroadcastBitInterrupt,
|
||||
event_sp))
|
||||
{
|
||||
if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
|
||||
state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
|
||||
|
@ -1509,6 +1525,7 @@ Process::SetExitStatus (int status, const char *cstr)
|
|||
DidExit ();
|
||||
|
||||
SetPrivateState (eStateExited);
|
||||
CancelWatchForSTDIN (true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2183,11 +2200,11 @@ Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardw
|
|||
load_addr = ResolveIndirectFunction (&symbol->GetAddress(), error);
|
||||
if (!error.Success() && show_error)
|
||||
{
|
||||
m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
|
||||
symbol->GetAddress().GetLoadAddress(&m_target),
|
||||
owner->GetBreakpoint().GetID(),
|
||||
owner->GetID(),
|
||||
error.AsCString() ? error.AsCString() : "unkown error");
|
||||
m_target.GetDebugger().GetErrorFile()->Printf ("warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
|
||||
symbol->GetAddress().GetLoadAddress(&m_target),
|
||||
owner->GetBreakpoint().GetID(),
|
||||
owner->GetID(),
|
||||
error.AsCString() ? error.AsCString() : "unkown error");
|
||||
return LLDB_INVALID_BREAK_ID;
|
||||
}
|
||||
Address resolved_address(load_addr);
|
||||
|
@ -2231,11 +2248,11 @@ Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardw
|
|||
if (show_error)
|
||||
{
|
||||
// Report error for setting breakpoint...
|
||||
m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
|
||||
load_addr,
|
||||
owner->GetBreakpoint().GetID(),
|
||||
owner->GetID(),
|
||||
error.AsCString() ? error.AsCString() : "unkown error");
|
||||
m_target.GetDebugger().GetErrorFile()->Printf ("warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
|
||||
load_addr,
|
||||
owner->GetBreakpoint().GetID(),
|
||||
owner->GetID(),
|
||||
error.AsCString() ? error.AsCString() : "unkown error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3756,8 +3773,6 @@ Process::Destroy ()
|
|||
}
|
||||
m_stdio_communication.StopReadThread();
|
||||
m_stdio_communication.Disconnect();
|
||||
if (m_process_input_reader && m_process_input_reader->IsActive())
|
||||
m_target.GetDebugger().PopInputReader (m_process_input_reader);
|
||||
if (m_process_input_reader)
|
||||
m_process_input_reader.reset();
|
||||
|
||||
|
@ -4147,9 +4162,14 @@ Process::HandlePrivateEvent (EventSP &event_sp)
|
|||
}
|
||||
Process::ProcessEventData::SetUpdateStateOnRemoval(event_sp.get());
|
||||
if (StateIsRunningState (new_state))
|
||||
PushProcessInputReader ();
|
||||
{
|
||||
// Only push the input handler if we aren't fowarding events,
|
||||
// as this means the curses GUI is in use...
|
||||
if (!GetTarget().GetDebugger().IsForwardingEvents())
|
||||
PushProcessIOHandler ();
|
||||
}
|
||||
else if (!Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
|
||||
PopProcessInputReader ();
|
||||
PopProcessIOHandler ();
|
||||
|
||||
BroadcastEvent (event_sp);
|
||||
}
|
||||
|
@ -4695,64 +4715,187 @@ Process::STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_
|
|||
process->AppendSTDOUT (static_cast<const char *>(src), src_len);
|
||||
}
|
||||
|
||||
size_t
|
||||
Process::ProcessInputReaderCallback (void *baton,
|
||||
InputReader &reader,
|
||||
lldb::InputReaderAction notification,
|
||||
const char *bytes,
|
||||
size_t bytes_len)
|
||||
{
|
||||
Process *process = (Process *) baton;
|
||||
|
||||
switch (notification)
|
||||
{
|
||||
case eInputReaderActivate:
|
||||
break;
|
||||
|
||||
case eInputReaderDeactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderReactivate:
|
||||
break;
|
||||
|
||||
case eInputReaderAsynchronousOutputWritten:
|
||||
break;
|
||||
|
||||
case eInputReaderGotToken:
|
||||
{
|
||||
Error error;
|
||||
process->PutSTDIN (bytes, bytes_len, error);
|
||||
}
|
||||
break;
|
||||
|
||||
case eInputReaderInterrupt:
|
||||
process->SendAsyncInterrupt();
|
||||
break;
|
||||
|
||||
case eInputReaderEndOfFile:
|
||||
process->AppendSTDOUT ("^D", 2);
|
||||
break;
|
||||
|
||||
case eInputReaderDone:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return bytes_len;
|
||||
}
|
||||
|
||||
void
|
||||
Process::ResetProcessInputReader ()
|
||||
Process::ResetProcessIOHandler ()
|
||||
{
|
||||
m_process_input_reader.reset();
|
||||
}
|
||||
|
||||
|
||||
class IOHandlerProcessSTDIO :
|
||||
public IOHandler
|
||||
{
|
||||
public:
|
||||
IOHandlerProcessSTDIO (Process *process,
|
||||
int write_fd) :
|
||||
IOHandler(process->GetTarget().GetDebugger()),
|
||||
m_process (process),
|
||||
m_read_file (),
|
||||
m_write_file (write_fd, false),
|
||||
m_pipe_read(),
|
||||
m_pipe_write()
|
||||
{
|
||||
m_read_file.SetDescriptor(GetInputFD(), false);
|
||||
}
|
||||
|
||||
virtual
|
||||
~IOHandlerProcessSTDIO ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
OpenPipes ()
|
||||
{
|
||||
if (m_pipe_read.IsValid() && m_pipe_write.IsValid())
|
||||
return true;
|
||||
|
||||
int fds[2];
|
||||
int err = pipe(fds);
|
||||
if (err == 0)
|
||||
{
|
||||
m_pipe_read.SetDescriptor(fds[0], true);
|
||||
m_pipe_write.SetDescriptor(fds[1], true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ClosePipes()
|
||||
{
|
||||
m_pipe_read.Close();
|
||||
m_pipe_write.Close();
|
||||
}
|
||||
|
||||
// Each IOHandler gets to run until it is done. It should read data
|
||||
// from the "in" and place output into "out" and "err and return
|
||||
// when done.
|
||||
virtual void
|
||||
Run ()
|
||||
{
|
||||
if (m_read_file.IsValid() && m_write_file.IsValid())
|
||||
{
|
||||
SetIsDone(false);
|
||||
if (OpenPipes())
|
||||
{
|
||||
const int read_fd = m_read_file.GetDescriptor();
|
||||
const int pipe_read_fd = m_pipe_read.GetDescriptor();
|
||||
TerminalState terminal_state;
|
||||
terminal_state.Save (read_fd, false);
|
||||
Terminal terminal(read_fd);
|
||||
terminal.SetCanonical(false);
|
||||
terminal.SetEcho(false);
|
||||
while (!GetIsDone())
|
||||
{
|
||||
fd_set read_fdset;
|
||||
FD_ZERO (&read_fdset);
|
||||
FD_SET (read_fd, &read_fdset);
|
||||
FD_SET (pipe_read_fd, &read_fdset);
|
||||
const int nfds = std::max<int>(read_fd, pipe_read_fd) + 1;
|
||||
int num_set_fds = select (nfds, &read_fdset, NULL, NULL, NULL);
|
||||
if (num_set_fds < 0)
|
||||
{
|
||||
const int select_errno = errno;
|
||||
|
||||
if (select_errno != EINTR)
|
||||
SetIsDone(true);
|
||||
}
|
||||
else if (num_set_fds > 0)
|
||||
{
|
||||
char ch = 0;
|
||||
size_t n;
|
||||
if (FD_ISSET (read_fd, &read_fdset))
|
||||
{
|
||||
n = 1;
|
||||
if (m_read_file.Read(&ch, n).Success() && n == 1)
|
||||
{
|
||||
if (m_write_file.Write(&ch, n).Fail() || n != 1)
|
||||
SetIsDone(true);
|
||||
}
|
||||
else
|
||||
SetIsDone(true);
|
||||
}
|
||||
if (FD_ISSET (pipe_read_fd, &read_fdset))
|
||||
{
|
||||
// Consume the interrupt byte
|
||||
n = 1;
|
||||
m_pipe_read.Read (&ch, n);
|
||||
SetIsDone(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
terminal_state.Restore();
|
||||
|
||||
}
|
||||
else
|
||||
SetIsDone(true);
|
||||
}
|
||||
else
|
||||
SetIsDone(true);
|
||||
}
|
||||
|
||||
// Hide any characters that have been displayed so far so async
|
||||
// output can be displayed. Refresh() will be called after the
|
||||
// output has been displayed.
|
||||
virtual void
|
||||
Hide ()
|
||||
{
|
||||
|
||||
}
|
||||
// Called when the async output has been received in order to update
|
||||
// the input reader (refresh the prompt and redisplay any current
|
||||
// line(s) that are being edited
|
||||
virtual void
|
||||
Refresh ()
|
||||
{
|
||||
|
||||
}
|
||||
virtual void
|
||||
Interrupt ()
|
||||
{
|
||||
size_t n = 1;
|
||||
char ch = 'q';
|
||||
m_pipe_write.Write (&ch, n);
|
||||
}
|
||||
|
||||
virtual void
|
||||
GotEOF()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
Process *m_process;
|
||||
File m_read_file; // Read from this file (usually actual STDIN for LLDB
|
||||
File m_write_file; // Write to this file (usually the master pty for getting io to debuggee)
|
||||
File m_pipe_read;
|
||||
File m_pipe_write;
|
||||
|
||||
};
|
||||
|
||||
void
|
||||
Process::SetSTDIOFileDescriptor (int file_descriptor)
|
||||
Process::WatchForSTDIN (IOHandler &io_handler)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Process::CancelWatchForSTDIN (bool exited)
|
||||
{
|
||||
if (m_process_input_reader)
|
||||
{
|
||||
if (exited)
|
||||
m_process_input_reader->SetIsDone(true);
|
||||
m_process_input_reader->Interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Process::SetSTDIOFileDescriptor (int fd)
|
||||
{
|
||||
// First set up the Read Thread for reading/handling process I/O
|
||||
|
||||
std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (file_descriptor, true));
|
||||
std::unique_ptr<ConnectionFileDescriptor> conn_ap (new ConnectionFileDescriptor (fd, true));
|
||||
|
||||
if (conn_ap.get())
|
||||
{
|
||||
|
@ -4765,70 +4908,37 @@ Process::SetSTDIOFileDescriptor (int file_descriptor)
|
|||
// Now read thread is set up, set up input reader.
|
||||
|
||||
if (!m_process_input_reader.get())
|
||||
{
|
||||
m_process_input_reader.reset (new InputReader(m_target.GetDebugger()));
|
||||
Error err (m_process_input_reader->Initialize (Process::ProcessInputReaderCallback,
|
||||
this,
|
||||
eInputReaderGranularityByte,
|
||||
NULL,
|
||||
NULL,
|
||||
false));
|
||||
|
||||
if (err.Fail())
|
||||
m_process_input_reader.reset();
|
||||
}
|
||||
m_process_input_reader.reset (new IOHandlerProcessSTDIO (this, fd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Process::PushProcessInputReader ()
|
||||
Process::PushProcessIOHandler ()
|
||||
{
|
||||
if (m_process_input_reader && !m_process_input_reader->IsActive())
|
||||
m_target.GetDebugger().PushInputReader (m_process_input_reader);
|
||||
IOHandlerSP io_handler_sp (m_process_input_reader);
|
||||
if (io_handler_sp)
|
||||
{
|
||||
io_handler_sp->SetIsDone(false);
|
||||
m_target.GetDebugger().PushIOHandler (io_handler_sp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Process::PopProcessInputReader ()
|
||||
Process::PopProcessIOHandler ()
|
||||
{
|
||||
if (m_process_input_reader && m_process_input_reader->IsActive())
|
||||
m_target.GetDebugger().PopInputReader (m_process_input_reader);
|
||||
IOHandlerSP io_handler_sp (m_process_input_reader);
|
||||
if (io_handler_sp)
|
||||
{
|
||||
io_handler_sp->Interrupt();
|
||||
m_target.GetDebugger().PopIOHandler (io_handler_sp);
|
||||
}
|
||||
}
|
||||
|
||||
// The process needs to know about installed plug-ins
|
||||
void
|
||||
Process::SettingsInitialize ()
|
||||
{
|
||||
// static std::vector<OptionEnumValueElement> g_plugins;
|
||||
//
|
||||
// int i=0;
|
||||
// const char *name;
|
||||
// OptionEnumValueElement option_enum;
|
||||
// while ((name = PluginManager::GetProcessPluginNameAtIndex (i)) != NULL)
|
||||
// {
|
||||
// if (name)
|
||||
// {
|
||||
// option_enum.value = i;
|
||||
// option_enum.string_value = name;
|
||||
// option_enum.usage = PluginManager::GetProcessPluginDescriptionAtIndex (i);
|
||||
// g_plugins.push_back (option_enum);
|
||||
// }
|
||||
// ++i;
|
||||
// }
|
||||
// option_enum.value = 0;
|
||||
// option_enum.string_value = NULL;
|
||||
// option_enum.usage = NULL;
|
||||
// g_plugins.push_back (option_enum);
|
||||
//
|
||||
// for (i=0; (name = SettingsController::instance_settings_table[i].var_name); ++i)
|
||||
// {
|
||||
// if (::strcmp (name, "plugin") == 0)
|
||||
// {
|
||||
// SettingsController::instance_settings_table[i].enum_values = &g_plugins[0];
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
Thread::SettingsInitialize ();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/SourceManager.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
#include "lldb/Core/ValueObject.h"
|
||||
|
@ -1006,11 +1007,11 @@ LoadScriptingResourceForModule (const ModuleSP &module_sp, Target *target)
|
|||
if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, &feedback_stream))
|
||||
{
|
||||
if (error.AsCString())
|
||||
target->GetDebugger().GetErrorStream().Printf("unable to load scripting data for module %s - error reported was %s\n",
|
||||
target->GetDebugger().GetErrorFile()->Printf("unable to load scripting data for module %s - error reported was %s\n",
|
||||
module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
|
||||
error.AsCString());
|
||||
if (feedback_stream.GetSize())
|
||||
target->GetDebugger().GetOutputStream().Printf("%s\n",
|
||||
target->GetDebugger().GetErrorFile()->Printf("%s\n",
|
||||
feedback_stream.GetData());
|
||||
}
|
||||
}
|
||||
|
@ -1998,13 +1999,13 @@ Target::GetSourceManager ()
|
|||
}
|
||||
|
||||
|
||||
lldb::user_id_t
|
||||
Target::AddStopHook (Target::StopHookSP &new_hook_sp)
|
||||
Target::StopHookSP
|
||||
Target::CreateStopHook ()
|
||||
{
|
||||
lldb::user_id_t new_uid = ++m_stop_hook_next_id;
|
||||
new_hook_sp.reset (new StopHook(shared_from_this(), new_uid));
|
||||
m_stop_hooks[new_uid] = new_hook_sp;
|
||||
return new_uid;
|
||||
Target::StopHookSP stop_hook_sp (new StopHook(shared_from_this(), new_uid));
|
||||
m_stop_hooks[new_uid] = stop_hook_sp;
|
||||
return stop_hook_sp;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2323,7 +2324,6 @@ Error
|
|||
Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
|
||||
{
|
||||
Error error;
|
||||
Error error2;
|
||||
|
||||
StateType state = eStateInvalid;
|
||||
|
||||
|
@ -2399,28 +2399,34 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
|
|||
{
|
||||
if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
|
||||
{
|
||||
StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false);
|
||||
ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
|
||||
|
||||
StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false, hijack_listener_sp.get());
|
||||
|
||||
if (state == eStateStopped)
|
||||
{
|
||||
error = m_process_sp->Resume();
|
||||
if (!synchronous_execution)
|
||||
m_process_sp->RestoreProcessEvents ();
|
||||
|
||||
error = m_process_sp->PrivateResume();
|
||||
|
||||
if (error.Success())
|
||||
{
|
||||
if (synchronous_execution)
|
||||
{
|
||||
state = m_process_sp->WaitForProcessToStop (NULL);
|
||||
state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get());
|
||||
const bool must_be_alive = false; // eStateExited is ok, so this must be false
|
||||
if (!StateIsStoppedState(state, must_be_alive))
|
||||
{
|
||||
error2.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
|
||||
return error2;
|
||||
error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Error error2;
|
||||
error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
|
||||
return error2;
|
||||
error = error2;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2428,11 +2434,13 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info)
|
|||
error.SetErrorStringWithFormat ("initial process state wasn't stopped: %s", StateAsCString(state));
|
||||
}
|
||||
}
|
||||
m_process_sp->RestoreProcessEvents ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error error2;
|
||||
error2.SetErrorStringWithFormat ("process launch failed: %s", error.AsCString());
|
||||
return error2;
|
||||
error = error2;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -2065,3 +2065,125 @@ Thread::IsStillAtLastBreakpointHit ()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Error
|
||||
Thread::StepIn (bool source_step,
|
||||
bool avoid_code_without_debug_info)
|
||||
|
||||
{
|
||||
Error error;
|
||||
Process *process = GetProcess().get();
|
||||
if (StateIsStoppedState (process->GetState(), true))
|
||||
{
|
||||
StackFrameSP frame_sp = GetStackFrameAtIndex (0);
|
||||
ThreadPlanSP new_plan_sp;
|
||||
const lldb::RunMode run_mode = eOnlyThisThread;
|
||||
const bool abort_other_plans = false;
|
||||
|
||||
if (source_step && frame_sp && frame_sp->HasDebugInformation ())
|
||||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
NULL,
|
||||
run_mode,
|
||||
avoid_code_without_debug_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_plan_sp = QueueThreadPlanForStepSingleInstruction (false,
|
||||
abort_other_plans,
|
||||
run_mode);
|
||||
}
|
||||
|
||||
new_plan_sp->SetIsMasterPlan(true);
|
||||
new_plan_sp->SetOkayToDiscard(false);
|
||||
|
||||
// Why do we need to set the current thread by ID here???
|
||||
process->GetThreadList().SetSelectedThreadByID (GetID());
|
||||
error = process->Resume();
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString("process not stopped");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error
|
||||
Thread::StepOver (bool source_step)
|
||||
|
||||
{
|
||||
Error error;
|
||||
Process *process = GetProcess().get();
|
||||
if (StateIsStoppedState (process->GetState(), true))
|
||||
{
|
||||
StackFrameSP frame_sp = GetStackFrameAtIndex (0);
|
||||
ThreadPlanSP new_plan_sp;
|
||||
|
||||
const lldb::RunMode run_mode = eOnlyThisThread;
|
||||
const bool abort_other_plans = false;
|
||||
|
||||
if (source_step && frame_sp && frame_sp->HasDebugInformation ())
|
||||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan_sp = QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
run_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_plan_sp = QueueThreadPlanForStepSingleInstruction (true,
|
||||
abort_other_plans,
|
||||
run_mode);
|
||||
}
|
||||
|
||||
new_plan_sp->SetIsMasterPlan(true);
|
||||
new_plan_sp->SetOkayToDiscard(false);
|
||||
|
||||
// Why do we need to set the current thread by ID here???
|
||||
process->GetThreadList().SetSelectedThreadByID (GetID());
|
||||
error = process->Resume();
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString("process not stopped");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error
|
||||
Thread::StepOut ()
|
||||
{
|
||||
Error error;
|
||||
Process *process = GetProcess().get();
|
||||
if (StateIsStoppedState (process->GetState(), true))
|
||||
{
|
||||
const bool first_instruction = false;
|
||||
const bool stop_other_threads = false;
|
||||
const bool abort_other_plans = false;
|
||||
|
||||
ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
first_instruction,
|
||||
stop_other_threads,
|
||||
eVoteYes,
|
||||
eVoteNoOpinion,
|
||||
0));
|
||||
|
||||
new_plan_sp->SetIsMasterPlan(true);
|
||||
new_plan_sp->SetOkayToDiscard(false);
|
||||
|
||||
// Why do we need to set the current thread by ID here???
|
||||
process->GetThreadList().SetSelectedThreadByID (GetID());
|
||||
error = process->Resume();
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorString("process not stopped");
|
||||
}
|
||||
return error;
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/Symbol/TypeList.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
|
@ -62,7 +63,7 @@ ThreadPlanTracer::GetLogStream ()
|
|||
{
|
||||
TargetSP target_sp (m_thread.CalculateTarget());
|
||||
if (target_sp)
|
||||
return &target_sp->GetDebugger().GetOutputStream();
|
||||
return target_sp->GetDebugger().GetOutputFile().get();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "lldb/Core/Timer.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreterPython.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
|
@ -120,6 +121,7 @@ lldb_private::Initialize ()
|
|||
SymbolFileDWARFDebugMap::Initialize();
|
||||
ItaniumABILanguageRuntime::Initialize();
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
ScriptInterpreterPython::InitializePrivate();
|
||||
OperatingSystemPython::Initialize();
|
||||
#endif
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@ class CommandRegexTestCase(TestBase):
|
|||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def test_command_regex(self):
|
||||
"""Test a simple scenario of 'command regexp' invocation and subsequent use."""
|
||||
"""Test a simple scenario of 'command regex' invocation and subsequent use."""
|
||||
prompt = "(lldb) "
|
||||
regex_prompt = "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:\r\n"
|
||||
regex_prompt = "Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\r\nTerminate the substitution list with an empty line.\r\n"
|
||||
regex_prompt1 = "\r\n"
|
||||
|
||||
child = pexpect.spawn('%s %s' % (self.lldbHere, self.lldbOption))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue