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,400), 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, _("15000"), wxPoint(100, 120));
208 void OnAbout(wxCommandEvent
& WXUNUSED(evt
))
213 f
.Open(_("README.txt"), wxFile::read
);
214 szBuffer
= new wxChar
[f
.Length() + 1];
215 f
.Read(szBuffer
, f
.Length());
218 wxMessageBox(wxString::Format(
220 _("-----------Regular Expression Test Application-----------\n"),
222 _("\n\n\n(c) 2003 Ryan Norton <wxprojects@comcast.net>\n"),
230 void OnMatch(wxCommandEvent
& WXUNUSED(evt
))
232 wxString szPattern
= PatternText
.GetValue();
233 wxString szSearch
= SearchText
.GetValue();
234 wxString szResult
, szResult2
, szResult3
, szResult4
; //Will be displayed in ResultText
235 wxString szStatus
, szStatus2
, szStatus3
, szStatus4
;
237 int nCompileFlags
= 0, nCompileFlags2
= 0, nCompileFlags3
= 0, nCompileFlags4
= 0;
238 int nMatchFlags
= 0, nMatchFlags2
= 0, nMatchFlags3
= 0, nMatchFlags4
= 0;
240 if (!(OptionsMenu
->IsChecked(ExtendedID
)))
243 nCompileFlags
|= wxRE_BASIC
;
249 nCompileFlags2
|= wxRe::wxRE_EXTENDED
;
251 // nCompileFlags3 |= EXTENDED;
254 if (OptionsMenu
->IsChecked(ICaseID
))
257 nCompileFlags
|= wxRE_ICASE
;
260 nCompileFlags2
|= wxRe::wxRE_ICASE
;
263 nCompileFlags3
|= NOCASE
;
267 if (OptionsMenu
->IsChecked(NewLineID
))
270 nCompileFlags
|= wxRE_NEWLINE
;
273 nCompileFlags2
|= wxRe::wxRE_NEWLINE
;
276 nCompileFlags3
|= MULTILINE
;
280 if (OptionsMenu
->IsChecked(NotBolID
))
283 nMatchFlags
|= wxRE_NOTBOL
;
286 nMatchFlags2
|= wxRe::wxRE_NOTBOL
;
290 if (OptionsMenu
->IsChecked(NotEolID
))
293 nMatchFlags
|= wxRE_NOTEOL
;
296 nMatchFlags2
|= wxRe::wxRE_NOTEOL
;
300 //Our regular expression object
302 //Success! Here we'll display some
303 //information to the user
304 size_t dwStartIndex
= 0, dwEndIndex
= 0,
305 dwStartIndex2
= 0, dwEndIndex2
= 0,
306 dwStartIndex3
= 0, dwEndIndex3
= 0,
307 dwStartIndex4
= 0, dwEndIndex4
= 0;
309 time_t dwStartTime
= 0, dwEndTime
= 0,
310 dwStartTime2
= 0, dwEndTime2
= 0,
311 dwStartTime3
= 0, dwEndTime3
= 0,
312 dwStartTime4
= 0, dwEndTime4
= 0;
316 if (!NumIters
.GetValue().ToLong(&n
))
322 //Regular Expressions must be compiled before
323 //you can search a string with them, or
324 //at least most implementations do.
325 //(Boost and Microsoft have templated
326 //versions that don't require compilation)
327 //Basically compilation breaks it down into
328 //something that's easier to parse, due
329 //to the syntax of regular expressions
330 if (!Regex
.Compile(szPattern
, nCompileFlags
))
331 szStatus
+= _("\nCompile Failed!\n");
334 //Here's where we actually search our string
335 if (!Regex
.Matches(szSearch
, nMatchFlags
))
336 szStatus
+= _("\nExecution/Matching Failed!\n");
339 Regex
.GetMatch(&dwStartIndex
, &dwEndIndex
);
341 szStatus
= _("Success");
343 //We're going to go ahead and time the match
344 //for fun (clock() is a c library routine that
345 //returns the current time since a certian point
347 dwStartTime
= clock();
349 if (OptionsMenu
->IsChecked(CompID
))
351 for(i
= 0; i
< n
; ++i
)
353 Regex
.Compile(szPattern
, nCompileFlags
);
356 if (OptionsMenu
->IsChecked(MatchID
))
358 for(i
= 0; i
< n
; ++i
)
360 Regex
.Matches(szSearch
, nMatchFlags
);
364 //This line gets the difference in time between now
365 //and when we first initialized dwStartTime.
366 dwEndTime
= clock() - dwStartTime
;
371 szResult
= wxString::Format(
372 _("--wxRegEx--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
373 dwStartIndex
, dwEndIndex
+dwStartIndex
,
374 szSearch
.Mid(dwStartIndex
, dwEndIndex
),
379 #endif //wxUSE_WXREGEX
384 if ((e
= Re
.Comp(szPattern
, nCompileFlags2
)) != wxRe::wxRE_OK
)
385 szStatus2
= wxString::Format(_("\nCompile Failed!\n%s\n"), wxRe::ErrorToString(e
));
388 //Here's where we actually search our string
389 if ((e
= Re
.Exec(szSearch
, nMatchFlags2
)) != wxRe::wxRE_OK
)
390 szStatus2
= wxString::Format(_("\nExecution/Matching Failed!\n%s\n"), wxRe::ErrorToString(e
));
393 dwStartIndex2
= Re
.GetMatch(0).first
;
394 dwEndIndex2
= Re
.GetMatch(0).second
;
396 szStatus2
= _("Success");
398 dwStartTime2
= clock();
400 if (OptionsMenu
->IsChecked(CompID
))
402 for(i
= 0; i
< n
; ++i
)
404 Re
.Comp(szPattern
, nCompileFlags2
);
407 if (OptionsMenu
->IsChecked(MatchID
))
409 for(i
= 0; i
< n
; ++i
)
411 Re
.Exec(szSearch
, nMatchFlags2
);
415 dwEndTime2
= clock() - dwStartTime2
;
418 szResult2
= wxString::Format(
419 _("--Ryan's wxRe--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
420 dwStartIndex2
, dwEndIndex2
+dwStartIndex2
,
421 szSearch
.Mid(dwStartIndex2
, dwEndIndex2
),
425 #endif //wxUSE_RNWXRE
428 std::string
stdszPattern(szPattern
);
429 rpattern
Greta (stdszPattern
,EXTENDED
,MODE_MIXED
);
431 std::string
stdszSearch(szSearch
);
433 //Here's where we actually search our string
434 if (!Greta
.match(stdszSearch
, r
).matched
)
435 szStatus3
+= _("\nExecution/Matching Failed!\n");
438 szStatus3
= _("Success");
440 dwStartTime3
= clock();
442 if (OptionsMenu
->IsChecked(CompID
))
444 for(i
= 0; i
< n
; ++i
)
446 //Supposively GRETA doesn't compile, but
447 //it's clear that it slows performance greatly
448 //when creating a rpattern object,
449 //so one can only surmize that it performs
450 //some kind of optimizations in the constructor
451 Greta
= rpattern(stdszPattern
,EXTENDED
,MODE_MIXED
);
454 if (OptionsMenu
->IsChecked(MatchID
))
456 for(i
= 0; i
< n
; ++i
)
458 Greta
.match(stdszSearch
, r
);
462 dwEndTime3
= clock() - dwStartTime3
;
465 szResult3
= wxString::Format(
466 _("--Greta--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
467 r
.rstart(), r
.rlength() + r
.rstart(),
468 szSearch
.Mid(r
.rstart(), r
.rlength()),
475 const wxChar
* szError
;
478 if ((pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0)) == NULL
)
479 szStatus4
= wxString::Format(_("\nCompile Failed!\nError:%s\nOffset:%i\n"), szError
, nErrOff
);
483 pcre_fullinfo(pPcre
, 0, PCRE_INFO_CAPTURECOUNT
, &msize
);
485 int *m
= new int[msize
];
487 //Here's where we actually search our string
488 if (!pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
))
489 szStatus4
= wxString::Format(_("\nExecution/Matching Failed!\n"));
492 dwStartIndex4
= m
[0];
493 dwEndIndex4
= m
[1] - m
[0];
495 szStatus4
= _("Success");
497 dwStartTime4
= clock();
500 if (OptionsMenu
->IsChecked(CompID
))
502 for(i
= 0; i
< n
; ++i
)
504 pPcre
= pcre_compile(szPattern
, nCompileFlags4
, &szError
, &nErrOff
, 0);
507 if (OptionsMenu
->IsChecked(MatchID
))
509 for(i
= 0; i
< n
; ++i
)
511 pcre_exec(pPcre
, 0, szSearch
, szSearch
.Length(), 0, 0, m
, msize
);
515 dwEndTime4
= clock() - dwStartTime4
;
518 szResult4
= wxString::Format(
519 _("--PCRE--\nIndex:[%i]-[%i]\nString:%s\nMatch Time:%ums\nStatus:%s"),
520 dwStartIndex4
, dwEndIndex4
+dwStartIndex4
,
521 szSearch
.Mid(dwStartIndex4
, dwEndIndex4
),
527 ResultText
.SetLabel(szResult
+ _("\n\n") + szResult2
);
528 ResultText2
.SetLabel(szResult3
+ _("\n\n") + szResult4
);
531 void OnQuit(wxCommandEvent
& WXUNUSED(evt
))
536 wxTextCtrl PatternText
, SearchText
, NumIters
;
537 wxStaticText PatternHeader
, SearchHeader
, IterHeader
, ResultText
, ResultText2
;
542 DECLARE_EVENT_TABLE()
545 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
548 EVT_MENU(wxID_EXIT
, MyFrame::OnQuit
)
549 EVT_MENU(wxID_ABOUT
, MyFrame::OnAbout
)
552 EVT_TEXT_ENTER(MyFrame::PatternTextID
, MyFrame::OnMatch
)
553 EVT_TEXT_ENTER(MyFrame::SearchTextID
, MyFrame::OnMatch
)
556 EVT_BUTTON(MyFrame::OkButtonID
, MyFrame::OnMatch
)
558 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
559 EVT_CONTEXT_MENU(MyFrame::OnContextMenu
)
561 EVT_RIGHT_UP(MyFrame::OnRightUp
)
566 //---------------------------------------------------------------------------
568 //---------------------------------------------------------------------------
570 class MyApp
: public wxApp
575 MyFrame
* dialog
= new MyFrame();