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 "constrhighlighter.h"
10
11 #include <sdk.h>
12 #ifndef CB_PRECOMP
13 #include <configmanager.h>
14 #include <editormanager.h>
15 #include <logmanager.h>
16 #include <cbstyledtextctrl.h>
17 #endif
18 #include <algorithm>
19
ConstrHighlighter()20 ConstrHighlighter::ConstrHighlighter():
21 m_MakeHighlight(true),
22 m_FullColour(100, 100, 255),
23 m_UnfinColour(255, 165, 0),
24 m_CurrentPosition(0),
25 m_IndicFound(24),
26 m_IndicNotFound(25),
27 m_WasCleared(true)
28 {
29 m_KeywordSet.insert(_T("if"));
30 m_KeywordSet.insert(_T("elseif"));
31 m_KeywordSet.insert(_T("then"));
32 m_KeywordSet.insert(_T("else"));
33 m_KeywordSet.insert(_T("endif"));
34 m_KeywordSet.insert(_T("do"));
35 m_KeywordSet.insert(_T("enddo"));
36 m_KeywordSet.insert(_T("while"));
37 m_KeywordSet.insert(_T("concurrent"));
38 m_KeywordSet.insert(_T("subroutine"));
39 m_KeywordSet.insert(_T("endsubroutine"));
40 m_KeywordSet.insert(_T("function"));
41 m_KeywordSet.insert(_T("endfunction"));
42 m_KeywordSet.insert(_T("abstract"));
43 m_KeywordSet.insert(_T("interface"));
44 m_KeywordSet.insert(_T("endinterface"));
45 m_KeywordSet.insert(_T("associate"));
46 m_KeywordSet.insert(_T("endassociate"));
47 m_KeywordSet.insert(_T("block"));
48 m_KeywordSet.insert(_T("endblock"));
49 m_KeywordSet.insert(_T("blockdata"));
50 m_KeywordSet.insert(_T("data"));
51 m_KeywordSet.insert(_T("endblockdata"));
52 m_KeywordSet.insert(_T("critical"));
53 m_KeywordSet.insert(_T("endcritical"));
54 m_KeywordSet.insert(_T("module"));
55 m_KeywordSet.insert(_T("endmodule"));
56 m_KeywordSet.insert(_T("program"));
57 m_KeywordSet.insert(_T("endprogram"));
58 m_KeywordSet.insert(_T("select"));
59 m_KeywordSet.insert(_T("case"));
60 m_KeywordSet.insert(_T("selectcase"));
61 m_KeywordSet.insert(_T("default"));
62 m_KeywordSet.insert(_T("is"));
63 m_KeywordSet.insert(_T("class"));
64 m_KeywordSet.insert(_T("selecttype"));
65 m_KeywordSet.insert(_T("endselect"));
66 m_KeywordSet.insert(_T("type"));
67 m_KeywordSet.insert(_T("endtype"));
68 m_KeywordSet.insert(_T("where"));
69 m_KeywordSet.insert(_T("elsewhere"));
70 m_KeywordSet.insert(_T("endwhere"));
71 m_KeywordSet.insert(_T("enum"));
72 m_KeywordSet.insert(_T("endenum"));
73 m_KeywordSet.insert(_T("forall"));
74 m_KeywordSet.insert(_T("endforall"));
75 m_KeywordSet.insert(_T("submodule"));
76 m_KeywordSet.insert(_T("endsubmodule"));
77 m_KeywordSet.insert(_T("end"));
78 m_KeywordSet.insert(_T("change"));
79 m_KeywordSet.insert(_T("team"));
80 m_KeywordSet.insert(_T("endteam"));
81 m_KeywordSet.insert(_T("procedure"));
82 m_KeywordSet.insert(_T("endprocedure"));
83
84 MakeFConstructTypeMap();
85 FConstruct::MakeFCLReMap();
86 FConstruct::MakeFCLWordMap();
87 FConstruct::MakeWordFCLidMap();
88 m_TimeMax = 100;
89 }
90
~ConstrHighlighter()91 ConstrHighlighter::~ConstrHighlighter()
92 {
93 FConstruct::DelFCLReMap();
94 }
95
ReadOptions()96 void ConstrHighlighter::ReadOptions()
97 {
98 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
99 m_MakeHighlight = cfg->ReadBool(_T("/do_construct_highlighting"), true);
100 m_FullColour = cfg->ReadColour(_T("/chighlighter_full_colour"),wxColour(165, 165, 255));
101 m_UnfinColour = cfg->ReadColour(_T("/chighlighter_unfinished_colour"),wxColour(255, 165, 0));
102 }
103
MakeFConstructTypeMap()104 void ConstrHighlighter::MakeFConstructTypeMap()
105 {
106 m_FConstructTypeMap[_T("end")] = FConstruct::ctProgramGroup;
107
108 m_FConstructTypeMap[_T("subroutine")] = FConstruct::ctProgramGroup;
109 m_FConstructTypeMap[_T("endsubroutine")] = FConstruct::ctProgramGroup;
110
111 m_FConstructTypeMap[_T("function")] = FConstruct::ctProgramGroup;
112 m_FConstructTypeMap[_T("endfunction")] = FConstruct::ctProgramGroup;
113
114 m_FConstructTypeMap[_T("program")] = FConstruct::ctProgramGroup;
115 m_FConstructTypeMap[_T("endprogram")] = FConstruct::ctProgramGroup;
116
117 m_FConstructTypeMap[_T("module")] = FConstruct::ctProgramGroup;
118 m_FConstructTypeMap[_T("endmodule")] = FConstruct::ctProgramGroup;
119
120 m_FConstructTypeMap[_T("submodule")] = FConstruct::ctProgramGroup;
121 m_FConstructTypeMap[_T("endsubmodule")] = FConstruct::ctProgramGroup;
122
123 m_FConstructTypeMap[_T("moduleprocedure")] = FConstruct::ctProgramGroup;
124 m_FConstructTypeMap[_T("endprocedure")] = FConstruct::ctProgramGroup;
125
126 m_FConstructTypeMap[_T("blockdata")] = FConstruct::ctProgramGroup;
127 m_FConstructTypeMap[_T("endblockdata")] = FConstruct::ctProgramGroup;
128
129 m_FConstructTypeMap[_T("interface")] = FConstruct::ctInterface;
130 m_FConstructTypeMap[_T("abstractinterface")] = FConstruct::ctInterface;
131 m_FConstructTypeMap[_T("endinterface")] = FConstruct::ctInterface;
132
133 m_FConstructTypeMap[_T("ifthen")] = FConstruct::ctIf;
134 m_FConstructTypeMap[_T("elseifthen")] = FConstruct::ctIf;
135 m_FConstructTypeMap[_T("else")] = FConstruct::ctIf;
136 m_FConstructTypeMap[_T("endif")] = FConstruct::ctIf;
137
138 m_FConstructTypeMap[_T("do")] = FConstruct::ctDo;
139 m_FConstructTypeMap[_T("dowhile")] = FConstruct::ctDo;
140 m_FConstructTypeMap[_T("doconcurrent")] = FConstruct::ctDo;
141 m_FConstructTypeMap[_T("enddo")] = FConstruct::ctDo;
142
143 m_FConstructTypeMap[_T("associate")] = FConstruct::ctAssiciate;
144 m_FConstructTypeMap[_T("endassociate")] = FConstruct::ctAssiciate;
145
146 m_FConstructTypeMap[_T("block")] = FConstruct::ctBlock;
147 m_FConstructTypeMap[_T("endblock")] = FConstruct::ctBlock;
148
149 m_FConstructTypeMap[_T("selectcase")] = FConstruct::ctSelectGroup;
150 m_FConstructTypeMap[_T("case")] = FConstruct::ctSelectGroup;
151 m_FConstructTypeMap[_T("casedefault")] = FConstruct::ctSelectGroup;
152 m_FConstructTypeMap[_T("endselect")] = FConstruct::ctSelectGroup;
153
154 m_FConstructTypeMap[_T("selecttype")] = FConstruct::ctSelectGroup;
155 m_FConstructTypeMap[_T("typeis")] = FConstruct::ctSelectGroup;
156 m_FConstructTypeMap[_T("classis")] = FConstruct::ctSelectGroup;
157 m_FConstructTypeMap[_T("classdefault")] = FConstruct::ctSelectGroup;
158
159 m_FConstructTypeMap[_T("type")] = FConstruct::ctType;
160 m_FConstructTypeMap[_T("endtype")] = FConstruct::ctType;
161
162 m_FConstructTypeMap[_T("critical")] = FConstruct::ctCritical;
163 m_FConstructTypeMap[_T("endcritical")] = FConstruct::ctCritical;
164
165 m_FConstructTypeMap[_T("where")] = FConstruct::ctWhere;
166 m_FConstructTypeMap[_T("elsewhere")] = FConstruct::ctWhere;
167 m_FConstructTypeMap[_T("endwhere")] = FConstruct::ctWhere;
168
169 m_FConstructTypeMap[_T("enum")] = FConstruct::ctEnum;
170 m_FConstructTypeMap[_T("endenum")] = FConstruct::ctEnum;
171
172 m_FConstructTypeMap[_T("forall")] = FConstruct::ctForall;
173 m_FConstructTypeMap[_T("endforall")] = FConstruct::ctForall;
174
175 m_FConstructTypeMap[_T("changeteam")] = FConstruct::ctTeam;
176 m_FConstructTypeMap[_T("endteam")] = FConstruct::ctTeam;
177 }
178
ClearHighlighting(cbStyledTextCtrl * control,bool forceAction)179 void ConstrHighlighter::ClearHighlighting(cbStyledTextCtrl* control, bool forceAction)
180 {
181 if (!control)
182 return;
183
184 if (!m_WasCleared || forceAction)
185 {
186 const int old_indic = control->GetIndicatorCurrent();
187 control->SetIndicatorCurrent(m_IndicFound);
188 control->IndicatorClearRange(0, control->GetLength());
189 control->SetIndicatorCurrent(m_IndicNotFound);
190 control->IndicatorClearRange(0, control->GetLength());
191 m_WasCleared = true;
192 control->SetIndicatorCurrent(old_indic);
193 if (forceAction)
194 m_CurrentPosition = 0;
195 }
196 }
197
DoWork(cbEditor * editor,FortranSourceForm fsForm)198 void ConstrHighlighter::DoWork(cbEditor* editor, FortranSourceForm fsForm)
199 {
200 cbStyledTextCtrl* control = editor->GetControl();
201
202 if (!m_MakeHighlight || !control->GetSelectionEmpty())
203 {
204 ClearHighlighting(control);
205 return;
206 }
207
208 m_Watch.Start();
209
210 int cpos = control->GetCurrentPos();
211 if (cpos == m_CurrentPosition)
212 return; // nothing is changed
213 m_CurrentPosition = cpos;
214 m_CurrentSForm = fsForm;
215
216 const int old_indic = control->GetIndicatorCurrent();
217 if (!m_WasCleared)
218 {
219 control->SetIndicatorCurrent(m_IndicFound);
220 control->IndicatorClearRange(0, control->GetLength());
221 m_WasCleared = true;
222 control->SetIndicatorCurrent(old_indic);
223 }
224
225 int style = control->GetStyleAt(cpos);
226 if (style != wxSCI_F_WORD)
227 return;
228
229 int wstart = control->WordStartPosition(cpos, true);
230 if (wstart == cpos)
231 return; // do not highlight if the cursor is on the start of keyword
232 int wend = control->WordEndPosition(cpos, true);
233 wxString cword = control->GetTextRange(wstart,wend).Lower();
234 if (cword.IsEmpty())
235 return;
236 else if (m_KeywordSet.count(cword) == 0)
237 return;
238
239 Keyword word1;
240 Keyword word2;
241 Keyword word3;
242 FConstruct::FCLid flid;
243 KeywordList myPairs;
244 bool foundFull;
245
246 std::vector<FConstruct::FCLid> flidAll;
247 flidAll = FConstruct::WordFCLidMap[cword];
248 if (flidAll.empty())
249 return;
250 bool containsK = false;
251 int flineStartPos;
252 int flineEndPos;
253 wxString fLine;
254 GetFortranLine(control, wstart, fLine, flineStartPos, flineEndPos);
255 for (size_t i=0; i<flidAll.size(); i++)
256 {
257 if (FConstruct::FCLReMap.count(flidAll[i]) == 0)
258 continue;
259
260 bool match = false;
261 if (flidAll[i] == FConstruct::fclIf_else)
262 {
263 if ( FConstruct::FCLReMap[FConstruct::fclIf_else]->Matches(fLine) &&
264 !FConstruct::FCLReMap[FConstruct::fclWhere_else_where]->Matches(fLine))
265 match = true;
266 }
267 else if (flidAll[i] == FConstruct::fclBlock_end_block)
268 {
269 if ( FConstruct::FCLReMap[FConstruct::fclBlock_end_block]->Matches(fLine) &&
270 !FConstruct::FCLReMap[FConstruct::fclBlockdata_end_blockdata]->Matches(fLine))
271 match = true;
272 }
273 else if (FConstruct::FCLReMap[flidAll[i]]->Matches(fLine))
274 {
275 match = true;
276 }
277
278 if (match)
279 {
280 wxString wstr1, wstr2, wstr3;
281 FConstruct::GetWordsFromFCLid(flidAll[i], wstr1, wstr2, wstr3);
282
283 wxString str1, str2, str3;
284 int str1Pos, str2Pos, str3Pos;
285 int pos = FindFKeyword(control, flineStartPos, control->GetLength(), flidAll[i], wstr1, wstr2, wstr3,
286 str1, str1Pos, str2, str2Pos, str3, str3Pos);
287 word1.word = str1;
288 word1.posStart = str1Pos;
289 word2.word = str2;
290 word2.posStart = str2Pos;
291 word3.word = str3;
292 word3.posStart = str3Pos;
293
294 if ((str1 + str2 + str3) == _T("end"))
295 flid = FConstruct::fclProgGroup_end;
296 else
297 flid = flidAll[i];
298
299 if (pos == wxSCI_INVALID_POSITION)
300 containsK = false;
301 else
302 containsK = true;
303 break;
304 }
305 }
306 if (!containsK)
307 return;
308
309 FindMyPairs(control, word1, word2, word3, flid, myPairs, foundFull);
310
311 if (m_Watch.Time() > m_TimeMax)
312 return;
313
314 if (foundFull)
315 control->IndicatorSetForeground(m_IndicFound, m_FullColour);
316 else
317 control->IndicatorSetForeground(m_IndicFound, m_UnfinColour);
318 control->IndicatorSetStyle(m_IndicFound, wxSCI_INDIC_ROUNDBOX);
319 control->IndicatorSetAlpha(m_IndicFound, 100);
320 control->IndicatorSetOutlineAlpha(m_IndicFound, 255);
321 control->IndicatorSetUnder(m_IndicFound,true);
322 control->SetIndicatorCurrent(m_IndicFound);
323
324 m_WasCleared = false;
325
326 for (KeywordList::iterator it = myPairs.begin(); it != myPairs.end(); ++it)
327 {
328 control->IndicatorFillRange(it->posStart, it->word.length());
329 }
330 control->SetIndicatorCurrent(old_indic);
331 }
332
333
FindMyPairs(cbStyledTextCtrl * control,Keyword & word1,Keyword & word2,Keyword & word3,FConstruct::FCLid flid,KeywordList & myPairs,bool & foundFull)334 void ConstrHighlighter::FindMyPairs(cbStyledTextCtrl* control, Keyword &word1, Keyword &word2, Keyword &word3, FConstruct::FCLid flid,
335 KeywordList &myPairs, bool &foundFull)
336 {
337 foundFull = false;
338 // Get Fortran construct to search for
339 FConstruct fcon; // full construct
340 FConstruct unFconBack; // unfinished construct we should search
341 FConstruct unFconForth;
342 GetFortranConstruct(word1, word2, word3, fcon);
343 if (fcon.GetType() != FConstruct::ctProgramGroup && fcon.GetType() != FConstruct::ctSelectGroup && fcon.Size() == 0)
344 return;
345
346 SearchDirection sdir;
347 GetSearchDirection(word1, word2, word3, sdir, unFconBack, unFconForth);
348 if (sdir == sdirUnknown)
349 return;
350
351 myPairs.push_back(word1);
352 int wordsEndPos = word1.posStart + word1.word.size();
353 if (!word2.word.IsEmpty())
354 {
355 myPairs.push_back(word2);
356 wordsEndPos = word2.posStart + word2.word.size();
357 if (!word3.word.IsEmpty())
358 {
359 myPairs.push_back(word3);
360 wordsEndPos = word3.posStart + word3.word.size();
361 }
362 }
363
364 bool foundBack = true;
365 if (sdir == sdirBack || sdir == sdirBackForth)
366 {
367 // Search backward
368 int pLimitBack = FindLimitPos(control, fcon, word1.posStart, sdirBack);
369 if (m_Watch.Time() > m_TimeMax)
370 return;
371 if (fcon.GetType() == FConstruct::ctProgramGroup || fcon.GetType() == FConstruct::ctSelectGroup)
372 SearchUnConGroup(control, word1.posStart, pLimitBack, fcon.GetType(), unFconBack, flid, foundBack, myPairs);
373 else
374 SearchUnCon(control, word1.posStart, pLimitBack, fcon, unFconBack, foundBack, myPairs);
375 }
376
377 bool foundForth = true;
378 if (sdir == sdirForth || sdir == sdirBackForth)
379 {
380 // Search forth
381 int pLimitForth = FindLimitPos(control, fcon, wordsEndPos, sdirForth);
382 if (m_Watch.Time() > m_TimeMax)
383 return;
384 if (fcon.GetType() == FConstruct::ctProgramGroup || fcon.GetType() == FConstruct::ctSelectGroup)
385 SearchUnConGroup(control, wordsEndPos, pLimitForth, fcon.GetType(), unFconForth, flid, foundForth, myPairs);
386 else
387 SearchUnCon(control, wordsEndPos, pLimitForth, fcon, unFconForth, foundForth, myPairs);
388 }
389 foundFull = (foundBack && foundForth);
390 }
391
SearchUnCon(cbStyledTextCtrl * control,int pStartC,int pEndC,const FConstruct & fcon,const FConstruct & unFcon,bool & foundEnd,KeywordList & myPairs)392 void ConstrHighlighter::SearchUnCon(cbStyledTextCtrl* control, int pStartC, int pEndC, const FConstruct& fcon, const FConstruct& unFcon,
393 bool& foundEnd, KeywordList& myPairs)
394 {
395 foundEnd = false;
396 wxString word1;
397 wxString word2;
398 wxString word3;
399 FConstruct::FCLid flid;
400 fcon.GetWords(0, word1, word2, word3, flid);
401
402 wxString wordE1;
403 wxString wordE2;
404 wxString wordE3;
405 FConstruct::FCLid flidE;
406 fcon.GetWords(fcon.Size()-1, wordE1, wordE2, wordE3, flidE);
407
408 bool searchBack = pStartC > pEndC;
409 int pStart = pStartC;
410 int pEnd = pEndC;
411 int level = 0;
412 int cutEnd = -1;
413 int cutStart = -1;
414 std::vector<int> cutEndVec;
415 std::vector<int> cutStartVec;
416
417 wxString str1, str2, str3;
418 int str1Pos, str2Pos, str3Pos;
419
420 wxString strE1, strE2, strE3;
421 int strE1Pos, strE2Pos, strE3Pos;
422 bool haveStart = false;
423 bool haveEnd = false;
424
425 while (true)
426 {
427 if (m_Watch.Time() > m_TimeMax)
428 return;
429 int posFCstart;
430 int posFCend;
431 if (!haveStart)
432 posFCstart = FindFKeyword(control, pStart, pEnd, flid, word1, word2, word3,
433 str1, str1Pos, str2, str2Pos, str3, str3Pos);
434 if (!haveEnd)
435 posFCend = FindFKeyword(control, pStart, pEnd, flidE, wordE1, wordE2, wordE3,
436 strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
437
438 if (searchBack)
439 {
440 if (posFCstart == wxSCI_INVALID_POSITION && posFCend != wxSCI_INVALID_POSITION)
441 {
442 pEnd = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
443 break; // try to search intermediate keywords
444 }
445 else if (posFCstart == wxSCI_INVALID_POSITION && posFCend == wxSCI_INVALID_POSITION)
446 {
447 pEnd = pEndC;
448 break; // try to search intermediate keywords
449 }
450 else if (posFCstart != wxSCI_INVALID_POSITION && posFCend == wxSCI_INVALID_POSITION)
451 posFCend = -1;
452 }
453 else
454 {
455 if (posFCstart != wxSCI_INVALID_POSITION && posFCend == wxSCI_INVALID_POSITION)
456 {
457 pEnd = posFCstart;
458 break; // try to search intermediate keywords
459 }
460 else if (posFCstart == wxSCI_INVALID_POSITION && posFCend == wxSCI_INVALID_POSITION)
461 {
462 pEnd = pEndC;
463 break; // try to search intermediate keywords
464 }
465 else if (posFCstart == wxSCI_INVALID_POSITION && posFCend != wxSCI_INVALID_POSITION)
466 posFCstart = control->GetLength();
467 }
468
469 if (searchBack)
470 {
471 if (posFCstart < posFCend)
472 {
473 // Starts another level of construct
474 if (level == 0)
475 cutEnd = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
476 level += 1;
477 pStart = posFCend;
478 haveStart = true;
479 haveEnd = false;
480 }
481 else // (posFCstart > posFCend)
482 {
483 if (level == 0)
484 {
485 PutToKeywordList(str1, str2, str3, str1Pos, str2Pos, str3Pos, myPairs);
486 foundEnd = true;
487 pEnd = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
488 break;
489 }
490 else if (level == 1)
491 {
492 cutStart = posFCstart;
493 cutEndVec.push_back(cutEnd);
494 cutStartVec.push_back(cutStart);
495 }
496 level -= 1;
497 pStart = posFCstart;
498 haveStart = false;
499 haveEnd = true;
500 }
501 }
502 else // search forth
503 {
504 if (posFCstart < posFCend)
505 {
506 // Starts another level of construct
507 if (level == 0)
508 cutStart = posFCstart;
509 level += 1;
510 pStart = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
511 haveStart = false;
512 haveEnd = true;
513 }
514 else // (posFCstart > posFCend)
515 {
516 if (level == 0)
517 {
518 PutToKeywordList(strE1, strE2, strE3, strE1Pos, strE2Pos, strE3Pos, myPairs);
519 foundEnd = true;
520 pEnd = strE1Pos;
521 break;
522 }
523 else if (level == 1)
524 {
525 cutEnd = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
526 cutEndVec.push_back(cutEnd);
527 cutStartVec.push_back(cutStart);
528 }
529 level -= 1;
530 pStart = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
531 haveStart = true;
532 haveEnd = false;
533 }
534 }
535 }
536
537 // Find intermediate keywords
538 SearchUnConIntermediate(control, pStartC, pEnd, unFcon, cutEndVec, cutStartVec, myPairs);
539 }
540
SearchUnConGroup(cbStyledTextCtrl * control,int pStartC,int pEndC,FConstruct::FConstructType fct,const FConstruct & unFcon,FConstruct::FCLid fcl,bool & foundEnd,KeywordList & myPairs)541 void ConstrHighlighter::SearchUnConGroup(cbStyledTextCtrl* control, int pStartC, int pEndC, FConstruct::FConstructType fct,
542 const FConstruct& unFcon, FConstruct::FCLid fcl, bool& foundEnd, KeywordList& myPairs)
543 {
544 foundEnd = false;
545
546 bool searchBack = pStartC > pEndC;
547 int pStart = pStartC;
548 int pEnd = pEndC;
549 int level = 0;
550 int cutEnd = -1;
551 int cutStart = -1;
552 std::vector<int> cutEndVec;
553 std::vector<int> cutStartVec;
554
555 wxString str1, str2, str3;
556 int str1Pos, str2Pos, str3Pos;
557
558 wxString strE1, strE2, strE3;
559 int strE1Pos, strE2Pos, strE3Pos;
560
561 FConstruct::FCLid flid;
562 FConstruct::FCLid flidE;
563 if (fct == FConstruct::ctProgramGroup)
564 {
565 flid = FConstruct::fclProgGroup_start;
566 flidE = FConstruct::fclProgGroup_end;
567 }
568 else if (fct == FConstruct::ctSelectGroup)
569 {
570 flid = FConstruct::fclSelGroup_start;
571 flidE = FConstruct::fclSelGroup_end;
572 }
573 else
574 return; // this should not happen
575
576 bool haveStart = false;
577 bool haveEnd = false;
578 int posFCstart;
579 int posFCend;
580
581 while (true)
582 {
583 if (m_Watch.Time() > m_TimeMax)
584 return;
585 int lineStartPos;
586 int lineEndPos;
587 FConstruct::FCLid flidFound;
588 if (!haveStart)
589 posFCstart = FindGroupKeyword(control, pStart, pEnd, flid,
590 str1, str1Pos, str2, str2Pos, str3, str3Pos);
591
592 bool oneWord;
593 if (!haveEnd)
594 {
595 if (fct == FConstruct::ctProgramGroup)
596 posFCend = FindProgGroupEndKeywordPos(control, pStart, pEnd, lineStartPos, lineEndPos, flidFound, oneWord);
597 else
598 posFCend = FindGroupKeyword(control, pStart, pEnd, flidE, strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
599 }
600
601 if (searchBack)
602 {
603 if (posFCstart == wxSCI_INVALID_POSITION)
604 break;
605 else if (posFCend == wxSCI_INVALID_POSITION)
606 posFCend = -1;
607 }
608 else
609 {
610 if (posFCend == wxSCI_INVALID_POSITION)
611 break;
612 else if (posFCstart == wxSCI_INVALID_POSITION)
613 posFCstart = control->GetLength();
614 }
615
616 if (searchBack)
617 {
618 if (posFCstart < posFCend)
619 {
620 // Starts another level of construct
621 if (level == 0)
622 cutEnd = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
623 level += 1;
624 pStart = posFCend;
625 haveStart = true;
626 haveEnd = false;
627 continue;
628 }
629 else if (posFCstart > posFCend)
630 {
631 if (level == 0)
632 {
633 wxString strFound = str1 + str2 + str3;
634 if ( fcl == FConstruct::fclProgGroup_end ||
635 (fcl == FConstruct::fclSub_end_sub && strFound.IsSameAs(_T("subroutine"))) ||
636 (fcl == FConstruct::fclFun_end_fun && strFound.IsSameAs(_T("function"))) ||
637 (fcl == FConstruct::fclMod_end_module && strFound.IsSameAs(_T("module"))) ||
638 (fcl == FConstruct::fclSubmod_end_submod && strFound.IsSameAs(_T("submodule"))) ||
639 (fcl == FConstruct::fclProg_end_prog && strFound.IsSameAs(_T("program"))) ||
640 (fcl == FConstruct::fclBlockdata_end_blockdata && strFound.IsSameAs(_T("blockdata"))) ||
641 (fcl == FConstruct::fclProc_end_proc && strFound.IsSameAs(_T("moduleprocedure"))) ||
642
643 fcl == FConstruct::fclSelect_end ||
644 (fcl == FConstruct::fclSelectCase_case && strFound.IsSameAs(_T("selectcase"))) ||
645 (fcl == FConstruct::fclSelectType_type_is && strFound.IsSameAs(_T("selecttype"))) ||
646 (fcl == FConstruct::fclSelectType_class_is && strFound.IsSameAs(_T("selecttype"))) ||
647 (fcl == FConstruct::fclSelectType_class_default && strFound.IsSameAs(_T("selecttype"))) )
648 {
649 PutToKeywordList(str1, str2, str3, str1Pos, str2Pos, str3Pos, myPairs);
650 foundEnd = true;
651 pEnd = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
652 }
653 break;
654 }
655 else if (fct == FConstruct::ctSelectGroup && level == 1)
656 {
657 cutStart = posFCstart;
658 cutEndVec.push_back(cutEnd);
659 cutStartVec.push_back(cutStart);
660 }
661 level -= 1;
662 pStart = posFCstart;
663 haveStart = false;
664 haveEnd = true;
665 }
666 }
667 else // search forth
668 {
669 if (posFCstart < posFCend)
670 {
671 // Starts another level of construct
672 if (level == 0)
673 cutStart = posFCstart;
674 level += 1;
675 pStart = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
676 haveStart = false;
677 haveEnd = true;
678 continue;
679 }
680 else if (posFCstart > posFCend)
681 {
682 if (level == 0)
683 {
684 if (fct == FConstruct::ctProgramGroup)
685 {
686 if ( oneWord ||
687 (fcl == FConstruct::fclBlockdata_blockdata && flidFound == FConstruct::fclBlockdata_end_blockdata))
688 {
689 GetKeyworsFromLine(control, flidFound, lineStartPos, lineEndPos, strE1, strE2, strE3, strE1Pos, strE2Pos, strE3Pos);
690
691 wxString strFound = strE1 + strE2 + strE3;
692 if ( strFound.IsSameAs(_T("end")) ||
693 (fcl == FConstruct::fclSub_sub && strFound.IsSameAs(_T("endsubroutine"))) ||
694 (fcl == FConstruct::fclFun_fun && strFound.IsSameAs(_T("endfunction"))) ||
695 (fcl == FConstruct::fclMod_module && strFound.IsSameAs(_T("endmodule"))) ||
696 (fcl == FConstruct::fclSubmod_submod && strFound.IsSameAs(_T("endsubmodule"))) ||
697 (fcl == FConstruct::fclProg_prog && strFound.IsSameAs(_T("endprogram"))) ||
698 (fcl == FConstruct::fclProc_mod_proc && strFound.IsSameAs(_T("endprocedure"))) )
699 {
700 PutToKeywordList(strE1, strE2, strE3, strE1Pos, strE2Pos, strE3Pos, myPairs);
701 foundEnd = true;
702 }
703 }
704 else if ((fcl == FConstruct::fclSub_sub && flidFound == FConstruct::fclSub_end_sub) ||
705 (fcl == FConstruct::fclFun_fun && flidFound == FConstruct::fclFun_end_fun) ||
706 (fcl == FConstruct::fclMod_module && flidFound == FConstruct::fclMod_end_module) ||
707 (fcl == FConstruct::fclSubmod_submod && flidFound == FConstruct::fclSubmod_end_submod) ||
708 (fcl == FConstruct::fclProg_prog && flidFound == FConstruct::fclProg_end_prog) ||
709 (fcl == FConstruct::fclProc_mod_proc && flidFound == FConstruct::fclProc_end_proc))
710 {
711 std::vector<wxString> sWords = FConstruct::FCLWordMap[flidFound];
712 strE1 = sWords[0]+sWords[1];
713 strE2 = wxEmptyString;
714 strE3 = wxEmptyString;
715 PutToKeywordList(strE1, strE2, strE3, posFCend, 0, 0, myPairs);
716 foundEnd = true;
717 }
718 }
719 else
720 {
721 wxString strFound = strE1 + strE2 + strE3;
722 if (strFound.IsSameAs(_T("endselect")))
723 {
724 PutToKeywordList(strE1, strE2, strE3, strE1Pos, strE2Pos, strE3Pos, myPairs);
725 foundEnd = true;
726 pEnd = strE1Pos;
727 }
728 }
729 break;
730 }
731 else if (fct == FConstruct::ctSelectGroup && level == 1)
732 {
733 cutEndVec.push_back(GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos));
734 cutStartVec.push_back(cutStart);
735 }
736 level -= 1;
737 if (fct == FConstruct::ctProgramGroup)
738 pStart = lineEndPos;
739 else
740 pStart = GetWordsEnd(strE1, strE1Pos, strE2, strE2Pos, strE3, strE3Pos);
741 haveStart = true;
742 haveEnd = false;
743 }
744 }
745 }
746
747 if (fct == FConstruct::ctSelectGroup)
748 {
749 // Find intermediate keywords
750 SearchUnConIntermediate(control, pStartC, pEnd, unFcon, cutEndVec, cutStartVec, myPairs);
751 }
752 }
753
SearchUnConIntermediate(cbStyledTextCtrl * control,int pStartC,int pEndC,const FConstruct & unFcon,std::vector<int> & cutEndVec,std::vector<int> & cutStartVec,KeywordList & myPairs)754 void ConstrHighlighter::SearchUnConIntermediate(cbStyledTextCtrl* control, int pStartC, int pEndC, const FConstruct& unFcon,
755 std::vector<int>& cutEndVec, std::vector<int>& cutStartVec, KeywordList& myPairs)
756 {
757 // Find intermediate keywords
758 bool searchBack = pStartC > pEndC;
759 FConstruct::FCLid flid;
760 wxString str1, str2, str3;
761 int str1Pos, str2Pos, str3Pos;
762
763 for (size_t i=1; i<unFcon.Size(); i++)
764 {
765 int ik = searchBack? i : i-1;
766 wxString word1, word2, word3;
767 unFcon.GetWords(ik, word1, word2, word3, flid);
768 if (flid == FConstruct::fclUnknown)
769 return; // something wrong
770 int pInterStart = pStartC;
771 int pInterEnd = pEndC;
772
773 while (true)
774 {
775 int pos = FindFKeyword(control, pInterStart, pInterEnd, flid, word1, word2, word3,
776 str1, str1Pos, str2, str2Pos, str3, str3Pos);
777 if (pos == wxSCI_INVALID_POSITION)
778 break;
779
780 bool wasCut = false;
781 for (size_t j=0; j<cutStartVec.size(); j++)
782 {
783 if (pos > cutStartVec[j] && pos < cutEndVec[j])
784 {
785 wasCut = true;
786 break;
787 }
788 }
789
790 if (!wasCut)
791 PutToKeywordList(str1, str2, str3, str1Pos, str2Pos, str3Pos, myPairs);
792
793 if (searchBack)
794 pInterStart = pos;
795 else
796 pInterStart = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
797 }
798 }
799 }
800
GetWordsEnd(wxString & str1,int str1Pos,wxString & str2,int str2Pos,wxString & str3,int str3Pos)801 int ConstrHighlighter::GetWordsEnd(wxString& str1, int str1Pos, wxString& str2, int str2Pos, wxString& str3, int str3Pos)
802 {
803 int wend = -1;
804 if (!str3.IsEmpty())
805 wend = str3Pos + str3.Length();
806 else if (!str2.IsEmpty())
807 wend = str2Pos + str2.Length();
808 else if (!str1.IsEmpty())
809 wend = str1Pos + str1.Length();
810 return wend;
811 }
812
PutToKeywordList(wxString & str1,wxString & str2,wxString & str3,int str1Pos,int str2Pos,int str3Pos,KeywordList & kList)813 void ConstrHighlighter::PutToKeywordList(wxString& str1, wxString& str2, wxString& str3,
814 int str1Pos, int str2Pos, int str3Pos, KeywordList& kList)
815 {
816 Keyword sk = {str1, str1Pos};
817 kList.push_back(sk);
818 if (str2Pos != wxSCI_INVALID_POSITION)
819 {
820 sk.word = str2;
821 sk.posStart = str2Pos;
822 kList.push_back(sk);
823 if (str3Pos != wxSCI_INVALID_POSITION)
824 {
825 sk.word = str3;
826 sk.posStart = str3Pos;
827 kList.push_back(sk);
828 }
829 }
830 }
831
FindFKeywordFull(cbStyledTextCtrl * control,int pStart,int pEnd,FConstruct::FCLid flid,const wxString & sWord1,const wxString & sWord2,const wxString & sWord3,wxString & str1,int & str1Pos,wxString & str2,int & str2Pos,wxString & str3,int & str3Pos)832 int ConstrHighlighter::FindFKeywordFull(cbStyledTextCtrl* control, int pStart, int pEnd, FConstruct::FCLid flid, const wxString& sWord1, const wxString& sWord2, const wxString& sWord3,
833 wxString& str1, int& str1Pos, wxString& str2, int& str2Pos, wxString& str3, int& str3Pos)
834 {
835 if (FConstruct::FCLReMap.count(flid) == 0)
836 return wxSCI_INVALID_POSITION;
837
838 bool searchBack = pStart > pEnd;
839 int flag;
840 wxString sw1;
841 int cStart = pStart;
842 if (sWord2.IsEmpty())
843 {
844 sw1 = sWord1;
845 flag = wxSCI_FIND_WORDSTART;
846 }
847 else
848 {
849 sw1 = sWord2;
850 flag = 0;
851 }
852
853 while (true)
854 {
855 int pos = FindText(control, cStart, pEnd, sw1, flag);
856 if (pos == wxSCI_INVALID_POSITION)
857 return wxSCI_INVALID_POSITION;
858
859 wxString fLine;
860 int lineStartPos;
861 int lineEndPos;
862 GetFortranLine(control, pos, fLine, lineStartPos, lineEndPos);
863
864 if (FConstruct::FCLReMap[flid]->Matches(fLine))
865 {
866 int nfilled = 0;
867 pos = FindText(control, lineStartPos, lineEndPos, sWord1, wxSCI_FIND_WHOLEWORD);
868 if (pos != wxSCI_INVALID_POSITION)
869 {
870 str1 = sWord1;
871 str1Pos = pos;
872 if (sWord2.IsEmpty())
873 return pos;
874 sw1 = sWord2;
875 nfilled++;
876 }
877 else
878 sw1 = sWord1 + sWord2;
879
880 pos = FindText(control, lineStartPos, lineEndPos, sw1, wxSCI_FIND_WHOLEWORD);
881 if (pos != wxSCI_INVALID_POSITION)
882 {
883 if (nfilled == 0)
884 {
885 str1 = sWord1;
886 str1Pos = pos;
887 }
888 else
889 {
890 str2 = sWord2;
891 str2Pos = pos;
892 }
893
894 if (sWord3.IsEmpty())
895 return pos;
896 sw1 = sWord3;
897 nfilled++;
898 }
899 else
900 return wxSCI_INVALID_POSITION;
901
902 pos = FindText(control, lineStartPos, lineEndPos, sw1, wxSCI_FIND_WHOLEWORD);
903 if (pos != wxSCI_INVALID_POSITION)
904 {
905 if (nfilled == 1)
906 {
907 str2 = sw1;
908 str2Pos = pos;
909 }
910 else
911 {
912 str3 = sw1;
913 str3Pos = pos;
914 }
915 }
916 else
917 return wxSCI_INVALID_POSITION;
918 }
919 else
920 {
921 if(searchBack)
922 {
923 cStart = lineStartPos;
924 if (cStart <= pEnd)
925 return wxSCI_INVALID_POSITION;
926 }
927 else
928 {
929 cStart = lineEndPos;
930 if (cStart >= pEnd)
931 return wxSCI_INVALID_POSITION;
932 }
933 }
934 }
935 }
936
FindProgGroupEndKeywordPos(cbStyledTextCtrl * control,int pStart,int pEnd,int & lineStartPos,int & lineEndPos,FConstruct::FCLid & flid,bool & oneWord)937 int ConstrHighlighter::FindProgGroupEndKeywordPos(cbStyledTextCtrl* control, int pStart, int pEnd, int& lineStartPos, int& lineEndPos,
938 FConstruct::FCLid& flid, bool& oneWord)
939 {
940 int nUsed = 0;
941 bool searchBack = pStart > pEnd;
942
943 flid = FConstruct::fclUnknown;
944 oneWord = false;
945
946 std::vector<FConstruct::FCLid> flidAll;
947 flidAll.push_back(FConstruct::fclFun_end_fun);
948 flidAll.push_back(FConstruct::fclSub_end_sub);
949 flidAll.push_back(FConstruct::fclProg_end_prog);
950 flidAll.push_back(FConstruct::fclMod_end_module);
951 flidAll.push_back(FConstruct::fclSubmod_end_submod);
952 flidAll.push_back(FConstruct::fclBlockdata_end_blockdata);
953 flidAll.push_back(FConstruct::fclProc_end_proc);
954
955 wxString sW = _T("end");
956 while (true)
957 {
958 int pos = FindText(control, pStart, pEnd, sW, wxSCI_FIND_WORDSTART);
959
960 if (pos == wxSCI_INVALID_POSITION)
961 break;
962
963 int wordendpos = control->WordEndPosition(pos, true);
964 wxString foundWord = control->GetTextRange(pos, wordendpos).Lower();
965 if (foundWord.IsSameAs(sW))
966 {
967 nUsed = 1;
968 }
969 else if (foundWord.IsSameAs(_T("endsubroutine")))
970 {
971 flid = FConstruct::fclSub_end_sub;
972 nUsed = 2;
973 }
974 else if (foundWord.IsSameAs(_T("endfunction")))
975 {
976 flid = FConstruct::fclFun_end_fun;
977 nUsed = 2;
978 }
979 else if (foundWord.IsSameAs(_T("endprogram")))
980 {
981 flid = FConstruct::fclProg_end_prog;
982 nUsed = 2;
983 }
984 else if (foundWord.IsSameAs(_T("endmodule")))
985 {
986 flid = FConstruct::fclMod_end_module;
987 nUsed = 2;
988 }
989 else if (foundWord.IsSameAs(_T("endsubmodule")))
990 {
991 flid = FConstruct::fclSubmod_end_submod;
992 nUsed = 2;
993 }
994 else if (foundWord.IsSameAs(_T("endblock")))
995 {
996 flid = FConstruct::fclBlockdata_end_blockdata;
997 nUsed = 2;
998 }
999 else if (foundWord.IsSameAs(_T("endblockdata")))
1000 {
1001 flid = FConstruct::fclBlockdata_end_blockdata;
1002 nUsed = 3;
1003 }
1004 else if (foundWord.IsSameAs(_T("endprocedure")))
1005 {
1006 flid = FConstruct::fclProc_end_proc;
1007 nUsed = 2;
1008 }
1009 else
1010 {
1011 pStart = searchBack? pos : pos+foundWord.Length();
1012 continue;
1013 }
1014
1015 wxString fLine;
1016 GetFortranLine(control, pos, fLine, lineStartPos, lineEndPos);
1017
1018 if (nUsed == 1)
1019 {
1020 for (size_t i=0; i<flidAll.size(); i++)
1021 {
1022 if (FConstruct::FCLReMap[flidAll[i]]->Matches(fLine))
1023 {
1024 oneWord = true;
1025 flid = flidAll[i];
1026 return pos;
1027 }
1028 }
1029 }
1030 else
1031 {
1032 if (FConstruct::FCLReMap[flid]->Matches(fLine))
1033 return pos;
1034 }
1035
1036 pStart = searchBack? pos : pos+foundWord.Length();
1037 }
1038 return wxSCI_INVALID_POSITION;
1039 }
1040
FindGroupKeyword(cbStyledTextCtrl * control,int pStart,int pEnd,FConstruct::FCLid flid,wxString & rstr1,int & rstr1Pos,wxString & rstr2,int & rstr2Pos,wxString & rstr3,int & rstr3Pos)1041 int ConstrHighlighter::FindGroupKeyword(cbStyledTextCtrl* control, int pStart, int pEnd, FConstruct::FCLid flid,
1042 wxString& rstr1, int& rstr1Pos, wxString& rstr2, int& rstr2Pos, wxString& rstr3, int& rstr3Pos)
1043 {
1044 int posGK = wxSCI_INVALID_POSITION;
1045 rstr1 = wxEmptyString;
1046 rstr1Pos = wxSCI_INVALID_POSITION;
1047 rstr2 = wxEmptyString;
1048 rstr2Pos = wxSCI_INVALID_POSITION;
1049 rstr3 = wxEmptyString;
1050 rstr3Pos = wxSCI_INVALID_POSITION;
1051
1052 std::vector<FConstruct::FCLid> flidAll;
1053 if (flid == FConstruct::fclProgGroup_end)
1054 {
1055 flidAll.push_back(FConstruct::fclFun_end_fun);
1056 flidAll.push_back(FConstruct::fclSub_end_sub);
1057 flidAll.push_back(FConstruct::fclProg_end_prog);
1058 flidAll.push_back(FConstruct::fclMod_end_module);
1059 flidAll.push_back(FConstruct::fclSubmod_end_submod);
1060 flidAll.push_back(FConstruct::fclBlockdata_end_blockdata);
1061 flidAll.push_back(FConstruct::fclProc_end_proc);
1062 }
1063 else if (flid == FConstruct::fclProgGroup_start)
1064 {
1065 flidAll.push_back(FConstruct::fclFun_fun);
1066 flidAll.push_back(FConstruct::fclSub_sub);
1067 flidAll.push_back(FConstruct::fclProg_prog);
1068 flidAll.push_back(FConstruct::fclMod_module);
1069 flidAll.push_back(FConstruct::fclSubmod_submod);
1070 flidAll.push_back(FConstruct::fclBlockdata_blockdata);
1071 flidAll.push_back(FConstruct::fclProc_mod_proc);
1072 }
1073 else if (flid == FConstruct::fclSelGroup_end)
1074 {
1075 flidAll.push_back(FConstruct::fclSelect_end);
1076 }
1077 else if (flid == FConstruct::fclSelGroup_start)
1078 {
1079 flidAll.push_back(FConstruct::fclSelectCase_start);
1080 flidAll.push_back(FConstruct::fclSelectType_start);
1081 }
1082 else
1083 return posGK;
1084
1085 wxString str1, str2, str3;
1086 int str1Pos, str2Pos, str3Pos;
1087 bool searchBack = pStart > pEnd;
1088
1089 for (size_t i=0; i<flidAll.size(); i++)
1090 {
1091 std::vector<wxString> sWords;
1092 if (FConstruct::FCLWordMap.count(flidAll[i]) == 0)
1093 continue;
1094 sWords = FConstruct::FCLWordMap[flidAll[i]];
1095
1096 int pos = FindFKeyword(control, pStart, pEnd, flidAll[i], sWords[0], sWords[1], sWords[2],
1097 str1, str1Pos, str2, str2Pos, str3, str3Pos);
1098 if (pos != wxSCI_INVALID_POSITION)
1099 {
1100 if ((posGK == wxSCI_INVALID_POSITION) ||
1101 (posGK != wxSCI_INVALID_POSITION && searchBack && pos > posGK) ||
1102 (posGK != wxSCI_INVALID_POSITION && !searchBack && pos < posGK))
1103 {
1104 posGK = pos;
1105 rstr1 = str1;
1106 rstr1Pos = str1Pos;
1107 rstr2 = str2;
1108 rstr2Pos = str2Pos;
1109 rstr3 = str3;
1110 rstr3Pos = str3Pos;
1111 if (searchBack)
1112 pEnd = pos + 2;
1113 else
1114 pEnd = pos - 2;
1115 }
1116 }
1117 }
1118 return posGK;
1119 }
1120
FindFKeyword(cbStyledTextCtrl * control,int pStart,int pEnd,FConstruct::FCLid flid,const wxString & sWord1,const wxString & sWord2,const wxString & sWord3,wxString & str1,int & str1Pos,wxString & str2,int & str2Pos,wxString & str3,int & str3Pos)1121 int ConstrHighlighter::FindFKeyword(cbStyledTextCtrl* control, int pStart, int pEnd, FConstruct::FCLid flid, const wxString& sWord1, const wxString& sWord2, const wxString& sWord3,
1122 wxString& str1, int& str1Pos, wxString& str2, int& str2Pos, wxString& str3, int& str3Pos)
1123 {
1124 const int flag = wxSCI_FIND_WORDSTART; // wxSCI_FIND_WHOLEWORD;
1125 int nUsed;
1126 str1 = wxEmptyString;
1127 str1Pos = wxSCI_INVALID_POSITION;
1128 str2 = wxEmptyString;
1129 str2Pos = wxSCI_INVALID_POSITION;
1130 str3 = wxEmptyString;
1131 str3Pos = wxSCI_INVALID_POSITION;
1132 bool searchBack = pStart > pEnd;
1133
1134 while (true)
1135 {
1136 wxString sW = sWord1;
1137 int pos = FindText(control, pStart, pEnd, sW, flag);
1138
1139 if (pos == wxSCI_INVALID_POSITION)
1140 return wxSCI_INVALID_POSITION;
1141
1142 int wordendpos = control->WordEndPosition(pos, true);
1143 wxString foundWord = control->GetTextRange(pos, wordendpos).Lower();
1144 if (foundWord.IsSameAs(sWord1))
1145 nUsed = 1;
1146 else if (!sWord2.IsEmpty() && foundWord.IsSameAs(sWord1+sWord2))
1147 nUsed = 2;
1148 else if (flid == FConstruct::fclBlockdata_end_blockdata && foundWord.IsSameAs(_T("endblockdata")))
1149 nUsed = 3;
1150 else
1151 {
1152 pStart = searchBack? pos : pos+foundWord.Length();
1153 continue;
1154 }
1155
1156 str1 = foundWord;
1157 str1Pos = pos;
1158 wxString fLine;
1159 int lineStartPos;
1160 int lineEndPos;
1161 GetFortranLine(control, pos, fLine, lineStartPos, lineEndPos);
1162
1163 if (FConstruct::FCLReMap.count(flid) == 0)
1164 return wxSCI_INVALID_POSITION;
1165
1166 bool match = false;
1167 if (flid == FConstruct::fclIf_else)
1168 {
1169 if ( FConstruct::FCLReMap[FConstruct::fclIf_else]->Matches(fLine) &&
1170 !FConstruct::FCLReMap[FConstruct::fclWhere_else_where]->Matches(fLine))
1171 match = true;
1172 }
1173 else if (flid == FConstruct::fclBlock_end_block)
1174 {
1175 if ( FConstruct::FCLReMap[FConstruct::fclBlock_end_block]->Matches(fLine) &&
1176 !FConstruct::FCLReMap[FConstruct::fclBlockdata_end_blockdata]->Matches(fLine))
1177 match = true;
1178 }
1179 else if (FConstruct::FCLReMap[flid]->Matches(fLine))
1180 match = true;
1181
1182 if (match)
1183 {
1184 // We already found keyword.
1185 // Now find positions of sWord2 and sWord3
1186 if (nUsed == 1 && sWord2.IsEmpty())
1187 {
1188 if (flid == FConstruct::fclInterf_interf)
1189 {
1190 // check "abstract interface"
1191 pos = FindText(control, pos-16, pos-1, _T("abstract"), wxSCI_FIND_WHOLEWORD);
1192 if (pos != wxSCI_INVALID_POSITION)
1193 {
1194 str2Pos = str1Pos;
1195 str2 = str1;
1196 str1Pos = pos;
1197 str1 = _T("abstract");
1198 }
1199 }
1200 else if (flid == FConstruct::fclDo_do)
1201 {
1202 pos = FindText(control, str1Pos+3, str1Pos+10, _T("while"), wxSCI_FIND_WHOLEWORD);
1203 if (pos != wxSCI_INVALID_POSITION)
1204 {
1205 str2Pos = pos;
1206 str2 = _T("while");
1207 }
1208 else
1209 {
1210 pos = FindText(control, str1Pos+3, str1Pos+15, _T("concurrent"), wxSCI_FIND_WHOLEWORD);
1211 if (pos != wxSCI_INVALID_POSITION)
1212 {
1213 str2Pos = pos;
1214 str2 = _T("concurrent");
1215 }
1216 }
1217 }
1218 return str1Pos;
1219 }
1220 else if (nUsed == 1)
1221 {
1222 sW = sWord2;
1223 nUsed = 2;
1224 }
1225 else if ((nUsed == 2) && sWord3.IsEmpty())
1226 return str1Pos;
1227 else if (nUsed == 3)
1228 return str1Pos;
1229 else
1230 {
1231 sW = sWord3;
1232 nUsed = 3;
1233 }
1234
1235 if (nUsed == 2 && flid == FConstruct::fclBlockdata_end_blockdata)
1236 {
1237 pos = FindText(control, pos+1, lineEndPos, sW, wxSCI_FIND_WORDSTART);
1238 wordendpos = control->WordEndPosition(pos, true);
1239 foundWord = control->GetTextRange(pos, wordendpos).Lower();
1240 if (foundWord.IsSameAs(_T("block")))
1241 {
1242 str2 = foundWord;
1243 str2Pos = pos;
1244 sW = sWord3;
1245 pos = FindText(control, pos+1, lineEndPos, sW, wxSCI_FIND_WHOLEWORD);
1246 if (pos == wxSCI_INVALID_POSITION)
1247 return str1Pos;
1248 else
1249 {
1250 str3 = sW;
1251 str3Pos = pos;
1252 return str1Pos;
1253 }
1254 }
1255 else if (foundWord.IsSameAs(_T("blockdata")))
1256 {
1257 str2 = foundWord;
1258 str2Pos = pos;
1259 return str1Pos;
1260 }
1261 else
1262 return wxSCI_INVALID_POSITION;
1263 }
1264 else
1265 pos = FindText(control, pos+1, lineEndPos, sW, wxSCI_FIND_WHOLEWORD);
1266
1267 if (pos == wxSCI_INVALID_POSITION)
1268 return str1Pos; // Second word was not found.
1269 if (nUsed == 2)
1270 {
1271 str2 = sW;
1272 str2Pos = pos;
1273 if (!sWord3.IsEmpty())
1274 {
1275 pos = FindText(control, pos+1, lineEndPos, sWord3, wxSCI_FIND_WHOLEWORD);
1276 if (pos != wxSCI_INVALID_POSITION)
1277 {
1278 str3 = sWord3;
1279 str3Pos = pos;
1280 }
1281 }
1282 }
1283 else // (nUsed == 3)
1284 {
1285 str2 = sW;
1286 str2Pos = pos;
1287 }
1288
1289 return str1Pos;
1290 }
1291 else
1292 {
1293 pStart = searchBack? pos : pos+foundWord.Length();
1294 }
1295 }
1296 return wxSCI_INVALID_POSITION;
1297 }
1298
GetKeyworsFromLine(cbStyledTextCtrl * control,FConstruct::FCLid flid,int lineStartPos,int lineEndPos,wxString & str1,wxString & str2,wxString & str3,int & str1Pos,int & str2Pos,int & str3Pos)1299 void ConstrHighlighter::GetKeyworsFromLine(cbStyledTextCtrl* control, FConstruct::FCLid flid, int lineStartPos, int lineEndPos,
1300 wxString& str1, wxString& str2, wxString& str3, int& str1Pos, int& str2Pos, int& str3Pos)
1301 {
1302 str1 = wxEmptyString;
1303 str2 = wxEmptyString;
1304 str3 = wxEmptyString;
1305
1306 if (FConstruct::FCLWordMap.count(flid) == 0)
1307 return;
1308
1309 std::vector<wxString> sWords = FConstruct::FCLWordMap[flid];
1310 wxString sw;
1311 int nFilled = 0;
1312 for (size_t i=0; i<3; i++)
1313 {
1314 if (sWords[i].IsEmpty())
1315 break;
1316 sw.Append(sWords[i]);
1317
1318 int pos = FindText(control, lineStartPos, lineEndPos, sw, wxSCI_FIND_WHOLEWORD);
1319 if (pos != wxSCI_INVALID_POSITION)
1320 {
1321 if (nFilled == 0)
1322 {
1323 str1 = sw;
1324 str1Pos = pos;
1325 }
1326 else if (nFilled == 1)
1327 {
1328 str2 = sw;
1329 str2Pos = pos;
1330 }
1331 else
1332 {
1333 str3 = sw;
1334 str3Pos = pos;
1335 }
1336 sw = wxEmptyString;
1337 nFilled++;
1338 }
1339 }
1340 }
1341
FindText(cbStyledTextCtrl * control,int pStart,int pEnd,const wxString & sWord,int flag)1342 int ConstrHighlighter::FindText(cbStyledTextCtrl* control, int pStart, int pEnd, const wxString& sWord, int flag)
1343 {
1344 int pos;
1345 int pS = pStart;
1346 while (true)
1347 {
1348 pos = control->FindText(pS, pEnd, sWord, flag);
1349 if (pos == wxSCI_INVALID_POSITION)
1350 return pos;
1351 else if (IsCommentOrString(control, pos))
1352 pS = pos + 1;
1353 else
1354 return pos;
1355 }
1356 }
1357
IsCommentOrString(cbStyledTextCtrl * control,int pos)1358 bool ConstrHighlighter::IsCommentOrString(cbStyledTextCtrl* control, int pos)
1359 {
1360 int line = control->LineFromPosition(pos);
1361 int lineStartPos = control->PositionFromLine(line);
1362 bool inStr1 = false;
1363 bool inStr2 = false;
1364 bool inCom = false;
1365
1366 if (m_CurrentSForm == fsfFixed && lineStartPos <= pos)
1367 {
1368 const wxChar cch = control->GetCharAt(lineStartPos);
1369 if (cch == 'C' || cch == 'c' || cch == '*' || cch == '!')
1370 return true; // comment line in fixed format file
1371 }
1372
1373 for (int i=lineStartPos; i<pos; i++)
1374 {
1375 const wxChar cch = control->GetCharAt(i);
1376 if (cch == '!' && !inStr1 && !inStr2)
1377 {
1378 inCom = true;
1379 break;
1380 }
1381 else if (cch == '\'' && !inStr2)
1382 {
1383 if (inStr1)
1384 inStr1 = false;
1385 else
1386 inStr1 = true;
1387 }
1388 else if (cch == '"' && !inStr1)
1389 {
1390 if (inStr2)
1391 inStr2 = false;
1392 else
1393 inStr2 = true;
1394 }
1395 }
1396
1397 if (inCom || inStr1 || inStr2)
1398 return true;
1399 else
1400 return false;
1401 }
1402
GetFortranConstruct(const Keyword & word1,const Keyword & word2,const Keyword & word3,FConstruct & fcon)1403 void ConstrHighlighter::GetFortranConstruct(const Keyword &word1, const Keyword &word2, const Keyword &word3, FConstruct &fcon)
1404 {
1405 fcon.Clear();
1406 wxString str = word1.word + word2.word + word3.word;
1407 if (m_FConstructTypeMap.count(str) == 0)
1408 return;
1409
1410 wxString estr;
1411 FConstruct::FConstructType fct = m_FConstructTypeMap[str];
1412 if (fct == FConstruct::ctProgramGroup || fct == FConstruct::ctSelectGroup)
1413 fcon.SetType(fct);
1414 else if (fct == FConstruct::ctIf)
1415 {
1416 fcon.AddPart(_T("if"), _T("then"), estr);
1417 fcon.AddPart(_T("else"), _T("if"), _T("then"));
1418 fcon.AddPart(_T("else"), estr, estr);
1419 fcon.AddPart(_T("end"), _T("if"), estr);
1420 fcon.SetType(FConstruct::ctIf);
1421 }
1422 else if (fct == FConstruct::ctDo)
1423 {
1424 fcon.AddPart(_T("do"), estr, estr);
1425 fcon.AddPart(_T("end"), _T("do"), estr);
1426 fcon.SetType(FConstruct::ctDo);
1427 }
1428 else if (fct == FConstruct::ctInterface)
1429 {
1430 fcon.AddPart(_T("interface"), estr, estr);
1431 fcon.AddPart(_T("end"), _T("interface"), estr);
1432 fcon.SetType(FConstruct::ctInterface);
1433 }
1434 else if (fct == FConstruct::ctFunction)
1435 {
1436 fcon.AddPart(_T("function"), estr, estr);
1437 fcon.AddPart(_T("end"), _T("function"), estr);
1438 fcon.SetType(FConstruct::ctFunction);
1439 }
1440 else if (fct == FConstruct::ctSubroutine)
1441 {
1442 fcon.AddPart(_T("subroutine"), estr, estr);
1443 fcon.AddPart(_T("end"), _T("subroutine"), estr);
1444 fcon.SetType(FConstruct::ctSubroutine);
1445 }
1446 else if (fct == FConstruct::ctProgram)
1447 {
1448 fcon.AddPart(_T("program"), estr, estr);
1449 fcon.AddPart(_T("end"), _T("program"), estr);
1450 fcon.SetType(FConstruct::ctProgram);
1451 }
1452 else if (fct == FConstruct::ctModule)
1453 {
1454 fcon.AddPart(_T("module"), estr, estr);
1455 fcon.AddPart(_T("end"), _T("module"), estr);
1456 fcon.SetType(FConstruct::ctModule);
1457 }
1458 else if (fct == FConstruct::ctSubmodule)
1459 {
1460 fcon.AddPart(_T("submodule"), estr, estr);
1461 fcon.AddPart(_T("end"), _T("submodule"), estr);
1462 fcon.SetType(FConstruct::ctSubmodule);
1463 }
1464 else if (fct == FConstruct::ctType)
1465 {
1466 fcon.AddPart(_T("type"), estr, estr);
1467 fcon.AddPart(_T("end"), _T("type"), estr);
1468 fcon.SetType(FConstruct::ctType);
1469 }
1470 else if (fct == FConstruct::ctEnum)
1471 {
1472 fcon.AddPart(_T("enum"), estr, estr);
1473 fcon.AddPart(_T("end"), _T("enum"), estr);
1474 fcon.SetType(FConstruct::ctEnum);
1475 }
1476 else if (fct == FConstruct::ctCritical)
1477 {
1478 fcon.AddPart(_T("critical"), estr, estr);
1479 fcon.AddPart(_T("end"), _T("critical"), estr);
1480 fcon.SetType(FConstruct::ctCritical);
1481 }
1482 else if (fct == FConstruct::ctForall)
1483 {
1484 fcon.AddPart(_T("forall"), estr, estr);
1485 fcon.AddPart(_T("end"), _T("forall"), estr);
1486 fcon.SetType(FConstruct::ctForall);
1487 }
1488 else if (fct == FConstruct::ctAssiciate)
1489 {
1490 fcon.AddPart(_T("associate"), estr, estr);
1491 fcon.AddPart(_T("end"), _T("associate"), estr);
1492 fcon.SetType(FConstruct::ctAssiciate);
1493 }
1494 else if (fct == FConstruct::ctBlock)
1495 {
1496 fcon.AddPart(_T("block"), estr, estr);
1497 fcon.AddPart(_T("end"), _T("block"), estr);
1498 fcon.SetType(FConstruct::ctBlock);
1499 }
1500 else if (fct == FConstruct::ctTeam)
1501 {
1502 fcon.AddPart(_T("change"), _T("team"), estr);
1503 fcon.AddPart(_T("end"), _T("team"), estr);
1504 fcon.SetType(FConstruct::ctTeam);
1505 }
1506 else if (fct == FConstruct::ctWhere)
1507 {
1508 fcon.AddPart(_T("where"), estr, estr);
1509 fcon.AddPart(_T("else"), _T("where"), estr);
1510 fcon.AddPart(_T("end"), _T("where"), estr);
1511 fcon.SetType(FConstruct::ctWhere);
1512 }
1513 else if (fct == FConstruct::ctBlockdata)
1514 {
1515 fcon.AddPart(_T("block"), _T("data"), estr);
1516 fcon.AddPart(_T("end"), _T("block"), _T("data"));
1517 fcon.SetType(FConstruct::ctBlockdata);
1518 }
1519 else if (fct == FConstruct::ctProcedure)
1520 {
1521 fcon.AddPart(_T("module"), _T("procedure"), estr);
1522 fcon.AddPart(_T("end"), _T("procedure"), estr);
1523 fcon.SetType(FConstruct::ctProcedure);
1524 }
1525 }
1526
GetSearchDirection(const Keyword & word1,const Keyword & word2,const Keyword & word3,SearchDirection & sdir,FConstruct & unFconBack,FConstruct & unFconForth)1527 void ConstrHighlighter::GetSearchDirection(const Keyword &word1, const Keyword &word2, const Keyword &word3,
1528 SearchDirection& sdir, FConstruct& unFconBack, FConstruct& unFconForth)
1529 {
1530 sdir = sdirUnknown;
1531 unFconBack.Clear();
1532 unFconForth.Clear();
1533 wxString str = word1.word + word2.word + word3.word;
1534 if (m_FConstructTypeMap.count(str) == 0)
1535 return;
1536
1537 FConstruct::FConstructType fct = m_FConstructTypeMap[str];
1538 wxString estr;
1539
1540 if (fct == FConstruct::ctProgramGroup)
1541 {
1542 if (str.IsSameAs(_T("end")) || str.IsSameAs(_T("endfunction")) || str.IsSameAs(_T("endsubroutine")) ||
1543 str.IsSameAs(_T("endprogram")) || str.IsSameAs(_T("endmodule")) || str.IsSameAs(_T("endsubmodule")) ||
1544 str.IsSameAs(_T("endblockdata")) || str.IsSameAs(_T("endprocedure")))
1545 {
1546 sdir = sdirBack;
1547 }
1548 else if (str.IsSameAs(_T("function")) || str.IsSameAs(_T("subroutine")) || str.IsSameAs(_T("program")) ||
1549 str.IsSameAs(_T("module")) || str.IsSameAs(_T("submodule")) || str.IsSameAs(_T("blockdata")) ||
1550 str.IsSameAs(_T("moduleprocedure")))
1551 {
1552 sdir = sdirForth;
1553 }
1554 }
1555 else if (fct== FConstruct::ctSelectGroup)
1556 {
1557 if (str.IsSameAs(_T("selectcase")) || str.IsSameAs(_T("selecttype")))
1558 {
1559 sdir = sdirForth;
1560 unFconForth.AddPart(_T("case"), estr, estr);
1561 unFconForth.AddPart(_T("case"), _T("default"), estr);
1562 unFconForth.AddPart(_T("type"), _T("is"), estr);
1563 unFconForth.AddPart(_T("class"), _T("is"), estr);
1564 unFconForth.AddPart(_T("class"), _T("default"), estr);
1565 unFconForth.AddPart(_T("end"), _T("select"), estr);
1566 }
1567 else if (str.IsSameAs(_T("endselect")))
1568 {
1569 sdir = sdirBack;
1570 unFconBack.AddPart(_T("select"), _T("case"), estr);
1571 unFconBack.AddPart(_T("case"), estr, estr);
1572 unFconBack.AddPart(_T("case"), _T("default"), estr);
1573 unFconBack.AddPart(_T("type"), _T("is"), estr);
1574 unFconBack.AddPart(_T("class"), _T("is"), estr);
1575 unFconBack.AddPart(_T("class"), _T("default"), estr);
1576 }
1577 else if (str.IsSameAs(_T("case")) || str.IsSameAs(_T("casedefault")))
1578 {
1579 sdir = sdirBackForth;
1580 unFconForth.AddPart(_T("case"), estr, estr);
1581 unFconForth.AddPart(_T("case"), _T("default"), estr);
1582 unFconForth.AddPart(_T("end"), _T("select"), estr);
1583
1584 unFconBack.AddPart(_T("select"), _T("case"), estr);
1585 unFconBack.AddPart(_T("case"), estr, estr);
1586 }
1587 else if (str.IsSameAs(_T("typeis")) || str.IsSameAs(_T("classis")) || str.IsSameAs(_T("classdefault")))
1588 {
1589 sdir = sdirBackForth;
1590 unFconForth.AddPart(_T("type"), _T("is"), estr);
1591 unFconForth.AddPart(_T("class"), _T("is"), estr);
1592 unFconForth.AddPart(_T("class"), _T("default"), estr);
1593 unFconForth.AddPart(_T("end"), _T("select"), estr);
1594
1595 unFconBack.AddPart(_T("select"), _T("type"), estr);
1596 unFconBack.AddPart(_T("type"), _T("is"), estr);
1597 unFconBack.AddPart(_T("class"), _T("is"), estr);
1598 unFconBack.AddPart(_T("class"), _T("default"), estr);
1599 }
1600 }
1601 else if (fct == FConstruct::ctIf)
1602 {
1603 if (str == _T("ifthen") || str == _T("elseifthen"))
1604 {
1605 sdir = sdirForth;
1606 unFconForth.AddPart(_T("else"), _T("if"), _T("then"));
1607 unFconForth.AddPart(_T("else"), estr, estr);
1608 unFconForth.AddPart(_T("end"), _T("if"), estr);
1609
1610 if (str == _T("elseifthen"))
1611 {
1612 sdir = sdirBackForth;
1613 unFconBack.AddPart(_T("if"), _T("then"), estr);
1614 unFconBack.AddPart(_T("else"), _T("if"), _T("then"));
1615 }
1616 }
1617 else if (str == _T("else"))
1618 {
1619 sdir = sdirBackForth;
1620 unFconForth.AddPart(_T("end"), _T("if"), estr);
1621
1622 unFconBack.AddPart(_T("if"), _T("then"), estr);
1623 unFconBack.AddPart(_T("else"), _T("if"), _T("then"));
1624 }
1625 else if (str == _T("endif"))
1626 {
1627 sdir = sdirBack;
1628 unFconBack.AddPart(_T("if"), _T("then"), estr);
1629 unFconBack.AddPart(_T("else"), _T("if"), _T("then"));
1630 unFconBack.AddPart(_T("else"), estr, estr);
1631 }
1632 }
1633 else if (fct == FConstruct::ctDo)
1634 {
1635 if (str.StartsWith(_T("do")))
1636 {
1637 sdir = sdirForth;
1638 unFconForth.AddPart(_T("end"), _T("do"), estr);
1639 }
1640 else if (str == _T("enddo"))
1641 {
1642 sdir = sdirBack;
1643 unFconBack.AddPart(_T("do"), estr, estr);
1644 }
1645 }
1646 else if (fct == FConstruct::ctInterface)
1647 {
1648 if (str == _T("interface") || str == _T("abstractinterface"))
1649 {
1650 sdir = sdirForth;
1651 unFconForth.AddPart(_T("end"), _T("interface"), estr);
1652 }
1653 else if (str == _T("endinterface"))
1654 {
1655 sdir = sdirBack;
1656 unFconBack.AddPart(_T("interface"), estr, estr);
1657 }
1658 }
1659 else if (fct == FConstruct::ctType)
1660 {
1661 if (str == _T("type"))
1662 {
1663 sdir = sdirForth;
1664 unFconForth.AddPart(_T("end"), _T("type"), estr);
1665 }
1666 else if (str == _T("endtype"))
1667 {
1668 sdir = sdirBack;
1669 unFconBack.AddPart(_T("type"), estr, estr);
1670 }
1671 }
1672 else if (fct == FConstruct::ctEnum)
1673 {
1674 if (str == _T("enum"))
1675 {
1676 sdir = sdirForth;
1677 unFconForth.AddPart(_T("end"), _T("enum"), estr);
1678 }
1679 else if (str == _T("endenum"))
1680 {
1681 sdir = sdirBack;
1682 unFconBack.AddPart(_T("enum"), estr, estr);
1683 }
1684 }
1685 else if (fct == FConstruct::ctCritical)
1686 {
1687 if (str == _T("critical"))
1688 {
1689 sdir = sdirForth;
1690 unFconForth.AddPart(_T("end"), _T("critical"), estr);
1691 }
1692 else if (str == _T("endcritical"))
1693 {
1694 sdir = sdirBack;
1695 unFconBack.AddPart(_T("critical"), estr, estr);
1696 }
1697 }
1698 else if (fct == FConstruct::ctForall)
1699 {
1700 if (str == _T("forall"))
1701 {
1702 sdir = sdirForth;
1703 unFconForth.AddPart(_T("end"), _T("forall"), estr);
1704 }
1705 else if (str == _T("endforall"))
1706 {
1707 sdir = sdirBack;
1708 unFconBack.AddPart(_T("forall"), estr, estr);
1709 }
1710 }
1711 else if (fct == FConstruct::ctAssiciate)
1712 {
1713 if (str == _T("associate"))
1714 {
1715 sdir = sdirForth;
1716 unFconForth.AddPart(_T("end"), _T("associate"), estr);
1717 }
1718 else if (str == _T("endassociate"))
1719 {
1720 sdir = sdirBack;
1721 unFconBack.AddPart(_T("associate"), estr, estr);
1722 }
1723 }
1724 else if (fct == FConstruct::ctBlock)
1725 {
1726 if (str == _T("block"))
1727 {
1728 sdir = sdirForth;
1729 unFconForth.AddPart(_T("end"), _T("block"), estr);
1730 }
1731 else if (str == _T("endblock"))
1732 {
1733 sdir = sdirBack;
1734 unFconBack.AddPart(_T("block"), estr, estr);
1735 }
1736 }
1737 else if (fct == FConstruct::ctTeam)
1738 {
1739 if (str == _T("changeteam"))
1740 {
1741 sdir = sdirForth;
1742 unFconForth.AddPart(_T("end"), _T("team"), estr);
1743 }
1744 else if (str == _T("endteam"))
1745 {
1746 sdir = sdirBack;
1747 unFconBack.AddPart(_T("change"), _T("team"), estr);
1748 }
1749 }
1750 else if (fct == FConstruct::ctWhere)
1751 {
1752 if (str == _T("where"))
1753 {
1754 sdir = sdirForth;
1755 unFconForth.AddPart(_T("else"), _T("where"), estr);
1756 unFconForth.AddPart(_T("end"), _T("where"), estr);
1757 }
1758 else if (str == _T("endwhere"))
1759 {
1760 sdir = sdirBack;
1761 unFconBack.AddPart(_T("where"), estr, estr);
1762 unFconBack.AddPart(_T("else"), _T("where"), estr);
1763 }
1764 else if (str == _T("elsewhere"))
1765 {
1766 sdir = sdirBackForth;
1767 unFconBack.AddPart(_T("where"), estr, estr);
1768 unFconBack.AddPart(_T("else"), _T("where"), estr);
1769
1770 unFconForth.AddPart(_T("else"), _T("where"), estr);
1771 unFconForth.AddPart(_T("end"), _T("where"), estr);
1772 }
1773 }
1774 }
1775
GetFortranLine(cbStyledTextCtrl * control,int pos,wxString & fLine,int & lineStartPos,int & lineEndPos)1776 void ConstrHighlighter::GetFortranLine(cbStyledTextCtrl* control, int pos, wxString& fLine, int& lineStartPos, int& lineEndPos)
1777 {
1778 bool tryBack;
1779 bool withContinuation;
1780 fLine = GetFortranLine2(control, pos, lineStartPos, lineEndPos, tryBack, withContinuation, true);
1781 if (m_CurrentSForm == fsfFree)
1782 {
1783 while (tryBack)
1784 {
1785 if (control->LineFromPosition(lineStartPos) == 0)
1786 break;
1787 pos = lineStartPos - 1;
1788 int lep;
1789 int lsBackPos;
1790 wxString lineBack = GetFortranLine2(control, pos, lsBackPos, lep, tryBack, withContinuation, false);
1791 if (withContinuation)
1792 {
1793 lineStartPos = lsBackPos;
1794 fLine.Prepend(lineBack);
1795 }
1796 else
1797 break;
1798 }
1799 }
1800 else // (m_CurrentSForm == fsfFixed)
1801 {
1802 while (tryBack && withContinuation)
1803 {
1804 if (control->LineFromPosition(lineStartPos) == 0)
1805 break;
1806 pos = lineStartPos - 1;
1807 int lep;
1808 int lsBackPos;
1809 wxString lineBack = GetFortranLine2(control, pos, lsBackPos, lep, tryBack, withContinuation, false);
1810 lineStartPos = lsBackPos;
1811 fLine.Prepend(lineBack);
1812 }
1813 }
1814 fLine = CutBracketsLevel2(fLine);
1815 fLine.Replace(_T("\t"), _T(" "));
1816 fLine.Trim();
1817 }
1818
GetFortranLine2(cbStyledTextCtrl * control,int posC,int & posStart,int & posEnd,bool & tryBack,bool & withContinuation,bool goForth)1819 wxString ConstrHighlighter::GetFortranLine2(cbStyledTextCtrl* control, int posC, int& posStart, int& posEnd, bool& tryBack,
1820 bool& withContinuation, bool goForth)
1821 {
1822 int line = control->LineFromPosition(posC);
1823 wxString lineStr = control->GetLine(line);
1824 posStart = control->PositionFromLine(line);
1825 posEnd = control->PositionFromLine(line+1);
1826 tryBack = true;
1827 withContinuation = false;
1828 bool inStr1 = false;
1829 bool inStr2 = false;
1830 bool spaceOnly = true;
1831 int lsl = lineStr.length();
1832 if (m_CurrentSForm == fsfFixed)
1833 {
1834 if (lsl <= 6)
1835 return wxEmptyString;
1836 const wxChar cch = lineStr.GetChar(0);
1837 if (cch == 'C' || cch == 'c' || cch == '*' || cch == '!')
1838 return wxEmptyString; // comment line in fixed format file
1839 if (lineStr.GetChar(5) != ' ' && lineStr.GetChar(5) != '0')
1840 withContinuation = true;
1841 }
1842 int i = 0;
1843 while (i < lsl)
1844 {
1845 if (inStr1 && lineStr.GetChar(i) == '\'')
1846 inStr1 = false;
1847 else if (inStr2 && lineStr.GetChar(i) == '"')
1848 inStr2 = false;
1849 else if (inStr1 || inStr2)
1850 lineStr.SetChar(i, ' ');
1851 else if (lineStr.GetChar(i) == '\'')
1852 {
1853 inStr1 = true;
1854 spaceOnly = false;
1855 }
1856 else if (lineStr.GetChar(i) == '"')
1857 {
1858 inStr2 = true;
1859 spaceOnly = false;
1860 }
1861 else if (lineStr.GetChar(i) == '!')
1862 {
1863 if (posStart + i >= posC)
1864 {
1865 lineStr = lineStr.Mid(0, i);
1866 posEnd = posStart + i;
1867 break;
1868 }
1869 else
1870 {
1871 lineStr = _T("");
1872 break;
1873 }
1874 }
1875 else if (lineStr.GetChar(i) == '&')
1876 {
1877 lineStr.SetChar(i, ' ');
1878 if (!spaceOnly && (m_CurrentSForm == fsfFree))
1879 {
1880 lineStr = lineStr.Mid(0, i+1);
1881
1882 if (goForth && line+1 < control->GetLineCount())
1883 {
1884 int posStart2;
1885 bool tback, econ;
1886 lineStr.Append(GetFortranLine2(control, control->PositionFromLine(line+1), posStart2, posEnd, tback, econ, true));
1887 }
1888 else
1889 withContinuation = true;
1890 break;
1891 }
1892 }
1893 else if (lineStr.GetChar(i) == ';')
1894 {
1895 if (posStart + i >= posC)
1896 {
1897 lineStr = lineStr.Mid(0, i);
1898 posEnd = posStart + i;
1899 break;
1900 }
1901 else
1902 {
1903 posStart = posStart + i + 1;
1904 lineStr = lineStr.Mid(i+1);
1905 lsl = lineStr.length();
1906 i = -1;
1907 tryBack = false;
1908 spaceOnly = false;
1909 }
1910 }
1911 else if (spaceOnly)
1912 spaceOnly = false;
1913 i++;
1914 }
1915
1916 if (m_CurrentSForm == fsfFixed)
1917 {
1918 if (goForth && line+1 < control->GetLineCount())
1919 {
1920 int posStart2;
1921 bool tback;
1922 bool wCon;
1923 wxString nextLine = GetFortranLine2(control, control->PositionFromLine(line+1), posStart2, posEnd, tback, wCon, true);
1924 if (wCon)
1925 lineStr.Append(nextLine);
1926 }
1927 }
1928 return lineStr;
1929 }
1930
CutBracketsLevel2(const wxString & str)1931 wxString ConstrHighlighter::CutBracketsLevel2(const wxString& str)
1932 {
1933 wxString retStr = str;
1934 int pos = str.Find('(');
1935 if (pos == wxNOT_FOUND)
1936 return retStr;
1937
1938 std::vector<int> cutStart;
1939 std::vector<int> cutEnd;
1940 int level = 0;
1941 for (size_t i=pos; i<str.Len(); i++)
1942 {
1943 if (str.GetChar(i) == '(')
1944 {
1945 if (level == 1)
1946 {
1947 cutStart.push_back(i);
1948 cutEnd.push_back(wxString::npos);
1949 }
1950 level++;
1951 }
1952 else if (str.GetChar(i) == ')')
1953 {
1954 if (level == 2)
1955 cutEnd[cutEnd.size()-1] = i;
1956 level--;
1957 }
1958 }
1959
1960 for (int i=int(cutStart.size())-1; i>=0; i--)
1961 {
1962 if (cutEnd[i] != int(wxString::npos))
1963 retStr = retStr.Mid(0,cutStart[i]) + _T(" ") + retStr.Mid(cutEnd[i]+1);
1964 else
1965 retStr = retStr.Mid(0,cutStart[i]) + _T(" ");
1966 }
1967 return retStr;
1968 }
1969
FindLimitPos(cbStyledTextCtrl * control,const FConstruct & fcon,int posStart,SearchDirection sdir)1970 int ConstrHighlighter::FindLimitPos(cbStyledTextCtrl* control, const FConstruct& fcon, int posStart, SearchDirection sdir)
1971 {
1972 int pEnd = (sdir == sdirBack) ? 0 : control->GetLength();
1973 int rpEnd = pEnd;
1974 FConstruct::FConstructType ct = fcon.GetType();
1975 if (ct == FConstruct::ctIf || ct == FConstruct::ctDo || ct == FConstruct::ctSelectGroup ||
1976 ct == FConstruct::ctCritical || ct == FConstruct::ctForall || ct == FConstruct::ctEnum ||
1977 ct == FConstruct::ctType || ct == FConstruct::ctAssiciate || ct == FConstruct::ctBlock ||
1978 ct == FConstruct::ctTeam )
1979 {
1980 wxString str1, str2, str3;
1981 int str1Pos, str2Pos, str3Pos;
1982
1983 if (sdir == sdirBack)
1984 {
1985 wxString word1 = _T("subroutine");
1986 wxString word2;
1987 wxString word3;
1988 FConstruct::FCLid flid1 = FConstruct::fclSub_sub;
1989 int cp1 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
1990 str1, str1Pos, str2, str2Pos, str3, str3Pos);
1991 if (cp1 == wxSCI_INVALID_POSITION)
1992 cp1 = rpEnd;
1993 else
1994 pEnd = cp1 + 10;
1995
1996 word1 = _T("function");
1997 word2 = wxEmptyString;
1998 word3 = wxEmptyString;
1999 flid1 = FConstruct::fclFun_fun;
2000 int cp2 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2001 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2002 if (cp2 == wxSCI_INVALID_POSITION)
2003 cp2 = rpEnd;
2004 else
2005 pEnd = cp2 + 8;
2006
2007 word1 = _T("program");
2008 word2 = wxEmptyString;
2009 word3 = wxEmptyString;
2010 flid1 = FConstruct::fclProg_prog;
2011 int cp3 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2012 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2013 if (cp3 == wxSCI_INVALID_POSITION)
2014 cp3 = rpEnd;
2015
2016 return std::max(std::max(cp1,cp2),cp3);
2017 }
2018 else
2019 {
2020 wxString word1 = _T("end");
2021 wxString word2 = _T("subroutine");
2022 wxString word3;
2023 FConstruct::FCLid flid1 = FConstruct::fclSub_end_sub;
2024 int cp1 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2025 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2026 if (cp1 == wxSCI_INVALID_POSITION)
2027 cp1 = rpEnd;
2028 else
2029 pEnd = cp1;
2030
2031 word1 = _T("end");
2032 word2 = _T("function");
2033 word3 = wxEmptyString;
2034 flid1 = FConstruct::fclFun_fun;
2035 int cp2 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2036 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2037 if (cp2 == wxSCI_INVALID_POSITION)
2038 cp2 = rpEnd;
2039 else
2040 pEnd = cp2;
2041
2042 word1 = _T("end");
2043 word2 = _T("program");
2044 word3 = wxEmptyString;
2045 flid1 = FConstruct::fclProg_prog;
2046 int cp3 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2047 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2048 if (cp3 == wxSCI_INVALID_POSITION)
2049 cp3 = rpEnd;
2050
2051 return std::min(std::min(cp1,cp2),cp3);
2052 }
2053 }
2054 else if (ct == FConstruct::ctProgramGroup || ct == FConstruct::ctInterface)
2055 {
2056 wxString str1, str2, str3;
2057 int str1Pos, str2Pos, str3Pos;
2058
2059 if (sdir == sdirBack)
2060 {
2061 wxString word1 = _T("module");
2062 wxString word2;
2063 wxString word3;
2064 FConstruct::FCLid flid1 = FConstruct::fclMod_module;
2065 int cp1 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2066 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2067 if (cp1 == wxSCI_INVALID_POSITION)
2068 cp1 = rpEnd;
2069 else
2070 pEnd = cp1 + 6;
2071
2072 word1 = _T("end");
2073 word2 = _T("module");
2074 word3 = wxEmptyString;
2075 flid1 = FConstruct::fclMod_end_module;
2076 int cp2 = FindFKeywordFull(control, posStart, pEnd, flid1, word1, word2, word3,
2077 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2078 if (cp2 == wxSCI_INVALID_POSITION)
2079 cp2 = rpEnd;
2080 else
2081 pEnd = cp2 + 3;
2082
2083 word1 = _T("submodule");
2084 word2 = wxEmptyString;
2085 word3 = wxEmptyString;
2086 flid1 = FConstruct::fclSubmod_submod;
2087 int cp3 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2088 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2089 if (cp3 == wxSCI_INVALID_POSITION)
2090 cp3 = rpEnd;
2091
2092 return std::max(std::max(cp1,cp2),cp3);
2093 }
2094 else
2095 {
2096 wxString word1 = _T("end");
2097 wxString word2 = _T("module");
2098 wxString word3;
2099 FConstruct::FCLid flid1 = FConstruct::fclMod_end_module;
2100
2101 int cp1 = FindFKeywordFull(control, posStart, pEnd, flid1, word1, word2, word3,
2102 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2103 if (cp1 != wxSCI_INVALID_POSITION)
2104 {
2105 pEnd = cp1;
2106 cp1 = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
2107 }
2108
2109 word1 = _T("module");
2110 word2 = wxEmptyString;
2111 word3 = wxEmptyString;
2112 flid1 = FConstruct::fclMod_module;
2113
2114 int cp2 = FindFKeyword(control, posStart, pEnd, flid1, word1, word2, word3,
2115 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2116 if (cp2 != wxSCI_INVALID_POSITION)
2117 pEnd = cp2;
2118 word1 = _T("end");
2119 word2 = _T("submodule");
2120 word3 = wxEmptyString;
2121 flid1 = FConstruct::fclSubmod_end_submod;
2122
2123 int cp3 = FindFKeywordFull(control, posStart, pEnd, flid1, word1, word2, word3,
2124 str1, str1Pos, str2, str2Pos, str3, str3Pos);
2125 if (cp3 != wxSCI_INVALID_POSITION)
2126 cp3 = GetWordsEnd(str1, str1Pos, str2, str2Pos, str3, str3Pos);
2127 if (cp1 == wxSCI_INVALID_POSITION)
2128 cp1 = rpEnd;
2129 if (cp2 == wxSCI_INVALID_POSITION)
2130 cp2 = rpEnd;
2131 if (cp3 == wxSCI_INVALID_POSITION)
2132 cp3 = rpEnd;
2133
2134 return std::min(std::min(cp1,cp2),cp3);
2135 }
2136 }
2137 return rpEnd;
2138 }
2139
2140
2141