1
2 #include "indentestimator.h"
3
4 #include <sdk.h>
5 #ifndef CB_PRECOMP
6 #include <wx/tokenzr.h>
7 #include <configmanager.h>
8 #endif
9
FormatIndentCodeTree()10 FormatIndentCodeTree::FormatIndentCodeTree()
11 {
12 Initialize(0);
13 }
14
~FormatIndentCodeTree()15 FormatIndentCodeTree::~FormatIndentCodeTree()
16 {
17
18 }
19
Initialize(int firstLineIndent)20 void FormatIndentCodeTree::Initialize(int firstLineIndent)
21 {
22 m_Tree.clear();
23 m_RootIndent = firstLineIndent;
24 }
25
GetCodeTreeIndent(CodeTreeKind iKind,int & myIndent)26 void FormatIndentCodeTree::GetCodeTreeIndent(CodeTreeKind iKind, int& myIndent)
27 {
28 if (iKind == ctcNone)
29 return;
30 else if (iKind == ctcAssociate || iKind == ctcCritical || iKind == ctcDoForall || iKind == ctcEnum ||
31 iKind == ctcFunction || iKind == ctcIfThen || iKind == ctcInterface || iKind == ctcProgramBlock ||
32 iKind == ctcModule || iKind == ctcSeclectCase || iKind == ctcSeclectType ||
33 iKind == ctcSubmodule || iKind == ctcSubroutine || iKind == ctcTypeDefine ||
34 iKind == ctcWhere)
35 {
36 treeNode tn;
37 tn.indent = myIndent;
38 tn.kind = iKind;
39 m_Tree.push_back(tn);
40 return;
41 }
42
43 CodeTreeKind startKind1 = ctcNone;
44 CodeTreeKind startKind2 = ctcNone;
45 CodeTreeKind startKind3 = ctcNone;
46 CodeTreeKind startKind4 = ctcNone;
47 CodeTreeKind startKind5 = ctcNone;
48 if (iKind == ctcEndAssociate)
49 startKind1 = ctcAssociate;
50 else if (iKind == ctcEndCritical)
51 startKind1 = ctcCritical;
52 else if (iKind == ctcEndDoForall)
53 startKind1 = ctcDoForall;
54 else if (iKind == ctcEndEnum)
55 startKind1 = ctcEnum;
56 else if (iKind == ctcEndInterface)
57 startKind1 = ctcInterface;
58 else if (iKind == ctcEndProgramBlockSubFun)
59 {
60 startKind1 = ctcProgramBlock;
61 startKind2 = ctcSubroutine;
62 startKind3 = ctcFunction;
63 }
64 else if (iKind == ctcEndModule)
65 startKind1 = ctcModule;
66 else if (iKind == ctcEndSeclectCase)
67 {
68 startKind1 = ctcSeclectCase;
69 startKind2 = ctcSeclectType;
70 }
71 else if (iKind == ctcEndSubmodule)
72 startKind1 = ctcSubmodule;
73 else if (iKind == ctcEndTypeDefine)
74 startKind1 = ctcTypeDefine;
75 else if (iKind == ctcEndWhere)
76 startKind1 = ctcWhere;
77 else if (iKind == ctcEndIf)
78 startKind1 = ctcIfThen;
79 else if (iKind == ctcEnd)
80 {
81 startKind1 = ctcProgramBlock;
82 startKind2 = ctcSubroutine;
83 startKind3 = ctcFunction;
84 startKind4 = ctcModule;
85 startKind5 = ctcSubmodule;
86 }
87
88 for (int i=int(m_Tree.size())-1; i >= 0; i--)
89 {
90 if ((m_Tree[i].kind == startKind1) ||
91 (m_Tree[i].kind == startKind2) ||
92 (m_Tree[i].kind == startKind3) ||
93 (m_Tree[i].kind == startKind4) ||
94 (m_Tree[i].kind == startKind5))
95 {
96 myIndent = m_Tree[i].indent;
97 m_Tree.resize(i);
98 break;
99 }
100 }
101 }
102
GetParentKind()103 FormatIndentCodeTree::CodeTreeKind FormatIndentCodeTree::GetParentKind()
104 {
105 CodeTreeKind pK = ctcNone;
106 if (m_Tree.size() > 0)
107 pK = m_Tree[m_Tree.size()-1].kind;
108
109 return pK;
110 }
111
112
113
114
115 //***************************************************************
116 //*
117 //***************************************************************
118
DelFormatIndentRegEx()119 void IndentEstimator::DelFormatIndentRegEx()
120 {
121 if( m_RegEx.empty() )
122 {
123 return ;
124 }
125 FormatIndentRegEx::iterator it = m_RegEx.begin();
126 // iterate over all the Hash Map
127 while( it != m_RegEx.end() )
128 {
129 wxRegEx * pIt = it->second;
130 delete pIt;
131 ++it;
132 }
133 m_RegEx.clear();
134 }
135
136
CreateFormatIndentRegEx()137 void IndentEstimator::CreateFormatIndentRegEx()
138 {
139 int options = wxRE_DEFAULT | wxRE_ADVANCED | wxRE_ICASE ;
140
141 DelFormatIndentRegEx();
142
143 m_RegEx[wxT("regexMultiLines")] = new wxRegEx( wxT("(&)((\r\n)|(\r)|(\n))?$"), options );
144 m_RegEx[wxT("regexEndProgram")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)((program)|((block)(\\s*)(data))|(subroutine)|(function))((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
145 m_RegEx[wxT("regexProgram")] = new wxRegEx( wxT("^(\\s*)((program)|((block)(\\s*)(data)))((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
146 m_RegEx[wxT("regexEndModule")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(module)((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
147 m_RegEx[wxT("regexModule")] = new wxRegEx( wxT("^(\\s*)(module)((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
148 m_RegEx[wxT("regexInterface")] = new wxRegEx( wxT("^(\\s*)((abstract)(\\s+))?(interface)((\\s+)(([a-zA-Z0-9_]+)|((assignment)(\\s*)\\((\\s*)(a+)(\\s*)\\))|((operator)(\\s*)\\((.+)\\))|((write|read)(\\s*)\\((.+)\\))))?((\\s*)!(.*))?(\\s*)$"), options );
149 m_RegEx[wxT("regexEndInterface")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(interface)((\\s+)(([a-zA-Z0-9_]+)|((assignment)(\\s*)\\((\\s*)(a+)(\\s*)\\))|((operator)(\\s*)\\((.+)\\))|((write|read)(\\s*)\\((.+)\\))))?((\\s*)!(.*))?(\\s*)$"), options );
150 m_RegEx[wxT("regexContains")] = new wxRegEx( wxT("^(\\s*)(contains)((\\s*)!(.*))?(\\s*)$"), options );
151 m_RegEx[wxT("regexSubroutine")] = new wxRegEx( wxT("^(\\s*)(((pure)|(impure)|(elemental)|(recursive)|(non_recursive)|(module))(\\s+))*((\\s+))?(subroutine)(\\s+)([a-zA-Z0-9_]+)((\\s*)(\\()(\\s*)(([a-zA-Z0-9_]+)((\\s*)(,)(\\s*)([a-zA-Z0-9_]+))*)?(\\s*)(\\))(\\s*))?"), options );
152 m_RegEx[wxT("regexFunction")] = new wxRegEx( wxT("^(((.*)(\\s+))|(\\s*)){1}(function)(\\s+)([a-zA-Z0-9_]+)(\\s*)\\((\\s*)(([a-zA-Z0-9_]+)((\\s*)(,)(\\s*)([a-zA-Z0-9_]+))*)?(\\s*)\\)"), options );
153 m_RegEx[wxT("regexType")] = new wxRegEx( wxT("^(\\s*)((type)(\\s*)(\\()(\\s*)([a-zA-Z0-9_]+)(\\s*)(\\)))(\\s*)"), options );
154 m_RegEx[wxT("regexTypeDefine")] = new wxRegEx( wxT("^(\\s*)((type)\\M((\\s*),(\\s*)((public)|(private)|(protected)))?((\\s*),(\\s*)((abstract)|((extends)(\\s*)\\((\\s*)([a-zA-Z0-9_]+)(\\s*)\\))))?((\\s*),(\\s*)((bind)(\\s*)\\((\\s*)([a-z0-9_]+)(\\s*)\\)))?((\\s*)(::)?(\\s*)([a-zA-Z0-9_]+)))(\\s*)"), options );
155 m_RegEx[wxT("regexEndType")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(type)((\\s+)([a-zA-Z0-9_]+))?(\\s*)"), options );
156 m_RegEx[wxT("regexEndDo")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)((do)|(forall))((\\s+)([a-zA-Z0-9_]+))?(\\s*)"), options );
157 m_RegEx[wxT("regexDo")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?(do)((\\s+)([a-zA-Z0-9_])(.+))?((\\s*)!(.*))?(\\s*)$"), options );
158 m_RegEx[wxT("regexForall")] = new wxRegEx( wxT("^([\\s\\t]*)([0-9]*)([\\s\\t]*)(([a-z0-9_]+)(\\s*)(:)(\\s*))?((forall)|((do)(\\s+)(while)))(\\s*)(\\([^\\)]+\\))(\\s*)$"), options );
159 m_RegEx[wxT("regexEndSelect")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(select)((\\s+)([a-zA-Z0-9_]+))?(\\s*)"), options );
160 m_RegEx[wxT("regexSelectCase")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?((select)(\\s*)(case))(\\s*)(\\()(.+)(\\))((\\s*)!(.*))?(\\s*)$"), options );
161 m_RegEx[wxT("regexSelectType")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?((select)(\\s*)(type))(\\s*)(\\()(.+)(\\))((\\s*)!(.*))?(\\s*)$"), options );
162 m_RegEx[wxT("regexCase")] = new wxRegEx( wxT("^(\\s*)((((case)|(((type)|(class))(\\s+)(is)))(\\s*)(\\()(.+)(\\))((\\s+)([a-zA-Z0-9_]+))?)|(((case)|(class))(\\s+)(default)((\\s+)([a-zA-Z0-9_]+))?))((\\s*)!(.*))?(\\s*)$"), options );
163 m_RegEx[wxT("regexIfThen")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?((if)(\\s*)(\\()(.+)(\\))(\\s*)(then))((\\s*)!(.*))?(\\s*)$"), options );
164 m_RegEx[wxT("regexElse")] = new wxRegEx( wxT("^(\\s*)(else)(\\s*)(((\\s+)([a-zA-Z0-9_]+))|((if)(\\s*)(\\()(.+)(\\))(\\s*)(then)((\\s+)([a-zA-Z0-9_]+))?))?((\\s*)!(.*))?(\\s*)$"), options );
165 m_RegEx[wxT("regexEndIf")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(if)((\\s+)([a-zA-Z0-9_]+))?(\\s*)"), options );
166 m_RegEx[wxT("regexWhere")] = new wxRegEx( wxT("^([\\s\\t]*)([0-9]*)([\\s\\t]*)(([a-z0-9_]+)(\\s*)(:)(\\s*))?(where)(\\s*)(\\([^\\)]+\\))(\\s*)$"), options );
167 m_RegEx[wxT("regexElseWhere")] = new wxRegEx( wxT("^(\\s*)(else)(\\s*)(where)(((\\s+)([a-zA-Z0-9_]+))|((\\s*)\\((.+)\\)((\\s+)([a-zA-Z0-9_]+))?))?((\\s*)!(.*))?(\\s*)$"), options );
168 m_RegEx[wxT("regexEndWhere")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(where)((\\s+)([a-zA-Z0-9_]+))?(\\s*)"), options );
169 m_RegEx[wxT("regexEndOnly")] = new wxRegEx( wxT("^(\\s*)(end)((\\s*)!(.*))?(\\s*)$"), options );
170
171 m_RegEx[wxT("regexAssociate")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?(associate)(\\s*)\\((.+)\\)((\\s*)!(.*))?(\\s*)$"), options );
172 m_RegEx[wxT("regexEndAssociate")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(associate)((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
173
174 m_RegEx[wxT("regexCritical")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?((block)|(critical))((\\s*)!(.*))?(\\s*)$"), options );
175 m_RegEx[wxT("regexEndCritical")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)((block)|(critical))((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
176
177 m_RegEx[wxT("regexSubmodule")] = new wxRegEx( wxT("^(\\s*)(([a-zA-Z0-9_]+)(\\s*)(:)(\\s*))?((submodule)(\\s*)\\((.+)\\)(\\s*)([a-zA-Z0-9_]+))((\\s*)!(.*))?(\\s*)$"), options );
178 m_RegEx[wxT("regexEndSubmodule")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(submodule)((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
179
180 m_RegEx[wxT("regexModuleProcedure")] = new wxRegEx( wxT("^(\\s*)(module(\\s*)procedure)(\\s*)([a-zA-Z0-9_]+)((\\s*)!(.*))?(\\s*)$"), options );
181 m_RegEx[wxT("regexEndProcedure")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(procedure)((\\s+)([a-zA-Z0-9_]+))?((\\s*)!(.*))?(\\s*)$"), options );
182
183 m_RegEx[wxT("regexEnum")] = new wxRegEx( wxT("^(\\s*)(enum)((\\s*),(\\s*)((bind)(\\s*)\\((\\s*)([a-zA-Z0-9_]+)(\\s*)\\)))((\\s*)!(.*))?(\\s*)$"), options );
184 m_RegEx[wxT("regexEndEnum")] = new wxRegEx( wxT("^(\\s*)(end)(\\s*)(enum)((\\s*)!(.*))?(\\s*)$"), options );
185
186 m_RegEx[wxT("regexComment")] = new wxRegEx( wxT("(!(.*))((\r\n)|(\r)|(\n))?$"), options | wxRE_NEWLINE );
187
188 m_RegEx[wxT("regexBlankLine")] = new wxRegEx( wxT("([ \t]+)((\r\n)|(\r)|(\n))"), options | wxRE_NEWLINE );
189
190 m_RegEx[wxT("regexPreprocessorC")] = new wxRegEx( wxT("^#(define|undef|ifdef|ifndef|if|elif|else|endif|include|error|warning|line)"), options );
191
192 }
193
194
Initialize(int firstLineIndent)195 void IndentEstimator::Initialize(int firstLineIndent)
196 {
197 m_CodeTree.Initialize(firstLineIndent);
198 }
199
200
GetFortranIndentLine(const wxString & src1,int & indentNum,int & indentNumNext)201 void IndentEstimator::GetFortranIndentLine(const wxString& src1, int& indentNum, int& indentNumNext)
202 {
203 indentNumNext = indentNum;
204 wxArrayString srcLines;
205 PrepareLine(src1, srcLines); // for case if several statements on one line
206 for (size_t i=0; i<srcLines.size(); i++)
207 {
208 int deltaIndentCur;
209 int deltaIndentNext;
210 FormatIndentCodeTree::CodeTreeKind iKind;
211 CalcFortranIndentLine(srcLines.Item(i), deltaIndentCur, deltaIndentNext, iKind);
212 if (i == 0)
213 {
214 indentNum += deltaIndentCur;
215 m_CodeTree.GetCodeTreeIndent(iKind, indentNum);
216 }
217
218 if (i+1 == srcLines.size())
219 {
220 m_CodeTree.GetCodeTreeIndent(iKind, indentNum);
221 indentNumNext = indentNum + deltaIndentNext;
222 }
223 }
224 }
225
226
CalcFortranIndentLine(const wxString & srcLine,int & deltaIndentCur,int & deltaIndentNext,FormatIndentCodeTree::CodeTreeKind & iKind)227 void IndentEstimator::CalcFortranIndentLine( const wxString & srcLine, int & deltaIndentCur, int & deltaIndentNext, FormatIndentCodeTree::CodeTreeKind & iKind )
228 {
229 // module program subroutine function forall
230 // Add a shiftwidth to statements following module, program, subroutine,
231 // function and forall statements
232 //Manager::Get()->GetLogManager()->Log( src1 );
233
234 iKind = FormatIndentCodeTree::ctcNone;
235
236 deltaIndentCur = 0;
237 deltaIndentNext = 0;
238
239 wxString src = srcLine;
240 src.Trim(true); // trim from right
241
242 // Program, Interface, Bblock Data, Subroutine, Function
243 if ( m_RegEx[wxT("regexEndProgram")]->Matches( src ) )
244 {
245 iKind = FormatIndentCodeTree::ctcEndProgramBlockSubFun;
246 if (m_IndentProgFunSub)
247 deltaIndentCur = -1;
248 else
249 deltaIndentCur = 0;
250 deltaIndentNext = 0;
251 }
252 else if ( m_RegEx[wxT("regexEndInterface")]->Matches( src ) )
253 {
254 iKind = FormatIndentCodeTree::ctcEndInterface;
255 deltaIndentCur = -1;
256 deltaIndentNext = 0;
257 }
258 else if ( m_RegEx[wxT("regexInterface")]->Matches( src ) )
259 {
260 iKind = FormatIndentCodeTree::ctcInterface;
261 deltaIndentCur = 0;
262 deltaIndentNext = 1;
263 }
264 else if ( m_RegEx[wxT("regexSubroutine")]->Matches( src ) )
265 {
266 iKind = FormatIndentCodeTree::ctcSubroutine;
267 deltaIndentCur = 0;
268 if (m_IndentProgFunSub)
269 deltaIndentNext = 1;
270 else
271 deltaIndentNext = 0;
272 }
273 else if ( m_RegEx[wxT("regexFunction")]->Matches( src ) )
274 {
275 iKind = FormatIndentCodeTree::ctcFunction;
276 deltaIndentCur = 0;
277 if (m_IndentProgFunSub)
278 deltaIndentNext = 1;
279 else
280 deltaIndentNext = 0;
281 }
282 else if ( m_RegEx[wxT("regexProgram")]->Matches( src ) )
283 {
284 iKind = FormatIndentCodeTree::ctcProgramBlock;
285 deltaIndentCur = 0;
286 if (m_IndentProgFunSub)
287 deltaIndentNext = 1;
288 else
289 deltaIndentNext = 0;
290 return ;
291 }
292 else if ( m_RegEx[wxT("regexEndModule")]->Matches( src ) )
293 {
294 iKind = FormatIndentCodeTree::ctcEndModule;
295 if (m_IndentModule)
296 deltaIndentCur = -1;
297 else
298 deltaIndentCur = 0;
299 deltaIndentNext = 0;
300 }
301 else if ( m_RegEx[wxT("regexModule")]->Matches( src ) )
302 {
303 iKind = FormatIndentCodeTree::ctcModule;
304 deltaIndentCur = 0;
305 if (m_IndentModule)
306 deltaIndentNext = 1;
307 else
308 deltaIndentNext = 0;
309 }
310 else if ( m_RegEx[wxT("regexContains")]->Matches( src ) )
311 {
312 FormatIndentCodeTree::CodeTreeKind pk = m_CodeTree.GetParentKind();
313
314 if (pk == FormatIndentCodeTree::ctcModule ||
315 pk == FormatIndentCodeTree::ctcSubmodule)
316 {
317 if (m_IndentContainsModule)
318 deltaIndentCur = -1;
319 if (m_IndentContainsModuleAfter)
320 deltaIndentNext = 1;
321 }
322 else if (pk == FormatIndentCodeTree::ctcSubroutine ||
323 pk == FormatIndentCodeTree::ctcFunction ||
324 pk == FormatIndentCodeTree::ctcProgramBlock)
325 {
326 if (m_IndentContainsProcedure)
327 deltaIndentCur = -1;
328 if (m_IndentContainsProcedureAfter)
329 deltaIndentNext = 1;
330 }
331 else if (pk == FormatIndentCodeTree::ctcTypeDefine)
332 {
333 if (m_IndentContainsTypedef)
334 deltaIndentCur = -1;
335 if (m_IndentContainsTypedefAfter)
336 deltaIndentNext = 1;
337 }
338 else // could it be?
339 {
340 deltaIndentCur = -1;
341 deltaIndentNext = 1;
342 }
343 }
344 else if ( m_RegEx[wxT("regexEndDo")]->Matches( src ) )
345 {
346 // do while # end do
347 // forall() # end forall
348 // Indent do loops only if they are all guaranteed to be of do/end do type
349 iKind = FormatIndentCodeTree::ctcEndDoForall;
350 deltaIndentCur = -1;
351 deltaIndentNext = 0;
352 }
353 else if ( m_RegEx[wxT("regexDo")]->Matches( src ) )
354 {
355 iKind = FormatIndentCodeTree::ctcDoForall;
356 deltaIndentCur = 0;
357 deltaIndentNext = 1;
358 }
359 else if ( m_RegEx[wxT("regexForall")]->Matches( src ) )
360 {
361 iKind = FormatIndentCodeTree::ctcDoForall;
362 deltaIndentCur = 0;
363 deltaIndentNext = 1;
364 }
365 else if ( m_RegEx[wxT("regexEndSelect")]->Matches( src ) )
366 {
367 // select case # case | case dafault # end select
368 iKind = FormatIndentCodeTree::ctcEndSeclectCase;
369 deltaIndentCur = -2;
370 deltaIndentNext = 0;
371 }
372 else if ( m_RegEx[wxT("regexSelectCase")]->Matches( src ) )
373 {
374 iKind = FormatIndentCodeTree::ctcSeclectCase;
375 deltaIndentCur = 0;
376 if (m_IndentSelectCaseAfter)
377 deltaIndentNext = 2;
378 else
379 deltaIndentNext = 1;
380 }
381 else if ( m_RegEx[wxT("regexSelectType")]->Matches( src ) )
382 {
383 iKind = FormatIndentCodeTree::ctcSeclectType;
384 deltaIndentCur = 0;
385 if (m_IndentSelectTypeAfter)
386 deltaIndentNext = 2;
387 else
388 deltaIndentNext = 1;
389 }
390 else if ( m_RegEx[wxT("regexCase")]->Matches( src ) )
391 {
392 deltaIndentCur = -1;
393 deltaIndentNext = 1;
394 }
395 else if ( m_RegEx[wxT("regexIfThen")]->Matches( src ) )
396 {
397 // if ## if then # else # end if
398 iKind = FormatIndentCodeTree::ctcIfThen;
399 deltaIndentCur = 0;
400 deltaIndentNext = 1;
401 }
402 else if ( m_RegEx[wxT("regexElse")]->Matches( src ) )
403 {
404 deltaIndentCur = -1;
405 deltaIndentNext = 1;
406 }
407 else if ( m_RegEx[wxT("regexEndIf")]->Matches( src ) )
408 {
409 iKind = FormatIndentCodeTree::ctcEndIf;
410 deltaIndentCur = -1;
411 deltaIndentNext = 0;
412 }
413 else if ( m_RegEx[wxT("regexWhere")]->Matches( src ) )
414 {
415 // where elsewhere
416 iKind = FormatIndentCodeTree::ctcWhere;
417 deltaIndentCur = 0;
418 deltaIndentNext = 1;
419 }
420 else if ( m_RegEx[wxT("regexElseWhere")]->Matches( src ) )
421 {
422 deltaIndentCur = -1;
423 deltaIndentNext = 1;
424 }
425 else if ( m_RegEx[wxT("regexEndWhere")]->Matches( src ) )
426 {
427 iKind = FormatIndentCodeTree::ctcEndWhere;
428 deltaIndentCur = -1;
429 deltaIndentNext = 0;
430 }
431 else if ( m_RegEx[wxT("regexEndType")]->Matches( src ) )
432 {
433 iKind = FormatIndentCodeTree::ctcEndTypeDefine;
434 deltaIndentCur = -1;
435 deltaIndentNext = 0;
436 }
437 else if ( ( false == m_RegEx[wxT("regexType")]->Matches( src ) ) &&
438 ( m_RegEx[wxT("regexTypeDefine")]->Matches( src ) ) )
439 {
440 iKind = FormatIndentCodeTree::ctcTypeDefine;
441 deltaIndentCur = 0;
442 deltaIndentNext = 1;
443 }
444 else if ( m_RegEx[wxT("regexEndAssociate")]->Matches( src ) )
445 {
446 iKind = FormatIndentCodeTree::ctcEndAssociate;
447 deltaIndentCur = -1;
448 deltaIndentNext = 0;
449 }
450 else if ( m_RegEx[wxT("regexAssociate")]->Matches( src ) )
451 {
452 iKind = FormatIndentCodeTree::ctcAssociate;
453 deltaIndentCur = 0;
454 deltaIndentNext = 1;
455 }
456 else if ( m_RegEx[wxT("regexEndCritical")]->Matches( src ) )
457 {
458 iKind = FormatIndentCodeTree::ctcEndCritical;
459 deltaIndentCur = -1;
460 deltaIndentNext = 0;
461 }
462 else if ( m_RegEx[wxT("regexCritical")]->Matches( src ) )
463 {
464 iKind = FormatIndentCodeTree::ctcCritical;
465 deltaIndentCur = 0;
466 deltaIndentNext = 1;
467 }
468 else if ( m_RegEx[wxT("regexSubmodule")]->Matches( src ) )
469 {
470 iKind = FormatIndentCodeTree::ctcSubmodule;
471 deltaIndentCur = 0;
472 if (m_IndentModule)
473 deltaIndentNext = 1;
474 else
475 deltaIndentNext = 0;
476 }
477 else if ( m_RegEx[wxT("regexEndSubmodule")]->Matches( src ) )
478 {
479 iKind = FormatIndentCodeTree::ctcEndSubmodule;
480 if (m_IndentModule)
481 deltaIndentCur = -1;
482 else
483 deltaIndentCur = 0;
484 deltaIndentNext = 0;
485 }
486 else if ( m_RegEx[wxT("regexEndEnum")]->Matches( src ) )
487 {
488 iKind = FormatIndentCodeTree::ctcEndEnum;
489 deltaIndentCur = -1;
490 deltaIndentNext = 0;
491 }
492 else if ( m_RegEx[wxT("regexEnum")]->Matches( src ) )
493 {
494 iKind = FormatIndentCodeTree::ctcEnum;
495 deltaIndentCur = 0;
496 deltaIndentNext = 1;
497 }
498 else if ( m_RegEx[wxT("regexEndOnly")]->Matches( src ) )
499 {
500 iKind = FormatIndentCodeTree::ctcEnd;
501 deltaIndentCur = -1;
502 deltaIndentNext = 0;
503 }
504 else if ( m_RegEx[wxT("regexModuleProcedure")]->Matches( src ) &&
505 m_CodeTree.GetParentKind() == FormatIndentCodeTree::ctcSubmodule )
506 {
507 iKind = FormatIndentCodeTree::ctcModuleProcedure;
508 deltaIndentCur = 0;
509 if (m_IndentProgFunSub)
510 deltaIndentNext = 1;
511 else
512 deltaIndentNext = 0;
513 }
514 else if ( m_RegEx[wxT("regexEndProcedure")]->Matches( src ) )
515 {
516 iKind = FormatIndentCodeTree::ctcEndProcedure;
517 if (m_IndentProgFunSub)
518 deltaIndentCur = -1;
519 else
520 deltaIndentCur = 0;
521 deltaIndentNext = 0;
522 }
523
524
525
526 }
527
528 // Special code to compare strings which doesn't care
529 // about spaces leading up to the EOL.
BuffersDiffer(const wxString & a,const wxString & b)530 bool IndentEstimator::BuffersDiffer( const wxString &a, const wxString &b )
531 {
532 wxString acopy = a;
533 acopy.Replace(_T("\r\n"), _T("\n"));
534 acopy.Replace(_T("\r"), _T("\n"));
535 wxStringTokenizer aTokenizer(acopy, _T("\n"), wxTOKEN_RET_EMPTY_ALL);
536 std::vector<wxString> aLines;
537 while (aTokenizer.HasMoreTokens())
538 aLines.push_back(aTokenizer.GetNextToken());
539
540 wxString bcopy = b;
541 bcopy.Replace(_T("\r\n"), _T("\n"));
542 bcopy.Replace(_T("\r"), _T("\n"));
543 wxStringTokenizer bTokenizer(bcopy, _T("\n"), wxTOKEN_RET_EMPTY_ALL);
544 std::vector<wxString> bLines;
545 while (bTokenizer.HasMoreTokens())
546 bLines.push_back(bTokenizer.GetNextToken());
547
548 size_t aSize = aLines.size();
549 if(aSize != bLines.size())
550 return true;
551
552 for (size_t i=0; i<aSize; i++)
553 {
554 wxString aLin = aLines[i];
555 aLin.Trim();
556 wxString bLin = bLines[i];
557 bLin.Trim();
558 if (aLin != bLin)
559 return true;
560 }
561 return false;
562 }
563
GetIsHasLineContinuation(const wxString & srcLine)564 bool IndentEstimator::GetIsHasLineContinuation( const wxString & srcLine )
565 {
566 wxASSERT( m_RegEx[wxT("regexMultiLines")] );
567 return m_RegEx[wxT("regexMultiLines")]->Matches( srcLine );
568 }
569
570
DelLineContinuation(wxString & srcLine)571 void IndentEstimator::DelLineContinuation( wxString & srcLine )
572 {
573 wxASSERT( m_RegEx[wxT("regexMultiLines")] );
574 m_RegEx[wxT("regexMultiLines")]->ReplaceAll( &srcLine, wxT("") );
575 }
576
577
DelComment(wxString & srcLine)578 void IndentEstimator::DelComment( wxString & srcLine )
579 {
580 wxASSERT( m_RegEx[wxT("regexComment")] );
581 m_RegEx[wxT("regexComment")]->ReplaceAll( &srcLine, wxT("") );
582 }
583
GetIsHasPreprocessor(const wxString & srcLine)584 bool IndentEstimator::GetIsHasPreprocessor(const wxString & srcLine)
585 {
586 bool bRet = false;
587 wxASSERT( m_RegEx[wxT("regexPreprocessorC")] );
588 bRet = m_RegEx[wxT("regexPreprocessorC")]->Matches( srcLine );
589
590 return bRet;
591 }
592
PrepareLine(const wxString & srcIn,wxArrayString & srcLines)593 void IndentEstimator::PrepareLine(const wxString& srcIn, wxArrayString& srcLines)
594 {
595 wxString src = srcIn;
596 CutStringAndComment(src);
597
598 wxStringTokenizer tokenizer(src, _T(";"), wxTOKEN_STRTOK);
599 while (tokenizer.HasMoreTokens())
600 {
601 wxString token = tokenizer.GetNextToken();
602 srcLines.Add(token);
603 }
604
605 }
606
CutStringAndComment(wxString & src)607 void IndentEstimator::CutStringAndComment(wxString& src)
608 {
609 src.Trim(false);
610
611 while(true)
612 {
613 int i1 = src.Find('\'');
614 int j1 = src.Find('"');
615 char curChar;
616 if (i1 != wxNOT_FOUND && j1 != wxNOT_FOUND)
617 curChar = i1<j1 ? '\'' : '"';
618 else if (i1 != wxNOT_FOUND)
619 curChar = '\'';
620 else if (j1 != wxNOT_FOUND)
621 curChar = '"';
622 else
623 break;
624
625 i1 = src.Find(curChar);
626 if (i1 != wxNOT_FOUND)
627 {
628 wxString str2 = src.Mid(i1+1);
629 int i2 = str2.Find(curChar);
630 if (i2 != wxNOT_FOUND)
631 src = src.Mid(0,i1) + _T("$_$") + str2.Mid(i2+1);
632 else
633 src = src.Mid(0,i1);
634 }
635 else
636 break;
637 }
638
639 src.Replace(_T("$_$"), _T("\" \""));
640 src = src.BeforeFirst('!').Trim();
641 if (src.IsEmpty())
642 return;
643
644 //Replace inside parentheses
645 int istart = -1;
646 int level = 0;
647 for (size_t i=0; i<src.size(); i++)
648 {
649 if (src[i] == '(')
650 {
651 if (level == 0)
652 istart = i;
653 level++;
654 }
655 else if (src[i] == ')')
656 {
657 level--;
658 if (level == 0)
659 {
660 for (size_t j=istart+1; j<i; j++)
661 src.SetChar(j, 'a');
662 }
663 }
664 }
665 }
666
ReadConfig()667 void IndentEstimator::ReadConfig()
668 {
669 ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("fortran_project"));
670
671 m_IndentProgFunSub = cfg->ReadBool(_T("/indent_prog_fun_sub_after"), true);
672 m_IndentModule = cfg->ReadBool(_T("/indent_module_after"), true);
673 m_IndentContainsModule = cfg->ReadBool(_T("/indent_contains_module"), true);
674 m_IndentContainsModuleAfter = cfg->ReadBool(_T("/indent_contains_module_after"), true);
675 m_IndentContainsProcedure = cfg->ReadBool(_T("/indent_contains_procedure"), true);
676 m_IndentContainsProcedureAfter = cfg->ReadBool(_T("/indent_contains_procedure_after"), true);
677 m_IndentContainsTypedef = cfg->ReadBool(_T("/indent_contains_typedef"), true);
678 m_IndentContainsTypedefAfter = cfg->ReadBool(_T("/indent_contains_typedef_after"), true);
679 m_IndentSelectCaseAfter = cfg->ReadBool(_T("/indent_selectcase_after"), true);
680 m_IndentSelectTypeAfter = cfg->ReadBool(_T("/indent_selecttype_after"), true);
681 }
682
683
684