1 //=============================================================================
2 //
3 // File : KviKvsKernel.cpp
4 // Creation date : Tue 30 Sep 2003 05.12 CEST 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 "KviKvsKernel.h"
26 #include "KviKvsParser.h"
27 #include "KviKvsHash.h"
28 #include "KviKvsAliasManager.h"
29 #include "KviKvsCoreSimpleCommands.h"
30 #include "KviKvsCoreFunctions.h"
31 #include "KviKvsCoreCallbackCommands.h"
32 #include "KviKvsSwitchList.h"
33 #include "KviKvsVariantList.h"
34 #include "KviKvsScript.h"
35 #include "KviKvsObjectController.h"
36 #include "KviKvsAsyncOperation.h"
37 #include "KviModuleManager.h"
38
39 #include <QDir>
40 KviKvsKernel * KviKvsKernel::m_pKvsKernel = nullptr;
41
42 //
43 // CONSTRUCTION AND DESTRUCTION
44 //
45
KviKvsKernel()46 KviKvsKernel::KviKvsKernel()
47 {
48 m_pKvsKernel = this;
49
50 m_pSpecialCommandParsingRoutineDict = new KviPointerHashTable<QString, KviKvsSpecialCommandParsingRoutine>(17, false);
51 m_pSpecialCommandParsingRoutineDict->setAutoDelete(true);
52 m_pCoreSimpleCommandExecRoutineDict = new KviPointerHashTable<QString, KviKvsCoreSimpleCommandExecRoutine>(51, false);
53 m_pCoreSimpleCommandExecRoutineDict->setAutoDelete(true);
54 m_pCoreFunctionExecRoutineDict = new KviPointerHashTable<QString, KviKvsCoreFunctionExecRoutine>(51, false);
55 m_pCoreFunctionExecRoutineDict->setAutoDelete(true);
56 m_pCoreCallbackCommandExecRoutineDict = new KviPointerHashTable<QString, KviKvsCoreCallbackCommandExecRoutine>(17, false);
57 m_pCoreCallbackCommandExecRoutineDict->setAutoDelete(true);
58
59 m_pGlobalVariables = new KviKvsHash();
60 m_pEmptyParameterList = new KviKvsVariantList();
61 m_pObjectController = new KviKvsObjectController();
62 m_pObjectController->init();
63 m_pAsyncOperationManager = new KviKvsAsyncOperationManager();
64
65 KviKvsParser::init();
66
67 KviKvsCoreSimpleCommands::init();
68 KviKvsCoreFunctions::init();
69 KviKvsCoreCallbackCommands::init();
70 }
71
~KviKvsKernel()72 KviKvsKernel::~KviKvsKernel()
73 {
74 delete m_pAsyncOperationManager;
75 delete m_pObjectController;
76 delete m_pEmptyParameterList;
77 delete m_pGlobalVariables;
78
79 delete m_pSpecialCommandParsingRoutineDict;
80 delete m_pCoreSimpleCommandExecRoutineDict;
81 delete m_pCoreFunctionExecRoutineDict;
82 delete m_pCoreCallbackCommandExecRoutineDict;
83 }
84
85 //
86 // INSTANCE MANAGEMENT
87 //
88
init()89 void KviKvsKernel::init()
90 {
91 if(!m_pKvsKernel)
92 m_pKvsKernel = new KviKvsKernel();
93 }
94
done()95 void KviKvsKernel::done()
96 {
97 if(m_pKvsKernel)
98 {
99 delete m_pKvsKernel;
100 m_pKvsKernel = nullptr;
101 }
102 }
103
104 #define COMPLETE_COMMAND_BY_DICT(__type, __dict) \
105 { \
106 KviPointerHashTableIterator<QString, __type> it(*__dict); \
107 int l = szCommandBegin.length(); \
108 while(it.current()) \
109 { \
110 if(KviQString::equalCIN(szCommandBegin, it.currentKey(), l)) \
111 pMatches.push_back(it.currentKey()); \
112 ++it; \
113 } \
114 }
115
completeCommand(const QString & szCommandBegin,std::vector<QString> & pMatches)116 void KviKvsKernel::completeCommand(const QString & szCommandBegin, std::vector<QString> & pMatches)
117 {
118 int idx = szCommandBegin.indexOf(QChar('.'));
119 if(idx == -1)
120 {
121 // no module name inside
122 COMPLETE_COMMAND_BY_DICT(KviKvsCoreSimpleCommandExecRoutine, m_pCoreSimpleCommandExecRoutineDict)
123 COMPLETE_COMMAND_BY_DICT(KviKvsSpecialCommandParsingRoutine, m_pSpecialCommandParsingRoutineDict)
124 COMPLETE_COMMAND_BY_DICT(KviKvsCoreCallbackCommandExecRoutine, m_pCoreCallbackCommandExecRoutineDict)
125
126 g_pModuleManager->completeModuleNames(szCommandBegin, pMatches);
127
128 KviKvsAliasManager::instance()->completeCommand(szCommandBegin, pMatches);
129 }
130 else
131 {
132 // contains a module name
133 QString szModuleName = szCommandBegin.left(idx);
134 QString szRight = szCommandBegin.right(szCommandBegin.length() - (idx + 1));
135 completeModuleCommand(szModuleName, szRight, pMatches);
136 }
137 }
138
completeModuleCommand(const QString & szModuleName,const QString & szCommandBegin,std::vector<QString> & pMatches)139 void KviKvsKernel::completeModuleCommand(const QString & szModuleName, const QString & szCommandBegin, std::vector<QString> & pMatches)
140 {
141 KviModule * pModule = g_pModuleManager->getModule(szModuleName);
142 if(!pModule)
143 return;
144
145 std::vector<QString> lModuleMatches;
146
147 pModule->completeCommand(szCommandBegin, lModuleMatches);
148 for(auto & pszModuleMatch : lModuleMatches)
149 {
150 pszModuleMatch.prepend(".");
151 pszModuleMatch.prepend(szModuleName);
152 pMatches.push_back(std::move(pszModuleMatch));
153 }
154 }
155
completeFunction(const QString & szFunctionBegin,std::vector<QString> & pMatches)156 void KviKvsKernel::completeFunction(const QString & szFunctionBegin, std::vector<QString> & pMatches)
157 {
158 int idx = szFunctionBegin.indexOf(QChar('.'));
159 if(idx == -1)
160 {
161 // no module name inside
162
163 KviPointerHashTableIterator<QString, KviKvsCoreFunctionExecRoutine> it(*m_pCoreFunctionExecRoutineDict);
164 int l = szFunctionBegin.length();
165 while(it.current())
166 {
167 if(KviQString::equalCIN(szFunctionBegin, it.currentKey(), l))
168 pMatches.push_back(it.currentKey());
169 ++it;
170 }
171
172 g_pModuleManager->completeModuleNames(szFunctionBegin, pMatches);
173
174 std::vector<QString> lAliases;
175
176 KviKvsAliasManager::instance()->completeCommand(szFunctionBegin, lAliases);
177 for(auto & pszAlias : lAliases)
178 pMatches.push_back(std::move(pszAlias));
179 }
180 else
181 {
182 // contains a module name
183 QString szModuleName = szFunctionBegin.left(idx);
184 QString szRight = szFunctionBegin.right(szFunctionBegin.length() - (idx + 1));
185 completeModuleFunction(szModuleName, szRight, pMatches);
186 }
187 }
188
completeModuleFunction(const QString & szModuleName,const QString & szCommandBegin,std::vector<QString> & pMatches)189 void KviKvsKernel::completeModuleFunction(const QString & szModuleName, const QString & szCommandBegin, std::vector<QString> & pMatches)
190 {
191 KviModule * pModule = g_pModuleManager->getModule(szModuleName);
192 if(!pModule)
193 return;
194
195 std::vector<QString> lModuleMatches;
196
197 pModule->completeFunction(szCommandBegin, lModuleMatches);
198 for(auto & pszModuleMatch : lModuleMatches)
199 {
200 pszModuleMatch.prepend(".");
201 pszModuleMatch.prepend(szModuleName);
202 pszModuleMatch.prepend("$");
203 pMatches.push_back(std::move(pszModuleMatch));
204 }
205 }
206
getAllFunctionsCommandsCore(QStringList * list)207 void KviKvsKernel::getAllFunctionsCommandsCore(QStringList * list)
208 {
209 KviPointerHashTableIterator<QString, KviKvsCoreFunctionExecRoutine> it(*m_pCoreFunctionExecRoutineDict);
210 while(it.current())
211 {
212 list->append("$" + it.currentKey());
213 ++it;
214 }
215 KviPointerHashTableIterator<QString, KviKvsCoreSimpleCommandExecRoutine> it2(*m_pCoreSimpleCommandExecRoutineDict);
216 while(it2.current())
217 {
218 list->append(it2.currentKey());
219 ++it2;
220 }
221 }
222