Merge pull request #1404 from b4n/search/gtk-3-20-history
[geany-mirror.git] / scintilla / src / ExternalLexer.cxx
blob2f81df7e02da4f40d9964ede19a69775ea046dbb
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 <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12 #include <ctype.h>
14 #include <stdexcept>
15 #include <string>
17 #include "Platform.h"
19 #include "ILexer.h"
20 #include "Scintilla.h"
21 #include "SciLexer.h"
23 #include "LexerModule.h"
24 #include "Catalogue.h"
25 #include "ExternalLexer.h"
27 #ifdef SCI_NAMESPACE
28 using namespace Scintilla;
29 #endif
31 LexerManager *LexerManager::theInstance = NULL;
33 //------------------------------------------
35 // ExternalLexerModule
37 //------------------------------------------
39 void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
40 fneFactory = fFactory;
41 fnFactory = fFactory(index);
44 //------------------------------------------
46 // LexerLibrary
48 //------------------------------------------
50 LexerLibrary::LexerLibrary(const char *ModuleName) {
51 // Initialise some members...
52 first = NULL;
53 last = NULL;
55 // Load the DLL
56 lib = DynamicLibrary::Load(ModuleName);
57 if (lib->IsValid()) {
58 m_sModuleName = ModuleName;
59 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
60 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
62 if (GetLexerCount) {
63 ExternalLexerModule *lex;
64 LexerMinder *lm;
66 // Find functions in the DLL
67 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
68 GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
70 int nl = GetLexerCount();
72 for (int i = 0; i < nl; i++) {
73 // Assign a buffer for the lexer name.
74 char lexname[100] = "";
75 GetLexerName(i, lexname, sizeof(lexname));
76 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
77 Catalogue::AddLexerModule(lex);
79 // Create a LexerMinder so we don't leak the ExternalLexerModule...
80 lm = new LexerMinder;
81 lm->self = lex;
82 lm->next = NULL;
83 if (first != NULL) {
84 last->next = lm;
85 last = lm;
86 } else {
87 first = lm;
88 last = lm;
91 // The external lexer needs to know how to call into its DLL to
92 // do its lexing and folding, we tell it here.
93 lex->SetExternal(fnFactory, i);
97 next = NULL;
100 LexerLibrary::~LexerLibrary() {
101 Release();
102 delete lib;
105 void LexerLibrary::Release() {
106 LexerMinder *lm;
107 LexerMinder *lmNext;
108 lm = first;
109 while (NULL != lm) {
110 lmNext = lm->next;
111 delete lm->self;
112 delete lm;
113 lm = lmNext;
116 first = NULL;
117 last = NULL;
120 //------------------------------------------
122 // LexerManager
124 //------------------------------------------
126 /// Return the single LexerManager instance...
127 LexerManager *LexerManager::GetInstance() {
128 if (!theInstance)
129 theInstance = new LexerManager;
130 return theInstance;
133 /// Delete any LexerManager instance...
134 void LexerManager::DeleteInstance() {
135 delete theInstance;
136 theInstance = NULL;
139 /// protected constructor - this is a singleton...
140 LexerManager::LexerManager() {
141 first = NULL;
142 last = NULL;
145 LexerManager::~LexerManager() {
146 Clear();
149 void LexerManager::Load(const char *path) {
150 LoadLexerLibrary(path);
153 void LexerManager::LoadLexerLibrary(const char *module) {
154 for (LexerLibrary *ll = first; ll; ll= ll->next) {
155 if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
156 return;
158 LexerLibrary *lib = new LexerLibrary(module);
159 if (NULL != first) {
160 last->next = lib;
161 last = lib;
162 } else {
163 first = lib;
164 last = lib;
168 void LexerManager::Clear() {
169 if (NULL != first) {
170 LexerLibrary *cur = first;
171 LexerLibrary *next;
172 while (cur) {
173 next = cur->next;
174 delete cur;
175 cur = next;
177 first = NULL;
178 last = NULL;
182 //------------------------------------------
184 // LexerManager
186 //------------------------------------------
188 LMMinder::~LMMinder() {
189 LexerManager::DeleteInstance();
192 LMMinder minder;