1 /*
2 * This file is part of the FortranProject plugin for Code::Blocks IDE
3 * and licensed under the GNU General Public License, version 3
4 * http://www.gnu.org/licenses/gpl-3.0.html
5 *
6 * Author: Darius Markauskas
7 *
8 */
9 #include "ccsmartfilter.h"
10
11 #ifndef CB_PRECOMP
12 #include <wx/string.h>
13 #endif
14
15 #include "tokenf.h"
16
GetTokenKind(wxArrayString & words,int & kindFilter,bool & allowVariables,kindOfCCList & kindCC)17 void CCSmartFilter::GetTokenKind(wxArrayString& words, int& kindFilter, bool& allowVariables, kindOfCCList& kindCC)
18 {
19 kindCC = kccOther;
20 allowVariables = false;
21 wxString wordLw;
22 wxString wordLastLw;
23 int woCount = words.GetCount();
24 if (woCount > 0)
25 {
26 wordLw = words.Item(0);
27 wordLastLw = words.Item(woCount-1);
28 }
29 if (woCount > 1)
30 {
31 if ( (wordLw.IsSameAs('(') && words.Item(1).IsSameAs(_T("type"))) ||
32 (wordLw.IsSameAs('(') && words.Item(1).IsSameAs(_T("extends"))) ||
33 (wordLw.IsSameAs('(') && words.Item(1).IsSameAs(_T("class"))))
34 wordLw.Prepend( words.Item(1) );
35 }
36
37 if (woCount >= 2 && wordLastLw.IsSameAs(_T("!")) &&
38 words.Item(woCount-2).IsSameAs(_T("$")) )
39 {
40 if (woCount >= 3 &&
41 (words.Item(woCount-3).IsSameAs(_T("omp")) || words.Item(woCount-3).IsSameAs(_T("acc"))))
42 {
43 kindFilter = tkOther;
44 int idxa = words.Index(_T("("));
45 if (idxa != wxNOT_FOUND)
46 {
47 int idxb = words.Index((_T(")")));
48 if (idxb == wxNOT_FOUND || idxb > idxa)
49 allowVariables = true;
50 }
51 return;
52 }
53 else
54 {
55 words.RemoveAt(words.GetCount()-1);
56 words.RemoveAt(words.GetCount()-1);
57 woCount = words.GetCount();
58 if (woCount > 0)
59 {
60 wordLastLw = words.Item(woCount-1);
61 }
62 else
63 {
64 wordLw = wxEmptyString;
65 wordLastLw = wxEmptyString;
66 }
67 }
68 }
69
70
71 if (wordLw.IsEmpty())
72 {
73 kindFilter = tkOther;
74 allowVariables = true;
75 }
76 else if (wordLw.IsSameAs(_T("call")))
77 {
78 kindFilter = tkSubroutine | tkInterface;
79 }
80 else if (woCount > 1 &&
81 ( wordLastLw.IsSameAs(_T("generic")) || wordLastLw.IsSameAs(_T("procedure")) ||
82 ( wordLastLw.IsSameAs(_T("module")) && words.Item(woCount-2).IsSameAs(_T("procedure")) ) ))
83 {
84 kindFilter = tkSubroutine | tkFunction | tkInterface;
85 if (words.Index(_T(":")) == wxNOT_FOUND)
86 kindFilter = kindFilter | tkOther;
87 }
88 else if (wordLw.IsSameAs(_T("use")) || wordLw.IsSameAs(_T("module")))
89 {
90 kindFilter = tkModule;
91 }
92 else if (wordLw.IsSameAs(_T("module")))
93 {
94 kindFilter = tkModule | tkSubmodule;
95 }
96 else if (woCount == 1 && wordLw.IsSameAs(_T("endmodule")))
97 {
98 kindFilter = tkModule;
99 }
100 else if (wordLastLw.IsSameAs(_T("submodule")))
101 {
102 kindFilter = tkModule | tkSubmodule;
103 }
104 else if ((woCount == 2 && wordLastLw.IsSameAs(_T("end")) && wordLw.IsSameAs(_T("submodule"))) ||
105 (woCount == 1 && wordLw.IsSameAs(_T("endsubmodule"))))
106 {
107 kindFilter = tkSubmodule;
108 }
109 else if (woCount > 1 && wordLastLw.IsSameAs(_T("use")))
110 {
111 if (woCount > 2 && wordLw.IsSameAs(_T(":")) && words.Item(1).IsSameAs(_T(":")))
112 {
113 kindFilter = tkModule;
114 }
115 else
116 {
117 kindFilter = tkVariable | tkSubroutine | tkFunction | tkInterface | tkOther;
118 allowVariables = true;
119 kindCC = kccUseAssocTokens;
120 }
121 }
122 else if (wordLastLw.IsSameAs(_T("private")) ||
123 wordLastLw.IsSameAs(_T("public")) ||
124 wordLastLw.IsSameAs(_T("protected")) )
125 {
126 kindFilter = tkVariable | tkSubroutine | tkFunction | tkInterface | tkType | tkOther;
127 allowVariables = true;
128 kindCC = kccAccessList;
129 }
130 else if (wordLw.IsSameAs('=') || wordLw.IsSameAs('+') || wordLw.IsSameAs('-') || wordLw.IsSameAs('*') ||
131 wordLw.IsSameAs('/') || wordLw.IsSameAs('>') || wordLw.IsSameAs('<') || wordLw.IsSameAs('.'))
132 {
133 kindFilter = tkFunction | tkInterface;
134 allowVariables = true;
135 }
136 else if (woCount == 3 && wordLw.IsSameAs('(') && words.Item(1).IsSameAs(_T("is"))
137 && (words.Item(2).IsSameAs(_T("type")) || words.Item(2).IsSameAs(_T("class"))) )
138 {
139 kindFilter = tkType;
140 }
141 else if ((woCount == 2 && wordLastLw.IsSameAs(_T("allocate")) && wordLw.IsSameAs('('))
142 || (woCount == 5 && wordLastLw.IsSameAs(_T("allocate")) && wordLw.IsSameAs(':')))
143 {
144 if (woCount == 2 && wordLw.IsSameAs('('))
145 {
146 kindFilter = tkType;
147 allowVariables = true;
148 }
149 else // (woCount == 5 && wordLw.IsSameAs(':'))
150 {
151 kindFilter = tkVariable;
152 allowVariables = true;
153 }
154 }
155 else if (woCount >= 2 && words.Item(1).IsSameAs(_T("c_funloc")) && wordLw.IsSameAs('('))
156 {
157 kindFilter = tkSubroutine | tkFunction | tkInterface;
158 }
159 else if (woCount > 2 && words.Item(1).IsSameAs(_T("intent")) && wordLw.IsSameAs('('))
160 {
161 kindFilter = tkOther;
162 allowVariables = false;
163 }
164 else if (wordLw.IsSameAs('(') || wordLw.IsSameAs(','))
165 {
166 kindFilter = tkFunction | tkInterface | tkOther;
167 allowVariables = true;
168 }
169 else if ( wordLw.IsSameAs(_T("subroutine")) || wordLw.IsSameAs(_T("function")) || wordLw.IsSameAs(_T("interface"))
170 || wordLw.IsSameAs(_T("procedure")) )
171 {
172 kindFilter = tkSubroutine | tkFunction | tkInterface;
173 }
174 else if (woCount == 1 && wordLw.IsSameAs(_T("endsubroutine")))
175 {
176 kindFilter = tkSubroutine | tkInterface;
177 }
178 else if (woCount == 1 && wordLw.IsSameAs(_T("endfunction")))
179 {
180 kindFilter = tkFunction | tkInterface;
181 }
182 else if (wordLw.IsSameAs(_T("type")) || wordLw.IsSameAs(_T("type(")) || wordLw.IsSameAs(_T("extends("))
183 || wordLw.IsSameAs(_T("class(")))
184 {
185 kindFilter = tkType;
186 }
187 else if (wordLw.IsSameAs(';'))
188 {
189 kindFilter = tkOther;
190 allowVariables = true;
191 }
192 else if (woCount >= 3 && wordLw.IsSameAs(':') && words.Item(1).IsSameAs(_T(":")) &&
193 ((words.Item(woCount-1).IsSameAs(_T("type")) && words.Item(woCount-2).IsSameAs('(')) ||
194 (words.Item(woCount-1).IsSameAs(_T("class")) && words.Item(woCount-2).IsSameAs('(')) ||
195 words.Item(woCount-1).IsSameAs(_T("integer")) ||
196 words.Item(woCount-1).IsSameAs(_T("real")) ||
197 words.Item(woCount-1).IsSameAs(_T("logical")) ||
198 words.Item(woCount-1).IsSameAs(_T("complex")) ||
199 words.Item(woCount-1).IsSameAs(_T("character")) ))
200 {
201 kindFilter = tkVariable;
202 allowVariables = true;
203 }
204 else if (wordLw.IsSameAs(':'))
205 {
206 kindFilter = tkSubroutine | tkFunction | tkInterface;
207 allowVariables = true;
208 }
209 else if (wordLw.IsSameAs(_T("do")))
210 {
211 kindFilter = tkOther;
212 allowVariables = true;
213 }
214 else if (woCount > 1 && wordLw.IsSameAs(')') && (
215 (wordLastLw.IsSameAs(_T("if")))
216 || (wordLastLw.IsSameAs(_T("read")))
217 || (wordLastLw.IsSameAs(_T("write"))) ))
218 {
219 kindFilter = tkOther | tkFunction | tkInterface;
220 allowVariables = true;
221 }
222 else if (wordLw.IsSameAs('['))
223 {
224 kindFilter = tkVariable;
225 allowVariables = true;
226 }
227 else
228 {
229 kindFilter = tkOther;
230 }
231 }
232
FitsToContext(const wxString & kw,const wxArrayString & firstWords)233 bool CCSmartFilter::FitsToContext(const wxString& kw, const wxArrayString& firstWords)
234 {
235 static std::set<wxString> onlyFirstSet;
236 if (onlyFirstSet.size() == 0)
237 {
238 onlyFirstSet.insert(_T("contains"));
239 onlyFirstSet.insert(_T("double"));
240 onlyFirstSet.insert(_T("doubleprecision"));
241 onlyFirstSet.insert(_T("else"));
242 onlyFirstSet.insert(_T("elseif"));
243 onlyFirstSet.insert(_T("elsewhere"));
244 onlyFirstSet.insert(_T("enum"));
245 onlyFirstSet.insert(_T("end"));
246 onlyFirstSet.insert(_T("endassociate"));
247 onlyFirstSet.insert(_T("endblock"));
248 onlyFirstSet.insert(_T("endblockdata"));
249 onlyFirstSet.insert(_T("endcritical"));
250 onlyFirstSet.insert(_T("endenum"));
251 onlyFirstSet.insert(_T("endfile"));
252 onlyFirstSet.insert(_T("endforall"));
253 onlyFirstSet.insert(_T("endfunction"));
254 onlyFirstSet.insert(_T("endif"));
255 onlyFirstSet.insert(_T("endinterface"));
256 onlyFirstSet.insert(_T("endprocedure"));
257 onlyFirstSet.insert(_T("enddo"));
258 onlyFirstSet.insert(_T("endmodule"));
259 onlyFirstSet.insert(_T("endprogram"));
260 onlyFirstSet.insert(_T("endselect"));
261 onlyFirstSet.insert(_T("endsubmodule"));
262 onlyFirstSet.insert(_T("endsubroutine"));
263 onlyFirstSet.insert(_T("endteam"));
264 onlyFirstSet.insert(_T("endtype"));
265 onlyFirstSet.insert(_T("endwhere"));
266 onlyFirstSet.insert(_T("entry"));
267 onlyFirstSet.insert(_T("error"));
268 onlyFirstSet.insert(_T("equivalence"));
269 onlyFirstSet.insert(_T("final"));
270 onlyFirstSet.insert(_T("flush"));
271 onlyFirstSet.insert(_T("forall"));
272 onlyFirstSet.insert(_T("format"));
273 onlyFirstSet.insert(_T("if"));
274 onlyFirstSet.insert(_T("implicit"));
275 onlyFirstSet.insert(_T("include"));
276 onlyFirstSet.insert(_T("inquire"));
277 onlyFirstSet.insert(_T("module"));
278 onlyFirstSet.insert(_T("namelist"));
279 onlyFirstSet.insert(_T("nullify"));
280 onlyFirstSet.insert(_T("open"));
281 onlyFirstSet.insert(_T("print"));
282 onlyFirstSet.insert(_T("program"));
283 }
284
285 bool kwFits = true;
286 wxString kwLw = kw.Lower();
287 int lenFW = firstWords.size();
288 wxArrayString fWL;
289 for (int i=0; i<lenFW; ++i) {
290 if (!firstWords[i].IsEmpty())
291 fWL.Add(firstWords[i]);
292 }
293 lenFW = fWL.size();
294
295 if (lenFW >= 1 && fWL[lenFW-1] == _T("end"))
296 {
297 if (kwLw == _T("associate") || kwLw == _T("block") || kwLw == _T("data") || kwLw == _T("critical") ||
298 kwLw == _T("do") || kwLw == _T("enum") || kwLw == _T("forall") ||
299 kwLw == _T("function") || kwLw == _T("if") || kwLw == _T("interface") || kwLw == _T("module") ||
300 kwLw == _T("procedure") || kwLw == _T("program") || kwLw == _T("select") || kwLw == _T("submodule") ||
301 kwLw == _T("subroutine") || kwLw == _T("team") || kwLw == _T("type") || kwLw == _T("where"))
302 {
303 kwFits = true;
304 }
305 else
306 kwFits = false;
307 }
308 else if (lenFW > 0 && onlyFirstSet.count(kwLw) != 0)
309 {
310 kwFits = false;
311 }
312 else if (kwLw == _T("associate") || kwLw == _T("do") || kwLw == _T("change"))
313 {
314 if (lenFW == 0 || (lenFW > 0 && fWL[0] == _T(":")))
315 kwFits = true;
316 else
317 kwFits = false;
318 }
319 else if (lenFW == 1 && fWL[0] == _T("implicit"))
320 {
321 if (kwLw == _T("none") || kwLw == _T("real") || kwLw == _T("integer") ||
322 kwLw == _T("logical") || kwLw == _T("character") ||kwLw == _T("type"))
323 kwFits = true;
324 else
325 kwFits = false;
326 }
327 else if (lenFW >= 1 && fWL[0] == _T("do"))
328 {
329 if (kwLw == _T("concurrent") || kwLw == _T("while"))
330 kwFits = true;
331 else
332 kwFits = false;
333 }
334 else if (kwLw == _T("do"))
335 {
336 long label;
337 if ((lenFW == 1 && fWL[0].ToLong(&label)) ||
338 (lenFW == 2 && (fWL[0] == _T(":"))) ||
339 lenFW == 0)
340 kwFits = true;
341 else
342 kwFits = false;
343 }
344 else if (kwLw == _T("concurrent"))
345 {
346 if (lenFW >= 1 && fWL[0] == _T("do"))
347 kwFits = true;
348 else
349 kwFits = false;
350 }
351 else if (kwLw == _T("if"))
352 {
353 long label;
354 if ((lenFW == 1 && (fWL[0].ToLong(&label) || fWL[0] == _T("else"))) ||
355 (lenFW == 2 && (fWL[0] == _T(":"))) ||
356 lenFW == 0)
357 kwFits = true;
358 else
359 kwFits = false;
360 }
361 else if (kwLw == _T("allocate") || kwLw == _T("deallocate"))
362 {
363 if (lenFW == 0 || (lenFW > 0 && fWL[lenFW-1] == _T("if") && fWL[0] == _T(")")))
364 kwFits = true;
365 else
366 kwFits = false;
367 }
368 else if (kwLw == _T("apostrophe"))
369 {
370 if (lenFW > 0 && fWL[lenFW-1] == _T("open"))
371 kwFits = true;
372 else
373 kwFits = false;
374 }
375 else if (lenFW > 2 && fWL[0] == _T("(") && fWL[1] == _T("intent"))
376 {
377 if (kwLw == _T("in") || kwLw == _T("inout") || kwLw == _T("out"))
378 kwFits = true;
379 else
380 kwFits = false;
381 }
382 else if (lenFW >= 2 && (fWL[lenFW-1] == _T("real") || fWL[lenFW-1] == _T("integer") || fWL[lenFW-1] == _T("logical") ||
383 fWL[lenFW-1] == _T("complex") || fWL[lenFW-1] == _T("character") ||
384 (fWL[lenFW-1] == _T("double") && fWL[lenFW-2] == _T("precision")) || fWL[lenFW-1] == _T("doubleprecision") ||
385 ((fWL[lenFW-1] == _T("type") || fWL[lenFW-1] == _T("class")) && fWL[lenFW-2] == _T("("))) &&
386 !CCSmartFilter::hasWord(_T("::"), fWL))
387 {
388 if (kwLw == _T("allocatable") || kwLw == _T("dimension") || kwLw == _T("pointer") || kwLw == _T("target") ||
389 kwLw == _T("contiguous") || kwLw == _T("selected_char_kind") || kwLw == _T("selected_int_kind") ||
390 kwLw == _T("selected_real_kind") || kwLw == _T("codimension") || kwLw == _T("size") || kwLw == _T("shape") ||
391 kwLw == _T("intent") || kwLw == _T("optional") || kwLw == _T("save") || kwLw == _T("parameter") ||
392 kwLw == _T("private") || kwLw == _T("public"))
393 {
394 kwFits = true;
395 }
396 else if (lenFW > 2 && fWL[0] == _T("(") && fWL[1] == _T("intent"))
397 {
398 if (kwLw == _T("in") || kwLw == _T("inout") || kwLw == _T("out"))
399 kwFits = true;
400 else
401 kwFits = false;
402 }
403 else
404 kwFits = false;
405 }
406 else if (kwLw == _T("allocatable") || kwLw == _T("dimension") || kwLw == _T("pointer") || kwLw == _T("target") ||
407 kwLw == _T("contiguous") || kwLw == _T("codimension") ||
408 kwLw == _T("intent") || kwLw == _T("contiguous") || kwLw == _T("optional"))
409 {
410 // the above keywords can be only as variable declaration attribute
411 kwFits = false;
412 }
413 else if (kwLw == _T("stop"))
414 {
415 if (lenFW == 0 || (lenFW > 0 && (fWL[0] == _T(")") || fWL[0] == _T("error"))))
416 kwFits = true;
417 else
418 kwFits = false;
419 }
420 else if (kwLw == _T("then"))
421 {
422 if (lenFW >= 3 && fWL[0] == _T(")"))
423 kwFits = true;
424 else
425 kwFits = false;
426 }
427 else if (kwLw == _T("bind"))
428 {
429 if (lenFW >= 2 && (fWL[0] == _T(",") || fWL[0] == _T(")")))
430 kwFits = true;
431 else
432 kwFits = false;
433 }
434 else if (kwLw == _T("only"))
435 {
436 if (lenFW >= 2 && fWL[lenFW-1] == _T("use"))
437 kwFits = true;
438 else
439 kwFits = false;
440 }
441 else if (lenFW >= 4 && (fWL[lenFW-1] == _T("open") || fWL[lenFW-1] == _T("read") || fWL[lenFW-1] == _T("write")) &&
442 fWL[lenFW-2] == _T("(") && fWL[0] == _T("=") && fWL[1] == _T("delim"))
443 {
444 if (kwLw == _T("quote") || kwLw == _T("apostrophe") || kwLw == _T("none"))
445 kwFits = true;
446 else
447 kwFits = false;
448 }
449 else if (kwLw == _T("quote") || kwLw == _T("apostrophe"))
450 {
451 kwFits = false;
452 }
453 else if (lenFW >= 2 && fWL[lenFW-1] == _T("open") && fWL[lenFW-2] == _T("("))
454 {
455 if (kwLw == _T("unit") || kwLw == _T("access") || kwLw == _T("action") || kwLw == _T("asynchronous") ||
456 kwLw == _T("blank") || kwLw == _T("decimal") || kwLw == _T("delim") || kwLw == _T("encoding") ||
457 kwLw == _T("err") || kwLw == _T("file") || kwLw == _T("form") || kwLw == _T("iomsg") || kwLw == _T("iostat") ||
458 kwLw == _T("newunit") || kwLw == _T("pad") || kwLw == _T("position") || kwLw == _T("recl") ||
459 kwLw == _T("round") || kwLw == _T("sign") || kwLw == _T("status"))
460 {
461 kwFits = true;
462 }
463 else
464 kwFits = false;
465 }
466 else if (lenFW >= 2 && fWL[lenFW-1] == _T("inquiry") && fWL[lenFW-2] == _T("("))
467 {
468 if (kwLw == _T("unit") || kwLw == _T("file") || kwLw == _T("access") || kwLw == _T("action") || kwLw == _T("asynchronous") ||
469 kwLw == _T("blank") || kwLw == _T("decimal") || kwLw == _T("delim") || kwLw == _T("direct") || kwLw == _T("encoding") ||
470 kwLw == _T("err") || kwLw == _T("exist") || kwLw == _T("form") || kwLw == _T("formated") || kwLw == _T("id") ||
471 kwLw == _T("iomsg") || kwLw == _T("iostat") || kwLw == _T("name") || kwLw == _T("named") || kwLw == _T("nextrec") ||
472 kwLw == _T("number") || kwLw == _T("opened") || kwLw == _T("pad") || kwLw == _T("pending") || kwLw == _T("pos") ||
473 kwLw == _T("position") || kwLw == _T("read") || kwLw == _T("readwrite") || kwLw == _T("recl") ||
474 kwLw == _T("round") || kwLw == _T("sequential") || kwLw == _T("sign") || kwLw == _T("size") || kwLw == _T("stream") ||
475 kwLw == _T("unformated") || kwLw == _T("write"))
476 {
477 kwFits = true;
478 }
479 else
480 kwFits = false;
481 }
482 else if (lenFW >= 2 && fWL[lenFW-1] == _T("close") && fWL[lenFW-2] == _T("("))
483 {
484 if (kwLw == _T("unit") || kwLw == _T("iomsg") || kwLw == _T("iostat") ||
485 kwLw == _T("err") || kwLw == _T("status"))
486 {
487 kwFits = true;
488 }
489 else
490 kwFits = false;
491 }
492 else if (lenFW >= 2 && (fWL[lenFW-1] == _T("read") || fWL[lenFW-1] == _T("write")) && fWL[lenFW-2] == _T("("))
493 {
494 if (kwLw == _T("unit") || kwLw == _T("fmt") || kwLw == _T("nml") || kwLw == _T("advance") || kwLw == _T("asynchronous") ||
495 kwLw == _T("blank") || kwLw == _T("decimal") || kwLw == _T("delim") || kwLw == _T("end") || kwLw == _T("eor") ||
496 kwLw == _T("err") || kwLw == _T("id") || kwLw == _T("iomsg") || kwLw == _T("iostat") || kwLw == _T("pad") ||
497 kwLw == _T("pos") || kwLw == _T("rec") || kwLw == _T("round") || kwLw == _T("sign") || kwLw == _T("size"))
498 {
499 kwFits = true;
500 }
501 else
502 kwFits = false;
503 }
504 else if (kwLw == _T("access") || kwLw == _T("action") || kwLw == _T("asynchronous") ||
505 kwLw == _T("blank") || kwLw == _T("decimal") || kwLw == _T("delim") || kwLw == _T("encoding") ||
506 kwLw == _T("err") || kwLw == _T("file") || kwLw == _T("form") || kwLw == _T("iomsg") || kwLw == _T("iostat") ||
507 kwLw == _T("newunit") || kwLw == _T("pad") || kwLw == _T("position") || kwLw == _T("recl") ||
508 kwLw == _T("round") || kwLw == _T("status ") || kwLw == _T("unit") || kwLw == _T("file") ||
509 kwLw == _T("direct") || kwLw == _T("exist") || kwLw == _T("formated") || kwLw == _T("id") || kwLw == _T("name") ||
510 kwLw == _T("named") || kwLw == _T("nextrec") ||
511 kwLw == _T("number") || kwLw == _T("opened") || kwLw == _T("pending") || kwLw == _T("pos") || kwLw == _T("readwrite") ||
512 kwLw == _T("sequential") || kwLw == _T("stream") || kwLw == _T("unformated"))
513 {
514 // the above keywords can be only in open, close, inquire, write and read statements.
515 kwFits = false;
516 }
517 else if (kwLw == _T("sequence"))
518 {
519 if (lenFW == 0)
520 kwFits = true;
521 else
522 kwFits = false;
523 }
524 else if (lenFW >= 1 && fWL[lenFW-1] == _T("go"))
525 {
526 if (kwLw == _T("to"))
527 kwFits = true;
528 else
529 kwFits = false;
530 }
531 return kwFits;
532 }
533
hasWord(const wxString & word,const wxArrayString & wordArr)534 bool CCSmartFilter::hasWord(const wxString& word, const wxArrayString& wordArr)
535 {
536 wxString str;
537 int wCount = wordArr.size();
538 for (int i=0; i<wCount; ++i)
539 {
540 str.Append(wordArr[i]);
541 }
542
543 return (str.Find(word) != wxNOT_FOUND);
544 }
545