*** empty log message ***
[anjuta-git-plugin.git] / scintilla / ExternalLexer.cxx
blob752118b7706251c005894feadf34d9ef5120b064
1 // Scintilla source code edit control
2 /** @file ExternalLexer.cxx
3 ** Support external lexers in DLLs.
4 **/
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.
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <ctype.h>
13 #include "Platform.h"
15 #include "SciLexer.h"
16 #include "PropSet.h"
17 #include "Accessor.h"
18 #include "DocumentAccessor.h"
19 #include "KeyWords.h"
20 #include "ExternalLexer.h"
22 LexerManager *LexerManager::theInstance = NULL;
24 //------------------------------------------
26 // ExternalLexerModule
28 //------------------------------------------
30 char **WordListsToStrings(WordList *val[]) {
31 int dim = 0;
32 while (val[dim])
33 dim++;
34 char **wls = new char * [dim + 1];
35 for (int i = 0;i < dim;i++) {
36 SString words;
37 words = "";
38 for (int n = 0; n < val[i]->len; n++) {
39 words += val[i]->words[n];
40 if (n != val[i]->len - 1)
41 words += " ";
43 wls[i] = new char[words.length() + 1];
44 strcpy(wls[i], words.c_str());
46 wls[dim] = 0;
47 return wls;
50 void DeleteWLStrings(char *strs[]) {
51 int dim = 0;
52 while (strs[dim]) {
53 delete strs[dim];
54 dim++;
56 delete [] strs;
59 void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
60 WordList *keywordlists[], Accessor &styler) const {
61 if (!fneLexer)
62 return ;
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);
74 delete ps;
75 DeleteWLStrings(kwds);
78 void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
79 WordList *keywordlists[], Accessor &styler) const {
80 if (!fneFolder)
81 return ;
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);
93 delete ps;
94 DeleteWLStrings(kwds);
97 void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
98 fneLexer = fLexer;
99 fneFolder = fFolder;
100 externalLanguage = index;
103 //------------------------------------------
105 // LexerLibrary
107 //------------------------------------------
109 LexerLibrary::LexerLibrary(const char* ModuleName) {
110 // Initialise some members...
111 first = NULL;
112 last = NULL;
114 // Load the DLL
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");
121 if (GetLexerCount) {
122 ExternalLexerModule *lex;
123 LexerMinder *lm;
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.
131 char lexname[100];
132 strcpy(lexname, "");
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;
142 lm->self = lex;
143 lm->next = NULL;
144 if (first != NULL) {
145 last->next = lm;
146 last = lm;
147 } else {
148 first = lm;
149 last = lm;
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);
158 next = NULL;
161 LexerLibrary::~LexerLibrary() {
162 Release();
163 delete lib;
166 void LexerLibrary::Release() {
167 //TODO maintain a list of lexers created, and delete them!
168 LexerMinder *lm;
169 LexerMinder *next;
170 lm = first;
171 while (NULL != lm) {
172 next = lm->next;
173 delete lm->self;
174 delete lm;
175 lm = next;
178 first = NULL;
179 last = NULL;
182 //------------------------------------------
184 // LexerManager
186 //------------------------------------------
188 /// Return the single LexerManager instance...
189 LexerManager *LexerManager::GetInstance() {
190 if(!theInstance)
191 theInstance = new LexerManager;
192 return theInstance;
195 /// Delete any LexerManager instance...
196 void LexerManager::DeleteInstance()
198 if(theInstance) {
199 delete theInstance;
200 theInstance = NULL;
204 /// protected constructor - this is a singleton...
205 LexerManager::LexerManager() {
206 first = NULL;
207 last = NULL;
210 LexerManager::~LexerManager() {
211 Clear();
214 void LexerManager::Load(const char* path)
216 LoadLexerLibrary(path);
219 void LexerManager::LoadLexerLibrary(const char* module)
221 LexerLibrary *lib = new LexerLibrary(module);
222 if (NULL != first) {
223 last->next = lib;
224 last = lib;
225 } else {
226 first = lib;
227 last = lib;
231 void LexerManager::Clear()
233 if (NULL != first) {
234 LexerLibrary *cur = first;
235 LexerLibrary *next;
236 while (cur) {
237 next = cur->next;
238 delete cur;
239 cur = next;
241 first = NULL;
242 last = NULL;
246 //------------------------------------------
248 // LexerManager
250 //------------------------------------------
252 LMMinder::~LMMinder()
254 LexerManager::DeleteInstance();
257 LMMinder minder;