summaryrefslogtreecommitdiffstats
path: root/src/kvirc/kvs/kvi_kvs_runtimecontext.h
blob: 373eb3925ffeb0a50ceb45bfa15beb05e651ab68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#ifndef _KVI_KVS_RUNTIMECONTEXT_H_
#define _KVI_KVS_RUNTIMECONTEXT_H_
//=============================================================================
//
//   File : kvi_kvs_runtimecontext.h
//   Created on Tue 07 Oct 2003 01:49:40 by Szymon Stefanek
//
//   This file is part of the KVIrc IRC client distribution
//   Copyright (C) 2003 Szymon Stefanek <pragma at kvirc dot net>
//
//   This program is FREE software. You can redistribute it and/or
//   modify it under the terms of the GNU General Public License
//   as published by the Free Software Foundation; either version 2
//   of the License, or (at your opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================

#include "kvi_settings.h"

#include "kvi_window.h"

#include "kvi_kvs_variant.h"
#include "kvi_kvs_hash.h"
#include "kvi_kvs_variantlist.h"
#include "kvi_kvs_switchlist.h"

class KviKvsScript;
class KviConsole;
class KviIrcContext;
class KviIrcConnection;
class KviKvsTreeNode;
class KviKvsObject;
class KviKvsReportHandler;

class KVIRC_API KviKvsExtendedRunTimeData
{
	friend class KviKvsRunTimeContext;
protected:
	KviKvsHash       * m_pExtendedScopeVariables; // extended scope vars, shallow, may be 0
	KviKvsSwitchList * m_pAliasSwitchList;        // switches for the aliases, shallow, may be 0
	KviKvsObject     * m_pThisObject;             // the current object for object function calls
	TQString          * m_pScriptFilePath;         // the current script file path, shallow, may be 0
	bool		   m_bAutoDelete;
public:
	// all shallow data, all may be 0
	KviKvsExtendedRunTimeData()
		: m_pExtendedScopeVariables(0),
		m_pAliasSwitchList(0),
		m_pThisObject(0),
		m_pScriptFilePath(0),
		m_bAutoDelete(FALSE)
		{};
	KviKvsExtendedRunTimeData(KviKvsHash * pExtScopeVariables,bool autoDelete=FALSE)
		: m_pExtendedScopeVariables(pExtScopeVariables),
		m_pAliasSwitchList(0),
		m_pThisObject(0),
		m_pScriptFilePath(0),
		m_bAutoDelete(autoDelete)
		{};
	KviKvsExtendedRunTimeData(KviKvsSwitchList * pAliasSwitchList,bool autoDelete=FALSE)
		: m_pExtendedScopeVariables(0),
		m_pAliasSwitchList(pAliasSwitchList),
		m_pThisObject(0),
		m_pScriptFilePath(0),
		m_bAutoDelete(autoDelete)
		{};
	KviKvsExtendedRunTimeData(KviKvsObject * pThisObject,bool autoDelete=FALSE)
		: m_pExtendedScopeVariables(0),
		m_pAliasSwitchList(0),
		m_pThisObject(pThisObject),
		m_pScriptFilePath(0),
		m_bAutoDelete(autoDelete)
		{};
	KviKvsExtendedRunTimeData(TQString * pScriptFilePath,bool autoDelete=FALSE)
		: m_pExtendedScopeVariables(0),
		m_pAliasSwitchList(0),
		m_pThisObject(0),
		m_pScriptFilePath(pScriptFilePath),
		m_bAutoDelete(autoDelete)
		{};
	~KviKvsExtendedRunTimeData();
public:
	KviKvsHash * extendedScopeVariables(){ return m_pExtendedScopeVariables; };
	KviKvsSwitchList * aliasSwitchList(){ return m_pAliasSwitchList; };
	KviKvsObject * thisObject(){ return m_pThisObject; };
	TQString * scriptFilePath(){ return m_pScriptFilePath; };
};


class KVIRC_API KviKvsRunTimeContext
{
	friend class KviKvsScript;
	friend class KviKvsObject;
	friend class KviKvsRunTimeCall;
	friend class KviKvsEventManager;
protected:
	// only KviKvsScript, KviKvsEventManager and KviKvsObject can instantiate this class
	KviKvsRunTimeContext(KviKvsScript * pScript,
				KviWindow * pWnd,
				KviKvsVariantList * pParams,
				KviKvsVariant * pRetVal,
				KviKvsExtendedRunTimeData * pExtData = 0);
public:
	~KviKvsRunTimeContext();
protected:
	// stuff that is fixed in the whole script context
	KviKvsScript              * m_pScript;                  // shallow, may be 0!
	KviKvsHash                * m_pLocalVariables;          // owned, never 0
	KviKvsVariantList         * m_pParameterList;           // shallow, never 0
	KviKvsVariant             * m_pReturnValue;             // shallow, never 0

	// stuff that is generally global but sometimes may change
	// during the execution of the script
	KviWindow                 * m_pWindow;                  // shallow, never 0

