1/*
2 * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2014-2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef CLI_CONTEXT_H
7#define CLI_CONTEXT_H
8
9
10#include <sys/cdefs.h>
11	// Needed in histedit.h.
12#include <histedit.h>
13
14#include <Locker.h>
15#include <Looper.h>
16
17#include "ExpressionInfo.h"
18#include "Team.h"
19#include "TeamMemoryBlock.h"
20#include "ValueNodeContainer.h"
21
22
23class SourceLanguage;
24class StackFrame;
25class StackTrace;
26class Team;
27class TeamMemoryBlock;
28class UserInterfaceListener;
29class ValueNodeManager;
30
31
32class CliContext : private Team::Listener,
33	public TeamMemoryBlock::Listener,
34	public ExpressionInfo::Listener,
35	private ValueNodeContainer::Listener,
36	public BLooper {
37public:
38			enum {
39				MSG_QUIT							= 'quit',
40				MSG_USER_INTERRUPT					= 'uint',
41				MSG_THREAD_ADDED					= 'thad',
42				MSG_THREAD_REMOVED					= 'thar',
43				MSG_THREAD_STATE_CHANGED			= 'tsch',
44				MSG_THREAD_STACK_TRACE_CHANGED		= 'tstc',
45				MSG_VALUE_NODE_CHANGED				= 'vnch',
46				MSG_TEAM_MEMORY_BLOCK_RETRIEVED		= 'tmbr',
47				MSG_EXPRESSION_EVALUATED			= 'exev',
48				MSG_DEBUG_REPORT_CHANGED			= 'drch',
49				MSG_CORE_FILE_CHANGED				= 'cfch'
50			};
51
52public:
53								CliContext();
54								~CliContext();
55
56			status_t			Init(::Team* team,
57									UserInterfaceListener* listener);
58			void				Cleanup();
59
60			void				Terminating();
61
62			bool				IsTerminating() const	{ return fTerminating; }
63
64	virtual	void				MessageReceived(BMessage* message);
65
66			// service methods for the input loop thread follow
67
68			::Team*				GetTeam() const	{ return fTeam; }
69			UserInterfaceListener* GetUserInterfaceListener() const
70									{ return fListener; }
71			ValueNodeManager*	GetValueNodeManager() const
72									{ return fNodeManager; }
73			StackTrace*			GetStackTrace() const
74									{ return fCurrentStackTrace; }
75
76			::Thread*			CurrentThread() const { return fCurrentThread; }
77			thread_id			CurrentThreadID() const;
78			void				SetCurrentThread(::Thread* thread);
79			void				PrintCurrentThread();
80
81			int32				CurrentStackFrameIndex() const
82									{ return fCurrentStackFrameIndex; }
83			void				SetCurrentStackFrameIndex(int32 index);
84
85			status_t			EvaluateExpression(const char * expression,
86									SourceLanguage* language, target_addr_t& address);
87
88			status_t			GetMemoryBlock(target_addr_t address,
89									TeamMemoryBlock*& block);
90
91			const char*			PromptUser(const char* prompt);
92			void				AddLineToInputHistory(const char* line);
93
94			void				QuitSession(bool killTeam);
95
96			void				WaitForThreadOrUser();
97			void				WaitForEvent(uint32 event);
98
99private:
100			struct Event;
101
102			typedef DoublyLinkedList<Event> EventList;
103
104private:
105	// Team::Listener
106	virtual	void				ThreadAdded(const Team::ThreadEvent& event);
107	virtual	void				ThreadRemoved(const Team::ThreadEvent& event);
108
109	virtual	void				ThreadStateChanged(
110									const Team::ThreadEvent& event);
111	virtual	void				ThreadStackTraceChanged(
112									const Team::ThreadEvent& event);
113
114	virtual	void				DebugReportChanged(
115									const Team::DebugReportEvent& event);
116
117	virtual	void				CoreFileChanged(
118									const Team::CoreFileChangedEvent& event);
119
120	// TeamMemoryBlock::Listener
121	virtual void				MemoryBlockRetrieved(TeamMemoryBlock* block);
122
123	// ExpressionInfo::Listener
124	virtual	void				ExpressionEvaluated(ExpressionInfo* info,
125									status_t result, ExpressionResult* value);
126
127	// ValueNodeContainer::Listener
128	virtual	void				ValueNodeChanged(ValueNodeChild* nodeChild,
129									ValueNode* oldNode, ValueNode* newNode);
130	virtual	void				ValueNodeChildrenCreated(ValueNode* node);
131	virtual	void				ValueNodeChildrenDeleted(ValueNode* node);
132	virtual	void				ValueNodeValueChanged(ValueNode* node);
133
134private:
135	static	const char*			_GetPrompt(EditLine* editLine);
136			void				_WaitForEvent(uint32 event);
137
138private:
139	mutable	BLocker				fLock;
140			::Team*				fTeam;
141			UserInterfaceListener* fListener;
142			ValueNodeManager*	fNodeManager;
143			EditLine*			fEditLine;
144			History*			fHistory;
145			const char*			fPrompt;
146			sem_id				fWaitForEventSemaphore;
147			uint32				fEventOccurred;
148	volatile bool				fTerminating;
149
150			BReference< ::Thread>	fStoppedThread;
151			::Thread*			fCurrentThread;
152			StackTrace*			fCurrentStackTrace;
153			int32				fCurrentStackFrameIndex;
154			TeamMemoryBlock*	fCurrentBlock;
155
156			ExpressionInfo*		fExpressionInfo;
157			status_t			fExpressionResult;
158			ExpressionResult*	fExpressionValue;
159};
160
161
162#endif	// CLI_CONTEXT_H
163