Workaround cannot operate with keyboard when MenuButton has only 1 entry
[TortoiseGit.git] / ext / scintilla / src / ExternalLexer.cxx
blob8ccb34fa354331e26887a47d57abfd789423a79d
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 <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12 #include <ctype.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);
43 //------------------------------------------
45 // LexerLibrary
47 //------------------------------------------
49 LexerLibrary::LexerLibrary(const char *ModuleName) {
50 // Initialise some members...
51 first = NULL;
52 last = NULL;
54 // Load the DLL
55 lib = DynamicLibrary::Load(ModuleName);
56 if (lib->IsValid()) {
57 m_sModuleName = ModuleName;
58 //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects
59 GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount");
61 if (GetLexerCount) {
62 ExternalLexerModule *lex;
63 LexerMinder *lm;
65 // Find functions in the DLL
66 GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
67 GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
69 int nl = GetLexerCount();
71 for (int i = 0; i < nl; i++) {
72 // Assign a buffer for the lexer name.
73 char lexname[100] = "";
74 GetLexerName(i, lexname, sizeof(lexname));
75 lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
76 Catalogue::AddLexerModule(lex);
78 // Create a LexerMinder so we don't leak the ExternalLexerModule...
79 lm = new LexerMinder;
80 lm->self = lex;
81 lm->next = NULL;
82 if (first != NULL) {
83 last->next = lm;
84 last = lm;
85 } else {
86 first = lm;
87 last = lm;
90 // The external lexer needs to know how to call into its DLL to
91 // do its lexing and folding, we tell it here.
92 lex->SetExternal(fnFactory, i);
96 next = NULL;
99 LexerLibrary::~LexerLibrary() {
100 Release();
101 delete lib;
104 void LexerLibrary::Release() {
105 LexerMinder *lm;
106 LexerMinder *lmNext;
107 lm = first;
108 while (NULL != lm) {
109 lmNext = lm->next;
110 delete lm->self;
111 delete lm;
112 lm = lmNext;
115 first = NULL;
116 last = NULL;
119 //------------------------------------------
121 // LexerManager
123 //------------------------------------------
125 /// Return the single LexerManager instance...
126 LexerManager *LexerManager::GetInstance() {
127 if (!theInstance)
128 theInstance = new LexerManager;
129 return theInstance;
132 /// Delete any LexerManager instance...
133 void LexerManager::DeleteInstance() {
134 delete theInstance;
135 theInstance = NULL;
138 /// protected constructor - this is a singleton...
139 LexerManager::LexerManager() {
140 first = NULL;
141 last = NULL;
144 LexerManager::~LexerManager() {
145 Clear();
148 void LexerManager::Load(const char *path) {
149 LoadLexerLibrary(path);
152 void LexerManager::LoadLexerLibrary(const char *module) {
153 for (LexerLibrary *ll = first; ll; ll= ll->next) {
154 if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
155 return;
157 LexerLibrary *lib = new LexerLibrary(module);
158 if (NULL != first) {
159 last->next = lib;
160 last = lib;
161 } else {
162 first = lib;
163 last = lib;
167 void LexerManager::Clear() {
168 if (NULL != first) {
169 LexerLibrary *cur = first;
170 LexerLibrary *next;
171 while (cur) {
172 next = cur->next;
173 delete cur;
174 cur = next;
176 first = NULL;
177 last = NULL;
181 //------------------------------------------
183 // LexerManager
185 //------------------------------------------
187 LMMinder::~LMMinder() {
188 LexerManager::DeleteInstance();
191 LMMinder minder;