1 /* c_hilit.cpp
2 *
3 * Copyright (c) 1994-1996, Marko Macek
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
10 #include "o_buflist.h"
11
12 #ifdef CONFIG_SYNTAX_HILIT
13
14 #include "sysdep.h"
15
16 #include <stdio.h>
17
18 static const struct {
19 const char Name[8];
20 int Num;
21 SyntaxProc Proc;
22 } HilitModes[] = {
23 { "PLAIN", HILIT_PLAIN, Hilit_Plain },
24 #ifdef CONFIG_HILIT_C
25 { "C", HILIT_C, Hilit_C },
26 #endif
27 #ifdef CONFIG_HILIT_REXX
28 { "REXX", HILIT_REXX, Hilit_REXX },
29 #endif
30 #ifdef CONFIG_HILIT_PERL
31 { "PERL", HILIT_PERL, Hilit_PERL },
32 #endif
33 #ifdef CONFIG_HILIT_MAKE
34 { "MAKE", HILIT_MAKE, Hilit_MAKE },
35 #endif
36 #ifdef CONFIG_HILIT_IPF
37 { "IPF", HILIT_IPF, Hilit_IPF },
38 #endif
39 #ifdef CONFIG_HILIT_ADA
40 { "Ada", HILIT_ADA, Hilit_ADA },
41 #endif
42 #ifdef CONFIG_HILIT_MSG
43 { "MSG", HILIT_MSG, Hilit_MSG },
44 #endif
45 #ifdef CONFIG_HILIT_SH
46 { "SH", HILIT_SH, Hilit_SH },
47 #endif
48 #ifdef CONFIG_HILIT_PASCAL
49 { "PASCAL", HILIT_PASCAL, Hilit_PASCAL },
50 #endif
51 #ifdef CONFIG_HILIT_TEX
52 { "TEX", HILIT_TEX, Hilit_TEX },
53 #endif
54 #ifdef CONFIG_HILIT_FTE
55 { "FTE", HILIT_FTE, Hilit_FTE },
56 #endif
57 #ifdef CONFIG_HILIT_CATBS
58 { "CATBS", HILIT_CATBS, Hilit_CATBS },
59 #endif
60 #ifdef CONFIG_HILIT_SIMPLE
61 { "SIMPLE", HILIT_SIMPLE, Hilit_SIMPLE },
62 #endif
63 };
64
65 static const struct {
66 const char Name[8];
67 int Num;
68 } IndentModes[] = {
69 #ifdef CONFIG_INDENT_C
70 { "C", INDENT_C },
71 #endif
72 #ifdef CONFIG_INDENT_REXX
73 { "REXX", INDENT_REXX },
74 #endif
75 #ifdef CONFIG_INDENT_SIMPLE
76 { "SIMPLE", INDENT_REXX },
77 #endif
78 { "PLAIN", INDENT_PLAIN },
79 };
80
81 EColorize *Colorizers = 0;
82
GetIndentMode(const char * Str)83 int GetIndentMode(const char *Str) {
84 for (size_t i = 0; i < FTE_ARRAY_SIZE(IndentModes); ++i)
85 if (strcmp(Str, IndentModes[i].Name) == 0)
86 return IndentModes[i].Num;
87 return 0;
88 }
89
GetHilitMode(const char * Str)90 int GetHilitMode(const char *Str) {
91 for (size_t i = 0; i < FTE_ARRAY_SIZE(HilitModes); ++i)
92 if (strcmp(Str, HilitModes[i].Name) == 0)
93 return HilitModes[i].Num;
94 return HILIT_PLAIN;
95 }
96
GetHilitProc(int id)97 SyntaxProc GetHilitProc(int id) {
98 for (size_t i = 0; i < FTE_ARRAY_SIZE(HilitModes); ++i)
99 if (id == HilitModes[i].Num)
100 return HilitModes[i].Proc;
101 return 0;
102 }
103
104 #ifdef CONFIG_WORD_HILIT
HilitAddWord(const char * Word)105 int EBuffer::HilitAddWord(const char *Word) {
106 if (HilitFindWord(Word) == 1)
107 return 1;
108 WordList.push_back(Word);
109 FullRedraw();
110 return 1;
111 }
112
HilitFindWord(const char * Word)113 int EBuffer::HilitFindWord(const char *Word) {
114 vector_iterate(StlString, WordList, it) {
115 if (BFI(this, BFI_MatchCase) == 1) {
116 if (strcmp(Word, (*it).c_str()) == 0) return 1;
117 } else {
118 if (stricmp(Word, (*it).c_str()) == 0) return 1;
119 }
120 }
121 return 0;
122 }
123
HilitRemoveWord(const char * Word)124 int EBuffer::HilitRemoveWord(const char *Word) {
125 vector_iterate(StlString, WordList, it) {
126 if (BFI(this, BFI_MatchCase) == 1) {
127 if (strcmp(Word, (*it).c_str()) != 0) continue;
128 } else {
129 if (stricmp(Word, (*it).c_str()) != 0) continue;
130 }
131 WordList.erase(it);
132 FullRedraw();
133 return 1;
134 }
135 return 0;
136 }
137
HilitWord()138 int EBuffer::HilitWord() {
139 PELine L = VLine(CP.Row);
140 char s[CK_MAXLEN + 2];
141 int P, len = 0;
142
143 P = CharOffset(L, CP.Col);
144 while ((P > 0) && ((ChClass(L->Chars[P - 1]) == 1) || (L->Chars[P - 1] == '_')))
145 P--;
146 while (len < CK_MAXLEN && P < (int)L->Count && (ChClass(L->Chars[P]) == 1 || L->Chars[P] == '_'))
147 s[len++] = L->Chars[P++];
148 if (len == 0)
149 return 0;
150 s[len] = 0;
151
152 return (HilitFindWord(s)) ? HilitRemoveWord(s) : HilitAddWord(s);
153 }
154 #endif
155
156 /* ======================================================================= */
157
EColorize(const char * AName,const char * AParent)158 EColorize::EColorize(const char *AName, const char *AParent) :
159 Name(AName),
160 Next(Colorizers),
161 Parent(FindColorizer(AParent)),
162 SyntaxParser(HILIT_PLAIN),
163 hm(0)
164 {
165 Colorizers = this;
166 memset(&Keywords, 0, sizeof(Keywords));
167 if (Parent) {
168 SyntaxParser = Parent->SyntaxParser;
169 memcpy(Colors, Parent->Colors, sizeof(Colors));
170 } else
171 memset(Colors, 0, sizeof(Colors));
172 }
173
~EColorize()174 EColorize::~EColorize() {
175 for (int i=0; i<CK_MAXLEN; i++)
176 free(Keywords.key[i]);
177
178 delete hm;
179 }
180
FindColorizer(const char * AName)181 EColorize *FindColorizer(const char *AName) {
182 EColorize *p = Colorizers;
183
184 while (p) {
185 if (p->Name == AName)
186 return p;
187 p = p->Next;
188 }
189 return 0;
190 }
191
SetColor(int idx,const char * Value)192 int EColorize::SetColor(int idx, const char *Value) {
193 unsigned int ColBg, ColFg;
194
195 if (sscanf(Value, "%1X %1X", &ColFg, &ColBg) != 2)
196 return 0;
197
198 if (idx < 0 || idx >= COUNT_CLR)
199 return 0;
200 Colors[idx] = ChColor(ColFg | (ColBg << 4));
201 return 1;
202 }
203
204 /* ======================================================================= */
205
InitTrans()206 void HTrans::InitTrans() {
207 match = 0;
208 matchLen = 0;
209 matchFlags = 0;
210 nextState = 0;
211 color = 0;
212 regexp = 0;
213 }
214
215 /* ======================================================================= */
216
InitState()217 void HState::InitState() {
218 memset((void *)&keywords, 0, sizeof(keywords));
219 firstTrans = 0;
220 transCount = 0;
221 color = 0;
222 wordChars = 0;
223 options = 0;
224 nextKwdMatchedState = -1;
225 nextKwdNotMatchedState = -1;
226 nextKwdNoCharState = -1;
227 }
228
GetHilitWord(ChColor & clr,const char * str,size_t len)229 int HState::GetHilitWord(ChColor &clr, const char *str, size_t len) {
230 char *p;
231
232 if (len >= CK_MAXLEN || !len)
233 return 0;
234
235 p = keywords.key[len];
236 if (options & STATE_NOCASE) {
237 while (p && *p) {
238 if (strnicmp(p, str, len) == 0) {
239 clr = ChColor(COUNT_CLR + ((unsigned char*)p)[len]);
240 return 1;
241 }
242 p += len + 1;
243 }
244 } else {
245 while (p && *p) {
246 if (memcmp(p, str, len) == 0) {
247 clr = ChColor(COUNT_CLR + ((unsigned char*)p)[len]);
248 return 1;
249 }
250 p += len + 1;
251 }
252 }
253 return 0;
254 }
255
256 /* ======================================================================= */
257
HMachine()258 HMachine::HMachine() :
259 stateCount(0),
260 transCount(0),
261 state(0),
262 trans(0)
263 {
264 }
265
~HMachine()266 HMachine::~HMachine() {
267
268 // free states
269 if (state) {
270 while (stateCount--) {
271 for (unsigned i = 0; i < CK_MAXLEN; ++i)
272 free(state[stateCount].keywords.key[i]);
273
274 free(state[stateCount].wordChars);
275 }
276
277 free(state);
278 }
279
280 // free transes
281 if (trans) {
282 while (transCount--) {
283 if (trans[transCount].match) free(trans[transCount].match);
284 if (trans[transCount].regexp) RxFree(trans[transCount].regexp);
285 }
286
287 free(trans);
288 }
289
290 }
291
AddState(HState & aState)292 void HMachine::AddState(HState &aState) {
293 state = (HState *)realloc(state, (stateCount + 1) * sizeof(HState) );
294 assert( state );
295 state[stateCount] = aState;
296 state[stateCount].firstTrans = transCount;
297 stateCount++;
298 }
299
AddTrans(HTrans & aTrans)300 void HMachine::AddTrans(HTrans &aTrans) {
301 assert(stateCount > 0);
302 trans = (HTrans *)realloc(trans, (transCount + 1) * sizeof(HTrans) );
303 assert( trans );
304 state[stateCount - 1].transCount++;
305 trans[transCount] = aTrans;
306 transCount++;
307 }
308
309 #endif // CONFIG_SYNTAX_HILIT
310