* Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2014-2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CLI_CONTEXT_H
#define CLI_CONTEXT_H
#include <sys/cdefs.h>
#include <histedit.h>
#include <Locker.h>
#include <Looper.h>
#include "ExpressionInfo.h"
#include "Team.h"
#include "TeamMemoryBlock.h"
#include "ValueNodeContainer.h"
class SourceLanguage;
class StackFrame;
class StackTrace;
class Team;
class TeamMemoryBlock;
class UserInterfaceListener;
class ValueNodeManager;
class CliContext : private Team::Listener,
public TeamMemoryBlock::Listener,
public ExpressionInfo::Listener,
private ValueNodeContainer::Listener,
public BLooper {
public:
enum {
MSG_QUIT = 'quit',
MSG_USER_INTERRUPT = 'uint',
MSG_THREAD_ADDED = 'thad',
MSG_THREAD_REMOVED = 'thar',
MSG_THREAD_STATE_CHANGED = 'tsch',
MSG_THREAD_STACK_TRACE_CHANGED = 'tstc',
MSG_VALUE_NODE_CHANGED = 'vnch',
MSG_TEAM_MEMORY_BLOCK_RETRIEVED = 'tmbr',
MSG_EXPRESSION_EVALUATED = 'exev',
MSG_DEBUG_REPORT_CHANGED = 'drch',
MSG_CORE_FILE_CHANGED = 'cfch'
};
public:
CliContext();
~CliContext();
status_t Init(::Team* team,
UserInterfaceListener* listener);
void Cleanup();
void Terminating();
bool IsTerminating() const { return fTerminating; }
virtual void MessageReceived(BMessage* message);
::Team* GetTeam() const { return fTeam; }
UserInterfaceListener* GetUserInterfaceListener() const
{ return fListener; }
ValueNodeManager* GetValueNodeManager() const
{ return fNodeManager; }
StackTrace* GetStackTrace() const
{ return fCurrentStackTrace; }
::Thread* CurrentThread() const { return fCurrentThread; }
thread_id CurrentThreadID() const;
void SetCurrentThread(::Thread* thread);
void PrintCurrentThread();
int32 CurrentStackFrameIndex() const
{ return fCurrentStackFrameIndex; }
void SetCurrentStackFrameIndex(int32 index);
status_t EvaluateExpression(const char * expression,
SourceLanguage* language, target_addr_t& address);
status_t GetMemoryBlock(target_addr_t address,
TeamMemoryBlock*& block);
const char* PromptUser(const char* prompt);
void AddLineToInputHistory(const char* line);
void QuitSession(bool killTeam);
void WaitForThreadOrUser();
void WaitForEvent(uint32 event);
private:
struct Event;
typedef DoublyLinkedList<Event> EventList;
private:
virtual void ThreadAdded(const Team::ThreadEvent& event);
virtual void ThreadRemoved(const Team::ThreadEvent& event);
virtual void ThreadStateChanged(
const Team::ThreadEvent& event);
virtual void ThreadStackTraceChanged(
const Team::ThreadEvent& event);
virtual void DebugReportChanged(
const Team::DebugReportEvent& event);
virtual void CoreFileChanged(
const Team::CoreFileChangedEvent& event);
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
virtual void ExpressionEvaluated(ExpressionInfo* info,
status_t result, ExpressionResult* value);
virtual void ValueNodeChanged(ValueNodeChild* nodeChild,
ValueNode* oldNode, ValueNode* newNode);
virtual void ValueNodeChildrenCreated(ValueNode* node);
virtual void ValueNodeChildrenDeleted(ValueNode* node);
virtual void ValueNodeValueChanged(ValueNode* node);
private:
static const char* _GetPrompt(EditLine* editLine);
void _WaitForEvent(uint32 event);
private:
mutable BLocker fLock;
::Team* fTeam;
UserInterfaceListener* fListener;
ValueNodeManager* fNodeManager;
EditLine* fEditLine;
History* fHistory;
const char* fPrompt;
sem_id fWaitForEventSemaphore;
uint32 fEventOccurred;
volatile bool fTerminating;
BReference< ::Thread> fStoppedThread;
::Thread* fCurrentThread;
StackTrace* fCurrentStackTrace;
int32 fCurrentStackFrameIndex;
TeamMemoryBlock* fCurrentBlock;
ExpressionInfo* fExpressionInfo;
status_t fExpressionResult;
ExpressionResult* fExpressionValue;
};
#endif