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