xref: /haiku/src/apps/debugger/user_interface/cli/CliContext.h (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 
23 class SourceLanguage;
24 class StackFrame;
25 class StackTrace;
26 class Team;
27 class TeamMemoryBlock;
28 class UserInterfaceListener;
29 class ValueNodeManager;
30 
31 
32 class CliContext : private Team::Listener,
33 	public TeamMemoryBlock::Listener,
34 	public ExpressionInfo::Listener,
35 	private ValueNodeContainer::Listener,
36 	public BLooper {
37 public:
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 
52 public:
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 
99 private:
100 			struct Event;
101 
102 			typedef DoublyLinkedList<Event> EventList;
103 
104 private:
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 
134 private:
135 	static	const char*			_GetPrompt(EditLine* editLine);
136 			void				_WaitForEvent(uint32 event);
137 
138 private:
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