updated Scintilla to 2.29
[TortoiseGit.git] / ext / scintilla / src / ExternalLexer.cxx
blobfc818ce566dc37f62abb4d132dc1e7b01603ef4b
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>
12 #include <assert.h>
14 #include <string>
16 #include "Platform.h"
18 #include "ILexer.h"
19 #include "Scintilla.h"
20 #include "SciLexer.h"
22 #include "LexerModule.h"
23 #include "Catalogue.h"
24 #include "ExternalLexer.h"
26 #ifdef SCI_NAMESPACE
27 using namespace Scintilla;
28 #endif
30 LexerManager *LexerManager::theInstance = NULL;
32 //------------------------------------------
34 // ExternalLexerModule
36 //------------------------------------------
38 void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
39 fneFactory = fFactory;
40 fnFactory = fFactory(index);
43 //------------------------------------------
45 // LexerLibrary
47 //------------------------------------------
49 LexerLibrary::LexerLibrary(const char *ModuleName) {
50 // Initialise some members...
51 first = NULL;
52 last = NULL;
54 // Load the DLL
55 lib = DynamicLibrary::Load(ModuleName);
56 if (lib->IsValid()) {
57 m_sModuleName = ModuleName;
58 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
59 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
61 if (GetLexerCount) {
62 ExternalLexerModule *lex;
63 LexerMinder *lm;
65 // Find functions in the DLL
66 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
67 GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
69 // Assign a buffer for the lexer name.
70 char lexname[100];
71 strcpy(lexname, "");
73 int nl = GetLexerCount();
75 for (int i = 0; i < nl; i++) {
76 GetLexerName(i, lexname, 100);
77 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
78 Catalogue::AddLexerModule(lex);
80 // Create a LexerMinder so we don't leak the ExternalLexerModule...
81 lm = new LexerMinder;
82 lm->self = lex;
83 lm->next = NULL;
84 if (first != NULL) {
85 last->next = lm;
86 last = lm;
87 } else {
88 first = lm;
89 last = lm;
92 // The external lexer needs to know how to call into its DLL to
93 // do its lexing and folding, we tell it here.
94 lex->SetExternal(fnFactory, i);
98 next = NULL;
101 LexerLibrary::~LexerLibrary() {
102 Release();
103 delete lib;
106 void LexerLibrary::Release() {
107 LexerMinder *lm;
108 LexerMinder *lmNext;
109 lm = first;
110 while (NULL != lm) {
111 lmNext = lm->next;
112 delete lm->self;
113 delete lm;
114 lm = lmNext;
117 first = NULL;
118 last = NULL;
121 //------------------------------------------
123 // LexerManager
125 //------------------------------------------
127 /// Return the single LexerManager instance...
128 LexerManager *LexerManager::GetInstance() {
129 if (!theInstance)
130 theInstance = new LexerManager;
131 return theInstance;
134 /// Delete any LexerManager instance...
135 void LexerManager::DeleteInstance() {
136 delete theInstance;
137 theInstance = NULL;
140 /// protected constructor - this is a singleton...
141 LexerManager::LexerManager() {
142 first = NULL;
143 last = NULL;
146 LexerManager::~LexerManager() {
147 Clear();
150 void LexerManager::Load(const char *path) {
151 LoadLexerLibrary(path);
154 void LexerManager::LoadLexerLibrary(const char *module) {
155 for (LexerLibrary *ll = first; ll; ll= ll->next) {
156 if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
157 return;
159 LexerLibrary *lib = new LexerLibrary(module);
160 if (NULL != first) {
161 last->next = lib;
162 last = lib;
163 } else {
164 first = lib;
165 last = lib;
169 void LexerManager::Clear() {
170 if (NULL != first) {
171 LexerLibrary *cur = first;
172 LexerLibrary *next;
173 while (cur) {
174 next = cur->next;
175 delete cur;
176 cur = next;
178 first = NULL;
179 last = NULL;
183 //------------------------------------------
185 // LexerManager
187 //------------------------------------------
189 LMMinder::~LMMinder() {
190 LexerManager::DeleteInstance();
193 LMMinder minder;