	enum RunTimeFlags { BreakPending = 1, HaltCalled = 2, DisableReporting = 4 };
	unsigned int                m_uRunTimeFlags;            // a combination of RunTimeFlags
	
	KviKvsExtendedRunTimeData * m_pExtendedData;            // shallow, may be 0

	// error handling
	bool                        m_bError;                   // was error() ever called ?
	KviKvsTreeNode            * m_pDefaultReportLocation;   // default report location for error()
public:
	// the window that this script is bound to (it MAY change during the script parsing)
	KviWindow * window()
		{ return m_pWindow; };
	// quick access to the irc context (it MAY be zero!)
	KviIrcContext * context()
		{ return m_pWindow->context(); };
	// quick access to the console that this script is bound to (it MAY be zero, if there is no console)
	KviConsole * console()
		{ return m_pWindow->console(); };
	// quick access to the connection: it MAY be zero!
	KviIrcConnection * connection()
		{ return m_pWindow->connection(); };

	// the local variables of this script
	KviKvsHash * localVariables()
		{ return m_pLocalVariables; };
	// the global application-wide variables
	KviKvsHash * globalVariables();
	// the parameters passed to this script
	KviKvsVariantList * parameterList()
		{ return m_pParameterList; };

	// parent script, may be 0!
	KviKvsScript * script()
		{ return m_pScript; };

	KviKvsVariant * returnValue()
		{ return m_pReturnValue; };
	
	// this is the default error reporting location
	// it is also used by rfc2812wrapper to find out the current command name!
	KviKvsTreeNode * defaultReportLocation()
		{ return m_pDefaultReportLocation; };

	// the extended stuff
	KviKvsHash * extendedScopeVariables()
		{ return m_pExtendedData ? m_pExtendedData->extendedScopeVariables() : 0; };
	KviKvsSwitchList * aliasSwitchList()
		{ return m_pExtendedData ? m_pExtendedData->aliasSwitchList() : 0; };
	KviKvsObject * thisObject()
		{ return m_pExtendedData ? m_pExtendedData->thisObject() : 0; };
	TQString * scriptFilePath()
		{ return m_pExtendedData ? m_pExtendedData->scriptFilePath() : 0; };

	// this MUST be called before any blocking call that might return to the main event loop
	// and eventually quit kvirc or close the window that this command is associated to
	// Actually this is a NO-OP but later may really do something that avoids kvirc to crash
	void enterBlockingSection();
	// this MUST be called after exiting the blocking section above
	// if this function returns false your parsing code MUST "return false" immediately:
	// it means that something rather critical happened and the script
	// execution cannot continue
	bool leaveBlockingSection();

	// Error handling

	// was error(...) ever called ?
	bool error() const { return m_bError; };

	void error(KviKvsTreeNode * pNode,const TQString &szMsgFmt,...);
	void warning(KviKvsTreeNode * pNode,const TQString &szMsgFmt,...);
	void error(const TQString &szMsgFmt,...);
	void warning(const TQString &szMsgFmt,...);
	void setDefaultReportLocation(KviKvsTreeNode * pNode);
	bool errorNoIrcContext();
	bool warningNoIrcConnection();
	bool warningMissingParameter();

//PRIVATE:
	// tricky
	// don't use it: it's only for the parser
	void setWindow(KviWindow * pWnd)
		{ m_pWindow = pWnd; };

	// returns the old pointer
	KviKvsVariant * swapReturnValuePointer(KviKvsVariant * pNewPointer);
	// the old pointer MUST be reset!
	
	// this is called by the parser when a break is encountered
	// the parser calls setBreakPending() and returns false
	// the contexts that can handle a break should check breakPending()
	// after an internal evaluation returned false.
	// if breakPending() they should handle it with handleBreak() and
	// return true instead.
	void setBreakPending()
		{ m_uRunTimeFlags |= BreakPending; };
	// this tells if a break command has been called
	// it may return true if an execution() command has returned false
	// (if breakPending() there should be no error()
	bool breakPending()
		{ return (m_uRunTimeFlags & BreakPending); };
	// this is called by the commands that can handle a break
	void handleBreak()
		{ m_uRunTimeFlags &= ~BreakPending; };

	// this is called by the parser when a halt is encountered
	// the parser then returns false and all the stack frames
	// above should do the same
	void setHaltCalled()
		{ m_uRunTimeFlags |= HaltCalled; };
	bool haltCalled()
		{ return (m_uRunTimeFlags & HaltCalled); };
	
	// this is used by KviKvsScript to disable reporting when the Quiet flag is used
	void disableReporting()
		{ m_uRunTimeFlags |= DisableReporting; };
	bool reportingDisabled()
		{ return (m_uRunTimeFlags & DisableReporting); };
	void enableReporting()
		{ m_uRunTimeFlags &= ~DisableReporting; };

	// clears the error status on this context
	// this is useful to continue execution after an error
	// and probably used only in /eval
	void clearError()
		{ m_bError = false; };
	protected:

	void report(bool bError,KviKvsTreeNode * pNode,const TQString &szMsgFmt,kvi_va_list va);

};

#endif //!_KVI_KVS_RUNTIMECONTEXT_H_