1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Test regex libs and some gui components
7 // Copyright: (c) 2003 Ryan Norton <wxprojects@comcast.net>
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
11 //===========================================================================
13 //===========================================================================
15 //wxWindows regular expression library
18 //RN (Ryan Norton's) regular expression library
19 //#define wxUSE_RNWXRE
21 //GRETA, Microsoft Research's templated regex library
22 //[http://research.microsoft.com/projects/greta/]
23 //Install - Get it from .net powertools, put the directory in this directory
24 //(I.E. All the files will be in $thisdir$/GRETA)
27 //PCRE (Perl Compatible Regular Expressions) [sourceforge.net/projects/pcre]
28 //Install - Get the GnuWin32 version and put the files in this directory
29 //MSVC - add libpcre.a from the GnuWin32 to this directory
32 //===========================================================================
34 //===========================================================================
36 // For compilers that support precompilation, includes "wx/wx.h".
37 #include "wx/wxprec.h"
43 // for all others, include the necessary headers (this file is usually all you
44 // need because it includes almost all "standard" wxWindows headers)
53 // This is the required header for wxRegEx
55 # include <wx/regex.h>
64 # pragma warning(disable:4018)
65 # pragma warning(disable:4100)
66 # pragma warning(disable:4146)
67 # pragma warning(disable:4244)
68 # pragma warning(disable:4663)
70 int __cdecl
_resetstkoflw(void) {return 0;}
73 # include "greta/regexpr2.h"
74 using namespace regex
;
80 # pragma comment(lib, "libpcre.a")
84 //===========================================================================
86 //===========================================================================
89 // One of the best sources for regex info is IEEE document/standard 1003.2
90 // From the open group.
91 // A current link - (http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap09.html).
94 //---------------------------------------------------------------------------
96 //---------------------------------------------------------------------------
98 class MyFrame
: public wxFrame
102 //IDs for our controls
123 void AddMenuItem(wxMenu
* pMenu
, int nID
= wxID_SEPARATOR
, const wxChar
* szTitle
= _(""),
124 const wxChar
* szToolTip
= _(""))
128 if (nID
== wxID_SEPARATOR
)
129 pItem
= new wxMenuItem (NULL
, wxID_SEPARATOR
, szTitle
, szToolTip
, wxITEM_SEPARATOR
);
131 pItem
= new wxMenuItem (NULL
, nID
, szTitle
, szToolTip
, wxITEM_CHECK
);
133 #if defined(__WXMSW __)
134 pItem
->SetBackgroundColour(wxColour(115, 113, 115));
135 pItem
->SetTextColour(*wxBLACK
);
137 pMenu
->Append(pItem
);
140 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
141 void OnContextMenu(wxContextMenuEvent
& event
)
142 { PopupMenu(OptionsMenu
, ScreenToClient(event
.GetPosition())); }
144 void OnRightUp(wxMouseEvent
& event
)
145 { PopupMenu(OptionsMenu
, event
.GetPosition()); }
148 MyFrame() : wxFrame( NULL
, -1, _("regextest - wxRegEx Testing App"),
149 wxPoint(20,20), wxSize(300,450), wxDEFAULT_FRAME_STYLE
| wxTAB_TRAVERSAL
)
151 //Set the background to something light gray-ish
152 SetBackgroundColour(wxColour(150,150,150));
155 // Create the menus (Exit & About)
158 wxMenu
*FileMenu
= new wxMenu
;
159 OptionsMenu
= new wxMenu
;
160 wxMenu
*HelpMenu
= new wxMenu
;
162 AddMenuItem(FileMenu
, wxID_EXIT
, _("&Exit"), _("Quit this program"));
164 AddMenuItem(OptionsMenu
, ExtendedID
, _T("wxRE_EXTENDED"), _("Extended Regular Expressions?"));
165 AddMenuItem(OptionsMenu
, ICaseID
, _T("wxRE_ICASE"), _("Enable case-insensitive matching?"));
166 AddMenuItem(OptionsMenu
, NewLineID
, _T("wxRE_NEWLINE"), _("Treat \n as special?"));
167 AddMenuItem(OptionsMenu
);
168 AddMenuItem(OptionsMenu
, NotBolID
, _T("wxRE_NOTBOL"), _("Use functionality of ^ character?"));
169 AddMenuItem(OptionsMenu
, NotEolID
, _T("wxRE_NOTEOL"), _("Use functionality of $ character?"));
170 AddMenuItem(OptionsMenu
);
171 AddMenuItem(OptionsMenu
);
172 AddMenuItem(OptionsMenu
, CompID
, _("Test Compile"), _("Added Compiling to Match Time?"));
173 AddMenuItem(OptionsMenu
, MatchID
, _("Test Match"), _("Added Matching to Match Time?"));
175 AddMenuItem(HelpMenu
, wxID_ABOUT
, _T("&About...\tF1"), _("Show about dialog"));
177 OptionsMenu
->Check(ExtendedID
, true);
179 OptionsMenu
->Check(CompID
, true);
180 OptionsMenu
->Check(MatchID
, true);
182 wxMenuBar
*MenuBar
= new wxMenuBar();
183 MenuBar
->Append(FileMenu
, _T("&File"));
184 MenuBar
->Append(OptionsMenu
, _T("&Options"));
185 MenuBar
->Append(HelpMenu
, _T("&Help"));
188 #endif // wxUSE_MENUS
191 PatternText
.Create(this, PatternTextID
, _(""), wxPoint(5, 30));
192 SearchText
.Create(this, SearchTextID
, _(""), wxPoint(5, 75));
193 //reset size of text controls
194 wxSize TextSize
= PatternText
.GetSize();
195 TextSize
.SetWidth(200);
196 PatternText
.SetSize(TextSize
);
197 SearchText
.SetSize(TextSize
);
200 PatternHeader
.Create(this, -1, _("Regular Expression:"), wxPoint(5, 10));
201 SearchHeader
.Create(this, -1, _("String to Search:"), wxPoint(5, 55));
202 IterHeader
.Create(this, -1, _("Iterations (Match Time):"), wxPoint(100, 100));
204 ResultText
.Create(this, -1, _(""), wxPoint(5, 150), wxSize(100,230), wxST_NO_AUTORESIZE
);
205 ResultText2
.Create(this, -1, _(""), wxPoint(115, 150), wxSize(100,230), wxST_NO_AUTORESIZE
);
208 OkButton
.Create(this, OkButtonID
, _("OK"), wxPoint(20, 120));
210 NumIters
.Create(this, -1, _("5000"), wxPoint(100, 120));
212 #if wxUSE_STATUSBAR && !defined(__WXWINCE__)
213 // create a status bar just for fun (by default with 1 pane only)
215 SetStatusText(_("Enter Some Values and Press the OK Button or Enter"));
216 #endif // wxUSE_STATUSBAR
219 void OnAbout(wxCommandEvent
& WXUNUSED(evt
))
224 f
.Open(_("README.txt"), wxFile::read
);
225 szBuffer
= new wxChar
[f
.Length() + 1];
226 f
.Read(szBuffer
, f
.Length());
229 wxMessageBox(wxString::Format(
231 _("-----------Regular Expression Test Application-----------\n"),
233 _("\n\n\n(c) 2003 Ryan Norton <wxprojects@comcast.net>\n"),
241 void OnMatch(wxCommandEvent
& WXUNUSED(evt
))
243 wxString szPattern
= PatternText
.GetValue();
244 wxString szSearch
= SearchText
.GetValue();
245 wxString szResult
, szResult2
, szResult3
, szResult4
; //Will be displayed in ResultText
246 wxString szStatus
, szStatus2
, szStatus3
, szStatus4
;
248 int nCompileFlags
= 0, nCompileFlags2
= 0, nCompileFlags3
= 0, nCompileFlags4
= 0;
249 int nMatchFlags
= 0, nMatchFlags2
= 0, nMatchFlags3
= 0, nMatchFlags4
= 0;
251 if (!(OptionsMenu
->IsChecked(ExtendedID
)))
254 nCompileFlags
|= wxRE_BASIC
;
260 nCompileFlags2
|= wxRe::wxRE_EXTENDED
;
262 // nCompileFlags3 |= EXTENDED;
265 if (OptionsMenu
->IsChecked(ICaseID
))
268 nCompileFlags
|= wxRE_ICASE
;
271 nCompileFlags2
|= wxRe::wxRE_ICASE
;
274 nCompileFlags3
|= NOCASE
;
278 if (OptionsMenu
->IsChecked(NewLineID
))
281 nCompileFlags
|= wxRE_NEWLINE
;
284 nCompileFlags2
|= wxRe::wxRE_NEWLINE
;
287 nCompileFlags3
|= MULTILINE
;
291 if (OptionsMenu
->IsChecked(NotBolID
))
294 nMatchFlags
|= wxRE_NOTBOL
;
297 nMatchFlags2
|= wxRe::wxRE_NOTBOL
;
301 if (OptionsMenu
->IsChecked(NotEolID
))
304 nMatchFlags
|= wxRE_NOTEOL
;
307 nMatchFlags2
|= wxRe::wxRE_NOTEOL
;
311 //Our regular expression object
313 //Success! Here we'll display some
314 //information to the user
315 size_t dwStartIndex
= 0, dwEndIndex
= 0,
316 dwStartIndex2
= 0, dwEndIndex2
= 0,
317 dwStartIndex3
= 0, dwEndIndex3
= 0,
318 dwStartIndex4
= 0, dwEndIndex4
= 0;
320 time_t dwStartTime
= 0, dwEndTime
= 0,
321 dwStartTime2
= 0, dwEndTime2
= 0,
322 dwStartTime3
= 0, dwEndTime3
= 0,
323 dwStartTime4
= 0, dwEndTime4
= 0;
327 if (!NumIters
.GetValue().ToLong(&n
))
332 SetStatusText("Testing wxRegEx...");
335 //Regular Expressions must be compiled before
336 //you can search a string with them, or
337 //at least most implementations do.
338 //(Boost and Microsoft have templated
339 //versions that don't require compilation)
340 //Basically compilation breaks it down into
341 //something that's easier to parse, due
342 //to the syntax of regular expressions
343 if (!Regex
.Compile(szPattern
, nCompileFlags
))
344 szStatus
+= _("\nCompile Failed!\n");
347 //Here's where we actually search our string
348 if (!Regex
.Matches(szSearch
, nMatchFlags
))
349 szStatus
+= _("\nExecution/Matching Failed!\n");
352 Regex
.GetMatch(&dwStartIndex
, &dwEndIndex
);
354 szStatus
= _("Success");
356 //We're going to go ahead and time the match
357 //for fun (clock() is a c library routine that
358 //returns the current time since a certian point
360 dwStartTime
= clock();
362 if (OptionsMenu
->IsChecked(CompID
))
364 for(i
= 0; i
< n
; ++i
)
366 SetStatusText(wxString::Format(_("wxRegEx Compile #%i"), i
));
367 Regex
.Compile(szPattern
, nCompileFlags
);
370 if (OptionsMenu
->IsChecked(MatchID
))
372 for(i
= 0; i
< n
; ++i
)
374 SetStatusText(wxString::Format(_("wxRegEx Match #%i"), i
));
375 Regex
.Matches(szSearch
, nMatchFlags
);
379 //This line gets the difference in time between now
380 //and when we first initialized dwStartTime.
381 dwEndTime
= clock() - dwStartTime
;
386 szResult
= wxString::Format(
387 _("--wxRegEx--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
388 dwStartIndex
, dwEndIndex
+dwStartIndex
,
389 szSearch
.Mid(dwStartIndex
, dwEndIndex
),
394 #endif //wxUSE_WXREGEX
397 SetStatusText("Testing RNWXRE...");
401 if ((e
= Re
.Comp(szPattern
, nCompileFlags2
)) != wxRe::wxRE_OK
)
402 szStatus2
= wxString::Format(_("\nCompile Failed!\n%s\n"), wxRe::ErrorToString(e
));
405 //Here's where we actually search our string
406 if ((e
= Re
.Exec(szSearch
, nMatchFlags2
)) != wxRe::wxRE_OK
)
407 szStatus2
= wxString::Format(_("\n%s\n"), wxRe::ErrorToString(e
));
410 dwStartIndex2
= Re
.GetMatch(0).first
;
411 dwEndIndex2
= Re
.GetMatch(0).second
;
413 szStatus2
= _("Success");
415 dwStartTime2
= clock();
417 if (OptionsMenu
->IsChecked(CompID
))
419 for(i
= 0; i
< n
; ++i
)
421 SetStatusText(wxString::Format(_("RNWXRE Compile #%i"), i
));
422 Re
.Comp(szPattern
, nCompileFlags2
);
425 if (OptionsMenu
->IsChecked(MatchID
))
427 for(i
= 0; i
< n
; ++i
)
429 SetStatusText(wxString::Format(_("RNWXRE Match #%i"), i
));
430 Re
.Exec(szSearch
, nMatchFlags2
);
434 dwEndTime2
= clock() - dwStartTime2
;
437 szResult2
= wxString::Format(
438 _("--Ryan's wxRe--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
439 dwStartIndex2
, dwEndIndex2
+dwStartIndex2
,
440 szSearch
.Mid(dwStartIndex2
, dwEndIndex2
),
444 #endif //wxUSE_RNWXRE
447 SetStatusText("Testing GRETA...");
448 bool bSuccess
= true;
450 std::string
stdszPattern(szPattern
);
454 Greta
= rpattern(stdszPattern
,EXTENDED
,MODE_MIXED
);
459 szStatus3
+= _("\nCompile Failed!\n");
462 std::string
stdszSearch(szSearch
);
466 //Here's where we actually search our string
467 if (!(bSuccess
= Greta
.match(stdszSearch
, r
).matched
))
468 szStatus3
+= _("\nExecution/Matching Failed!\n");
471 szStatus3
= _("Success");
473 dwStartTime3
= clock();
475 if (OptionsMenu
->IsChecked(CompID
))
477 for(i
= 0; i
< n
; ++i
)
479 //Supposively GRETA doesn't compile, but
480 //it's clear that it slows performance greatly
481 //when creating a rpattern object,
482 //so one can only surmize that it performs
483 //some kind of optimizations in the constructor
484 Greta
= rpattern(stdszPattern
,EXTENDED
,MODE_MIXED
);
485 SetStatusText(wxString::Format(_("GRETA Compile #%i"), i
));
488 if (OptionsMenu
->IsChecked(MatchID
))
490 for(i
= 0; i
< n
; ++i
)
492 Greta
.match(stdszSearch
, r
);
493 SetStatusText(wxString::Format(_("GRETA Match #%i"), i
));
497 dwEndTime3
= clock() - dwStartTime3
;
503 dwStartIndex3
= r
.rstart();
504 dwEndIndex3
= r
.rlength();
507 szResult3
= wxString::Format(
508 _("--Greta--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
509 dwStartIndex3
, dwStartIndex3
+ dwEndIndex3
,
510 szSearch
.Mid(dwStartIndex3
, dwEndIndex3
),
516 SetStatusText("Testing PCRE...");
519 const wxChar
* szError
;
522 if ((pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0)) == NULL
)
523 szStatus4
= wxString::Format(_("\nCompile Failed!\nError:%s\nOffset:%i\n"), szError
, nErrOff
);
527 pcre_fullinfo(pPcre
, 0, PCRE_INFO_CAPTURECOUNT
, &msize
);
529 int *m
= new int[msize
];
531 //Here's where we actually search our string
532 pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
);
534 szStatus4
= wxString::Format(_("\nExecution/Matching Failed!\n"));
537 dwStartIndex4
= m
[0];
538 dwEndIndex4
= m
[1] - m
[0];
540 szStatus4
= _("Success");
542 dwStartTime4
= clock();
545 if (OptionsMenu
->IsChecked(CompID
))
547 for(i
= 0; i
< n
; ++i
)
549 pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0);
550 SetStatusText(wxString::Format(_("PCRE Compile #%i"), i
));
553 if (OptionsMenu
->IsChecked(MatchID
))
555 for(i
= 0; i
< n
; ++i
)
557 pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
);
558 SetStatusText(wxString::Format(_("PCRE Match #%i"), i
));
562 dwEndTime4
= clock() - dwStartTime4
;
565 szResult4
= wxString::Format(
566 _("--PCRE--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
567 dwStartIndex4
, dwEndIndex4
+dwStartIndex4
,
568 szSearch
.Mid(dwStartIndex4
, dwEndIndex4
),
574 SetStatusText("Regex Run Complete");
576 ResultText
.SetLabel(szResult
+ _("\n\n") + szResult2
);
577 ResultText2
.SetLabel(szResult3
+ _("\n\n") + szResult4
);
580 void OnQuit(wxCommandEvent
& WXUNUSED(evt
))
585 wxTextCtrl PatternText
, SearchText
, NumIters
;
586 wxStaticText PatternHeader
, SearchHeader
, IterHeader
, ResultText
, ResultText2
;
591 DECLARE_EVENT_TABLE()
594 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
597 EVT_MENU(wxID_EXIT
, MyFrame::OnQuit
)
598 EVT_MENU(wxID_ABOUT
, MyFrame::OnAbout
)
601 EVT_TEXT_ENTER(MyFrame::PatternTextID
, MyFrame::OnMatch
)
602 EVT_TEXT_ENTER(MyFrame::SearchTextID
, MyFrame::OnMatch
)
605 EVT_BUTTON(MyFrame::OkButtonID
, MyFrame::OnMatch
)
607 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
608 EVT_CONTEXT_MENU(MyFrame::OnContextMenu
)
610 EVT_RIGHT_UP(MyFrame::OnRightUp
)
615 //---------------------------------------------------------------------------
617 //---------------------------------------------------------------------------
619 class MyApp
: public wxApp
624 MyFrame
* dialog
= new MyFrame();