xref: /haiku/src/apps/debugger/user_interface/cli/CliContext.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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 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 				EVENT_CORE_FILE_CHANGED				= 0x400
47 			};
48 
49 public:
50 								CliContext();
51 								~CliContext();
52 
53 			status_t			Init(Team* team,
54 									UserInterfaceListener* listener);
55 			void				Cleanup();
56 
57 			void				Terminating();
58 
59 			bool				IsTerminating() const	{ return fTerminating; }
60 
61 			// service methods for the input loop thread follow
62 
63 			Team*				GetTeam() const	{ return fTeam; }
64 			UserInterfaceListener* GetUserInterfaceListener() const
65 									{ return fListener; }
66 			ValueNodeManager*	GetValueNodeManager() const
67 									{ return fNodeManager; }
68 			StackTrace*			GetStackTrace() const
69 									{ return fCurrentStackTrace; }
70 
71 			Thread*				CurrentThread() const { return fCurrentThread; }
72 			thread_id			CurrentThreadID() const;
73 			void				SetCurrentThread(Thread* thread);
74 			void				PrintCurrentThread();
75 
76 			int32				CurrentStackFrameIndex() const
77 									{ return fCurrentStackFrameIndex; }
78 			void				SetCurrentStackFrameIndex(int32 index);
79 
80 			TeamMemoryBlock*	CurrentBlock() const { return fCurrentBlock; }
81 
82 			ExpressionInfo*		GetExpressionInfo() const
83 									{ return fExpressionInfo; }
84 			status_t			GetExpressionResult() const
85 									{ return fExpressionResult; }
86 			ExpressionResult*	GetExpressionValue() const
87 									{ return fExpressionValue; }
88 
89 			const char*			PromptUser(const char* prompt);
90 			void				AddLineToInputHistory(const char* line);
91 
92 			void				QuitSession(bool killTeam);
93 
94 			void				WaitForThreadOrUser();
95 			void				WaitForEvents(int32 eventMask);
96 			void				ProcessPendingEvents();
97 
98 private:
99 			struct Event;
100 
101 			typedef DoublyLinkedList<Event> EventList;
102 
103 private:
104 	// Team::Listener
105 	virtual	void				ThreadAdded(const Team::ThreadEvent& event);
106 	virtual	void				ThreadRemoved(const Team::ThreadEvent& event);
107 
108 	virtual	void				ThreadStateChanged(
109 									const Team::ThreadEvent& event);
110 	virtual	void				ThreadStackTraceChanged(
111 									const Team::ThreadEvent& event);
112 
113 	virtual	void				DebugReportChanged(
114 									const Team::DebugReportEvent& event);
115 
116 	virtual	void				CoreFileChanged(
117 									const Team::CoreFileChangedEvent& event);
118 
119 	// TeamMemoryBlock::Listener
120 	virtual void				MemoryBlockRetrieved(TeamMemoryBlock* block);
121 
122 	// ExpressionInfo::Listener
123 	virtual	void				ExpressionEvaluated(ExpressionInfo* info,
124 									status_t result, ExpressionResult* value);
125 
126 	// ValueNodeContainer::Listener
127 	virtual	void				ValueNodeChanged(ValueNodeChild* nodeChild,
128 									ValueNode* oldNode, ValueNode* newNode);
129 	virtual	void				ValueNodeChildrenCreated(ValueNode* node);
130 	virtual	void				ValueNodeChildrenDeleted(ValueNode* node);
131 	virtual	void				ValueNodeValueChanged(ValueNode* node);
132 
133 private:
134 			void				_QueueEvent(Event* event);
135 
136 			void				_PrepareToWaitForEvents(uint32 eventMask);
137 			uint32				_WaitForEvents();
138 			void				_SignalInputLoop(uint32 events);
139 
140 	static	const char*			_GetPrompt(EditLine* editLine);
141 
142 private:
143 			BLocker				fLock;
144 			Team*				fTeam;
145 			UserInterfaceListener* fListener;
146 			ValueNodeManager*	fNodeManager;
147 			EditLine*			fEditLine;
148 			History*			fHistory;
149 			const char*			fPrompt;
150 			sem_id				fBlockingSemaphore;
151 			uint32				fInputLoopWaitingForEvents;
152 			uint32				fEventsOccurred;
153 			bool				fInputLoopWaiting;
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