xref: /haiku/src/apps/debugger/user_interface/cli/CliContext.h (revision 4958c5d7b68abe13db5fbfa61305db81693f0eef)
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 
16 #include "ExpressionInfo.h"
17 #include "Team.h"
18 #include "TeamMemoryBlock.h"
19 #include "ValueNodeContainer.h"
20 
21 
22 class SourceLanguage;
23 class StackFrame;
24 class StackTrace;
25 class Team;
26 class TeamMemoryBlock;
27 class UserInterfaceListener;
28 class ValueNodeManager;
29 
30 
31 class CliContext : private Team::Listener,
32 	public TeamMemoryBlock::Listener,
33 	public ExpressionInfo::Listener,
34 	private ValueNodeContainer::Listener {
35 public:
36 			enum {
37 				EVENT_QUIT							= 0x01,
38 				EVENT_USER_INTERRUPT				= 0x02,
39 				EVENT_THREAD_ADDED					= 0x04,
40 				EVENT_THREAD_REMOVED				= 0x08,
41 				EVENT_THREAD_STOPPED				= 0x10,
42 				EVENT_THREAD_STACK_TRACE_CHANGED	= 0x20,
43 				EVENT_VALUE_NODE_CHANGED			= 0x40,
44 				EVENT_TEAM_MEMORY_BLOCK_RETRIEVED	= 0x80,
45 				EVENT_EXPRESSION_EVALUATED			= 0x100,
46 				EVENT_DEBUG_REPORT_CHANGED			= 0x200,
47 				EVENT_CORE_FILE_CHANGED				= 0x400
48 			};
49 
50 public:
51 								CliContext();
52 								~CliContext();
53 
54 			status_t			Init(Team* team,
55 									UserInterfaceListener* listener);
56 			void				Cleanup();
57 
58 			void				Terminating();
59 
60 			bool				IsTerminating() const	{ return fTerminating; }
61 
62 			// service methods for the input loop thread follow
63 
64 			Team*				GetTeam() const	{ return fTeam; }
65 			UserInterfaceListener* GetUserInterfaceListener() const
66 									{ return fListener; }
67 			ValueNodeManager*	GetValueNodeManager() const
68 									{ return fNodeManager; }
69 			StackTrace*			GetStackTrace() const
70 									{ return fCurrentStackTrace; }
71 
72 			Thread*				CurrentThread() const { return fCurrentThread; }
73 			thread_id			CurrentThreadID() const;
74 			void				SetCurrentThread(Thread* thread);
75 			void				PrintCurrentThread();
76 
77 			int32				CurrentStackFrameIndex() const
78 									{ return fCurrentStackFrameIndex; }
79 			void				SetCurrentStackFrameIndex(int32 index);
80 
81 			status_t			EvaluateExpression(const char * expression,
82 									SourceLanguage* language, target_addr_t& address);
83 
84 			status_t			GetMemoryBlock(target_addr_t address,
85 									TeamMemoryBlock*& block);
86 
87 			const char*			PromptUser(const char* prompt);
88 			void				AddLineToInputHistory(const char* line);
89 
90 			void				QuitSession(bool killTeam);
91 
92 			void				WaitForThreadOrUser();
93 			void				WaitForEvents(int32 eventMask);
94 			void				ProcessPendingEvents();
95 
96 private:
97 			struct Event;
98 
99 			typedef DoublyLinkedList<Event> EventList;
100 
101 private:
102 	// Team::Listener
103 	virtual	void				ThreadAdded(const Team::ThreadEvent& event);
104 	virtual	void				ThreadRemoved(const Team::ThreadEvent& event);
105 
106 	virtual	void				ThreadStateChanged(
107 									const Team::ThreadEvent& event);
108 	virtual	void				ThreadStackTraceChanged(
109 									const Team::ThreadEvent& event);
110 
111 	virtual	void				DebugReportChanged(
112 									const Team::DebugReportEvent& event);
113 
114 	virtual	void				CoreFileChanged(
115 									const Team::CoreFileChangedEvent& event);
116 
117 	// TeamMemoryBlock::Listener
118 	virtual void				MemoryBlockRetrieved(TeamMemoryBlock* block);
119 
120 	// ExpressionInfo::Listener
121 	virtual	void				ExpressionEvaluated(ExpressionInfo* info,
122 									status_t result, ExpressionResult* value);
123 
124 	// ValueNodeContainer::Listener
125 	virtual	void				ValueNodeChanged(ValueNodeChild* nodeChild,
126 									ValueNode* oldNode, ValueNode* newNode);
127 	virtual	void				ValueNodeChildrenCreated(ValueNode* node);
128 	virtual	void				ValueNodeChildrenDeleted(ValueNode* node);
129 	virtual	void				ValueNodeValueChanged(ValueNode* node);
130 
131 private:
132 			void				_QueueEvent(Event* event);
133 
134 			void				_PrepareToWaitForEvents(uint32 eventMask);
135 			uint32				_WaitForEvents();
136 			void				_SignalInputLoop(uint32 events);
137 
138 	static	const char*			_GetPrompt(EditLine* editLine);
139 
140 private:
141 			BLocker				fLock;
142 			Team*				fTeam;
143 			UserInterfaceListener* fListener;
144 			ValueNodeManager*	fNodeManager;
145 			EditLine*			fEditLine;
146 			History*			fHistory;
147 			const char*			fPrompt;
148 			sem_id				fBlockingSemaphore;
149 			uint32				fInputLoopWaitingForEvents;
150 			uint32				fEventsOccurred;
151 			bool				fInputLoopWaiting;
152 	volatile bool				fTerminating;
153 
154 			Thread*				fCurrentThread;
155 			StackTrace*			fCurrentStackTrace;
156 			int32				fCurrentStackFrameIndex;
157 			TeamMemoryBlock*	fCurrentBlock;
158 
159 			ExpressionInfo*		fExpressionInfo;
160 			status_t			fExpressionResult;
161 			ExpressionResult*	fExpressionValue;
162 
163 			EventList			fPendingEvents;
164 };
165 
166 
167 #endif	// CLI_CONTEXT_H
168