1 // Scintilla source code edit control
2 /** @file ExternalLexer.cxx
3 ** Support external lexers in DLLs.
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.
20 #include "Scintilla.h"
23 #include "LexerModule.h"
24 #include "Catalogue.h"
25 #include "ExternalLexer.h"
28 using namespace Scintilla
;
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 //------------------------------------------
48 //------------------------------------------
50 LexerLibrary::LexerLibrary(const char *ModuleName
) {
51 // Initialise some members...
56 lib
= DynamicLibrary::Load(ModuleName
);
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");
63 ExternalLexerModule
*lex
;
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...
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
);
100 LexerLibrary::~LexerLibrary() {
105 void LexerLibrary::Release() {
120 //------------------------------------------
124 //------------------------------------------
126 /// Return the single LexerManager instance...
127 LexerManager
*LexerManager::GetInstance() {
129 theInstance
= new LexerManager
;
133 /// Delete any LexerManager instance...
134 void LexerManager::DeleteInstance() {
139 /// protected constructor - this is a singleton...
140 LexerManager::LexerManager() {
145 LexerManager::~LexerManager() {
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)
158 LexerLibrary
*lib
= new LexerLibrary(module
);
168 void LexerManager::Clear() {
170 LexerLibrary
*cur
= first
;
182 //------------------------------------------
186 //------------------------------------------
188 LMMinder::~LMMinder() {
189 LexerManager::DeleteInstance();