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"
24 LexerManager
*LexerManager::theInstance
= NULL
;
26 //------------------------------------------
28 // ExternalLexerModule
30 //------------------------------------------
32 char **WordListsToStrings(WordList
*val
[]) {
36 char **wls
= new char * [dim
+ 1];
37 for (int i
= 0;i
< dim
;i
++) {
40 for (int n
= 0; n
< val
[i
]->len
; n
++) {
41 words
+= val
[i
]->words
[n
];
42 if (n
!= val
[i
]->len
- 1)
45 wls
[i
] = new char[words
.length() + 1];
46 strcpy(wls
[i
], words
.c_str());
52 void DeleteWLStrings(char *strs
[]) {
61 void ExternalLexerModule::Lex(unsigned int startPos
, int lengthDoc
, int initStyle
,
62 WordList
*keywordlists
[], Accessor
&styler
) const {
66 char **kwds
= WordListsToStrings(keywordlists
);
67 char *ps
= styler
.GetProperties();
69 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
70 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
71 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
72 WindowID wID
= da
.GetWindow();
74 fneLexer(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
77 DeleteWLStrings(kwds
);
80 void ExternalLexerModule::Fold(unsigned int startPos
, int lengthDoc
, int initStyle
,
81 WordList
*keywordlists
[], Accessor
&styler
) const {
85 char **kwds
= WordListsToStrings(keywordlists
);
86 char *ps
= styler
.GetProperties();
88 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
89 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
90 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
91 WindowID wID
= da
.GetWindow();
93 fneFolder(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
96 DeleteWLStrings(kwds
);
99 void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer
, ExtFoldFunction fFolder
, int index
) {
102 externalLanguage
= index
;
105 //------------------------------------------
109 //------------------------------------------
111 LexerLibrary::LexerLibrary(const char* ModuleName
) {
112 // Initialise some members...
117 lib
= DynamicLibrary::Load(ModuleName
);
118 if (lib
->IsValid()) {
119 m_sModuleName
= ModuleName
;
120 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
121 GetLexerCountFn GetLexerCount
= (GetLexerCountFn
)(sptr_t
)lib
->FindFunction("GetLexerCount");
124 ExternalLexerModule
*lex
;
127 // Find functions in the DLL
128 GetLexerNameFn GetLexerName
= (GetLexerNameFn
)(sptr_t
)lib
->FindFunction("GetLexerName");
129 ExtLexerFunction Lexer
= (ExtLexerFunction
)(sptr_t
)lib
->FindFunction("Lex");
130 ExtFoldFunction Folder
= (ExtFoldFunction
)(sptr_t
)lib
->FindFunction("Fold");
132 // Assign a buffer for the lexer name.
136 int nl
= GetLexerCount();
138 for (int i
= 0; i
< nl
; i
++) {
139 GetLexerName(i
, lexname
, 100);
140 lex
= new ExternalLexerModule(SCLEX_AUTOMATIC
, NULL
, lexname
, NULL
);
142 // Create a LexerMinder so we don't leak the ExternalLexerModule...
143 lm
= new LexerMinder
;
154 // The external lexer needs to know how to call into its DLL to
155 // do its lexing and folding, we tell it here. Folder may be null.
156 lex
->SetExternal(Lexer
, Folder
, i
);
163 LexerLibrary::~LexerLibrary() {
168 void LexerLibrary::Release() {
169 //TODO maintain a list of lexers created, and delete them!
184 //------------------------------------------
188 //------------------------------------------
190 /// Return the single LexerManager instance...
191 LexerManager
*LexerManager::GetInstance() {
193 theInstance
= new LexerManager
;
197 /// Delete any LexerManager instance...
198 void LexerManager::DeleteInstance()
206 /// protected constructor - this is a singleton...
207 LexerManager::LexerManager() {
212 LexerManager::~LexerManager() {
216 void LexerManager::Load(const char* path
)
218 LoadLexerLibrary(path
);
221 void LexerManager::LoadLexerLibrary(const char* module)
223 LexerLibrary
*lib
= new LexerLibrary(module);
233 void LexerManager::Clear()
236 LexerLibrary
*cur
= first
;
248 //------------------------------------------
252 //------------------------------------------
254 LMMinder::~LMMinder()
256 LexerManager::DeleteInstance();