1 #ifndef _KVI_KVS_SCRIPT_H_
2 #define _KVI_KVS_SCRIPT_H_
3 //=============================================================================
4 //
5 //   File : KviKvsScript.h
6 //   Creation date : Thu 25 Sep 2003 05.12 CEST by Szymon Stefanek
7 //
8 //   This file is part of the KVIrc IRC client distribution
9 //   Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net)
10 //
11 //   This program is FREE software. You can redistribute it and/or
12 //   modify it under the terms of the GNU General Public License
13 //   as published by the Free Software Foundation; either version 2
14 //   of the License, or (at your option) any later version.
15 //
16 //   This program is distributed in the HOPE that it will be USEFUL,
17 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
18 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 //   See the GNU General Public License for more details.
20 //
21 //   You should have received a copy of the GNU General Public License
22 //   along with this program. If not, write to the Free Software Foundation,
23 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 //
25 //=============================================================================
26 
27 /**
28 * \file KviKvsScript.h
29 * \author Szymon Stefanek
30 * \brief KVIrc Script manager
31 */
32 
33 #include "kvi_settings.h"
34 #include "KviQString.h"
35 #include "KviWindow.h"
36 #include "KviPointerList.h"
37 #include "KviKvsVariant.h"
38 #include "KviKvsVariantList.h"
39 #include "KviHeapObject.h"
40 
41 class KviKvsTreeNodeInstruction;
42 class KviKvsExtendedRunTimeData;
43 class KviKvsScriptData;
44 class KviKvsReport;
45 class KviKvsRunTimeContext;
46 
47 // X defines this stuff: ugly :/
48 #ifdef Error
49 #undef Error
50 #endif
51 #ifdef Success
52 #undef Success
53 #endif
54 
55 /**
56 * \class KviKvsScript
57 * \brief The KVIrc Script class
58 */
59 class KVIRC_API KviKvsScript : public KviHeapObject
60 {
61 	friend class KviKvsObject;
62 	friend class KviKvsParser;
63 	friend class KviKvsRunTimeContext;
64 
65 public:
66 	/**
67 	* \enum RunStatus
68 	* \brief Holds the run status of the script
69 	*/
70 	enum RunStatus
71 	{
72 		Error = 0,          /**< The script returned an error */
73 		Success = 1,        /**< The script ran successfully */
74 		HaltEncountered = 2 /**< The script ran successfully and halt was encountered */
75 	};
76 
77 	/**
78 	* \enum ScriptType
79 	* \brief Holds the type of the script
80 	*/
81 	enum ScriptType
82 	{
83 		InstructionList, /**< The most common script type: a sequence of instructions */
84 		Expression,      /**< An expression to be evaluated as in a $() call (pRetVal should be always set!) */
85 		Parameter        /**< A parameter to be evaluated (pRetVal should be always set!) */
86 	};
87 
88 	/**
89 	* \enum RunFlags
90 	* \brief Holds the run flags of the script
91 	*/
92 	enum RunFlags
93 	{
94 		PreserveParams = 1, /**< Do not delete the eventual parameters passed (only execute() and run()) */
95 		// FIXME: This should be a global option, eventually
96 		AssumeLocals = 2, /**< Assume that the variables are local unless explicitly declared (flag used only for parse()) */
97 		// FIXME: This should be a global option, eventually
98 		Pedantic = 4, /**< Be more pedantic: spit more warnings and sometimes more errors */
99 		Quiet = 8     /**< Don't print any errors */
100 	};
101 
102 public:
103 	/**
104 	* \brief Constructs a KVIrc Script object
105 	*
106 	* This is a shallow copy of the script data useful when a script can
107 	* be destroyed while running (like in timers)
108 	* \param src The source script
109 	* \return KviKvsScript
110 	*/
111 	KviKvsScript(const KviKvsScript & src);
112 
113 	/**
114 	* \brief Constructs a KVIrc Script object
115 	* \param szName The name of the context
116 	* \param szBuffer The buffer :)
117 	* \param eType The type of the code in the buffer
118 	* \return KviKvsScript
119 	*/
120 	KviKvsScript(const QString & szName, const QString & szBuffer, ScriptType eType = InstructionList);
121 
122 	/**
123 	* \brief Destroys a KVIrc Script object
124 	*/
125 	~KviKvsScript();
126 
127 protected:
128 	/**
129 	* \brief Constructs a KVIrc Script object
130 	* \param szName The name of the context
131 	* \param szBuffer The buffer :)
132 	* \param pPreparsedTree The synthax tree
133 	* \param eType The type of the code in the buffer
134 	* \return KviKvsScript
135 	*/
136 	KviKvsScript(const QString & szName, const QString & szBuffer, KviKvsTreeNodeInstruction * pPreparsedTree, ScriptType eType = InstructionList);
137 
138 private:
139 	KviKvsScriptData * m_pData;
140 
141 public:
142 	/**
143 	* \brief Returns the name of the script context
144 	* \return const QString &
145 	*/
146 	const QString & name() const;
147 
148 	/**
149 	* \brief Returns the code of the script
150 	* \return const QString &
151 	*/
152 	const QString & code() const;
153 
154 	/**
155 	* \brief Returns true if the script is locked, false otherwise
156 	*
157 	* The lock is set while the script is being executed
158 	* \return bool
159 	*/
160 	bool locked() const;
161 
162 	/**
163 	* \brief Sets the name of the script context
164 	* \param szName The name of the context
165 	* \return void
166 	*/
167 	void setName(const QString & szName);
168 
169 	/**
170 	* \brief Runs the script
171 	*
172 	* Returns 0 (KviKvsScript::RunFailure) on error
173 	* Returns a nonzero combination of RunStatus flags on success
174 	*
175 	* If PreserverParams is not used, the ownership is transferred.
176 	* Extended data is used if you need to pass extended scope variables or alias switch lists...)
177 	* \param pWnd The window that the command has to be bound to
178 	* \param pParams The parameter list (0 if you don't pass params)
179 	* \param pRetVal Return value buffer (0 if you ignore it)
180 	* \param iRunFlags A combination of run flags (usually default)
181 	* \param pExtData Extended data (usually 0)
182 	* \return int
183 	*/
184 	int run(KviWindow * pWnd, KviKvsVariantList * pParams = nullptr, KviKvsVariant * pRetVal = nullptr, int iRunFlags = 0, KviKvsExtendedRunTimeData * pExtData = nullptr);
185 
186 	/**
187 	* \brief Runs the script
188 	*
189 	* Returns 0 (KviKvsScript::RunFailure) on error
190 	* Returns a nonzero combination of RunStatus flags on success
191 	*
192 	* The QString return buffer is useful only for evaluating InstructionList scripts.
193 	* If PreserverParams is not used, the ownership is transferred.
194 	* Extended data is used if you need to pass extended scope variables or alias switch lists...)
195 	* \param pWnd The window that the command has to be bound to
196 	* \param pParams The parameter list (0 if you don't pass params)
197 	* \param szRetVal Return value buffer
198 	* \param iRunFlags A combination of run flags (usually default)
199 	* \param pExtData Extended data (usually 0)
200 	* \return int
201 	*/
202 	int run(KviWindow * pWnd, KviKvsVariantList * pParams, QString & szRetVal, int iRunFlags = 0, KviKvsExtendedRunTimeData * pExtData = nullptr);
203 
204 	/**
205 	* \brief Runs the script
206 	*
207 	* Returns 0 (KviKvsScript::RunFailure) on error
208 	* Returns a nonzero combination of RunStatus flags on success
209 	*
210 	* This is probably used only in /eval
211 	* \param pContext The context where the script is bound to
212 	* \param iRunFlags A combination of run flags (usually default)
213 	* \return int
214 	*/
215 	int run(KviKvsRunTimeContext * pContext, int iRunFlags = 0);
216 
217 	/**
218 	* \brief Static helper for quick running
219 	*
220 	* Returns a combination of RunStatus flags (nonzero on no error)
221 	* It does NOT take params ownership
222 	* \param szCode The source code to run
223 	* \param pWindow The window that the command has to be bound to
224 	* \param pParams The parameter list (0 if you don't pass params)
225 	* \param pRetVal Return value buffer (0 if you ignore it)
226 	* \return int
227 	*/
228 	static int run(const QString & szCode, KviWindow * pWindow, KviKvsVariantList * pParams = nullptr, KviKvsVariant * pRetVal = nullptr);
229 
230 	/**
231 	* \brief Static helper for quick evaluating parameters
232 	*
233 	* Returns a combination of RunStatus flags (nonzero on no error)
234 	* It does NOT take params ownership.
235 	* pRetVal CAN'T be zero here since we're evaluating stuff here
236 	* \param szCode The source code to run
237 	* \param pWindow The window that the command has to be bound to
238 	* \param pParams The parameter list
239 	* \param pRetVal Return value buffer
240 	* \return int
241 	*/
242 	static int evaluate(const QString & szCode, KviWindow * pWindow, KviKvsVariantList * pParams, KviKvsVariant * pRetVal);
243 
244 	/**
245 	* \brief Static helper for quick evaluating parameters
246 	*
247 	* Returns a combination of RunStatus flags (nonzero on no error)
248 	* It does NOT take params ownership.
249 	* The QString return buffer CAN'T be zero here since we're evaluating stuff here
250 	* \param szCode The source code to run
251 	* \param pWindow The window that the command has to be bound to
252 	* \param pParams The parameter list
253 	* \param szRetVal Return value buffer
254 	* \return int
255 	*/
256 	static int evaluateAsString(const QString & szCode, KviWindow * pWindow, KviKvsVariantList * pParams, QString & szRetVal);
257 
258 	/**
259 	* \brief Dumps the instructions tree
260 	* \param prefix The prefix of the instruction
261 	* \return void
262 	*/
263 	void dump(const char * prefix);
264 
265 protected:
266 	/**
267 	* \brief Returns true after a successful parsing, false otherwise
268 	*
269 	* pOutput is useful only for printing errors; if 0, no errors are printed
270 	* \param pOutput The output window for errors
271 	* \param iRunFlags A combination of run flags (usually default)
272 	* \return bool
273 	*/
274 	bool parse(KviWindow * pOutput = nullptr, int iRunFlags = 0);
275 
276 	/**
277 	* \brief Runs the script
278 	*
279 	* Returns 0 (KviKvsScript::RunFailure) on error
280 	* Returns a nonzero combination of RunStatus flags on success
281 	* \param pWnd The window that the command has to be bound to
282 	* \param pParams The parameter list (0 if you don't pass params)
283 	* \param pRetVal Return value buffer (0 if you ignore it)
284 	* \param iRunFlags A combination of run flags (usually default)
285 	* \param pExtData Extended data (usually 0)
286 	* \return int
287 	*/
288 	int execute(KviWindow * pWnd, KviKvsVariantList * pParams = nullptr, KviKvsVariant * pRetVal = nullptr, int iRunFlags = 0, KviKvsExtendedRunTimeData * pExtData = nullptr);
289 
290 	/**
291 	* \brief Runs the script
292 	*
293 	* Returns 0 (KviKvsScript::RunFailure) on error
294 	* Returns a nonzero combination of RunStatus flags on success
295 	* \param pContext The context where the script is bound to
296 	* \return int
297 	*/
298 	int executeInternal(KviKvsRunTimeContext * pContext);
299 
300 	/**
301 	* \brief Returns the data of the script
302 	* \return const QChar *
303 	*/
304 	const QChar * buffer() const;
305 
306 	/**
307 	* \brief Detaches this script from any other shallow copies
308 	* \return void
309 	*/
310 	void detach();
311 };
312 
313 /**
314 * \class KviKvsScriptData
315 * \brief Holds the data of the script
316 */
317 class KVIRC_API KviKvsScriptData
318 {
319 	friend class KviKvsScript;
320 
321 protected:
322 	unsigned int m_uRefs; // Reference count for this structure
323 
324 	QString m_szName;        // script context name
325 	QString m_szBuffer;      // NEVER TOUCH THIS
326 	const QChar * m_pBuffer; // this points to m_szBuffer: use it to extract string data
327 
328 	KviKvsScript::ScriptType m_eType; // the type of the code in m_szBuffer
329 
330 	KviKvsTreeNodeInstruction * m_pTree; // syntax tree
331 	unsigned int m_uLock;                // this is increased while the script is being executed
332 };
333 
334 #endif //_KVI_KVS_SCRIPT_H_
335