///////////////////////////////////////////////////////////////////////////// // Name: regextest.cpp // Purpose: Application to test regular expression (wxRegEx) // Author: Ryan Norton // Modified by: // RCS-ID: $Id$ // Copyright: (c) 2003 Ryan Norton // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// //=========================================================================== // REGEX LIBS //=========================================================================== //wxWindows regular expression library #define wxUSE_WXREGEX //RN (Ryan Norton's) regular expression library //#define wxUSE_RNWXRE //GRETA, Microsoft Research's templated regex library //[http://research.microsoft.com/projects/greta/] //Install - Get it from .net powertools, put the directory in this directory //#define wxUSE_GRETA //PCRE (Perl Compatible Regular Expressions) [sourceforge.net/projects/pcre] //Install - Get the GnuWin32 version and put the files in this directory //#define wxUSE_PCRE //=========================================================================== // HEADERS //=========================================================================== // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif // for all others, include the necessary headers (this file is usually all you // need because it includes almost all "standard" wxWindows headers) #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/file.h" #ifdef wxUSE_WXREGEX // // This is the required header for wxRegEx // # include #endif #ifdef wxUSE_RNWXRE # include "re.h" #endif #ifdef wxUSE_GRETA # ifdef _MSC_VER # pragma warning(disable:4018) # pragma warning(disable:4100) # pragma warning(disable:4146) # pragma warning(disable:4244) # pragma warning(disable:4663) extern "C" { int __cdecl _resetstkoflw(void) {return 0;} } # endif //_MSC_VER # include "greta/regexpr2.h" using namespace regex; #endif //wxUSE_GRETA #ifdef wxUSE_PCRE # include "pcre.h" # ifdef _MSC_VER # pragma comment(lib, "libpcre.a") # endif #endif //=========================================================================== // IMPLEMENTATION //=========================================================================== // // One of the best sources for regex info is IEEE document/standard 1003.2 // From the open group. // A current link - (http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap09.html). // //--------------------------------------------------------------------------- // MyDialog //--------------------------------------------------------------------------- class MyDialog : public wxFrame { public: //IDs for our controls enum { PatternTextID, SearchTextID, OkButtonID }; //Menu IDs enum { ExtendedID, ICaseID, NewLineID, NotBolID, NotEolID, CompID }; MyDialog() : wxFrame( NULL, -1, _("regextest - wxRegEx Testing App"), wxPoint(20,20), wxSize(300,400), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL ) { //Set the background to something light gray-ish SetBackgroundColour(wxColour(150,150,150)); // // Create the menus (Exit & About) // #if wxUSE_MENUS wxMenu *FileMenu = new wxMenu; OptionsMenu = new wxMenu; wxMenu *HelpMenu = new wxMenu; FileMenu->Append(wxID_EXIT, _T("&Exit"), _("Quit this program")); OptionsMenu->AppendCheckItem(ExtendedID, _T("wxRE_EXTENDED"), _("Extended Regular Expressions?")); OptionsMenu->AppendCheckItem(ICaseID, _T("wxRE_ICASE"), _("Enable case-insensitive matching?")); OptionsMenu->AppendCheckItem(NewLineID, _T("wxRE_NEWLINE"), _("Treat \n as special?")); OptionsMenu->AppendSeparator(); OptionsMenu->AppendCheckItem(NotBolID, _T("wxRE_NOTBOL"), _("Use functionality of ^ character?")); OptionsMenu->AppendCheckItem(NotEolID, _T("wxRE_NOTEOL"), _("Use functionality of $ character?")); OptionsMenu->AppendSeparator(); OptionsMenu->AppendSeparator(); OptionsMenu->AppendCheckItem(CompID, _T("Test Compile"), _("Added Compiling to Match Time?")); OptionsMenu->Check(ExtendedID, true); HelpMenu->Append(wxID_ABOUT, _T("&About...\tF1"), _("Show about dialog")); wxMenuBar *MenuBar = new wxMenuBar(); MenuBar->Append(FileMenu, _T("&File")); MenuBar->Append(OptionsMenu, _T("&Options")); MenuBar->Append(HelpMenu, _T("&Help")); SetMenuBar(MenuBar); #endif // wxUSE_MENUS // Text controls PatternText.Create(this, PatternTextID, _(""), wxPoint(5, 30)); SearchText.Create(this, SearchTextID, _(""), wxPoint(5, 75)); //reset size of text controls wxSize TextSize = PatternText.GetSize(); TextSize.SetWidth(200); PatternText.SetSize(TextSize); SearchText.SetSize(TextSize); // StaticText PatternHeader.Create(this, -1, _("Regular Expression:"), wxPoint(5, 10)); SearchHeader.Create(this, -1, _("String to Search:"), wxPoint(5, 55)); IterHeader.Create(this, -1, _("Iterations (Match Time):"), wxPoint(100, 100)); ResultText.Create(this, -1, _(""), wxPoint(5, 150), wxSize(100,200), wxST_NO_AUTORESIZE); ResultText2.Create(this, -1, _(""), wxPoint(115, 150), wxSize(100,200), wxST_NO_AUTORESIZE); // Button OkButton.Create(this, OkButtonID, _("OK"), wxPoint(20, 120)); NumIters.Create(this, -1, _("15000"), wxPoint(100, 120)); } void OnAbout(wxCommandEvent& WXUNUSED(evt)) { wxChar* szBuffer; wxFile f; f.Open(_("README.txt"), wxFile::read); szBuffer = new wxChar[f.Length() + 1]; f.Read(szBuffer, f.Length()); f.Close(); wxMessageBox(wxString::Format( _("%s%s%s%s"), _("-----------Regular Expression Test Application-----------\n"), szBuffer, _("\n\n\n(c) 2003 Ryan Norton \n"), wxVERSION_STRING ) ); delete szBuffer; } void OnMatch(wxCommandEvent& WXUNUSED(evt)) { wxString szPattern = PatternText.GetValue(); wxString szSearch = SearchText.GetValue(); wxString szResult, szResult2, szResult3, szResult4; //Will be displayed in ResultText wxString szStatus, szStatus2, szStatus3, szStatus4; int nCompileFlags = 0, nCompileFlags2 = 0, nCompileFlags3 = 0, nCompileFlags4 = 0; int nMatchFlags = 0, nMatchFlags2 = 0, nMatchFlags3 = 0, nMatchFlags4 = 0; if (!(OptionsMenu->IsChecked(ExtendedID))) { #ifdef wxUSE_WXREGEX nCompileFlags |= wxRE_BASIC; #endif } else { #ifdef wxUSE_RNWXRE nCompileFlags2 |= wxRe::wxRE_EXTENDED; #endif // nCompileFlags3 |= EXTENDED; } if (OptionsMenu->IsChecked(ICaseID)) { #ifdef wxUSE_WXREGEX nCompileFlags |= wxRE_ICASE; #endif #ifdef wxUSE_RNWXRE nCompileFlags2 |= wxRe::wxRE_ICASE; #endif #ifdef wxUSE_GRETA nCompileFlags3 |= NOCASE; #endif } if (OptionsMenu->IsChecked(NewLineID)) { #ifdef wxUSE_WXREGEX nCompileFlags |= wxRE_NEWLINE; #endif #ifdef wxUSE_RNWXRE nCompileFlags2 |= wxRe::wxRE_NEWLINE; #endif #ifdef wxUSE_GRETA nCompileFlags3 |= MULTILINE; #endif } if (OptionsMenu->IsChecked(NotBolID)) { #ifdef wxUSE_WXREGEX nMatchFlags |= wxRE_NOTBOL; #endif #ifdef wxUSE_RNWXRE nMatchFlags2 |= wxRe::wxRE_NOTBOL; #endif } if (OptionsMenu->IsChecked(NotEolID)) { #ifdef wxUSE_WXREGEX nMatchFlags |= wxRE_NOTEOL; #endif #ifdef wxUSE_RNWXRE nMatchFlags2 |= wxRe::wxRE_NOTEOL; #endif } //Our regular expression object //Success! Here we'll display some //information to the user size_t dwStartIndex = 0, dwEndIndex = 0, dwStartIndex2= 0, dwEndIndex2= 0, dwStartIndex3= 0, dwEndIndex3= 0, dwStartIndex4= 0, dwEndIndex4= 0; time_t dwStartTime = 0, dwEndTime = 0, dwStartTime2= 0, dwEndTime2= 0, dwStartTime3= 0, dwEndTime3= 0, dwStartTime4= 0, dwEndTime4= 0; int i = 0; long n; if (!NumIters.GetValue().ToLong(&n)) n = 0; #ifdef wxUSE_WXREGEX wxRegEx Regex; //Regular Expressions must be compiled before //you can search a string with them, or //at least most implementations do. //(Boost and Microsoft have templated //versions that don't require compilation) //Basically compilation breaks it down into //something that's easier to parse, due //to the syntax of regular expressions if (!Regex.Compile(szPattern, nCompileFlags)) szStatus += _("\nCompile Failed!\n"); else { //Here's where we actually search our string if (!Regex.Matches(szSearch, nMatchFlags)) szStatus += _("\nExecution/Matching Failed!\n"); else { Regex.GetMatch(&dwStartIndex, &dwEndIndex); szStatus = _("Success"); //We're going to go ahead and time the match //for fun (clock() is a c library routine that //returns the current time since a certian point //in milliseconds dwStartTime = clock(); if (OptionsMenu->IsChecked(CompID)) { for(i = 0; i < n; ++i) { Regex.Compile(szPattern, nCompileFlags); Regex.Matches(szSearch, nMatchFlags); } } else { for(i = 0; i < n; ++i) { Regex.Matches(szSearch, nMatchFlags); } } //This line gets the difference in time between now //and when we first initialized dwStartTime. dwEndTime = clock() - dwStartTime; } } szResult = wxString::Format( _("--wxRegEx--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"), dwStartIndex, dwEndIndex+dwStartIndex, szSearch.Mid(dwStartIndex, dwEndIndex), dwEndTime, szStatus ); #endif //wxUSE_WXREGEX #ifdef wxUSE_RNWXRE wxRe Re; wxRe::wxReError e; if ((e = Re.Comp(szPattern, nCompileFlags2)) != wxRe::wxRE_OK) szStatus2 = wxString::Format(_("\nCompile Failed!\n%s\n"), wxRe::ErrorToString(e)); else { //Here's where we actually search our string if ((e = Re.Exec(szSearch, nMatchFlags2)) != wxRe::wxRE_OK) szStatus2 = wxString::Format(_("\nExecution/Matching Failed!\n%s\n"), wxRe::ErrorToString(e)); else { dwStartIndex2 = Re.GetMatch(0).first; dwEndIndex2 = Re.GetMatch(0).second; szStatus2 = _("Success"); dwStartTime2 = clock(); if (OptionsMenu->IsChecked(CompID)) { for(i = 0; i < n; ++i) { Re.Comp(szPattern, nCompileFlags2); Re.Exec(szSearch, nMatchFlags2); } } else { for(i = 0; i < n; ++i) { Re.Exec(szSearch, nMatchFlags2); } } dwEndTime2 = clock() - dwStartTime2; } } szResult2 = wxString::Format( _("--Ryan's wxRe--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"), dwStartIndex2, dwEndIndex2+dwStartIndex2, szSearch.Mid(dwStartIndex2, dwEndIndex2), dwEndTime2, szStatus2 ); #endif //wxUSE_RNWXRE #ifdef wxUSE_GRETA std::string stdszPattern(szPattern); rpattern Greta (stdszPattern,EXTENDED,MODE_MIXED); match_results r; std::string stdszSearch(szSearch); //Here's where we actually search our string if (!Greta.match(stdszSearch, r).matched) szStatus3 += _("\nExecution/Matching Failed!\n"); else { szStatus3 = _("Success"); dwStartTime3 = clock(); if (OptionsMenu->IsChecked(CompID)) { for(i = 0; i < n; ++i) { Greta = rpattern(stdszPattern,EXTENDED,MODE_MIXED); Greta.match(stdszSearch, r); } } else { for(i = 0; i < n; ++i) { Greta.match(stdszSearch, r); } } dwEndTime3 = clock() - dwStartTime3; } szResult3 = wxString::Format( _("--Greta--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"), r.rstart(), r.rlength() + r.rstart(), szSearch.Mid(r.rstart(), r.rlength()), dwEndTime3, szStatus3); #endif //wxUSE_GRETA #ifdef wxUSE_PCRE pcre* pPcre; const wxChar* szError; int nErrOff; if ((pPcre = pcre_compile(szPattern, nCompileFlags4, &szError, &nErrOff, 0)) == NULL) szStatus4 = wxString::Format(_("\nCompile Failed!\nError:%s\nOffset:%i\n"), szError, nErrOff); else { size_t msize; pcre_fullinfo(pPcre, 0, PCRE_INFO_CAPTURECOUNT, &msize); msize = 3*(msize+1); int *m = new int[msize]; //Here's where we actually search our string if (!pcre_exec(pPcre, 0, szSearch, szSearch.Length(), 0, 0, m, msize)) szStatus4 = wxString::Format(_("\nExecution/Matching Failed!\n")); else { dwStartIndex4 = m[0]; dwEndIndex4 = m[1] - m[0]; szStatus4 = _("Success"); dwStartTime4 = clock(); if (OptionsMenu->IsChecked(CompID)) { for(i = 0; i < n; ++i) { pPcre = pcre_compile(szPattern, nCompileFlags4, &szError, &nErrOff, 0); pcre_exec(pPcre, 0, szSearch, szSearch.Length(), 0, 0, m, msize); } } else { for(i = 0; i < n; ++i) { pcre_exec(pPcre, 0, szSearch, szSearch.Length(), 0, 0, m, msize); } } dwEndTime4 = clock() - dwStartTime4; } } szResult4 = wxString::Format( _("--PCRE--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"), dwStartIndex4, dwEndIndex4+dwStartIndex4, szSearch.Mid(dwStartIndex4, dwEndIndex4), dwEndTime4, szStatus4 ); #endif //wxUSE_PCRE ResultText.SetLabel(szResult + _("\n\n") + szResult2); ResultText2.SetLabel(szResult3 + _("\n\n") + szResult4); } void OnQuit(wxCommandEvent& WXUNUSED(evt)) { Close(TRUE); } wxTextCtrl PatternText, SearchText, NumIters; wxStaticText PatternHeader, SearchHeader, IterHeader, ResultText, ResultText2; wxButton OkButton; wxMenu *OptionsMenu; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(MyDialog, wxFrame) //menu EVT_MENU(wxID_EXIT, MyDialog::OnQuit) EVT_MENU(wxID_ABOUT, MyDialog::OnAbout) //text EVT_TEXT_ENTER(MyDialog::PatternTextID, MyDialog::OnMatch) EVT_TEXT_ENTER(MyDialog::SearchTextID, MyDialog::OnMatch) //button EVT_BUTTON(MyDialog::OkButtonID, MyDialog::OnMatch) END_EVENT_TABLE() //--------------------------------------------------------------------------- // MyApp //--------------------------------------------------------------------------- class MyApp : public wxApp { public: bool OnInit() { MyDialog* dialog = new MyDialog(); dialog->Show(); return true; } }; IMPLEMENT_APP(MyApp)