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
26 //PCRE (Perl Compatible Regular Expressions) [sourceforge.net/projects/pcre]
27 //Install - Get the GnuWin32 version and put the files in this directory
30 //===========================================================================
32 //===========================================================================
34 // For compilers that support precompilation, includes "wx/wx.h".
35 #include "wx/wxprec.h"
41 // for all others, include the necessary headers (this file is usually all you
42 // need because it includes almost all "standard" wxWindows headers)
51 // This is the required header for wxRegEx
53 # include <wx/regex.h>
62 # pragma warning(disable:4018)
63 # pragma warning(disable:4100)
64 # pragma warning(disable:4146)
65 # pragma warning(disable:4244)
66 # pragma warning(disable:4663)
68 int __cdecl
_resetstkoflw(void) {return 0;}
71 # include "greta/regexpr2.h"
72 using namespace regex
;
78 # pragma comment(lib, "libpcre.a")
82 //===========================================================================
84 //===========================================================================
87 // One of the best sources for regex info is IEEE document/standard 1003.2
88 // From the open group.
89 // A current link - (http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap09.html).
92 //---------------------------------------------------------------------------
94 //---------------------------------------------------------------------------
96 class MyFrame
: public wxFrame
100 //IDs for our controls
121 void AddMenuItem(wxMenu
* pMenu
, int nID
= wxID_SEPARATOR
, const wxChar
* szTitle
= _(""),
122 const wxChar
* szToolTip
= _(""))
126 if (nID
== wxID_SEPARATOR
)
127 pItem
= new wxMenuItem (NULL
, wxID_SEPARATOR
, szTitle
, szToolTip
, wxITEM_SEPARATOR
);
129 pItem
= new wxMenuItem (NULL
, nID
, szTitle
, szToolTip
, wxITEM_CHECK
);
131 pItem
->SetBackgroundColour(wxColour(115, 113, 115));
132 pItem
->SetTextColour(*wxBLACK
);
134 pMenu
->Append(pItem
);
137 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
138 void OnContextMenu(wxContextMenuEvent
& event
)
139 { PopupMenu(OptionsMenu
, ScreenToClient(event
.GetPosition())); }
141 void OnRightUp(wxMouseEvent
& event
)
142 { PopupMenu(OptionsMenu
, event
.GetPosition()); }
145 MyFrame() : wxFrame( NULL
, -1, _("regextest - wxRegEx Testing App"),
146 wxPoint(20,20), wxSize(300,450), wxDEFAULT_FRAME_STYLE
| wxTAB_TRAVERSAL
)
148 //Set the background to something light gray-ish
149 SetBackgroundColour(wxColour(150,150,150));
152 // Create the menus (Exit & About)
155 wxMenu
*FileMenu
= new wxMenu
;
156 OptionsMenu
= new wxMenu
;
157 wxMenu
*HelpMenu
= new wxMenu
;
159 AddMenuItem(FileMenu
, wxID_EXIT
, _("&Exit"), _("Quit this program"));
161 AddMenuItem(OptionsMenu
, ExtendedID
, _T("wxRE_EXTENDED"), _("Extended Regular Expressions?"));
162 AddMenuItem(OptionsMenu
, ICaseID
, _T("wxRE_ICASE"), _("Enable case-insensitive matching?"));
163 AddMenuItem(OptionsMenu
, NewLineID
, _T("wxRE_NEWLINE"), _("Treat \n as special?"));
164 AddMenuItem(OptionsMenu
);
165 AddMenuItem(OptionsMenu
, NotBolID
, _T("wxRE_NOTBOL"), _("Use functionality of ^ character?"));
166 AddMenuItem(OptionsMenu
, NotEolID
, _T("wxRE_NOTEOL"), _("Use functionality of $ character?"));
167 AddMenuItem(OptionsMenu
);
168 AddMenuItem(OptionsMenu
);
169 AddMenuItem(OptionsMenu
, CompID
, _("Test Compile"), _("Added Compiling to Match Time?"));
170 AddMenuItem(OptionsMenu
, MatchID
, _("Test Match"), _("Added Matching to Match Time?"));
172 AddMenuItem(HelpMenu
, wxID_ABOUT
, _T("&About...\tF1"), _("Show about dialog"));
174 OptionsMenu
->Check(ExtendedID
, true);
175 OptionsMenu
->Check(MatchID
, true);
177 wxMenuBar
*MenuBar
= new wxMenuBar();
178 MenuBar
->Append(FileMenu
, _T("&File"));
179 MenuBar
->Append(OptionsMenu
, _T("&Options"));
180 MenuBar
->Append(HelpMenu
, _T("&Help"));
183 #endif // wxUSE_MENUS
186 PatternText
.Create(this, PatternTextID
, _(""), wxPoint(5, 30));
187 SearchText
.Create(this, SearchTextID
, _(""), wxPoint(5, 75));
188 //reset size of text controls
189 wxSize TextSize
= PatternText
.GetSize();
190 TextSize
.SetWidth(200);
191 PatternText
.SetSize(TextSize
);
192 SearchText
.SetSize(TextSize
);
195 PatternHeader
.Create(this, -1, _("Regular Expression:"), wxPoint(5, 10));
196 SearchHeader
.Create(this, -1, _("String to Search:"), wxPoint(5, 55));
197 IterHeader
.Create(this, -1, _("Iterations (Match Time):"), wxPoint(100, 100));
199 ResultText
.Create(this, -1, _(""), wxPoint(5, 150), wxSize(100,200), wxST_NO_AUTORESIZE
);
200 ResultText2
.Create(this, -1, _(""), wxPoint(115, 150), wxSize(100,200), wxST_NO_AUTORESIZE
);
203 OkButton
.Create(this, OkButtonID
, _("OK"), wxPoint(20, 120));
205 NumIters
.Create(this, -1, _("5000"), wxPoint(100, 120));
207 #if wxUSE_STATUSBAR && !defined(__WXWINCE__)
208 // create a status bar just for fun (by default with 1 pane only)
210 SetStatusText(_("Enter Some Values and Press the OK Button or Enter"));
211 #endif // wxUSE_STATUSBAR
214 void OnAbout(wxCommandEvent
& WXUNUSED(evt
))
219 f
.Open(_("README.txt"), wxFile::read
);
220 szBuffer
= new wxChar
[f
.Length() + 1];
221 f
.Read(szBuffer
, f
.Length());
224 wxMessageBox(wxString::Format(
226 _("-----------Regular Expression Test Application-----------\n"),
228 _("\n\n\n(c) 2003 Ryan Norton <wxprojects@comcast.net>\n"),
236 void OnMatch(wxCommandEvent
& WXUNUSED(evt
))
238 wxString szPattern
= PatternText
.GetValue();
239 wxString szSearch
= SearchText
.GetValue();
240 wxString szResult
, szResult2
, szResult3
, szResult4
; //Will be displayed in ResultText
241 wxString szStatus
, szStatus2
, szStatus3
, szStatus4
;
243 int nCompileFlags
= 0, nCompileFlags2
= 0, nCompileFlags3
= 0, nCompileFlags4
= 0;
244 int nMatchFlags
= 0, nMatchFlags2
= 0, nMatchFlags3
= 0, nMatchFlags4
= 0;
246 if (!(OptionsMenu
->IsChecked(ExtendedID
)))
249 nCompileFlags
|= wxRE_BASIC
;
255 nCompileFlags2
|= wxRe::wxRE_EXTENDED
;
257 // nCompileFlags3 |= EXTENDED;
260 if (OptionsMenu
->IsChecked(ICaseID
))
263 nCompileFlags
|= wxRE_ICASE
;
266 nCompileFlags2
|= wxRe::wxRE_ICASE
;
269 nCompileFlags3
|= NOCASE
;
273 if (OptionsMenu
->IsChecked(NewLineID
))
276 nCompileFlags
|= wxRE_NEWLINE
;
279 nCompileFlags2
|= wxRe::wxRE_NEWLINE
;
282 nCompileFlags3
|= MULTILINE
;
286 if (OptionsMenu
->IsChecked(NotBolID
))
289 nMatchFlags
|= wxRE_NOTBOL
;
292 nMatchFlags2
|= wxRe::wxRE_NOTBOL
;
296 if (OptionsMenu
->IsChecked(NotEolID
))
299 nMatchFlags
|= wxRE_NOTEOL
;
302 nMatchFlags2
|= wxRe::wxRE_NOTEOL
;
306 //Our regular expression object
308 //Success! Here we'll display some
309 //information to the user
310 size_t dwStartIndex
= 0, dwEndIndex
= 0,
311 dwStartIndex2
= 0, dwEndIndex2
= 0,
312 dwStartIndex3
= 0, dwEndIndex3
= 0,
313 dwStartIndex4
= 0, dwEndIndex4
= 0;
315 time_t dwStartTime
= 0, dwEndTime
= 0,
316 dwStartTime2
= 0, dwEndTime2
= 0,
317 dwStartTime3
= 0, dwEndTime3
= 0,
318 dwStartTime4
= 0, dwEndTime4
= 0;
322 if (!NumIters
.GetValue().ToLong(&n
))
327 SetStatusText("Testing wxRegEx...");
330 //Regular Expressions must be compiled before
331 //you can search a string with them, or
332 //at least most implementations do.
333 //(Boost and Microsoft have templated
334 //versions that don't require compilation)
335 //Basically compilation breaks it down into
336 //something that's easier to parse, due
337 //to the syntax of regular expressions
338 if (!Regex
.Compile(szPattern
, nCompileFlags
))
339 szStatus
+= _("\nCompile Failed!\n");
342 //Here's where we actually search our string
343 if (!Regex
.Matches(szSearch
, nMatchFlags
))
344 szStatus
+= _("\nExecution/Matching Failed!\n");
347 Regex
.GetMatch(&dwStartIndex
, &dwEndIndex
);
349 szStatus
= _("Success");
351 //We're going to go ahead and time the match
352 //for fun (clock() is a c library routine that
353 //returns the current time since a certian point
355 dwStartTime
= clock();
357 if (OptionsMenu
->IsChecked(CompID
))
359 for(i
= 0; i
< n
; ++i
)
361 SetStatusText(wxString::Format(_("wxRegEx Compile #%i"), i
));
362 Regex
.Compile(szPattern
, nCompileFlags
);
365 if (OptionsMenu
->IsChecked(MatchID
))
367 for(i
= 0; i
< n
; ++i
)
369 SetStatusText(wxString::Format(_("wxRegEx Match #%i"), i
));
370 Regex
.Matches(szSearch
, nMatchFlags
);
374 //This line gets the difference in time between now
375 //and when we first initialized dwStartTime.
376 dwEndTime
= clock() - dwStartTime
;
381 szResult
= wxString::Format(
382 _("--wxRegEx--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
383 dwStartIndex
, dwEndIndex
+dwStartIndex
,
384 szSearch
.Mid(dwStartIndex
, dwEndIndex
),
389 #endif //wxUSE_WXREGEX
392 SetStatusText("Testing RNWXRE...");
396 if ((e
= Re
.Comp(szPattern
, nCompileFlags2
)) != wxRe::wxRE_OK
)
397 szStatus2
= wxString::Format(_("\nCompile Failed!\n%s\n"), wxRe::ErrorToString(e
));
400 //Here's where we actually search our string
401 if ((e
= Re
.Exec(szSearch
, nMatchFlags2
)) != wxRe::wxRE_OK
)
402 szStatus2
= wxString::Format(_("\nExecution/Matching Failed!\n%s\n"), wxRe::ErrorToString(e
));
405 dwStartIndex2
= Re
.GetMatch(0).first
;
406 dwEndIndex2
= Re
.GetMatch(0).second
;
408 szStatus2
= _("Success");
410 dwStartTime2
= clock();
412 if (OptionsMenu
->IsChecked(CompID
))
414 for(i
= 0; i
< n
; ++i
)
416 SetStatusText(wxString::Format(_("RNWXRE Compile #%i"), i
));
417 Re
.Comp(szPattern
, nCompileFlags2
);
420 if (OptionsMenu
->IsChecked(MatchID
))
422 for(i
= 0; i
< n
; ++i
)
424 SetStatusText(wxString::Format(_("RNWXRE Match #%i"), i
));
425 Re
.Exec(szSearch
, nMatchFlags2
);
429 dwEndTime2
= clock() - dwStartTime2
;
432 szResult2
= wxString::Format(
433 _("--Ryan's wxRe--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
434 dwStartIndex2
, dwEndIndex2
+dwStartIndex2
,
435 szSearch
.Mid(dwStartIndex2
, dwEndIndex2
),
439 #endif //wxUSE_RNWXRE
442 SetStatusText("Testing GRETA...");
444 std::string
stdszPattern(szPattern
);
445 rpattern
Greta (stdszPattern
,EXTENDED
,MODE_MIXED
);
447 std::string
stdszSearch(szSearch
);
449 //Here's where we actually search our string
450 if (!Greta
.match(stdszSearch
, r
).matched
)
451 szStatus3
+= _("\nExecution/Matching Failed!\n");
454 szStatus3
= _("Success");
456 dwStartTime3
= clock();
458 if (OptionsMenu
->IsChecked(CompID
))
460 for(i
= 0; i
< n
; ++i
)
462 //Supposively GRETA doesn't compile, but
463 //it's clear that it slows performance greatly
464 //when creating a rpattern object,
465 //so one can only surmize that it performs
466 //some kind of optimizations in the constructor
467 Greta
= rpattern(stdszPattern
,EXTENDED
,MODE_MIXED
);
468 SetStatusText(wxString::Format(_("GRETA Compile #%i"), i
));
471 if (OptionsMenu
->IsChecked(MatchID
))
473 for(i
= 0; i
< n
; ++i
)
475 Greta
.match(stdszSearch
, r
);
476 SetStatusText(wxString::Format(_("GRETA Match #%i"), i
));
480 dwEndTime3
= clock() - dwStartTime3
;
483 szResult3
= wxString::Format(
484 _("--Greta--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
485 r
.rstart(), r
.rlength() + r
.rstart(),
486 szSearch
.Mid(r
.rstart(), r
.rlength()),
492 SetStatusText("Testing PCRE...");
495 const wxChar
* szError
;
498 if ((pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0)) == NULL
)
499 szStatus4
= wxString::Format(_("\nCompile Failed!\nError:%s\nOffset:%i\n"), szError
, nErrOff
);
503 pcre_fullinfo(pPcre
, 0, PCRE_INFO_CAPTURECOUNT
, &msize
);
505 int *m
= new int[msize
];
507 //Here's where we actually search our string
508 if (!pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
))
509 szStatus4
= wxString::Format(_("\nExecution/Matching Failed!\n"));
512 dwStartIndex4
= m
[0];
513 dwEndIndex4
= m
[1] - m
[0];
515 szStatus4
= _("Success");
517 dwStartTime4
= clock();
520 if (OptionsMenu
->IsChecked(CompID
))
522 for(i
= 0; i
< n
; ++i
)
524 pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0);
525 SetStatusText(wxString::Format(_("PCRE Compile #%i"), i
));
528 if (OptionsMenu
->IsChecked(MatchID
))
530 for(i
= 0; i
< n
; ++i
)
532 pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
);
533 SetStatusText(wxString::Format(_("PCRE Match #%i"), i
));
537 dwEndTime4
= clock() - dwStartTime4
;
540 szResult4
= wxString::Format(
541 _("--PCRE--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
542 dwStartIndex4
, dwEndIndex4
+dwStartIndex4
,
543 szSearch
.Mid(dwStartIndex4
, dwEndIndex4
),
549 SetStatusText("Regex Run Complete");
551 ResultText
.SetLabel(szResult
+ _("\n\n") + szResult2
);
552 ResultText2
.SetLabel(szResult3
+ _("\n\n") + szResult4
);
555 void OnQuit(wxCommandEvent
& WXUNUSED(evt
))
560 wxTextCtrl PatternText
, SearchText
, NumIters
;
561 wxStaticText PatternHeader
, SearchHeader
, IterHeader
, ResultText
, ResultText2
;
566 DECLARE_EVENT_TABLE()
569 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
572 EVT_MENU(wxID_EXIT
, MyFrame::OnQuit
)
573 EVT_MENU(wxID_ABOUT
, MyFrame::OnAbout
)
576 EVT_TEXT_ENTER(MyFrame::PatternTextID
, MyFrame::OnMatch
)
577 EVT_TEXT_ENTER(MyFrame::SearchTextID
, MyFrame::OnMatch
)
580 EVT_BUTTON(MyFrame::OkButtonID
, MyFrame::OnMatch
)
582 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
583 EVT_CONTEXT_MENU(MyFrame::OnContextMenu
)
585 EVT_RIGHT_UP(MyFrame::OnRightUp
)
590 //---------------------------------------------------------------------------
592 //---------------------------------------------------------------------------
594 class MyApp
: public wxApp
599 MyFrame
* dialog
= new MyFrame();