]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/src/ExternalLexer.cxx
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / stc / scintilla / src / ExternalLexer.cxx
CommitLineData
e14d10b0
RD
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.
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include <ctype.h>
1dcf666d 12#include <assert.h>
e14d10b0 13
9e96e16f
RD
14#include <string>
15
e14d10b0
RD
16#include "Platform.h"
17
1dcf666d 18#include "ILexer.h"
b8193d80 19#include "Scintilla.h"
e14d10b0 20#include "SciLexer.h"
1dcf666d
RD
21
22#include "LexerModule.h"
23#include "Catalogue.h"
e14d10b0
RD
24#include "ExternalLexer.h"
25
7e0c58e9
RD
26#ifdef SCI_NAMESPACE
27using namespace Scintilla;
28#endif
29
e14d10b0
RD
30LexerManager *LexerManager::theInstance = NULL;
31
32//------------------------------------------
33//
34// ExternalLexerModule
35//
36//------------------------------------------
37
1dcf666d
RD
38void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
39 fneFactory = fFactory;
40 fnFactory = fFactory(index);
e14d10b0
RD
41}
42
43//------------------------------------------
44//
45// LexerLibrary
46//
47//------------------------------------------
48
1dcf666d 49LexerLibrary::LexerLibrary(const char *ModuleName) {
e14d10b0
RD
50 // Initialise some members...
51 first = NULL;
52 last = NULL;
53
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
b8193d80 59 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
e14d10b0
RD
60
61 if (GetLexerCount) {
62 ExternalLexerModule *lex;
63 LexerMinder *lm;
64
65 // Find functions in the DLL
b8193d80 66 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
1dcf666d 67 GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
e14d10b0
RD
68
69 // Assign a buffer for the lexer name.
70 char lexname[100];
71 strcpy(lexname, "");
72
73 int nl = GetLexerCount();
74
75 for (int i = 0; i < nl; i++) {
76 GetLexerName(i, lexname, 100);
77 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
1dcf666d 78 Catalogue::AddLexerModule(lex);
e14d10b0
RD
79
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;
90 }
91
92 // The external lexer needs to know how to call into its DLL to
1dcf666d
RD
93 // do its lexing and folding, we tell it here.
94 lex->SetExternal(fnFactory, i);
e14d10b0
RD
95 }
96 }
97 }
98 next = NULL;
99}
100
101LexerLibrary::~LexerLibrary() {
102 Release();
103 delete lib;
104}
105
106void LexerLibrary::Release() {
e14d10b0 107 LexerMinder *lm;
9e96e16f 108 LexerMinder *lmNext;
e14d10b0
RD
109 lm = first;
110 while (NULL != lm) {
9e96e16f 111 lmNext = lm->next;
e14d10b0
RD
112 delete lm->self;
113 delete lm;
9e96e16f 114 lm = lmNext;
e14d10b0
RD
115 }
116
117 first = NULL;
118 last = NULL;
119}
120
121//------------------------------------------
122//
123// LexerManager
124//
125//------------------------------------------
126
127/// Return the single LexerManager instance...
128LexerManager *LexerManager::GetInstance() {
1dcf666d 129 if (!theInstance)
e14d10b0
RD
130 theInstance = new LexerManager;
131 return theInstance;
132}
133
134/// Delete any LexerManager instance...
1dcf666d
RD
135void LexerManager::DeleteInstance() {
136 delete theInstance;
137 theInstance = NULL;
e14d10b0
RD
138}
139
140/// protected constructor - this is a singleton...
141LexerManager::LexerManager() {
142 first = NULL;
143 last = NULL;
144}
145
146LexerManager::~LexerManager() {
147 Clear();
148}
149
1dcf666d 150void LexerManager::Load(const char *path) {
e14d10b0
RD
151 LoadLexerLibrary(path);
152}
153
1dcf666d
RD
154void 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;
158 }
e14d10b0
RD
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;
166 }
167}
168
1dcf666d 169void LexerManager::Clear() {
e14d10b0
RD
170 if (NULL != first) {
171 LexerLibrary *cur = first;
8e54aaed 172 LexerLibrary *next;
e14d10b0 173 while (cur) {
8e54aaed 174 next = cur->next;
e14d10b0
RD
175 delete cur;
176 cur = next;
177 }
178 first = NULL;
179 last = NULL;
180 }
181}
182
183//------------------------------------------
184//
185// LexerManager
186//
187//------------------------------------------
188
1dcf666d 189LMMinder::~LMMinder() {
e14d10b0
RD
190 LexerManager::DeleteInstance();
191}
192
193LMMinder minder;