Move document encoding conversion with BOM support to encodings.[ch]
[geany-mirror.git] / scintilla / src / ExternalLexer.cxx
blob02b7eaa8d8e7e7d16e6fdb57a726cb6591b3739e
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>
12 #include <assert.h>
14 #include <string>
16 #include "Platform.h"
18 #include "ILexer.h"
19 #include "Scintilla.h"
20 #include "SciLexer.h"
22 #include "LexerModule.h"
23 #include "Catalogue.h"
24 #include "ExternalLexer.h"
26 #ifdef SCI_NAMESPACE
27 using namespace Scintilla;
28 #endif
30 LexerManager *LexerManager::theInstance = NULL;
32 //------------------------------------------
34 // ExternalLexerModule
36 //------------------------------------------
38 void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
39 fneFactory = fFactory;
40 fnFactory = fFactory(index);
41 externalLanguage = index;
44 //------------------------------------------
46 // LexerLibrary
48 //------------------------------------------
50 LexerLibrary::LexerLibrary(const char *ModuleName) {
51 // Initialise some members...
52 first = NULL;
53 last = NULL;
55 // Load the DLL
56 lib = DynamicLibrary::Load(ModuleName);
57 if (lib->IsValid()) {
58 m_sModuleName = ModuleName;
59 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
60 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
62 if (GetLexerCount) {
63 ExternalLexerModule *lex;
64 LexerMinder *lm;
66 // Find functions in the DLL
67 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
68 GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
70 // Assign a buffer for the lexer name.
71 char lexname[100];
72 strcpy(lexname, "");
74 int nl = GetLexerCount();
76 for (int i = 0; i < nl; i++) {
77 GetLexerName(i, lexname, 100);
78 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
79 Catalogue::AddLexerModule(lex);
81 // Create a LexerMinder so we don't leak the ExternalLexerModule...
82 lm = new LexerMinder;
83 lm->self = lex;
84 lm->next = NULL;
85 if (first != NULL) {
86 last->next = lm;
87 last = lm;
88 } else {
89 first = lm;
90 last = lm;
93 // The external lexer needs to know how to call into its DLL to
94 // do its lexing and folding, we tell it here.
95 lex->SetExternal(fnFactory, i);
99 next = NULL;
102 LexerLibrary::~LexerLibrary() {
103 Release();
104 delete lib;
107 void LexerLibrary::Release() {
108 LexerMinder *lm;
109 LexerMinder *lmNext;
110 lm = first;
111 while (NULL != lm) {
112 lmNext = lm->next;
113 delete lm->self;
114 delete lm;
115 lm = lmNext;
118 first = NULL;
119 last = NULL;
122 //------------------------------------------
124 // LexerManager
126 //------------------------------------------
128 /// Return the single LexerManager instance...
129 LexerManager *LexerManager::GetInstance() {
130 if (!theInstance)
131 theInstance = new LexerManager;
132 return theInstance;
135 /// Delete any LexerManager instance...
136 void LexerManager::DeleteInstance() {
137 delete theInstance;
138 theInstance = NULL;
141 /// protected constructor - this is a singleton...
142 LexerManager::LexerManager() {
143 first = NULL;
144 last = NULL;
147 LexerManager::~LexerManager() {
148 Clear();
151 void LexerManager::Load(const char *path) {
152 LoadLexerLibrary(path);
155 void LexerManager::LoadLexerLibrary(const char *module) {
156 for (LexerLibrary *ll = first; ll; ll= ll->next) {
157 if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
158 return;
160 LexerLibrary *lib = new LexerLibrary(module);
161 if (NULL != first) {
162 last->next = lib;
163 last = lib;
164 } else {
165 first = lib;
166 last = lib;
170 void LexerManager::Clear() {
171 if (NULL != first) {
172 LexerLibrary *cur = first;
173 LexerLibrary *next;
174 while (cur) {
175 next = cur->next;
176 delete cur;
177 cur = next;
179 first = NULL;
180 last = NULL;
184 //------------------------------------------
186 // LexerManager
188 //------------------------------------------
190 LMMinder::~LMMinder() {
191 LexerManager::DeleteInstance();
194 LMMinder minder;