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