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