1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  * $Revision: 11520 $
5  * $Id: cctest_frame.cpp 11520 2018-12-11 15:31:09Z ollydbg $
6  * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/codecompletion/cctest/cctest_frame.cpp $
7  */
8 
9 #ifdef __BORLANDC__
10 #pragma hdrstop
11 #endif
12 
13 #ifndef WX_PRECOMP
14     #include <wx/wx.h>
15     #include <wx/file.h>
16 #endif
17 
18 #include "ccdebuginfo.h"
19 
20 #include "cctest_frame.h"
21 #include "cclogger.h"
22 #include "token.h"
23 #include "tokentree.h"
24 
25 #include "nativeparser_test.h"
26 
27 //(*InternalHeaders(CCTestFrame)
28 #include <wx/intl.h>
29 #include <wx/settings.h>
30 #include <wx/string.h>
31 //*)
32 
33 #include <wx/arrstr.h>
34 #include <wx/dir.h>
35 #include <wx/filename.h>
36 #include <wx/font.h>
37 #include <wx/progdlg.h>
38 #include <wx/textdlg.h>
39 #include <wx/tokenzr.h>
40 
41 //(*IdInit(CCTestFrame)
42 const long CCTestFrame::ID_CHK_HIDE = wxNewId();
43 const long CCTestFrame::wxID_TEST_SINGLE = wxNewId();
44 const long CCTestFrame::wxID_PARSE = wxNewId();
45 const long CCTestFrame::wxID_PRINT_TREE = wxNewId();
46 const long CCTestFrame::wxID_SAVE_TEST_RESULT = wxNewId();
47 const long CCTestFrame::wxID_TOKEN = wxNewId();
48 //*)
49 
50 namespace CCTestAppGlobal
51 {
52     extern wxArrayString s_includeDirs;
53     extern wxArrayString s_fileQueue;
54     extern wxArrayString s_filesParsed;
55 }// CCTestAppGlobal
56 
57 int idCCLogger   = wxNewId();
58 int idCCAddToken = wxNewId();
59 
60 const int C_FOLDING_MARGIN = 3; // as in C::B (fwiw...)
61 
BEGIN_EVENT_TABLE(CCTestFrame,wxFrame)62 BEGIN_EVENT_TABLE(CCTestFrame, wxFrame)
63     //(*EventTable(CCTestFrame)
64     //*)
65     EVT_FIND            (wxID_ANY,     CCTestFrame::OnFindDialog)
66     EVT_FIND_NEXT       (wxID_ANY,     CCTestFrame::OnFindDialog)
67     EVT_FIND_REPLACE    (wxID_ANY,     CCTestFrame::OnFindDialog)
68     EVT_FIND_REPLACE_ALL(wxID_ANY,     CCTestFrame::OnFindDialog)
69     EVT_FIND_CLOSE      (wxID_ANY,     CCTestFrame::OnFindDialog)
70     EVT_MENU            (idCCLogger,   CCTestFrame::OnCCLogger  )
71     EVT_MENU            (idCCAddToken, CCTestFrame::OnCCAddToken)
72 END_EVENT_TABLE()
73 
74 CCTestFrame::CCTestFrame(const wxString& main_file) :
75     m_ProgDlg(NULL),
76     m_MainFile(main_file),
77     m_CurrentFile(),
78     m_LogCount(0),
79     m_FRDlg(NULL)
80 {
81     //(*Initialize(CCTestFrame)
82     wxBoxSizer* bszCompletionTest;
83     wxBoxSizer* bszParserInput;
84     wxBoxSizer* bszParserOutput;
85     wxBoxSizer* bszParserSearchTree;
86     wxBoxSizer* bsz_include;
87     wxBoxSizer* bsz_main;
88     wxBoxSizer* bsz_misc;
89     wxBoxSizer* bsz_parser;
90     wxBoxSizer* bsz_search_tree;
91     wxMenu* mnu_file;
92     wxMenu* mnu_help;
93     wxMenu* mnu_search;
94     wxMenuBar* mnu_main;
95     wxMenuItem* mnu_item_about;
96     wxMenuItem* mnu_item_find;
97     wxMenuItem* mnu_item_token;
98     wxMenuItem* mnu_itm_open;
99     wxMenuItem* mnu_itm_quit;
100     wxMenuItem* mnu_itm_reparse;
101     wxMenuItem* mnu_itm_save_log;
102     wxPanel* panParserInput;
103     wxPanel* panParserOutput;
104     wxPanel* panParserSearchTree;
105     wxStaticText* lbl_include;
106 
107     Create(0, wxID_ANY, _("CC Testing"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("wxID_ANY"));
108     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
109     bsz_main = new wxBoxSizer(wxVERTICAL);
110     bsz_misc = new wxBoxSizer(wxVERTICAL);
111     bsz_include = new wxBoxSizer(wxVERTICAL);
112     lbl_include = new wxStaticText(this, wxID_ANY, _("Add include directories to search for files here (one directory per line):"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
113     bsz_include->Add(lbl_include, 0, wxBOTTOM|wxEXPAND, 5);
114     m_IncludeCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator, _T("wxID_ANY"));
115     m_IncludeCtrl->SetMinSize(wxSize(-1,60));
116     bsz_include->Add(m_IncludeCtrl, 0, wxEXPAND, 5);
117     bsz_misc->Add(bsz_include, 0, wxBOTTOM|wxEXPAND, 5);
118     bsz_main->Add(bsz_misc, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 5);
119     bsz_search_tree = new wxBoxSizer(wxHORIZONTAL);
120     m_DoTreeCtrl = new wxCheckBox(this, wxID_ANY, _("Enable creation of parser\'s internal search tree (might get HUGE!!!)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("wxID_ANY"));
121     m_DoTreeCtrl->SetValue(false);
122     bsz_search_tree->Add(m_DoTreeCtrl, 0, wxALIGN_CENTER_VERTICAL, 5);
123     m_DoHideCtrl = new wxCheckBox(this, ID_CHK_HIDE, _("Hide frame"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHK_HIDE"));
124     m_DoHideCtrl->SetValue(true);
125     bsz_search_tree->Add(m_DoHideCtrl, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
126     bsz_search_tree->Add(-1,-1,1, wxALIGN_CENTER_VERTICAL, 5);
127     btnTestSingle = new wxButton(this, wxID_TEST_SINGLE, _("Test Single"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("wxID_TEST_SINGLE"));
128     bsz_search_tree->Add(btnTestSingle, 1, wxALL|wxALIGN_BOTTOM, 5);
129     btnParse = new wxButton(this, wxID_PARSE, _("Test All"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("wxID_PARSE"));
130     bsz_search_tree->Add(btnParse, 1, wxALIGN_CENTER_VERTICAL, 5);
131     btnPrintTree = new wxButton(this, wxID_PRINT_TREE, _("Print Tree"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("wxID_PRINT_TREE"));
132     bsz_search_tree->Add(btnPrintTree, 1, wxALL|wxALIGN_BOTTOM, 5);
133     btnSaveTestResult = new wxButton(this, wxID_SAVE_TEST_RESULT, _("Save Test Result"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("wxID_SAVE_TEST_RESULT"));
134     bsz_search_tree->Add(btnSaveTestResult, 1, wxALL|wxALIGN_BOTTOM, 5);
135     bsz_main->Add(bsz_search_tree, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND, 5);
136     bsz_parser = new wxBoxSizer(wxVERTICAL);
137     m_ParserCtrl = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
138     panParserInput = new wxPanel(m_ParserCtrl, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("wxID_ANY"));
139     bszParserInput = new wxBoxSizer(wxVERTICAL);
140     m_Control = new wxScintilla(panParserInput,wxID_ANY,wxDefaultPosition,wxDefaultSize);
141     bszParserInput->Add(m_Control, 1, wxEXPAND, 5);
142     panParserInput->SetSizer(bszParserInput);
143     bszParserInput->Fit(panParserInput);
144     bszParserInput->SetSizeHints(panParserInput);
145     panParserOutput = new wxPanel(m_ParserCtrl, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("wxID_ANY"));
146     bszParserOutput = new wxBoxSizer(wxVERTICAL);
147     m_LogCtrl = new wxTextCtrl(panParserOutput, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2|wxHSCROLL, wxDefaultValidator, _T("wxID_ANY"));
148     m_LogCtrl->SetMinSize(wxSize(640,250));
149     bszParserOutput->Add(m_LogCtrl, 1, wxEXPAND, 5);
150     panParserOutput->SetSizer(bszParserOutput);
151     bszParserOutput->Fit(panParserOutput);
152     bszParserOutput->SetSizeHints(panParserOutput);
153     panParserSearchTree = new wxPanel(m_ParserCtrl, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("wxID_ANY"));
154     bszParserSearchTree = new wxBoxSizer(wxVERTICAL);
155     m_TreeCtrl = new wxTextCtrl(panParserSearchTree, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2|wxHSCROLL, wxDefaultValidator, _T("wxID_ANY"));
156     m_TreeCtrl->SetMinSize(wxSize(640,150));
157     bszParserSearchTree->Add(m_TreeCtrl, 1, wxEXPAND, 5);
158     panParserSearchTree->SetSizer(bszParserSearchTree);
159     bszParserSearchTree->Fit(panParserSearchTree);
160     bszParserSearchTree->SetSizeHints(panParserSearchTree);
161     panCompletionTest = new wxPanel(m_ParserCtrl, wxID_ANY, wxPoint(274,5), wxDefaultSize, wxTAB_TRAVERSAL, _T("wxID_ANY"));
162     bszCompletionTest = new wxBoxSizer(wxHORIZONTAL);
163     m_CompletionTestCtrl = new wxTextCtrl(panCompletionTest, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_RICH2|wxHSCROLL, wxDefaultValidator, _T("wxID_ANY"));
164     bszCompletionTest->Add(m_CompletionTestCtrl, 1, wxALL|wxEXPAND, 5);
165     panCompletionTest->SetSizer(bszCompletionTest);
166     bszCompletionTest->Fit(panCompletionTest);
167     bszCompletionTest->SetSizeHints(panCompletionTest);
168     m_ParserCtrl->AddPage(panParserInput, _("Parser input"), true);
169     m_ParserCtrl->AddPage(panParserOutput, _("Parser output"), false);
170     m_ParserCtrl->AddPage(panParserSearchTree, _("Parser search tree"), false);
171     m_ParserCtrl->AddPage(panCompletionTest, _("Completion test"), false);
172     bsz_parser->Add(m_ParserCtrl, 1, wxEXPAND, 5);
173     bsz_main->Add(bsz_parser, 1, wxALL|wxEXPAND, 5);
174     SetSizer(bsz_main);
175     mnu_main = new wxMenuBar();
176     mnu_file = new wxMenu();
177     mnu_itm_open = new wxMenuItem(mnu_file, wxID_OPEN, _("&Open...\tCtrl+O"), _("Open the source code to be tested"), wxITEM_NORMAL);
178     mnu_file->Append(mnu_itm_open);
179     mnu_itm_reparse = new wxMenuItem(mnu_file, wxID_REFRESH, _("&Re-parse\tF5"), _("Re-parse test file / buffer"), wxITEM_NORMAL);
180     mnu_file->Append(mnu_itm_reparse);
181     mnu_file->AppendSeparator();
182     mnu_itm_save_log = new wxMenuItem(mnu_file, wxID_SAVE, _("&Save Log...\tCtrl+S"), _("Save log file to hard disk "), wxITEM_NORMAL);
183     mnu_file->Append(mnu_itm_save_log);
184     mnu_file->AppendSeparator();
185     mnu_itm_quit = new wxMenuItem(mnu_file, wxID_EXIT, _("&Quit\tCtrl+Q"), wxEmptyString, wxITEM_NORMAL);
186     mnu_file->Append(mnu_itm_quit);
187     mnu_main->Append(mnu_file, _("&File"));
188     mnu_search = new wxMenu();
189     mnu_item_find = new wxMenuItem(mnu_search, wxID_FIND, _("&Find...\tCtrl+F"), _("Find keyword"), wxITEM_NORMAL);
190     mnu_search->Append(mnu_item_find);
191     mnu_item_token = new wxMenuItem(mnu_search, wxID_TOKEN, _("&Token...\tCtrl+T"), _("Find token"), wxITEM_NORMAL);
192     mnu_search->Append(mnu_item_token);
193     mnu_main->Append(mnu_search, _("&Search"));
194     mnu_help = new wxMenu();
195     mnu_item_about = new wxMenuItem(mnu_help, wxID_ABOUT, _("&About"), wxEmptyString, wxITEM_NORMAL);
196     mnu_help->Append(mnu_item_about);
197     mnu_main->Append(mnu_help, _("&Help"));
198     SetMenuBar(mnu_main);
199     m_StatuBar = new wxStatusBar(this, wxID_ANY, 0, _T("wxID_ANY"));
200     int __wxStatusBarWidths_1[1] = { -10 };
201     int __wxStatusBarStyles_1[1] = { wxSB_NORMAL };
202     m_StatuBar->SetFieldsCount(1,__wxStatusBarWidths_1);
203     m_StatuBar->SetStatusStyles(1,__wxStatusBarStyles_1);
204     SetStatusBar(m_StatuBar);
205     m_OpenFile = new wxFileDialog(this, _("Select Test Source File"), _("."), wxEmptyString, _("*.cpp;*.h"), wxFD_DEFAULT_STYLE, wxDefaultPosition, wxDefaultSize, _T("wxFileDialog"));
206     m_SaveFile = new wxFileDialog(this, _("Select file"), _("."), _("log.txt"), _("*.txt"), wxFD_SAVE, wxDefaultPosition, wxDefaultSize, _T("wxFileDialog"));
207     bsz_main->Fit(this);
208     bsz_main->SetSizeHints(this);
209     Center();
210 
211     Connect(wxID_TEST_SINGLE,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CCTestFrame::OnTestSingle);
212     Connect(wxID_PARSE,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CCTestFrame::OnParse);
213     Connect(wxID_PRINT_TREE,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CCTestFrame::OnPrintTree);
214     Connect(wxID_SAVE_TEST_RESULT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&CCTestFrame::OnSaveTestResultClick);
215     Connect(wxID_OPEN,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuOpenSelected);
216     Connect(wxID_REFRESH,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuReparseSelected);
217     Connect(wxID_SAVE,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuSaveSelected);
218     Connect(wxID_EXIT,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuQuitSelected);
219     Connect(wxID_FIND,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuFindSelected);
220     Connect(wxID_TOKEN,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuTokenSelected);
221     Connect(wxID_ABOUT,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&CCTestFrame::OnMenuAboutSelected);
222     //*)
223 
224     // redirect the wxLogMessage to the text ctrl of the frame
225     wxLogTextCtrl* textLog = new wxLogTextCtrl(m_CompletionTestCtrl);
226     wxLog::SetActiveTarget(textLog);
227 #if wxCHECK_VERSION(3, 0, 0)
228     wxLog::DisableTimestamp(); // do not show the time stamp
229 #else
230     wxLog::SetTimestamp(NULL); // do not show the time stamp
231 #endif
232 
233     // TODO: Make this base folders configurable
234     wxString wx_base (wxT("E:\\code\\cb\\wx\\wxWidgets-2.8.12\\"));
235     wxString gcc_base(wxT("E:\\code\\gcc\\pcxmingw463\\" ));
236     wxString mingwver(wxT("i686-w64-mingw32"));
237     wxString gccver(wxT("4.6.3"));
238 
239     m_IncludeCtrl->SetValue(wx_base  + wxT("include")                                                                 + wxT("\n") +
240                             wx_base  + wxT("lib\\gcc_dll\\mswu")                                                      + wxT("\n") +
241                             gcc_base + wxT("lib\\gcc\\")+mingwver+wxT("\\")+gccver+wxT("\\include\\c++")              + wxT("\n") +
242                             gcc_base + wxT("lib\\gcc\\")+mingwver+wxT("\\")+gccver+wxT("\\include\\c++\\") + mingwver + wxT("\n") +
243                             gcc_base + wxT("lib\\gcc\\")+mingwver+wxT("\\")+gccver+wxT("\\include\\c++\\backward")    + wxT("\n") +
244                             gcc_base + wxT("lib\\gcc\\")+mingwver+wxT("\\")+gccver+wxT("\\include")                   + wxT("\n") +
245                             gcc_base + wxT("include")                                                                 + wxT("\n") +
246                             gcc_base + wxT("lib\\gcc\\")+mingwver+wxT("\\")+gccver+wxT("\\include-fixed")             + wxT("\n") +
247                             gcc_base + mingwver + wxT("\\include")                                                    + wxT("\n"));
248 
249 
250     CCLogger::Get()->Init(this, idCCLogger, idCCLogger, idCCAddToken);
251     m_StatuBar->SetStatusText(_("Ready!"));
252 
253     InitControl();
254     LoadToControl();
255 }
256 
~CCTestFrame()257 CCTestFrame::~CCTestFrame()
258 {
259     //(*Destroy(CCTestFrame)
260     //*)
261     delete m_FRDlg;
262 }
263 
Start()264 void CCTestFrame::Start()
265 {
266     if (m_ParserCtrl)
267         m_ParserCtrl->SetSelection(1); // make sure "Output" tab is selected
268 
269     CCTestAppGlobal::s_includeDirs.Clear();
270     CCTestAppGlobal::s_fileQueue.Clear();
271     CCTestAppGlobal::s_filesParsed.Clear();
272 
273     // Obtain all include directories, this is copy the paths in UI to CCTestAppGlobal::s_includeDirs
274     wxStringTokenizer tkz_inc(m_IncludeCtrl->GetValue(), wxT("\r\n"));
275     while ( tkz_inc.HasMoreTokens() )
276     {
277         wxString include = tkz_inc.GetNextToken().Trim(true).Trim(false);
278         if (!include.IsEmpty())
279             CCTestAppGlobal::s_includeDirs.Add(include);
280     }
281 
282     // set the macro replacement rule, and include search paths of the Parser object
283     m_NativeParser.Init();
284 
285     if (m_DoHideCtrl && m_DoHideCtrl->IsChecked())
286         Hide();
287 
288     m_ProgDlg = new wxProgressDialog(_("Please wait, operating..."),
289                                      _("Preparing...\nPlease wait..."), 0, this, wxPD_APP_MODAL);
290     m_ProgDlg->SetSize(640,100);
291     m_ProgDlg->Layout();
292     m_ProgDlg->CenterOnParent();
293 
294     m_LogCount = 0;
295     m_LogCtrl->Clear();
296 
297     if (!m_MainFile.IsEmpty())
298     {
299         wxFileName fn(m_MainFile);
300         fn.Normalize(); // cwd is used
301         wxString absFilePath = fn.GetFullPath();
302         CCTestAppGlobal::s_fileQueue.Add(absFilePath);
303     }
304 
305     // scan the files with pattern "cc_*.cpp"
306     wxArrayString testFiles;
307     // if we only debug a single file, we use a file pattern ccc_*.cpp
308     m_ProgDlg->Update(-1, _("Collecting ccc_*.cpp files..."));
309     wxDir::GetAllFiles(wxGetCwd(), &testFiles, wxT("ccc_*.cpp"));
310     if (testFiles.size() > 0)
311     {
312         m_ProgDlg->Update(-1, wxString::Format(_("Adding %lu ccc_*.cpp files."), static_cast<unsigned long>(testFiles.size())));
313         wxString filename = testFiles[0];
314         // only test the first matched file
315         CCTestAppGlobal::s_fileQueue.Add(filename);
316         if (!filename.IsEmpty() && !m_Control->LoadFile(filename))
317         {
318             wxMessageBox(_("Could not load input file."), _("CCTest"),
319                          wxOK | wxICON_EXCLAMATION, this);
320         }
321     }
322     else // otherwise, we collect all the files with pattern cc_*.cpp
323     {
324         m_ProgDlg->Update(-1, _("Collecting cc_*.cpp files..."));
325         wxDir::GetAllFiles(wxGetCwd(), &testFiles, wxT("cc_*.cpp"));
326         m_ProgDlg->Update(-1, wxString::Format(_("Adding %lu cc_*.cpp files."), static_cast<unsigned long>(testFiles.size())));
327         for (size_t i=0; i<testFiles.size(); i++)
328             CCTestAppGlobal::s_fileQueue.Add(testFiles[i]);
329     }
330 
331     AppendToLog(_("--------------M-a-i-n--L-o-g--------------\r\n\r\n"));
332 
333     // parse file from the queue one-by-one
334     while (!CCTestAppGlobal::s_fileQueue.IsEmpty())
335     {
336         wxString file = CCTestAppGlobal::s_fileQueue.Item(0);
337         CCTestAppGlobal::s_fileQueue.Remove(file);
338         if (file.IsEmpty()) continue;
339 
340         AppendToLog(_("-----------I-n-t-e-r-i-m--L-o-g-----------"));
341         m_CurrentFile = file;
342 
343         m_ProgDlg->Update(-1, m_CurrentFile);
344         m_StatuBar->SetStatusText(m_CurrentFile);
345 
346         // parse the file and test the expression solving algorithm
347         m_NativeParser.ParseAndCodeCompletion(m_CurrentFile);
348 
349         CCTestAppGlobal::s_filesParsed.Add(m_CurrentFile); // done
350     }
351 
352     delete m_ProgDlg;
353     m_ProgDlg = 0;
354 
355     if ( !IsShown() )
356     {
357         Show();
358         Raise();
359     }
360 }
361 
AppendToLog(const wxString & log)362 void CCTestFrame::AppendToLog(const wxString& log)
363 {
364     Freeze();
365 
366     m_LogCtrl->AppendText( wxString::Format(wxT("%06lu. "), static_cast<unsigned long>(++m_LogCount)) );
367     m_LogCtrl->AppendText( log );
368     m_LogCtrl->AppendText( wxT("\r\n") );
369 
370     m_LogCtrl->SetInsertionPoint(m_LogCtrl->GetLastPosition());
371 
372     Thaw();
373 }
374 
InitControl()375 void CCTestFrame::InitControl()
376 {
377     m_Control->StyleClearAll();
378 
379     m_Control->SetLexer(wxSCI_LEX_CPP);
380 
381     m_Control->StyleSetForeground(wxSCI_C_DEFAULT,        wxColour(0, 0, 0));
382     m_Control->StyleSetFontAttr  (wxSCI_C_DEFAULT,        10, wxT("Courier New"), false, false, false);
383 
384     m_Control->StyleSetForeground(wxSCI_C_COMMENT,        wxColour(160, 160, 160));
385     m_Control->StyleSetFontAttr  (wxSCI_C_COMMENT,        10, wxT("Courier New"), false, false, false);
386 
387     m_Control->StyleSetForeground(wxSCI_C_COMMENTLINE,    wxColour(190, 190, 230));
388     m_Control->StyleSetFontAttr  (wxSCI_C_COMMENTLINE,    10, wxT("Courier New"), false, false, false);
389 
390     m_Control->StyleSetForeground(wxSCI_C_COMMENTDOC,     wxColour(128, 128, 255));
391     m_Control->StyleSetFontAttr  (wxSCI_C_COMMENTDOC,     10, wxT("Courier New"), false, false, false);
392 
393     m_Control->StyleSetForeground(wxSCI_C_NUMBER,         wxColour(240, 0, 240));
394     m_Control->StyleSetFontAttr  (wxSCI_C_NUMBER,         10, wxT("Courier New"), false, false, false);
395 
396     m_Control->StyleSetForeground(wxSCI_C_WORD,           wxColour(0, 0, 160));
397     m_Control->StyleSetFontAttr  (wxSCI_C_WORD,           10, wxT("Courier New"), false, false, false);
398 
399     m_Control->StyleSetForeground(wxSCI_C_STRING,         wxColour(0, 0, 255));
400     m_Control->StyleSetFontAttr  (wxSCI_C_STRING,         10, wxT("Courier New"), false, false, false);
401 
402     m_Control->StyleSetForeground(wxSCI_C_CHARACTER,      wxColour(224, 160, 0));
403     m_Control->StyleSetFontAttr  (wxSCI_C_CHARACTER,      10, wxT("Courier New"), false, false, false);
404 
405     m_Control->StyleSetForeground(wxSCI_C_UUID,           wxColour(0, 0, 0));
406     m_Control->StyleSetFontAttr  (wxSCI_C_UUID,           10, wxT("Courier New"), false, false, false);
407 
408     m_Control->StyleSetForeground(wxSCI_C_PREPROCESSOR,   wxColour(0, 128, 0));
409     m_Control->StyleSetFontAttr  (wxSCI_C_PREPROCESSOR,   10, wxT("Courier New"), false, false, false);
410 
411     m_Control->StyleSetForeground(wxSCI_C_OPERATOR,       wxColour(255, 0, 0));
412     m_Control->StyleSetFontAttr  (wxSCI_C_OPERATOR,       10, wxT("Courier New"), false, false, false);
413 
414     m_Control->StyleSetForeground(wxSCI_C_IDENTIFIER,     wxColour(0, 0, 0));
415     m_Control->StyleSetFontAttr  (wxSCI_C_IDENTIFIER,     10, wxT("Courier New"), false, false, false);
416 
417     m_Control->StyleSetForeground(wxSCI_C_STRINGEOL,      wxColour(0, 0, 255));
418     m_Control->StyleSetFontAttr  (wxSCI_C_STRINGEOL,      10, wxT("Courier New"), false, false, false);
419 
420     m_Control->StyleSetForeground(wxSCI_C_COMMENTLINEDOC, wxColour(128, 128, 255));
421     m_Control->StyleSetFontAttr  (wxSCI_C_COMMENTLINEDOC, 10, wxT("Courier New"), false, false, false);
422 
423     m_Control->StyleSetForeground(wxSCI_C_WORD2,          wxColour(0, 160, 0));
424     m_Control->StyleSetFontAttr  (wxSCI_C_WORD2,          10, wxT("Courier New"), false, false, false);
425 
426     m_Control->StyleSetForeground(wxSCI_C_PREPROCESSORCOMMENT, wxColour(160, 160, 160));
427     m_Control->StyleSetFontAttr  (wxSCI_C_PREPROCESSORCOMMENT, 10, wxT("Courier New"), false, false, false);
428 
429     const wxString kw(wxT(
430     "_Char16_t _Char32_t align_union alignof asm auto bool break case catch char class const "
431     "const_cast constexpr continue decltype default delete do double dynamic_cast else enum "
432     "explicit export extern false final float for friend goto if import inline int long "
433     "mutable namespace new nullptr operator override private protected public register "
434     "reinterpret_cast return short signed sizeof static static_cast struct switch template "
435     "this throw true try typedef typeid typename union unsigned using virtual void volatile "
436     "wchar_t while static_assert int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t "
437     "uint64_t int_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t "
438     "uint_least32_t int_least64_t uint_least64_t int_fast8_t uint_fast8_t int_fast16_t "
439     "uint_fast16_t int_fast32_t uint_fast32_t int_fast64_t uint_fast64_t intptr_t uintptr_t "
440     "intmax_t uintmax_t wint_t wchar_t wctrans_t wctype_t size_t time_t and and_eq bitand "
441     "bitor compl not not_eq or or_eq xor xor_eq"));
442 
443     m_Control->SetKeyWords(0, kw);
444 
445     const wxString kwStl(wxT(
446     "basic_string bitset deque hash_map hash_multimap hash_multiset hash_set list map multimap "
447     "multiset pair priority_queue queue set stack std string valarray vector"));
448 
449     m_Control->SetKeyWords(1, kwStl);
450 
451     m_Control->SetProperty(wxT("fold"),              wxT("1"));
452     m_Control->SetProperty(wxT("fold.html"),         wxT("1"));
453     m_Control->SetProperty(wxT("fold.comment"),      wxT("1"));
454     m_Control->SetProperty(wxT("fold.compact"),      wxT("0"));
455     m_Control->SetProperty(wxT("fold.preprocessor"), wxT("1"));
456 
457     m_Control->SetFoldFlags(16);
458     m_Control->SetMarginType(C_FOLDING_MARGIN, wxSCI_MARGIN_SYMBOL);
459     m_Control->SetMarginWidth(C_FOLDING_MARGIN, 16);
460     // use "|" here or we might break plugins that use the margin (none at the moment)
461     m_Control->SetMarginMask(C_FOLDING_MARGIN,
462                              m_Control->GetMarginMask(C_FOLDING_MARGIN)
463                              | (  wxSCI_MASK_FOLDERS
464                                 - (  (1 << wxSCI_MARKNUM_CHANGEUNSAVED)
465                                    | (1 << wxSCI_MARKNUM_CHANGESAVED))) );
466     m_Control->SetMarginSensitive(C_FOLDING_MARGIN, 1);
467 
468     wxColor f(0xff, 0xff, 0xff); // foreground colour
469     wxColor b(0x80, 0x80, 0x80); // background colour
470     SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPEN,    wxSCI_MARK_MINUS,      f, b);
471     SetMarkerStyle(wxSCI_MARKNUM_FOLDER,        wxSCI_MARK_PLUS,       f, b);
472     SetMarkerStyle(wxSCI_MARKNUM_FOLDERSUB,     wxSCI_MARK_BACKGROUND, f, b);
473     SetMarkerStyle(wxSCI_MARKNUM_FOLDERTAIL,    wxSCI_MARK_BACKGROUND, f, b);
474     SetMarkerStyle(wxSCI_MARKNUM_FOLDEREND,     wxSCI_MARK_PLUS,       f, b);
475     SetMarkerStyle(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_MINUS,      f, b);
476     SetMarkerStyle(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_BACKGROUND, f, b);
477 
478     Connect(m_Control->GetId(), -1, wxEVT_SCI_MARGINCLICK,
479             (wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
480             &CCTestFrame::OnMarginClick);
481 }
482 
SetMarkerStyle(int marker,int markerType,wxColor fore,wxColor back)483 void CCTestFrame::SetMarkerStyle(int marker, int markerType, wxColor fore, wxColor back)
484 {
485     m_Control->MarkerDefine(marker, markerType);
486     m_Control->MarkerSetForeground(marker, fore);
487     m_Control->MarkerSetBackground(marker, back);
488 }
489 
LoadToControl()490 void CCTestFrame::LoadToControl()
491 {
492     if (!m_MainFile.IsEmpty() && !m_Control->LoadFile(m_MainFile))
493     {
494         // NOTE: comment out the below lines, since we can have m_MainFile empty
495         //wxMessageBox(_("Could not load input file."), _("CCTest"),
496         //             wxOK | wxICON_EXCLAMATION, this);
497     }
498 }
499 
OnMenuQuitSelected(wxCommandEvent &)500 void CCTestFrame::OnMenuQuitSelected(wxCommandEvent& /*event*/)
501 {
502     Close();
503 }
504 
OnMenuSaveSelected(wxCommandEvent &)505 void CCTestFrame::OnMenuSaveSelected(wxCommandEvent& /*event*/)
506 {
507     if (m_SaveFile->ShowModal() == wxID_OK)
508     {
509         wxFile file(m_SaveFile->GetPath(), wxFile::write);
510         file.Write(m_LogCtrl->GetValue());
511     }
512 }
513 
514 // load the select source file to wxScintilla control
OnMenuOpenSelected(wxCommandEvent &)515 void CCTestFrame::OnMenuOpenSelected(wxCommandEvent& /*event*/)
516 {
517     if (m_OpenFile->ShowModal() == wxID_OK)
518     {
519         m_MainFile = m_OpenFile->GetPath();
520         LoadToControl();
521     }
522 }
523 
OnMenuFindSelected(wxCommandEvent &)524 void CCTestFrame::OnMenuFindSelected(wxCommandEvent& /*event*/)
525 {
526     if (m_FRDlg != NULL)
527     {
528         delete m_FRDlg;
529         m_FRDlg = NULL;
530     }
531     else
532     {
533         m_FRData.SetFlags(wxFR_DOWN);
534         m_FRDlg = new wxFindReplaceDialog(this, &m_FRData, _("Find dialog"));
535         m_FRDlg->Show(true);
536     }
537 }
538 
OnMenuTokenSelected(wxCommandEvent &)539 void CCTestFrame::OnMenuTokenSelected(wxCommandEvent& /*event*/)
540 {
541     ParserBase* pb = &(m_NativeParser.m_Parser);
542     TokenTree*  tt = m_NativeParser.m_Parser.GetTokenTree();
543     if (!pb || !tt) return;
544     wxTextEntryDialog dlg(this, _("Enter name of token to debug:"), _("CCTest"));
545     if (dlg.ShowModal()==wxID_OK)
546     {
547         wxString target = dlg.GetValue().Trim(true).Trim(false);
548         if (target.IsEmpty()) return;
549 
550         // Search over all tokens, no AI whatsoever available
551         bool found = false;
552         for (size_t i=0; i<tt->size(); ++i)
553         {
554             Token* t = tt->at(i);
555             if (t && t->m_Name.Matches(target))
556             {
557                 CCDebugInfo di(this, pb, t); di.ShowModal();
558                 found = true;
559                 break; // found, exit for-loop
560             }
561         }
562         if (!found)
563             wxMessageBox(_("Token not found."), _("CCTest"),
564                          wxOK | wxICON_INFORMATION, this);
565     }
566 }
567 
OnMenuReparseSelected(wxCommandEvent &)568 void CCTestFrame::OnMenuReparseSelected(wxCommandEvent& /*event*/)
569 {
570     Start();
571 }
572 
OnMenuAboutSelected(wxCommandEvent &)573 void CCTestFrame::OnMenuAboutSelected(wxCommandEvent& /*event*/)
574 {
575     wxString str;
576     str.Printf(_("CCTest build with %s!\nRunning under %s."),
577                wxVERSION_STRING, wxGetOsDescription().c_str());
578     wxMessageBox(str, _("About CCTest"), wxOK | wxICON_INFORMATION, this);
579 }
580 
OnParse(wxCommandEvent & WXUNUSED (event))581 void CCTestFrame::OnParse(wxCommandEvent& WXUNUSED(event))
582 {
583     Start();
584 }
585 
OnMarginClick(wxScintillaEvent & event)586 void CCTestFrame::OnMarginClick(wxScintillaEvent& event)
587 {
588     if (event.GetMargin()==C_FOLDING_MARGIN)
589     {
590         int lineYpix = event.GetPosition();
591         int line     = m_Control->LineFromPosition(lineYpix);
592 
593         m_Control->ToggleFold(line);
594     }
595 }
596 
OnFindDialog(wxFindDialogEvent & event)597 void CCTestFrame::OnFindDialog(wxFindDialogEvent& event)
598 {
599     wxEventType type = event.GetEventType();
600     if (type == wxEVT_COMMAND_FIND || type == wxEVT_COMMAND_FIND_NEXT)
601     {
602         if (event.GetFlags() & wxFR_DOWN)
603         {
604             if (type == wxEVT_COMMAND_FIND)
605             {
606                 m_LastIndex = m_LogCtrl->GetInsertionPoint();
607                 wxString tmp = m_LogCtrl->GetValue().SubString(m_LastIndex, m_LogCtrl->GetLastPosition() - 1);
608                 int i;
609                 if (event.GetFlags() & wxFR_MATCHCASE)
610                     i = m_LogCtrl->GetValue().Find(event.GetFindString().c_str());
611                 else
612                     i = tmp.Upper().Find(event.GetFindString().Upper().c_str());
613                 if (i >= 0)
614                 {
615                     m_LastIndex += i;
616                     m_LogCtrl->SetSelection(m_LastIndex, m_LastIndex + event.GetFindString().Length());
617                 }
618             }
619             else // find next
620             {
621                 wxString tmp = m_LogCtrl->GetValue().SubString(++m_LastIndex, m_LogCtrl->GetLastPosition() - 1) ;
622                 int i;
623                 if (event.GetFlags() & wxFR_MATCHCASE)
624                     i = tmp.Find(event.GetFindString().c_str());
625                 else
626                     i = tmp.Upper().Find(event.GetFindString().Upper().c_str());
627                 if (i >= 0)
628                 {
629                     m_LastIndex += i;
630                     m_LogCtrl->SetSelection(m_LastIndex, m_LastIndex + event.GetFindString().Length());
631                 }
632             }
633             m_LogCtrl->SetFocus();
634         }
635         else //find up
636         {
637             if (type == wxEVT_COMMAND_FIND)
638             {
639                 m_LastIndex = m_LogCtrl->GetInsertionPoint();
640                 int i;
641                 if (event.GetFlags() & wxFR_MATCHCASE)
642                     i = m_LogCtrl->GetValue().rfind(event.GetFindString().c_str(), m_LastIndex);
643                 else
644                     i = m_LogCtrl->GetValue().Upper().rfind(event.GetFindString().Upper().c_str(), m_LastIndex);
645 
646                 if (i >= 0)
647                 {
648                     m_LogCtrl->SetSelection(i, i + event.GetFindString().Length());
649                     m_LastIndex = i;
650                 }
651             }
652             else
653             {
654                 wxString tmp = m_LogCtrl->GetValue().SubString(0, --m_LastIndex) ;
655                 int i;
656                 if (event.GetFlags() & wxFR_MATCHCASE)
657                     i = tmp.rfind(event.GetFindString().c_str(), m_LastIndex);
658                 else
659                     i = tmp.Upper().rfind(event.GetFindString().Upper().c_str(), m_LastIndex);
660                 if (i >= 0)
661                 {
662                     m_LastIndex = i;
663                     m_LogCtrl->SetSelection(m_LastIndex, m_LastIndex + event.GetFindString().Length());
664                 }
665             }
666         }
667 
668         m_LogCtrl->SetFocus();
669     }
670     else if (type == wxEVT_COMMAND_FIND_CLOSE)
671     {
672         delete m_FRDlg;
673         m_FRDlg = NULL;
674     }
675 }
676 
OnCCLogger(wxCommandEvent & event)677 void CCTestFrame::OnCCLogger(wxCommandEvent& event)
678 {
679     wxString log(event.GetString());
680 
681     for (size_t i = 0; i < log.Len(); ++i) // Convert '\r' to "\r", '\n' to "\n"
682     {
683         if (log.GetChar(i) == wxT('\r'))
684         {
685             log.SetChar(i, wxT('\\'));
686             log.insert(++i, 1, wxT('r'));
687         }
688         else if (log.GetChar(i) == wxT('\n'))
689         {
690             log.SetChar(i, wxT('\\'));
691             log.insert(++i, 1, wxT('n'));
692         }
693     }
694 
695     AppendToLog(log);
696 }
697 
OnCCAddToken(wxCommandEvent & event)698 void CCTestFrame::OnCCAddToken(wxCommandEvent& event)
699 {
700     wxString log(event.GetString());
701     if (m_ProgDlg)
702         m_ProgDlg->Update(-1, m_CurrentFile + wxT("\n") + log);
703 }
704 
OnPrintTree(cb_unused wxCommandEvent & event)705 void CCTestFrame::OnPrintTree(cb_unused wxCommandEvent& event)
706 {
707     m_ProgDlg = new wxProgressDialog(_("Please wait, operating..."), _("Preparing...\nPlease wait..."), 0, this, wxPD_APP_MODAL);
708     m_ProgDlg->SetSize(640,100);
709     m_ProgDlg->Layout();
710     m_ProgDlg->CenterOnParent();
711     // print tree information below
712 
713     m_ProgDlg->Update(-1, _("Creating tree log..."));
714     AppendToLog(_("--------------T-r-e-e--L-o-g--------------\r\n"));
715     m_NativeParser.PrintTree();
716 
717     m_ProgDlg->Update(-1, _("Creating list log..."));
718     AppendToLog(_("--------------L-i-s-t--L-o-g--------------\r\n"));
719     m_NativeParser.PrintList();
720 
721     if (m_DoTreeCtrl->IsChecked())
722     {
723         m_ProgDlg->Update(-1, wxT("Serializing tree..."));
724 
725         Freeze();
726         m_TreeCtrl->SetValue( m_NativeParser.SerializeTree() );
727         Thaw();
728     }
729 
730     if (m_ProgDlg) { delete m_ProgDlg; m_ProgDlg = 0; }
731 
732     if ( !IsShown() ) Show();
733 
734     TokenTree* tt = m_NativeParser.m_Parser.GetTokenTree();
735     if (tt)
736     {
737         AppendToLog((wxString::Format(_("The parser contains %lu tokens, found in %lu files."),
738                                       static_cast<unsigned long>(tt->size()), static_cast<unsigned long>(tt->m_FileMap.size()))));
739     }
740 }
741 
OnTestSingle(wxCommandEvent & WXUNUSED (event))742 void CCTestFrame::OnTestSingle(wxCommandEvent& WXUNUSED(event))
743 {
744     // Note that we don't call the Start() here, because we only want to test a single file,
745     // so the include paths is not updated here(It will be updated in Start() function)
746 
747     // read the contents of the Control, and parse it.
748     // no need to save the file to hard dist and after parsing, delete it.
749     wxString content = m_Control->GetText();
750     m_NativeParser.ParseAndCodeCompletion(content, /* isLocalFile */ false);
751 }
752 
OnSaveTestResultClick(wxCommandEvent & event)753 void CCTestFrame::OnSaveTestResultClick(wxCommandEvent& event)
754 {
755     // save the content of the Completion test panel to the result file
756     wxString content = m_CompletionTestCtrl->GetValue();
757     wxFileDialog dlg(this, _T("Save .txt file..."),
758                      _T(""), _T(""),
759                      _T("Save Files (*.txt)|*.txt|All files(*.*)|*.*"),
760                      wxFD_SAVE);
761     if (dlg.ShowModal() == wxID_OK)
762     {
763         wxFile file(dlg.GetPath(), wxFile::write);
764         if( file.IsOpened() )
765         {
766             file.Write(content);
767             file.Close();
768         }
769     }
770     return;
771 
772 }
773