1 //=============================================================================
2 //
3 // File : KviKvsRunTimeContext.cpp
4 // Creation date : Tue 07 Oct 2003 01:49:40 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2003-2010 Szymon Stefanek <pragma at kvirc dot net>
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #include "KviKvsRunTimeContext.h"
26 #include "KviKvsScript.h"
27 #include "KviKvsKernel.h"
28 #include "KviKvsReport.h"
29 #include "KviConsoleWindow.h"
30 #include "KviKvsTreeNodeBase.h"
31 #include "KviLocale.h"
32 #include "KviApplication.h"
33 #include "KviKvsObject.h"
34
~KviKvsExtendedRunTimeData()35 KviKvsExtendedRunTimeData::~KviKvsExtendedRunTimeData()
36 {
37 if(m_bAutoDelete)
38 {
39 if(m_pExtendedScopeVariables)
40 delete m_pExtendedScopeVariables;
41 if(m_pAliasSwitchList)
42 delete m_pAliasSwitchList;
43 if(m_pThisObject)
44 delete m_pThisObject;
45 if(m_pScriptFilePath)
46 delete m_pScriptFilePath;
47 // don't delete m_pPopupId;
48 }
49 }
50
setPopupId(QString * pPopupId)51 void KviKvsExtendedRunTimeData::setPopupId(QString * pPopupId)
52 {
53 m_pPopupId = pPopupId;
54 };
55
KviKvsRunTimeContext(KviKvsScript * pScript,KviWindow * pWnd,KviKvsVariantList * pParams,KviKvsVariant * pRetVal,KviKvsExtendedRunTimeData * pExtData)56 KviKvsRunTimeContext::KviKvsRunTimeContext(KviKvsScript * pScript, KviWindow * pWnd, KviKvsVariantList * pParams, KviKvsVariant * pRetVal, KviKvsExtendedRunTimeData * pExtData)
57 {
58 m_bError = false;
59 m_pScript = pScript;
60 m_pParameterList = pParams;
61 m_pWindow = pWnd;
62 m_pLocalVariables = new KviKvsHash();
63 m_pReturnValue = pRetVal;
64 m_uRunTimeFlags = 0;
65 m_pExtendedData = pExtData;
66 m_pDefaultReportLocation = nullptr;
67 }
68
~KviKvsRunTimeContext()69 KviKvsRunTimeContext::~KviKvsRunTimeContext()
70 {
71 delete m_pLocalVariables;
72 }
73
globalVariables()74 KviKvsHash * KviKvsRunTimeContext::globalVariables()
75 {
76 return KviKvsKernel::instance()->globalVariables();
77 }
78
enterBlockingSection()79 void KviKvsRunTimeContext::enterBlockingSection()
80 {
81 // actually a NO-OP
82 }
83
leaveBlockingSection()84 bool KviKvsRunTimeContext::leaveBlockingSection()
85 {
86 if(g_pApp->kviClosingDown())
87 return false; // application quitting
88 if(!g_pApp->windowExists(m_pWindow))
89 return false; // window lost
90 return true;
91 }
92
swapReturnValuePointer(KviKvsVariant * pNewPointer)93 KviKvsVariant * KviKvsRunTimeContext::swapReturnValuePointer(KviKvsVariant * pNewPointer)
94 {
95 KviKvsVariant * pAux = m_pReturnValue;
96 m_pReturnValue = pNewPointer;
97 return pAux;
98 }
99
report(bool bError,KviKvsTreeNode * pNode,const QString & szMsgFmt,kvi_va_list va)100 void KviKvsRunTimeContext::report(bool bError, KviKvsTreeNode * pNode, const QString & szMsgFmt, kvi_va_list va)
101 {
102 QString szMsg;
103 KviQString::vsprintf(szMsg, szMsgFmt, va);
104
105 KviPointerList<QString> * pCodeListing = nullptr;
106 KviPointerList<QString> * pCallStack = nullptr;
107 QString szLocation;
108
109 if(pNode)
110 {
111 if(pNode->location() && m_pScript)
112 {
113 pCodeListing = new KviPointerList<QString>;
114 pCodeListing->setAutoDelete(true);
115
116 int iLine, iCol;
117
118 KviKvsReport::findLineColAndListing(m_pScript->buffer(), pNode->location(), iLine, iCol, pCodeListing);
119
120 szLocation = QString(__tr2qs_ctx("line %1, near character %2", "kvs")).arg(iLine).arg(iCol);
121 }
122
123 // create the call stack
124 int iFrame = 0;
125
126 pCallStack = new KviPointerList<QString>;
127 pCallStack->setAutoDelete(true);
128
129 while(pNode && (iFrame < 12))
130 {
131 QString * pString = new QString();
132 QString szTmp;
133 pNode->contextDescription(szTmp);
134 *pString = QString("#%1 %2").arg(iFrame).arg(szTmp);
135 if(pNode->location())
136 {
137 int iLine, iCol;
138 KviKvsReport::findLineAndCol(m_pScript->buffer(), pNode->location(), iLine, iCol);
139 QString tmpi = QString(" [line %1, near character %2]").arg(iLine).arg(iCol);
140 *pString += tmpi;
141 }
142 pCallStack->append(pString);
143 iFrame++;
144 pNode = pNode->parent();
145 }
146 if(pNode)
147 pCallStack->append(new QString("#12 ..."));
148 }
149
150 QString szContext = m_pScript ? m_pScript->name() : "kvirc core code";
151 KviKvsReport rep(bError ? KviKvsReport::RunTimeError : KviKvsReport::RunTimeWarning, szContext, szMsg, szLocation, m_pWindow);
152 if(pCodeListing)
153 rep.setCodeListing(pCodeListing);
154 if(pCallStack)
155 rep.setCallStack(pCallStack);
156
157 KviKvsReport::report(&rep, m_pWindow);
158 }
159
error(KviKvsTreeNode * pNode,QString szMsgFmt,...)160 void KviKvsRunTimeContext::error(KviKvsTreeNode * pNode, QString szMsgFmt, ...)
161 {
162 m_bError = true;
163
164 kvi_va_list va;
165 kvi_va_start(va, szMsgFmt);
166 report(true, pNode, szMsgFmt, va);
167 kvi_va_end(va);
168 }
169
warning(KviKvsTreeNode * pNode,QString szMsgFmt,...)170 void KviKvsRunTimeContext::warning(KviKvsTreeNode * pNode, QString szMsgFmt, ...)
171 {
172 kvi_va_list va;
173 kvi_va_start(va, szMsgFmt);
174 report(false, pNode, szMsgFmt, va);
175 kvi_va_end(va);
176 }
177
error(QString szMsgFmt,...)178 void KviKvsRunTimeContext::error(QString szMsgFmt, ...)
179 {
180 m_bError = true;
181
182 kvi_va_list va;
183 kvi_va_start(va, szMsgFmt);
184 report(true, m_pDefaultReportLocation, szMsgFmt, va);
185 kvi_va_end(va);
186 }
187
warning(QString szMsgFmt,...)188 void KviKvsRunTimeContext::warning(QString szMsgFmt, ...)
189 {
190 kvi_va_list va;
191 kvi_va_start(va, szMsgFmt);
192 report(false, m_pDefaultReportLocation, szMsgFmt, va);
193 kvi_va_end(va);
194 }
195
errorNoIrcContext()196 bool KviKvsRunTimeContext::errorNoIrcContext()
197 {
198 error(m_pDefaultReportLocation, __tr2qs_ctx("This command can be used only in windows bound to an IRC context", "kvs"));
199 return false;
200 }
201
warningNoIrcConnection()202 bool KviKvsRunTimeContext::warningNoIrcConnection()
203 {
204 warning(m_pDefaultReportLocation, __tr2qs_ctx("You're not connected to an IRC server", "kvs"));
205 return true;
206 }
207
warningMissingParameter()208 bool KviKvsRunTimeContext::warningMissingParameter()
209 {
210 warning(m_pDefaultReportLocation, __tr2qs_ctx("Missing parameter", "kvs"));
211 return true;
212 }
213
setDefaultReportLocation(KviKvsTreeNode * pNode)214 void KviKvsRunTimeContext::setDefaultReportLocation(KviKvsTreeNode * pNode)
215 {
216 m_pDefaultReportLocation = pNode;
217 }
218