]> git.saurik.com Git - wxWidgets.git/blob - samples/regextest/regextest.cpp
3dc9486ba9562b3bf4cc206b3197f2cbf0d3073a
[wxWidgets.git] / samples / regextest / regextest.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: regextest.cpp
3 // Purpose: Test regex libs and some gui components
4 // Author: Ryan Norton
5 // Modified by:
6 // RCS-ID: $Id$
7 // Copyright: (c) 2003 Ryan Norton <wxprojects@comcast.net>
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 //===========================================================================
12 // REGEX LIBS
13 //===========================================================================
14
15 //wxWindows regular expression library
16 #define wxUSE_WXREGEX
17
18 //RN (Ryan Norton's) regular expression library
19 //#define wxUSE_RNWXRE
20
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 //#define wxUSE_GRETA
25
26 //PCRE (Perl Compatible Regular Expressions) [sourceforge.net/projects/pcre]
27 //Install - Get the GnuWin32 version and put the files in this directory
28 //#define wxUSE_PCRE
29
30 //===========================================================================
31 // HEADERS
32 //===========================================================================
33
34 // For compilers that support precompilation, includes "wx/wx.h".
35 #include "wx/wxprec.h"
36
37 #ifdef __BORLANDC__
38 #pragma hdrstop
39 #endif
40
41 // for all others, include the necessary headers (this file is usually all you
42 // need because it includes almost all "standard" wxWindows headers)
43 #ifndef WX_PRECOMP
44 #include "wx/wx.h"
45 #endif
46
47 #include "wx/file.h"
48
49 #ifdef wxUSE_WXREGEX
50 //
51 // This is the required header for wxRegEx
52 //
53 # include <wx/regex.h>
54 #endif
55
56 #ifdef wxUSE_RNWXRE
57 # include "re.h"
58 #endif
59
60 #ifdef wxUSE_GRETA
61 # ifdef _MSC_VER
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)
67 extern "C" {
68 int __cdecl _resetstkoflw(void) {return 0;}
69 }
70 # endif //_MSC_VER
71 # include "greta/regexpr2.h"
72 using namespace regex;
73 #endif //wxUSE_GRETA
74
75 #ifdef wxUSE_PCRE
76 # include "pcre.h"
77 # ifdef _MSC_VER
78 # pragma comment(lib, "libpcre.a")
79 # endif
80 #endif
81
82 //===========================================================================
83 // IMPLEMENTATION
84 //===========================================================================
85
86 //
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).
90 //
91
92 //---------------------------------------------------------------------------
93 // MyFrame
94 //---------------------------------------------------------------------------
95
96 class MyFrame : public wxFrame
97 {
98 public:
99
100 //IDs for our controls
101 enum
102 {
103 PatternTextID,
104 SearchTextID,
105 OkButtonID
106 };
107
108 //Menu IDs
109 enum
110 {
111 ExtendedID,
112 ICaseID,
113 NewLineID,
114 NotBolID,
115 NotEolID,
116 CompID,
117 MatchID
118 };
119
120
121 void AddMenuItem(wxMenu* pMenu, int nID = wxID_SEPARATOR, const wxChar* szTitle = _(""),
122 const wxChar* szToolTip = _(""))
123 {
124 wxMenuItem* pItem;
125
126 if (nID == wxID_SEPARATOR)
127 pItem = new wxMenuItem (NULL, wxID_SEPARATOR, szTitle, szToolTip, wxITEM_SEPARATOR);
128 else
129 pItem = new wxMenuItem (NULL, nID, szTitle, szToolTip, wxITEM_CHECK);
130
131 pItem->SetBackgroundColour(wxColour(115, 113, 115));
132 pItem->SetTextColour(*wxBLACK);
133
134 pMenu->Append(pItem);
135 }
136
137 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
138 void OnContextMenu(wxContextMenuEvent& event)
139 { PopupMenu(OptionsMenu, ScreenToClient(event.GetPosition())); }
140 #else
141 void OnRightUp(wxMouseEvent& event)
142 { PopupMenu(OptionsMenu, event.GetPosition()); }
143 #endif
144
145 MyFrame() : wxFrame( NULL, -1, _("regextest - wxRegEx Testing App"),
146 wxPoint(20,20), wxSize(300,450), wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL )
147 {
148 //Set the background to something light gray-ish
149 SetBackgroundColour(wxColour(150,150,150));
150
151 //
152 // Create the menus (Exit & About)
153 //
154 #if wxUSE_MENUS
155 wxMenu *FileMenu = new wxMenu;
156 OptionsMenu = new wxMenu;
157 wxMenu *HelpMenu = new wxMenu;
158
159 AddMenuItem(FileMenu, wxID_EXIT, _("&Exit"), _("Quit this program"));
160
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?"));
171
172 AddMenuItem(HelpMenu, wxID_ABOUT, _T("&About...\tF1"), _("Show about dialog"));
173
174 OptionsMenu->Check(ExtendedID, true);
175 OptionsMenu->Check(MatchID, true);
176
177 wxMenuBar *MenuBar = new wxMenuBar();
178 MenuBar->Append(FileMenu, _T("&File"));
179 MenuBar->Append(OptionsMenu, _T("&Options"));
180 MenuBar->Append(HelpMenu, _T("&Help"));
181
182 SetMenuBar(MenuBar);
183 #endif // wxUSE_MENUS
184
185 // Text controls
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);
193
194 // StaticText
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));
198
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);
201
202 // Button
203 OkButton.Create(this, OkButtonID, _("OK"), wxPoint(20, 120));
204
205 NumIters.Create(this, -1, _("5000"), wxPoint(100, 120));
206
207 #if wxUSE_STATUSBAR && !defined(__WXWINCE__)
208 // create a status bar just for fun (by default with 1 pane only)
209 CreateStatusBar(1);
210 SetStatusText(_("Enter Some Values and Press the OK Button or Enter"));
211 #endif // wxUSE_STATUSBAR
212 }
213
214 void OnAbout(wxCommandEvent& WXUNUSED(evt))
215 {
216 wxChar* szBuffer;
217 wxFile f;
218
219 f.Open(_("README.txt"), wxFile::read);
220 szBuffer = new wxChar[f.Length() + 1];
221 f.Read(szBuffer, f.Length());
222 f.Close();
223
224 wxMessageBox(wxString::Format(
225 _("%s%s%s%s"),
226 _("-----------Regular Expression Test Application-----------\n"),
227 szBuffer,
228 _("\n\n\n(c) 2003 Ryan Norton <wxprojects@comcast.net>\n"),
229 wxVERSION_STRING
230 )
231 );
232
233 delete szBuffer;
234 }
235
236 void OnMatch(wxCommandEvent& WXUNUSED(evt))
237 {
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;
242
243 int nCompileFlags = 0, nCompileFlags2 = 0, nCompileFlags3 = 0, nCompileFlags4 = 0;
244 int nMatchFlags = 0, nMatchFlags2 = 0, nMatchFlags3 = 0, nMatchFlags4 = 0;
245
246 if (!(OptionsMenu->IsChecked(ExtendedID)))
247 {
248 #ifdef wxUSE_WXREGEX
249 nCompileFlags |= wxRE_BASIC;
250 #endif
251 }
252 else
253 {
254 #ifdef wxUSE_RNWXRE
255 nCompileFlags2 |= wxRe::wxRE_EXTENDED;
256 #endif
257 // nCompileFlags3 |= EXTENDED;
258 }
259
260 if (OptionsMenu->IsChecked(ICaseID))
261 {
262 #ifdef wxUSE_WXREGEX
263 nCompileFlags |= wxRE_ICASE;
264 #endif
265 #ifdef wxUSE_RNWXRE
266 nCompileFlags2 |= wxRe::wxRE_ICASE;
267 #endif
268 #ifdef wxUSE_GRETA
269 nCompileFlags3 |= NOCASE;
270 #endif
271 }
272
273 if (OptionsMenu->IsChecked(NewLineID))
274 {
275 #ifdef wxUSE_WXREGEX
276 nCompileFlags |= wxRE_NEWLINE;
277 #endif
278 #ifdef wxUSE_RNWXRE
279 nCompileFlags2 |= wxRe::wxRE_NEWLINE;
280 #endif
281 #ifdef wxUSE_GRETA
282 nCompileFlags3 |= MULTILINE;
283 #endif
284 }
285
286 if (OptionsMenu->IsChecked(NotBolID))
287 {
288 #ifdef wxUSE_WXREGEX
289 nMatchFlags |= wxRE_NOTBOL;
290 #endif
291 #ifdef wxUSE_RNWXRE
292 nMatchFlags2 |= wxRe::wxRE_NOTBOL;
293 #endif
294 }
295
296 if (OptionsMenu->IsChecked(NotEolID))
297 {
298 #ifdef wxUSE_WXREGEX
299 nMatchFlags |= wxRE_NOTEOL;
300 #endif
301 #ifdef wxUSE_RNWXRE
302 nMatchFlags2 |= wxRe::wxRE_NOTEOL;
303 #endif
304 }
305
306 //Our regular expression object
307
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;
314
315 time_t dwStartTime = 0, dwEndTime = 0,
316 dwStartTime2= 0, dwEndTime2= 0,
317 dwStartTime3= 0, dwEndTime3= 0,
318 dwStartTime4= 0, dwEndTime4= 0;
319
320 int i = 0;
321 long n;
322 if (!NumIters.GetValue().ToLong(&n))
323 n = 0;
324
325
326 #ifdef wxUSE_WXREGEX
327 SetStatusText("Testing wxRegEx...");
328
329 wxRegEx Regex;
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");
340 else
341 {
342 //Here's where we actually search our string
343 if (!Regex.Matches(szSearch, nMatchFlags))
344 szStatus += _("\nExecution/Matching Failed!\n");
345 else
346 {
347 Regex.GetMatch(&dwStartIndex, &dwEndIndex);
348
349 szStatus = _("Success");
350
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
354 //in milliseconds
355 dwStartTime = clock();
356
357 if (OptionsMenu->IsChecked(CompID))
358 {
359 for(i = 0; i < n; ++i)
360 {
361 SetStatusText(wxString::Format(_("wxRegEx Compile #%i"), i));
362 Regex.Compile(szPattern, nCompileFlags);
363 }
364 }
365 if (OptionsMenu->IsChecked(MatchID))
366 {
367 for(i = 0; i < n; ++i)
368 {
369 SetStatusText(wxString::Format(_("wxRegEx Match #%i"), i));
370 Regex.Matches(szSearch, nMatchFlags);
371 }
372 }
373
374 //This line gets the difference in time between now
375 //and when we first initialized dwStartTime.
376 dwEndTime = clock() - dwStartTime;
377 }
378 }
379
380
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),
385 dwEndTime,
386 szStatus
387 );
388
389 #endif //wxUSE_WXREGEX
390
391 #ifdef wxUSE_RNWXRE
392 SetStatusText("Testing RNWXRE...");
393
394 wxRe Re;
395 wxRe::wxReError e;
396 if ((e = Re.Comp(szPattern, nCompileFlags2)) != wxRe::wxRE_OK)
397 szStatus2 = wxString::Format(_("\nCompile Failed!\n%s\n"), wxRe::ErrorToString(e));
398 else
399 {
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));
403 else
404 {
405 dwStartIndex2 = Re.GetMatch(0).first;
406 dwEndIndex2 = Re.GetMatch(0).second;
407
408 szStatus2 = _("Success");
409
410 dwStartTime2 = clock();
411
412 if (OptionsMenu->IsChecked(CompID))
413 {
414 for(i = 0; i < n; ++i)
415 {
416 SetStatusText(wxString::Format(_("RNWXRE Compile #%i"), i));
417 Re.Comp(szPattern, nCompileFlags2);
418 }
419 }
420 if (OptionsMenu->IsChecked(MatchID))
421 {
422 for(i = 0; i < n; ++i)
423 {
424 SetStatusText(wxString::Format(_("RNWXRE Match #%i"), i));
425 Re.Exec(szSearch, nMatchFlags2);
426 }
427 }
428
429 dwEndTime2 = clock() - dwStartTime2;
430 }
431 }
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),
436 dwEndTime2,
437 szStatus2
438 );
439 #endif //wxUSE_RNWXRE
440
441 #ifdef wxUSE_GRETA
442 SetStatusText("Testing GRETA...");
443
444 std::string stdszPattern(szPattern);
445 rpattern Greta (stdszPattern,EXTENDED,MODE_MIXED);
446 match_results r;
447 std::string stdszSearch(szSearch);
448
449 //Here's where we actually search our string
450 if (!Greta.match(stdszSearch, r).matched)
451 szStatus3 += _("\nExecution/Matching Failed!\n");
452 else
453 {
454 szStatus3 = _("Success");
455
456 dwStartTime3 = clock();
457
458 if (OptionsMenu->IsChecked(CompID))
459 {
460 for(i = 0; i < n; ++i)
461 {
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));
469 }
470 }
471 if (OptionsMenu->IsChecked(MatchID))
472 {
473 for(i = 0; i < n; ++i)
474 {
475 Greta.match(stdszSearch, r);
476 SetStatusText(wxString::Format(_("GRETA Match #%i"), i));
477 }
478 }
479
480 dwEndTime3 = clock() - dwStartTime3;
481 }
482
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()),
487 dwEndTime3,
488 szStatus3);
489 #endif //wxUSE_GRETA
490
491 #ifdef wxUSE_PCRE
492 SetStatusText("Testing PCRE...");
493
494 pcre* pPcre;
495 const wxChar* szError;
496 int nErrOff;
497
498 if ((pPcre = pcre_compile(szPattern, nCompileFlags4, &szError, &nErrOff, 0)) == NULL)
499 szStatus4 = wxString::Format(_("\nCompile Failed!\nError:%s\nOffset:%i\n"), szError, nErrOff);
500 else
501 {
502 size_t msize;
503 pcre_fullinfo(pPcre, 0, PCRE_INFO_CAPTURECOUNT, &msize);
504 msize = 3*(msize+1);
505 int *m = new int[msize];
506
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"));
510 else
511 {
512 dwStartIndex4 = m[0];
513 dwEndIndex4 = m[1] - m[0];
514
515 szStatus4 = _("Success");
516
517 dwStartTime4 = clock();
518
519
520 if (OptionsMenu->IsChecked(CompID))
521 {
522 for(i = 0; i < n; ++i)
523 {
524 pPcre = pcre_compile(szPattern, nCompileFlags4, &szError, &nErrOff, 0);
525 SetStatusText(wxString::Format(_("PCRE Compile #%i"), i));
526 }
527 }
528 if (OptionsMenu->IsChecked(MatchID))
529 {
530 for(i = 0; i < n; ++i)
531 {
532 pcre_exec(pPcre, 0, szSearch, szSearch.Length(), 0, 0, m, msize);
533 SetStatusText(wxString::Format(_("PCRE Match #%i"), i));
534 }
535 }
536
537 dwEndTime4 = clock() - dwStartTime4;
538 }
539 }
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),
544 dwEndTime4,
545 szStatus4
546 );
547 #endif //wxUSE_PCRE
548
549 SetStatusText("Regex Run Complete");
550
551 ResultText.SetLabel(szResult + _("\n\n") + szResult2);
552 ResultText2.SetLabel(szResult3 + _("\n\n") + szResult4);
553 }
554
555 void OnQuit(wxCommandEvent& WXUNUSED(evt))
556 {
557 Close(TRUE);
558 }
559
560 wxTextCtrl PatternText, SearchText, NumIters;
561 wxStaticText PatternHeader, SearchHeader, IterHeader, ResultText, ResultText2;
562 wxButton OkButton;
563
564 wxMenu *OptionsMenu;
565
566 DECLARE_EVENT_TABLE()
567 };
568
569 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
570
571 //menu
572 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
573 EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
574
575 //text
576 EVT_TEXT_ENTER(MyFrame::PatternTextID, MyFrame::OnMatch)
577 EVT_TEXT_ENTER(MyFrame::SearchTextID, MyFrame::OnMatch)
578
579 //button
580 EVT_BUTTON(MyFrame::OkButtonID, MyFrame::OnMatch)
581
582 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
583 EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
584 #else
585 EVT_RIGHT_UP(MyFrame::OnRightUp)
586 #endif
587
588 END_EVENT_TABLE()
589
590 //---------------------------------------------------------------------------
591 // MyApp
592 //---------------------------------------------------------------------------
593
594 class MyApp : public wxApp
595 {
596 public:
597 bool OnInit()
598 {
599 MyFrame* dialog = new MyFrame();
600 dialog->Show();
601 return true;
602 }
603 };
604
605 IMPLEMENT_APP(MyApp)
606