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.
18 #include "DocumentAccessor.h"
20 #include "ExternalLexer.h"
22 LexerManager
*LexerManager::theInstance
= NULL
;
24 //------------------------------------------
26 // ExternalLexerModule
28 //------------------------------------------
30 char **WordListsToStrings(WordList
*val
[]) {
34 char **wls
= new char * [dim
+ 1];
35 for (int i
= 0;i
< dim
;i
++) {
38 for (int n
= 0; n
< val
[i
]->len
; n
++) {
39 words
+= val
[i
]->words
[n
];
40 if (n
!= val
[i
]->len
- 1)
43 wls
[i
] = new char[words
.length() + 1];
44 strcpy(wls
[i
], words
.c_str());
50 void DeleteWLStrings(char *strs
[]) {
59 void ExternalLexerModule::Lex(unsigned int startPos
, int lengthDoc
, int initStyle
,
60 WordList
*keywordlists
[], Accessor
&styler
) const {
64 char **kwds
= WordListsToStrings(keywordlists
);
65 char *ps
= styler
.GetProperties();
67 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
68 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
69 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
70 WindowID wID
= da
.GetWindow();
72 fneLexer(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
75 DeleteWLStrings(kwds
);
78 void ExternalLexerModule::Fold(unsigned int startPos
, int lengthDoc
, int initStyle
,
79 WordList
*keywordlists
[], Accessor
&styler
) const {
83 char **kwds
= WordListsToStrings(keywordlists
);
84 char *ps
= styler
.GetProperties();
86 // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
87 // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
88 DocumentAccessor
&da
= static_cast<DocumentAccessor
&>(styler
);
89 WindowID wID
= da
.GetWindow();
91 fneFolder(externalLanguage
, startPos
, lengthDoc
, initStyle
, kwds
, wID
, ps
);
94 DeleteWLStrings(kwds
);
97 void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer
, ExtFoldFunction fFolder
, int index
) {
100 externalLanguage
= index
;
103 //------------------------------------------
107 //------------------------------------------
109 LexerLibrary::LexerLibrary(const char* ModuleName
) {
110 // Initialise some members...
115 lib
= DynamicLibrary::Load(ModuleName
);
116 if (lib
->IsValid()) {
117 m_sModuleName
= ModuleName
;
118 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
119 GetLexerCountFn GetLexerCount
= (GetLexerCountFn
)lib
->FindFunction("GetLexerCount");
122 ExternalLexerModule
*lex
;
125 // Find functions in the DLL
126 GetLexerNameFn GetLexerName
= (GetLexerNameFn
)lib
->FindFunction("GetLexerName");
127 ExtLexerFunction Lexer
= (ExtLexerFunction
)lib
->FindFunction("Lex");
128 ExtFoldFunction Folder
= (ExtFoldFunction
)lib
->FindFunction("Fold");
130 // Assign a buffer for the lexer name.
134 int nl
= GetLexerCount();
136 for (int i
= 0; i
< nl
; i
++) {
137 GetLexerName(i
, lexname
, 100);
138 lex
= new ExternalLexerModule(SCLEX_AUTOMATIC
, NULL
, lexname
, NULL
);
140 // Create a LexerMinder so we don't leak the ExternalLexerModule...
141 lm
= new LexerMinder
;
152 // The external lexer needs to know how to call into its DLL to
153 // do its lexing and folding, we tell it here. Folder may be null.
154 lex
->SetExternal(Lexer
, Folder
, i
);
161 LexerLibrary::~LexerLibrary() {
166 void LexerLibrary::Release() {
167 //TODO maintain a list of lexers created, and delete them!
182 //------------------------------------------
186 //------------------------------------------
188 /// Return the single LexerManager instance...
189 LexerManager
*LexerManager::GetInstance() {
191 theInstance
= new LexerManager
;
195 /// Delete any LexerManager instance...
196 void LexerManager::DeleteInstance()
204 /// protected constructor - this is a singleton...
205 LexerManager::LexerManager() {
210 LexerManager::~LexerManager() {
214 void LexerManager::Load(const char* path
)
216 LoadLexerLibrary(path
);
219 void LexerManager::LoadLexerLibrary(const char* module)
221 LexerLibrary
*lib
= new LexerLibrary(module);
231 void LexerManager::Clear()
234 LexerLibrary
*cur
= first
;
246 //------------------------------------------
250 //------------------------------------------
252 LMMinder::~LMMinder()
254 LexerManager::DeleteInstance();