Add an UI to enable/disable specific overlay handlers.
[TortoiseGit.git] / ext / scintilla / src / ExternalLexer.cxx
blob086b544780e2f28b05f86af252443d6482ef6687
1 // Scintilla source code edit control
2 /** @file ExternalLexer.cxx
3 ** Support external lexers in DLLs.
4 **/
5 // Copyright 2001 Simon Steele <ss@pnotepad.org>, portions copyright Neil Hodgson.
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <ctype.h>
13 #include "Platform.h"
15 #include "Scintilla.h"
17 #include "SciLexer.h"
18 #include "PropSet.h"
19 #include "Accessor.h"
20 #include "DocumentAccessor.h"
21 #include "KeyWords.h"
22 #include "ExternalLexer.h"
24 #ifdef SCI_NAMESPACE
25 using namespace Scintilla;
26 #endif
28 LexerManager *LexerManager::theInstance = NULL;
30 //------------------------------------------
32 // ExternalLexerModule
34 //------------------------------------------
36 char **WordListsToStrings(WordList *val[]) {
37 int dim = 0;
38 while (val[dim])
39 dim++;
40 char **wls = new char * [dim + 1];
41 for (int i = 0;i < dim;i++) {
42 SString words;
43 words = "";
44 for (int n = 0; n < val[i]->len; n++) {
45 words += val[i]->words[n];
46 if (n != val[i]->len - 1)
47 words += " ";
49 wls[i] = new char[words.length() + 1];
50 strcpy(wls[i], words.c_str());
52 wls[dim] = 0;
53 return wls;
56 void DeleteWLStrings(char *strs[]) {
57 int dim = 0;
58 while (strs[dim]) {
59 delete strs[dim];
60 dim++;
62 delete [] strs;
65 void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
66 WordList *keywordlists[], Accessor &styler) const {
67 if (!fneLexer)
68 return ;
70 char **kwds = WordListsToStrings(keywordlists);
71 char *ps = styler.GetProperties();
73 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
74 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
75 DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
76 WindowID wID = da.GetWindow();
78 fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
80 delete ps;
81 DeleteWLStrings(kwds);
84 void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
85 WordList *keywordlists[], Accessor &styler) const {
86 if (!fneFolder)
87 return ;
89 char **kwds = WordListsToStrings(keywordlists);
90 char *ps = styler.GetProperties();
92 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
93 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
94 DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
95 WindowID wID = da.GetWindow();
97 fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
99 delete ps;
100 DeleteWLStrings(kwds);
103 void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
104 fneLexer = fLexer;
105 fneFolder = fFolder;
106 externalLanguage = index;
109 //------------------------------------------
111 // LexerLibrary
113 //------------------------------------------
115 LexerLibrary::LexerLibrary(const char* ModuleName) {
116 // Initialise some members...
117 first = NULL;
118 last = NULL;
120 // Load the DLL
121 lib = DynamicLibrary::Load(ModuleName);
122 if (lib->IsValid()) {
123 m_sModuleName = ModuleName;
124 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
125 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
127 if (GetLexerCount) {
128 ExternalLexerModule *lex;
129 LexerMinder *lm;
131 // Find functions in the DLL
132 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
133 ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
134 ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
136 // Assign a buffer for the lexer name.
137 char lexname[100];
138 strcpy(lexname, "");
140 int nl = GetLexerCount();
142 for (int i = 0; i < nl; i++) {
143 GetLexerName(i, lexname, 100);
144 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
146 // Create a LexerMinder so we don't leak the ExternalLexerModule...
147 lm = new LexerMinder;
148 lm->self = lex;
149 lm->next = NULL;
150 if (first != NULL) {
151 last->next = lm;
152 last = lm;
153 } else {
154 first = lm;
155 last = lm;
158 // The external lexer needs to know how to call into its DLL to
159 // do its lexing and folding, we tell it here. Folder may be null.
160 lex->SetExternal(Lexer, Folder, i);
164 next = NULL;
167 LexerLibrary::~LexerLibrary() {
168 Release();
169 delete lib;
172 void LexerLibrary::Release() {
173 //TODO maintain a list of lexers created, and delete them!
174 LexerMinder *lm;
175 LexerMinder *lmNext;
176 lm = first;
177 while (NULL != lm) {
178 lmNext = lm->next;
179 delete lm->self;
180 delete lm;
181 lm = lmNext;
184 first = NULL;
185 last = NULL;
188 //------------------------------------------
190 // LexerManager
192 //------------------------------------------
194 /// Return the single LexerManager instance...
195 LexerManager *LexerManager::GetInstance() {
196 if(!theInstance)
197 theInstance = new LexerManager;
198 return theInstance;
201 /// Delete any LexerManager instance...
202 void LexerManager::DeleteInstance()
204 if(theInstance) {
205 delete theInstance;
206 theInstance = NULL;
210 /// protected constructor - this is a singleton...
211 LexerManager::LexerManager() {
212 first = NULL;
213 last = NULL;
216 LexerManager::~LexerManager() {
217 Clear();
220 void LexerManager::Load(const char* path)
222 LoadLexerLibrary(path);
225 void LexerManager::LoadLexerLibrary(const char* module)
227 LexerLibrary *lib = new LexerLibrary(module);
228 if (NULL != first) {
229 last->next = lib;
230 last = lib;
231 } else {
232 first = lib;
233 last = lib;
237 void LexerManager::Clear()
239 if (NULL != first) {
240 LexerLibrary *cur = first;
241 LexerLibrary *next;
242 while (cur) {
243 next = cur->next;
244 delete cur;
245 cur = next;
247 first = NULL;
248 last = NULL;
252 //------------------------------------------
254 // LexerManager
256 //------------------------------------------
258 LMMinder::~LMMinder()
260 LexerManager::DeleteInstance();
263 LMMinder minder;