1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        MadEdit/MadSyntax.h
3 // Description: syntax parsing and syntax file management
4 // Author:      madedit@gmail.com
5 // Licence:     GPL
6 ///////////////////////////////////////////////////////////////////////////////
7 
8 #ifndef _MADSYNTAX_H_
9 #define _MADSYNTAX_H_
10 
11 #include <wx/wxprec.h>
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 // Include your minimal set of headers here, or wx.h
19 #include <wx/wx.h>
20 #endif
21 
22 #include <wx/hashset.h>
23 #include <wx/colour.h>
24 #include <wx/string.h>
25 
26 #include <vector>
27 using std::vector;
28 
29 #include "ucs4_t.h"
30 #include "MadLines.h"
31 
32 
33 WX_DECLARE_HASH_SET( wxString, wxStringHash, wxStringEqual, MadKeywordSet );
34 
35 
36 enum MadFontStyle { fsNone=0, fsBold=1, fsItalic=2, fsUnderline=4, fsStrikeOut=8 };
37 typedef int MadFontStyles;
38 
39 struct MadAttributes    // font attributes
40 {
41     wxColour color;        // text color
42     wxColour bgcolor;      // background color
43     MadFontStyles style;   // style
MadAttributesMadAttributes44     MadAttributes():color(wxNullColour),bgcolor(wxNullColour),style(fsNone)
45     {}
46 };
47 
48 struct MadSyntaxRange
49 {
50     unsigned long id;
51     wxString begin;
52     wxString end;
53     wxColour bgcolor;
MadSyntaxRangeMadSyntaxRange54     MadSyntaxRange():id(0),bgcolor(wxNullColour)
55     {}
56 };
57 
58 struct MadSyntaxKeyword
59 {
60     wxString m_Name;
61     MadAttributes m_Attr;
62     vector < int > m_InRange;
63     MadKeywordSet m_Keywords;
64     bool m_CaseSensitive;
65 
MadSyntaxKeywordMadSyntaxKeyword66     MadSyntaxKeyword() : m_CaseSensitive(false)
67     {}
68 };
69 
70 enum MadAttributeElement
71 {
72     aeText, aeDelimiter, aeSpace, aeNumber, aeString, aeComment, aeDirective,
73     aeSpecialWord, aeLineNumber, aeActiveLine, aeBookmark, aeNone
74 };
75 
76 struct MadState
77 {
78     wxByte rangeid;
79     wxByte blkcmtid;
80     wxByte linecmt;
81     wxByte stringid;
82     wxByte directive;
ResetMadState83     void Reset()
84     {
85         rangeid=blkcmtid=stringid=linecmt=directive=0;
86     }
87 };
88 
89 
90 class MadEdit;
91 class MadEncoding;
92 class wxFileConfig;
93 
94 class MadSyntax
95 {
96 private: // syntax files manager
97     static wxString s_AttributeFilePath;
98     static bool s_Loaded;
99     static void LoadSyntaxFiles();
100 public:
SetAttributeFilePath(const wxString & path)101     static void SetAttributeFilePath(const wxString &path) // where to load/save .clr files
102     {
103         s_AttributeFilePath=path;
104     }
105     static void AddSyntaxFilesPath(const wxString &path);
106     static size_t GetSyntaxCount();
107     static wxString GetSyntaxTitle(size_t index); //index must < GetSyntaxCount()
108     static wxString GetSyntaxFile(size_t index); //index must < GetSyntaxCount()
109     static wxString GetSyntaxFileByTitle(const wxString &title);
110     static wxString GetAttributeFileByTitle(const wxString &title);
111 
112     // if title was not found it will return a default MadSyntax obj
113     static MadSyntax* GetSyntaxByTitle(const wxString &title);
114 
115     // below functions will return NULL if not found
116     static MadSyntax* GetSyntaxByExt(const wxString &ext);
117     static MadSyntax* GetSyntaxByFirstLine(wxByte *data, int size);
118     static MadSyntax* GetSyntaxByFileName(const wxString &filename);
119 
120     // .sch files management functions
121     static size_t GetSchemeCount();
122     static wxString GetSchemeName(size_t index);
123     static wxString GetSchemeFileByName(const wxString &schname, MadSyntax *default_syn, bool &star);
124     static bool LoadScheme(const wxString &schname, MadSyntax *syn); // apply scheme to syn
125     static bool SaveScheme(const wxString &schname, MadSyntax *syn); // save scheme from syn
126     static bool DeleteScheme(const wxString &schname);
127 
128 private:
129     friend class MadEdit;
130     friend class MadLines;
131     MadAttributes m_SystemAttributes[aeNone];
132 
133     void  ParseSyntax(const wxString &filename);
134     MadAttributes *GetAttributes(const wxString &name);
135     MadSyntaxKeyword *GetCustomKeyword(const wxString &name);
136 
137     void  SetColor(const wxString &value, wxColour &c);
138     void  SetStyle(const wxString &value, MadFontStyles &fs);
139     void  SetInRange(const wxString &value, vector < int > &ir);
140 
141 public:
142     wxString            m_Title;
143     bool                m_CaseSensitive;
144     wxString            m_Delimiter;
145     vector < wxString > m_LineComment;
146     vector < wxString > m_BlockCommentOn;
147     vector < wxString > m_BlockCommentOff;
148     wxString            m_EscapeChar;
149     wxString            m_StringChar;
150     wxString            m_DirectiveLeading;
151     wxString            m_KeywordPrefix;
152     wxString            m_SpecialWordPrefix;
153     wxString            m_IndentChar;
154     wxString            m_UnindentChar;
155     vector < wxString > m_LeftBrace;
156     vector < wxString > m_RightBrace;
157     wxString            m_AutoCompleteLeftChar;
158     wxString            m_AutoCompleteRightChar;
159     wxString            m_Encoding;
160 
161     vector < int >      m_StringInRange;
162     vector < int >      m_LineCommentInRange;
163     vector < std::vector < int > >m_BlockCommentInRange;
164 
165     bool                m_LineCommentAtBOL; // for diff/patch syntax
166     bool                m_DirectiveLeadingAtBOL;
167 
168     vector < MadSyntaxRange > m_CustomRange; // user defined ranges
169     vector < wxString >       m_RangeBeginString;
170 
171     vector < MadSyntaxKeyword > m_CustomKeyword; // user defined keywords
172 
173     bool m_CheckState;
174 
175 public:
176     MadSyntax(const wxString &filename, bool loadAttr = true);
177     MadSyntax(bool loadAttr = true);
178     ~MadSyntax();
179 
180     void LoadFromFile(const wxString &filename);
181     void Reset();
182     void LoadAttributes(const wxString &file = wxEmptyString); // if file IsEmpty, load from default .att file
183     void SaveAttributes(const wxString &file = wxEmptyString); // if file IsEmpty, save to default .att file
184     void AssignAttributes(MadSyntax *syn, bool add = false); // assign attributes from syn
185 
186     bool IsInRange(int range, vector < int >&InRangeVector);
187     MadSyntaxRange *GetSyntaxRange(int rangeid);
188 
GetAttributes(MadAttributeElement ae)189     MadAttributes *GetAttributes(MadAttributeElement ae)
190     {
191         return m_SystemAttributes + ae;
192     }
193     static wxString GetAttributeName(MadAttributeElement ae);
194 
IsSpace(ucs4_t uc)195     bool IsSpace(ucs4_t uc)
196     {
197         return (uc == 0x20 || (uc <= 0x0D && uc >= 0x09));
198     }
199 
IsDelimiter(ucs4_t uc)200     bool IsDelimiter(ucs4_t uc)
201     {
202         return (uc < 0x100 && m_Delimiter.Find(wxChar(uc))>=0);
203     }
IsNotDelimiter(ucs4_t uc)204     bool IsNotDelimiter(ucs4_t uc)
205     {
206         return (uc < 0x100 && m_Delimiter.Find(wxChar(uc))<0 && !IsSpace(uc));
207     }
208 
SetAttributes(MadAttributeElement ae)209     void SetAttributes(MadAttributeElement ae)
210     {
211         SetAttributes(m_SystemAttributes+ae);
212     }
213     void SetAttributes(MadAttributes *attr);
214 
215 private: // for NextWord()
216     MadLines    *nw_MadLines;
217     MadEdit     *nw_MadEdit;
218     MadEncoding *nw_Encoding;
219     ucs4_t      *nw_Word;
220     int         *nw_Widths;
221     wxString    nw_FontName;
222     int         nw_FontSize;
223     int         nw_FontFamily;
224 
225     size_t      nw_MaxKeywordLen;
226 
227     MadState nw_State, nw_NextState;
228 
229     size_t nw_NotSpaceCount;
230     bool nw_ContainCommentOff;
231     bool nw_CommentUntilEOL;
232     bool nw_BeginOfLine;
233 
234     MadSyntaxRange *nw_SynRange;
235 
236     ucs4_t nw_StringChar, nw_EscapeChar;
237 
238     MadLineIterator nw_LineIter;
239     MadRowIndexIterator nw_RowIndexIter;
240 
241     int nw_LineWidth;
242     size_t nw_FirstIndex;
243     size_t nw_RestCount;
244     size_t nw_MaxLength;
245     MadUCQueue nw_ucqueue;
246 
247     bool nw_EndOfLine;
248     wxColor nw_Color, nw_BgColor, nw_CurrentBgColor;
249     wxFont *nw_Font;
250 
251     int FindStringCase(MadUCQueue & ucqueue, size_t first,
252                    MadStringIterator begin, const MadStringIterator & end,
253                    size_t & len);
254     int FindStringNoCase(MadUCQueue & ucqueue, size_t first,
255                    MadStringIterator begin, const MadStringIterator & end,
256                    size_t & len);
257 
258     typedef int (MadSyntax::*FindStringPtr)(MadUCQueue & ucqueue, size_t first,
259                    MadStringIterator begin, const MadStringIterator & end,
260                    size_t & len);
261     FindStringPtr FindString;
262 
263 public:
264     void InitNextWord1(MadLines *madlines, ucs4_t *word, int *widths, const wxString &fontname, int fontsize, int fontfamily);
265     void InitNextWord2(MadLineIterator &lit, size_t row);
266     void SetEncoding(MadEncoding *encoding);
267 
268     // return wordlength
269     int NextWord(int &wordwidth);
270 
271 private: // for Printing
272     bool m_PrintSyntax;
273     MadAttributes m_old_SystemAttributes[aeNone];
274     vector < wxColour > m_CustomRangeBgColor;
275     vector < MadAttributes > m_CustomKeywordColor;
276     void BeginPrint(bool printSyntax);
277     void EndPrint();
278 
279 };
280 
281 extern const wxString MadPlainTextTitle;
282 
283 #endif
284