1 /**
2 * Yudit Unicode Editor Source File
3 *
4 * GNU Copyright (C) 1997-2006 Gaspar Sinai <gaspar@yudit.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2,
8 * dated June 1991. See file COPYYING for details.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "stoolkit/syntax/SPattern.h"
21 #include "stoolkit/SCharClass.h"
22
23 /**
24 * A sample pattern that can be extended. This pattern
25 * now highlights the following:
26 *
27 * 123... number
28 * Yuko keyword
29 * yuko error
30 * YUKO (kanji) define
31 * characters none
32 * other control
33 *
34 * @author Gaspar Sinai
35 * @version 2007-11-27
36 */
SPattern(void)37 SPattern::SPattern (void) :
38 ACT_NONE ("none"),
39 ACT_ERROR ("error"),
40 ACT_NUMBER ("number"),
41 ACT_KEYWORD ("keyword"),
42 ACT_VARIABLE ("variable"),
43 ACT_DEFINE ("define"),
44 ACT_CONTROL ("control"),
45 ACT_OTHER ("other")
46 {
47 clear ();
48 }
49
~SPattern()50 SPattern::~SPattern ()
51 {
52 }
53
54 //
55 void
clear()56 SPattern::clear ()
57 {
58 action = ACT_NONE;
59 matchBegin = SD_MATCH_EOD;
60 matchEnd = 0;
61 next = 0;
62 current.clear ();
63 }
64
65 // This method will be overwritten
66 bool
checkMatch()67 SPattern::checkMatch ()
68 {
69 return checkMatchTest();
70 }
71
72 void
append(SS_UCS4 in)73 SPattern::append (SS_UCS4 in)
74 {
75 if (next == 0) matchEnd = 0;
76 current.append (in);
77 next++;
78 }
79
80 // We all ignore the last character in the buffer,
81 // that is next position, and it is non-inclusive
82 // note that current position is next - 1, and
83 // we dont look at current.
84 bool
checkMatchTest()85 SPattern::checkMatchTest ()
86 {
87 // We are lucky, none of our staring chars are used in the other pattern.
88 if (current.size() >= 3 &&
89 current[current.size()-3] == 0x512A // YUU
90 && current[current.size()-2] == 0x5B50) // KO
91 {
92 if (singleMatchTest (3)) return true;
93 current.remove(0);
94 current.remove(0);
95
96 matchBegin = next-1-2;
97 matchEnd = next-1;
98 action = ACT_DEFINE;
99 return true;
100 }
101 else if (current.size() >= 2
102 && current[current.size()-2] == (SS_UCS4)'\n') // YUU
103 {
104 if (singleMatchTest (2)) return true;
105 current.remove(0);
106 matchBegin = next-1-1;
107 matchEnd = next-1;
108 action = ACT_CONTROL;
109 return true;
110 }
111 else if (current.size() >= 5
112 && current[current.size()-5] == (SS_UCS4)'y'
113 && current[current.size()-4] == (SS_UCS4)'u'
114 && current[current.size()-3] == (SS_UCS4)'k'
115 && current[current.size()-2] == (SS_UCS4)'o')
116 {
117 if (singleMatchTest (5)) return true;
118 current.remove(0);
119 current.remove(0);
120 current.remove(0);
121 current.remove(0);
122 matchBegin = next-1-4;
123 matchEnd = next-1;
124 action = ACT_ERROR;
125 return true;
126 }
127 else if (current.size() >= 5
128 && current[current.size()-5] == (SS_UCS4)'Y'
129 && current[current.size()-4] == (SS_UCS4)'u'
130 && current[current.size()-3] == (SS_UCS4)'k'
131 && current[current.size()-2] == (SS_UCS4)'o')
132 {
133 if (singleMatchTest (5)) return true;
134 current.remove(0);
135 current.remove(0);
136 current.remove(0);
137 current.remove(0);
138 matchBegin = next-1-4;
139 matchEnd = next-1;
140 action = ACT_KEYWORD;
141 return true;
142 }
143 bool isEOD = current.size() > 0 && current[current.size()-1] == SD_MATCH_EOD;
144 return singleMatchTest (isEOD ? 1: 5);
145 }
146
147 // match current[0] and remove it.
148 bool
singleMatchTest(unsigned int leaveSize)149 SPattern::singleMatchTest (unsigned int leaveSize)
150 {
151 if (current.size() > leaveSize)
152 {
153 matchBegin = matchEnd;
154 matchEnd++;
155 action = ACT_NONE;
156 SD_CharClass cc = getCharClass (current[0]);
157 switch (cc)
158 {
159 // letter
160 case SD_CC_Lu:
161 case SD_CC_Ll:
162 case SD_CC_Lt:
163 case SD_CC_Lm:
164 case SD_CC_Lo:
165 current.remove (0);
166 if (!singleMatchTest (leaveSize))
167 {
168 return false;
169 }
170 return true;
171 case SD_CC_Nd:
172 case SD_CC_Nl:
173 case SD_CC_No:
174 action = ACT_NUMBER;
175 break;
176 case SD_CC_So:
177 action = ACT_OTHER;
178 break;
179 default:
180 action = ACT_CONTROL;
181 }
182 current.remove (0);
183 return true;
184 }
185 return false;
186 }
187