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.
15 #include "Scintilla.h"
20 #include "DocumentAccessor.h"
22 #include "ExternalLexer.h"
25 using namespace Scintilla
;
28 LexerManager
*LexerManager::theInstance
= NULL
;
30 //------------------------------------------
32 // ExternalLexerModule
34 //------------------------------------------
36 char **WordListsToStrings(WordList
*val
[]) {
40 char **wls
= new char * [dim
+ 1];
41 for (int i
= 0;i
< dim
;i
++) {
44 for (int n
= 0; n
< val
[i
]->len
; n
++) {
45 words
+= val
[i
]->words
[n
];
46 if (n
!= val
[i
]->len
- 1)
49 wls
[i
] = new char[words
.length() + 1];
50 strcpy(wls
[i
], words
.c_str());
56 void DeleteWLStrings(char *strs
[]) {
65 void ExternalLexerModule::Lex(unsigned int startPos
, int lengthDoc
, int initStyle
,
66 WordList
*keywordlists
[], Accessor
&styler
) const {
70 char **kwds
= WordListsToStrings(keywordlists
);
71 char *ps
= styler
.GetProperties();
73 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
74 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
75 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
76 WindowID wID
= da
.GetWindow();
78 fneLexer(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
81 DeleteWLStrings(kwds
);
84 void ExternalLexerModule::Fold(unsigned int startPos
, int lengthDoc
, int initStyle
,
85 WordList
*keywordlists
[], Accessor
&styler
) const {
89 char **kwds
= WordListsToStrings(keywordlists
);
90 char *ps
= styler
.GetProperties();
92 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
93 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
94 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
95 WindowID wID
= da
.GetWindow();
97 fneFolder(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
100 DeleteWLStrings(kwds
);
103 void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer
, ExtFoldFunction fFolder
, int index
) {
106 externalLanguage
= index
;
109 //------------------------------------------
113 //------------------------------------------
115 LexerLibrary::LexerLibrary(const char* ModuleName
) {
116 // Initialise some members...
121 lib
= DynamicLibrary::Load(ModuleName
);
122 if (lib
->IsValid()) {
123 m_sModuleName
= ModuleName
;
124 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
125 GetLexerCountFn GetLexerCount
= (GetLexerCountFn
)(sptr_t
)lib
->FindFunction("GetLexerCount");
128 ExternalLexerModule
*lex
;
131 // Find functions in the DLL
132 GetLexerNameFn GetLexerName
= (GetLexerNameFn
)(sptr_t
)lib
->FindFunction("GetLexerName");
133 ExtLexerFunction Lexer
= (ExtLexerFunction
)(sptr_t
)lib
->FindFunction("Lex");
134 ExtFoldFunction Folder
= (ExtFoldFunction
)(sptr_t
)lib
->FindFunction("Fold");
136 // Assign a buffer for the lexer name.
140 int nl
= GetLexerCount();
142 for (int i
= 0; i
< nl
; i
++) {
143 GetLexerName(i
, lexname
, 100);
144 lex
= new ExternalLexerModule(SCLEX_AUTOMATIC
, NULL
, lexname
, NULL
);
146 // Create a LexerMinder so we don't leak the ExternalLexerModule...
147 lm
= new LexerMinder
;
158 // The external lexer needs to know how to call into its DLL to
159 // do its lexing and folding, we tell it here. Folder may be null.
160 lex
->SetExternal(Lexer
, Folder
, i
);
167 LexerLibrary::~LexerLibrary() {
172 void LexerLibrary::Release() {
173 //TODO maintain a list of lexers created, and delete them!
188 //------------------------------------------
192 //------------------------------------------
194 /// Return the single LexerManager instance...
195 LexerManager
*LexerManager::GetInstance() {
197 theInstance
= new LexerManager
;
201 /// Delete any LexerManager instance...
202 void LexerManager::DeleteInstance()
210 /// protected constructor - this is a singleton...
211 LexerManager::LexerManager() {
216 LexerManager::~LexerManager() {
220 void LexerManager::Load(const char* path
)
222 LoadLexerLibrary(path
);
225 void LexerManager::LoadLexerLibrary(const char* module)
227 LexerLibrary
*lib
= new LexerLibrary(module);
237 void LexerManager::Clear()
240 LexerLibrary
*cur
= first
;
252 //------------------------------------------
256 //------------------------------------------
258 LMMinder::~LMMinder()
260 LexerManager::DeleteInstance();