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.
19 #include "Scintilla.h"
22 #include "LexerModule.h"
23 #include "Catalogue.h"
24 #include "ExternalLexer.h"
27 using namespace Scintilla
;
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 //------------------------------------------
47 //------------------------------------------
49 LexerLibrary::LexerLibrary(const char *ModuleName
) {
50 // Initialise some members...
55 lib
= DynamicLibrary::Load(ModuleName
);
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");
62 ExternalLexerModule
*lex
;
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 int nl
= GetLexerCount();
71 for (int i
= 0; i
< nl
; i
++) {
72 // Assign a buffer for the lexer name.
73 char lexname
[100] = "";
74 GetLexerName(i
, lexname
, sizeof(lexname
));
75 lex
= new ExternalLexerModule(SCLEX_AUTOMATIC
, NULL
, lexname
, NULL
);
76 Catalogue::AddLexerModule(lex
);
78 // Create a LexerMinder so we don't leak the ExternalLexerModule...
90 // The external lexer needs to know how to call into its DLL to
91 // do its lexing and folding, we tell it here.
92 lex
->SetExternal(fnFactory
, i
);
99 LexerLibrary::~LexerLibrary() {
104 void LexerLibrary::Release() {
119 //------------------------------------------
123 //------------------------------------------
125 /// Return the single LexerManager instance...
126 LexerManager
*LexerManager::GetInstance() {
128 theInstance
= new LexerManager
;
132 /// Delete any LexerManager instance...
133 void LexerManager::DeleteInstance() {
138 /// protected constructor - this is a singleton...
139 LexerManager::LexerManager() {
144 LexerManager::~LexerManager() {
148 void LexerManager::Load(const char *path
) {
149 LoadLexerLibrary(path
);
152 void LexerManager::LoadLexerLibrary(const char *module
) {
153 for (LexerLibrary
*ll
= first
; ll
; ll
= ll
->next
) {
154 if (strcmp(ll
->m_sModuleName
.c_str(), module
) == 0)
157 LexerLibrary
*lib
= new LexerLibrary(module
);
167 void LexerManager::Clear() {
169 LexerLibrary
*cur
= first
;
181 //------------------------------------------
185 //------------------------------------------
187 LMMinder::~LMMinder() {
188 LexerManager::DeleteInstance();