]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
b6935ada98a036d77edeee47d67b4f8493643058
[wxWidgets.git] / samples / console / console.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/console/console.cpp
3 // Purpose: a sample console (as opposed to GUI) progam using wxWindows
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 04.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include <stdio.h>
21
22 #include <wx/string.h>
23 #include <wx/file.h>
24 #include <wx/app.h>
25
26 // without this pragma, the stupid compiler precompiles #defines below so that
27 // changing them doesn't "take place" later!
28 #ifdef __VISUALC__
29 #pragma hdrstop
30 #endif
31
32 // ----------------------------------------------------------------------------
33 // conditional compilation
34 // ----------------------------------------------------------------------------
35
36 // what to test (in alphabetic order)?
37
38 //#define TEST_ARRAYS
39 //#define TEST_CMDLINE
40 //#define TEST_DATETIME
41 //#define TEST_DIR
42 //#define TEST_DLLLOADER
43 //#define TEST_ENVIRON
44 //#define TEST_EXECUTE
45 #define TEST_FILE
46 //#define TEST_FILECONF
47 //#define TEST_FTP
48 //#define TEST_HASH
49 //#define TEST_LIST
50 //#define TEST_LOG
51 //#define TEST_LONGLONG
52 //#define TEST_MIME
53 //#define TEST_INFO_FUNCTIONS
54 //#define TEST_REGISTRY
55 //#define TEST_SOCKETS
56 //#define TEST_STREAMS
57 //#define TEST_STRINGS
58 //#define TEST_THREADS
59 //#define TEST_TIMER
60 //#define TEST_VCARD -- don't enable this (VZ)
61 //#define TEST_WCHAR
62 //#define TEST_ZIP
63 //#define TEST_ZLIB
64
65 // ----------------------------------------------------------------------------
66 // test class for container objects
67 // ----------------------------------------------------------------------------
68
69 #if defined(TEST_ARRAYS) || defined(TEST_LIST)
70
71 class Bar // Foo is already taken in the hash test
72 {
73 public:
74 Bar(const wxString& name) : m_name(name) { ms_bars++; }
75 ~Bar() { ms_bars--; }
76
77 static size_t GetNumber() { return ms_bars; }
78
79 const char *GetName() const { return m_name; }
80
81 private:
82 wxString m_name;
83
84 static size_t ms_bars;
85 };
86
87 size_t Bar::ms_bars = 0;
88
89 #endif // defined(TEST_ARRAYS) || defined(TEST_LIST)
90
91 // ============================================================================
92 // implementation
93 // ============================================================================
94
95 // ----------------------------------------------------------------------------
96 // helper functions
97 // ----------------------------------------------------------------------------
98
99 #if defined(TEST_STRINGS) || defined(TEST_SOCKETS)
100
101 // replace TABs with \t and CRs with \n
102 static wxString MakePrintable(const wxChar *s)
103 {
104 wxString str(s);
105 (void)str.Replace(_T("\t"), _T("\\t"));
106 (void)str.Replace(_T("\n"), _T("\\n"));
107 (void)str.Replace(_T("\r"), _T("\\r"));
108
109 return str;
110 }
111
112 #endif // MakePrintable() is used
113
114 // ----------------------------------------------------------------------------
115 // wxCmdLineParser
116 // ----------------------------------------------------------------------------
117
118 #ifdef TEST_CMDLINE
119
120 #include <wx/cmdline.h>
121 #include <wx/datetime.h>
122
123 static void ShowCmdLine(const wxCmdLineParser& parser)
124 {
125 wxString s = "Input files: ";
126
127 size_t count = parser.GetParamCount();
128 for ( size_t param = 0; param < count; param++ )
129 {
130 s << parser.GetParam(param) << ' ';
131 }
132
133 s << '\n'
134 << "Verbose:\t" << (parser.Found("v") ? "yes" : "no") << '\n'
135 << "Quiet:\t" << (parser.Found("q") ? "yes" : "no") << '\n';
136
137 wxString strVal;
138 long lVal;
139 wxDateTime dt;
140 if ( parser.Found("o", &strVal) )
141 s << "Output file:\t" << strVal << '\n';
142 if ( parser.Found("i", &strVal) )
143 s << "Input dir:\t" << strVal << '\n';
144 if ( parser.Found("s", &lVal) )
145 s << "Size:\t" << lVal << '\n';
146 if ( parser.Found("d", &dt) )
147 s << "Date:\t" << dt.FormatISODate() << '\n';
148 if ( parser.Found("project_name", &strVal) )
149 s << "Project:\t" << strVal << '\n';
150
151 wxLogMessage(s);
152 }
153
154 #endif // TEST_CMDLINE
155
156 // ----------------------------------------------------------------------------
157 // wxDir
158 // ----------------------------------------------------------------------------
159
160 #ifdef TEST_DIR
161
162 #include <wx/dir.h>
163
164 static void TestDirEnumHelper(wxDir& dir,
165 int flags = wxDIR_DEFAULT,
166 const wxString& filespec = wxEmptyString)
167 {
168 wxString filename;
169
170 if ( !dir.IsOpened() )
171 return;
172
173 bool cont = dir.GetFirst(&filename, filespec, flags);
174 while ( cont )
175 {
176 printf("\t%s\n", filename.c_str());
177
178 cont = dir.GetNext(&filename);
179 }
180
181 puts("");
182 }
183
184 static void TestDirEnum()
185 {
186 wxDir dir(wxGetCwd());
187
188 puts("Enumerating everything in current directory:");
189 TestDirEnumHelper(dir);
190
191 puts("Enumerating really everything in current directory:");
192 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
193
194 puts("Enumerating object files in current directory:");
195 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
196
197 puts("Enumerating directories in current directory:");
198 TestDirEnumHelper(dir, wxDIR_DIRS);
199
200 puts("Enumerating files in current directory:");
201 TestDirEnumHelper(dir, wxDIR_FILES);
202
203 puts("Enumerating files including hidden in current directory:");
204 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
205
206 #ifdef __UNIX__
207 dir.Open("/");
208 #elif defined(__WXMSW__)
209 dir.Open("c:\\");
210 #else
211 #error "don't know where the root directory is"
212 #endif
213
214 puts("Enumerating everything in root directory:");
215 TestDirEnumHelper(dir, wxDIR_DEFAULT);
216
217 puts("Enumerating directories in root directory:");
218 TestDirEnumHelper(dir, wxDIR_DIRS);
219
220 puts("Enumerating files in root directory:");
221 TestDirEnumHelper(dir, wxDIR_FILES);
222
223 puts("Enumerating files including hidden in root directory:");
224 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
225
226 puts("Enumerating files in non existing directory:");
227 wxDir dirNo("nosuchdir");
228 TestDirEnumHelper(dirNo);
229 }
230
231 #endif // TEST_DIR
232
233 // ----------------------------------------------------------------------------
234 // wxDllLoader
235 // ----------------------------------------------------------------------------
236
237 #ifdef TEST_DLLLOADER
238
239 #include <wx/dynlib.h>
240
241 static void TestDllLoad()
242 {
243 #if defined(__WXMSW__)
244 static const wxChar *LIB_NAME = _T("kernel32.dll");
245 static const wxChar *FUNC_NAME = _T("lstrlenA");
246 #elif defined(__UNIX__)
247 // weird: using just libc.so does *not* work!
248 static const wxChar *LIB_NAME = _T("/lib/libc-2.0.7.so");
249 static const wxChar *FUNC_NAME = _T("strlen");
250 #else
251 #error "don't know how to test wxDllLoader on this platform"
252 #endif
253
254 puts("*** testing wxDllLoader ***\n");
255
256 wxDllType dllHandle = wxDllLoader::LoadLibrary(LIB_NAME);
257 if ( !dllHandle )
258 {
259 wxPrintf(_T("ERROR: failed to load '%s'.\n"), LIB_NAME);
260 }
261 else
262 {
263 typedef int (*strlenType)(char *);
264 strlenType pfnStrlen = (strlenType)wxDllLoader::GetSymbol(dllHandle, FUNC_NAME);
265 if ( !pfnStrlen )
266 {
267 wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
268 FUNC_NAME, LIB_NAME);
269 }
270 else
271 {
272 if ( pfnStrlen("foo") != 3 )
273 {
274 wxPrintf(_T("ERROR: loaded function is not strlen()!\n"));
275 }
276 else
277 {
278 puts("... ok");
279 }
280 }
281
282 wxDllLoader::UnloadLibrary(dllHandle);
283 }
284 }
285
286 #endif // TEST_DLLLOADER
287
288 // ----------------------------------------------------------------------------
289 // wxGet/SetEnv
290 // ----------------------------------------------------------------------------
291
292 #ifdef TEST_ENVIRON
293
294 #include <wx/utils.h>
295
296 static wxString MyGetEnv(const wxString& var)
297 {
298 wxString val;
299 if ( !wxGetEnv(var, &val) )
300 val = _T("<empty>");
301 else
302 val = wxString(_T('\'')) + val + _T('\'');
303
304 return val;
305 }
306
307 static void TestEnvironment()
308 {
309 const wxChar *var = _T("wxTestVar");
310
311 puts("*** testing environment access functions ***");
312
313 printf("Initially getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
314 wxSetEnv(var, _T("value for wxTestVar"));
315 printf("After wxSetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
316 wxSetEnv(var, _T("another value"));
317 printf("After 2nd wxSetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
318 wxUnsetEnv(var);
319 printf("After wxUnsetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
320 printf("PATH = %s\n", MyGetEnv(_T("PATH")));
321 }
322
323 #endif // TEST_ENVIRON
324
325 // ----------------------------------------------------------------------------
326 // wxExecute
327 // ----------------------------------------------------------------------------
328
329 #ifdef TEST_EXECUTE
330
331 #include <wx/utils.h>
332
333 static void TestExecute()
334 {
335 puts("*** testing wxExecute ***");
336
337 #ifdef __UNIX__
338 #define COMMAND "cat -n ../../Makefile" // "echo hi"
339 #define SHELL_COMMAND "echo hi from shell"
340 #define REDIRECT_COMMAND COMMAND // "date"
341 #elif defined(__WXMSW__)
342 #define COMMAND "command.com -c 'echo hi'"
343 #define SHELL_COMMAND "echo hi"
344 #define REDIRECT_COMMAND COMMAND
345 #else
346 #error "no command to exec"
347 #endif // OS
348
349 printf("Testing wxShell: ");
350 fflush(stdout);
351 if ( wxShell(SHELL_COMMAND) )
352 puts("Ok.");
353 else
354 puts("ERROR.");
355
356 printf("Testing wxExecute: ");
357 fflush(stdout);
358 if ( wxExecute(COMMAND, TRUE /* sync */) == 0 )
359 puts("Ok.");
360 else
361 puts("ERROR.");
362
363 #if 0 // no, it doesn't work (yet?)
364 printf("Testing async wxExecute: ");
365 fflush(stdout);
366 if ( wxExecute(COMMAND) != 0 )
367 puts("Ok (command launched).");
368 else
369 puts("ERROR.");
370 #endif // 0
371
372 printf("Testing wxExecute with redirection:\n");
373 wxArrayString output;
374 if ( wxExecute(REDIRECT_COMMAND, output) != 0 )
375 {
376 puts("ERROR.");
377 }
378 else
379 {
380 size_t count = output.GetCount();
381 for ( size_t n = 0; n < count; n++ )
382 {
383 printf("\t%s\n", output[n].c_str());
384 }
385
386 puts("Ok.");
387 }
388 }
389
390 #endif // TEST_EXECUTE
391
392 // ----------------------------------------------------------------------------
393 // file
394 // ----------------------------------------------------------------------------
395
396 #ifdef TEST_FILE
397
398 #include <wx/file.h>
399 #include <wx/ffile.h>
400 #include <wx/textfile.h>
401
402 static void TestFileRead()
403 {
404 puts("*** wxFile read test ***");
405
406 wxFile file(_T("testdata.fc"));
407 if ( file.IsOpened() )
408 {
409 printf("File length: %lu\n", file.Length());
410
411 puts("File dump:\n----------");
412
413 static const off_t len = 1024;
414 char buf[len];
415 for ( ;; )
416 {
417 off_t nRead = file.Read(buf, len);
418 if ( nRead == wxInvalidOffset )
419 {
420 printf("Failed to read the file.");
421 break;
422 }
423
424 fwrite(buf, nRead, 1, stdout);
425
426 if ( nRead < len )
427 break;
428 }
429
430 puts("----------");
431 }
432 else
433 {
434 printf("ERROR: can't open test file.\n");
435 }
436
437 puts("");
438 }
439
440 static void TestTextFileRead()
441 {
442 puts("*** wxTextFile read test ***");
443
444 wxTextFile file(_T("testdata.fc"));
445 if ( file.Open() )
446 {
447 printf("Number of lines: %u\n", file.GetLineCount());
448 printf("Last line: '%s'\n", file.GetLastLine().c_str());
449
450 wxString s;
451
452 puts("\nDumping the entire file:");
453 for ( s = file.GetFirstLine(); !file.Eof(); s = file.GetNextLine() )
454 {
455 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
456 }
457 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
458
459 puts("\nAnd now backwards:");
460 for ( s = file.GetLastLine();
461 file.GetCurrentLine() != 0;
462 s = file.GetPrevLine() )
463 {
464 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
465 }
466 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
467 }
468 else
469 {
470 printf("ERROR: can't open '%s'\n", file.GetName());
471 }
472
473 puts("");
474 }
475
476 static void TestFileCopy()
477 {
478 puts("*** Testing wxCopyFile ***");
479
480 static const wxChar *filename1 = _T("testdata.fc");
481 static const wxChar *filename2 = _T("test2");
482 if ( !wxCopyFile(filename1, filename2) )
483 {
484 puts("ERROR: failed to copy file");
485 }
486 else
487 {
488 wxFFile f1(filename1, "rb"),
489 f2(filename2, "rb");
490
491 if ( !f1.IsOpened() || !f2.IsOpened() )
492 {
493 puts("ERROR: failed to open file(s)");
494 }
495 else
496 {
497 wxString s1, s2;
498 if ( !f1.ReadAll(&s1) || !f2.ReadAll(&s2) )
499 {
500 puts("ERROR: failed to read file(s)");
501 }
502 else
503 {
504 if ( (s1.length() != s2.length()) ||
505 (memcmp(s1.c_str(), s2.c_str(), s1.length()) != 0) )
506 {
507 puts("ERROR: copy error!");
508 }
509 else
510 {
511 puts("File was copied ok.");
512 }
513 }
514 }
515 }
516
517 if ( !wxRemoveFile(filename2) )
518 {
519 puts("ERROR: failed to remove the file");
520 }
521
522 puts("");
523 }
524
525 #endif // TEST_FILE
526
527 // ----------------------------------------------------------------------------
528 // wxFileConfig
529 // ----------------------------------------------------------------------------
530
531 #ifdef TEST_FILECONF
532
533 #include <wx/confbase.h>
534 #include <wx/fileconf.h>
535
536 static const struct FileConfTestData
537 {
538 const wxChar *name; // value name
539 const wxChar *value; // the value from the file
540 } fcTestData[] =
541 {
542 { _T("value1"), _T("one") },
543 { _T("value2"), _T("two") },
544 { _T("novalue"), _T("default") },
545 };
546
547 static void TestFileConfRead()
548 {
549 puts("*** testing wxFileConfig loading/reading ***");
550
551 wxFileConfig fileconf(_T("test"), wxEmptyString,
552 _T("testdata.fc"), wxEmptyString,
553 wxCONFIG_USE_RELATIVE_PATH);
554
555 // test simple reading
556 puts("\nReading config file:");
557 wxString defValue(_T("default")), value;
558 for ( size_t n = 0; n < WXSIZEOF(fcTestData); n++ )
559 {
560 const FileConfTestData& data = fcTestData[n];
561 value = fileconf.Read(data.name, defValue);
562 printf("\t%s = %s ", data.name, value.c_str());
563 if ( value == data.value )
564 {
565 puts("(ok)");
566 }
567 else
568 {
569 printf("(ERROR: should be %s)\n", data.value);
570 }
571 }
572
573 // test enumerating the entries
574 puts("\nEnumerating all root entries:");
575 long dummy;
576 wxString name;
577 bool cont = fileconf.GetFirstEntry(name, dummy);
578 while ( cont )
579 {
580 printf("\t%s = %s\n",
581 name.c_str(),
582 fileconf.Read(name.c_str(), _T("ERROR")).c_str());
583
584 cont = fileconf.GetNextEntry(name, dummy);
585 }
586 }
587
588 #endif // TEST_FILECONF
589
590 // ----------------------------------------------------------------------------
591 // wxHashTable
592 // ----------------------------------------------------------------------------
593
594 #ifdef TEST_HASH
595
596 #include <wx/hash.h>
597
598 struct Foo
599 {
600 Foo(int n_) { n = n_; count++; }
601 ~Foo() { count--; }
602
603 int n;
604
605 static size_t count;
606 };
607
608 size_t Foo::count = 0;
609
610 WX_DECLARE_LIST(Foo, wxListFoos);
611 WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
612
613 #include <wx/listimpl.cpp>
614
615 WX_DEFINE_LIST(wxListFoos);
616
617 static void TestHash()
618 {
619 puts("*** Testing wxHashTable ***\n");
620
621 {
622 wxHashFoos hash;
623 hash.DeleteContents(TRUE);
624
625 printf("Hash created: %u foos in hash, %u foos totally\n",
626 hash.GetCount(), Foo::count);
627
628 static const int hashTestData[] =
629 {
630 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
631 };
632
633 size_t n;
634 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
635 {
636 hash.Put(hashTestData[n], n, new Foo(n));
637 }
638
639 printf("Hash filled: %u foos in hash, %u foos totally\n",
640 hash.GetCount(), Foo::count);
641
642 puts("Hash access test:");
643 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
644 {
645 printf("\tGetting element with key %d, value %d: ",
646 hashTestData[n], n);
647 Foo *foo = hash.Get(hashTestData[n], n);
648 if ( !foo )
649 {
650 printf("ERROR, not found.\n");
651 }
652 else
653 {
654 printf("%d (%s)\n", foo->n,
655 (size_t)foo->n == n ? "ok" : "ERROR");
656 }
657 }
658
659 printf("\nTrying to get an element not in hash: ");
660
661 if ( hash.Get(1234) || hash.Get(1, 0) )
662 {
663 puts("ERROR: found!");
664 }
665 else
666 {
667 puts("ok (not found)");
668 }
669 }
670
671 printf("Hash destroyed: %u foos left\n", Foo::count);
672 }
673
674 #endif // TEST_HASH
675
676 // ----------------------------------------------------------------------------
677 // wxList
678 // ----------------------------------------------------------------------------
679
680 #ifdef TEST_LIST
681
682 #include <wx/list.h>
683
684 WX_DECLARE_LIST(Bar, wxListBars);
685 #include <wx/listimpl.cpp>
686 WX_DEFINE_LIST(wxListBars);
687
688 static void TestListCtor()
689 {
690 puts("*** Testing wxList construction ***\n");
691
692 {
693 wxListBars list1;
694 list1.Append(new Bar(_T("first")));
695 list1.Append(new Bar(_T("second")));
696
697 printf("After 1st list creation: %u objects in the list, %u objects total.\n",
698 list1.GetCount(), Bar::GetNumber());
699
700 wxListBars list2;
701 list2 = list1;
702
703 printf("After 2nd list creation: %u and %u objects in the lists, %u objects total.\n",
704 list1.GetCount(), list2.GetCount(), Bar::GetNumber());
705
706 list1.DeleteContents(TRUE);
707 }
708
709 printf("After list destruction: %u objects left.\n", Bar::GetNumber());
710 }
711
712 #endif // TEST_LIST
713
714 // ----------------------------------------------------------------------------
715 // MIME types
716 // ----------------------------------------------------------------------------
717
718 #ifdef TEST_MIME
719
720 #include <wx/mimetype.h>
721
722 static wxMimeTypesManager g_mimeManager;
723
724 static void TestMimeEnum()
725 {
726 wxArrayString mimetypes;
727
728 size_t count = g_mimeManager.EnumAllFileTypes(mimetypes);
729
730 printf("*** All %u known filetypes: ***\n", count);
731
732 wxArrayString exts;
733 wxString desc;
734
735 for ( size_t n = 0; n < count; n++ )
736 {
737 wxFileType *filetype = g_mimeManager.GetFileTypeFromMimeType(mimetypes[n]);
738 if ( !filetype )
739 {
740 printf("nothing known about the filetype '%s'!\n",
741 mimetypes[n].c_str());
742 continue;
743 }
744
745 filetype->GetDescription(&desc);
746 filetype->GetExtensions(exts);
747
748 filetype->GetIcon(NULL);
749
750 wxString extsAll;
751 for ( size_t e = 0; e < exts.GetCount(); e++ )
752 {
753 if ( e > 0 )
754 extsAll << _T(", ");
755 extsAll += exts[e];
756 }
757
758 printf("\t%s: %s (%s)\n",
759 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
760 }
761 }
762
763 static void TestMimeOverride()
764 {
765 wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
766
767 wxString mailcap = _T("/tmp/mailcap"),
768 mimetypes = _T("/tmp/mime.types");
769
770 wxPrintf(_T("Loading mailcap from '%s': %s\n"),
771 mailcap.c_str(),
772 g_mimeManager.ReadMailcap(mailcap) ? _T("ok") : _T("ERROR"));
773 wxPrintf(_T("Loading mime.types from '%s': %s\n"),
774 mimetypes.c_str(),
775 g_mimeManager.ReadMimeTypes(mimetypes) ? _T("ok") : _T("ERROR"));
776 }
777
778 static void TestMimeFilename()
779 {
780 wxPuts(_T("*** Testing MIME type from filename query ***\n"));
781
782 static const wxChar *filenames[] =
783 {
784 _T("readme.txt"),
785 _T("document.pdf"),
786 _T("image.gif"),
787 };
788
789 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
790 {
791 const wxString fname = filenames[n];
792 wxString ext = fname.AfterLast(_T('.'));
793 wxFileType *ft = g_mimeManager.GetFileTypeFromExtension(ext);
794 if ( !ft )
795 {
796 wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext.c_str());
797 }
798 else
799 {
800 wxString desc;
801 if ( !ft->GetDescription(&desc) )
802 desc = _T("<no description>");
803
804 wxString cmd;
805 if ( !ft->GetOpenCommand(&cmd,
806 wxFileType::MessageParameters(fname, _T(""))) )
807 cmd = _T("<no command available>");
808
809 wxPrintf(_T("To open %s (%s) do '%s'.\n"),
810 fname.c_str(), desc.c_str(), cmd.c_str());
811
812 delete ft;
813 }
814 }
815 }
816
817 static void TestMimeAssociate()
818 {
819 wxPuts(_T("*** Testing creation of filetype association ***\n"));
820
821 wxFileType *ft = g_mimeManager.Associate
822 (
823 _T(".xyz"),
824 _T("application/x-xyz"),
825 _T("XYZFile"), // filetype (MSW only)
826 _T("XYZ File") // description (Unix only)
827 );
828 if ( !ft )
829 {
830 wxPuts(_T("ERROR: failed to create association!"));
831 }
832 else
833 {
834 if ( !ft->SetOpenCommand(_T("myprogram")) )
835 {
836 wxPuts(_T("ERROR: failed to set open command!"));
837 }
838
839 delete ft;
840 }
841 }
842
843 #endif // TEST_MIME
844
845 // ----------------------------------------------------------------------------
846 // misc information functions
847 // ----------------------------------------------------------------------------
848
849 #ifdef TEST_INFO_FUNCTIONS
850
851 #include <wx/utils.h>
852
853 static void TestOsInfo()
854 {
855 puts("*** Testing OS info functions ***\n");
856
857 int major, minor;
858 wxGetOsVersion(&major, &minor);
859 printf("Running under: %s, version %d.%d\n",
860 wxGetOsDescription().c_str(), major, minor);
861
862 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
863
864 printf("Host name is %s (%s).\n",
865 wxGetHostName().c_str(), wxGetFullHostName().c_str());
866
867 puts("");
868 }
869
870 static void TestUserInfo()
871 {
872 puts("*** Testing user info functions ***\n");
873
874 printf("User id is:\t%s\n", wxGetUserId().c_str());
875 printf("User name is:\t%s\n", wxGetUserName().c_str());
876 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
877 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
878
879 puts("");
880 }
881
882 #endif // TEST_INFO_FUNCTIONS
883
884 // ----------------------------------------------------------------------------
885 // long long
886 // ----------------------------------------------------------------------------
887
888 #ifdef TEST_LONGLONG
889
890 #include <wx/longlong.h>
891 #include <wx/timer.h>
892
893 // make a 64 bit number from 4 16 bit ones
894 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
895
896 // get a random 64 bit number
897 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
898
899 #if wxUSE_LONGLONG_WX
900 inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
901 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
902 inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
903 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
904 #endif // wxUSE_LONGLONG_WX
905
906 static void TestSpeed()
907 {
908 static const long max = 100000000;
909 long n;
910
911 {
912 wxStopWatch sw;
913
914 long l = 0;
915 for ( n = 0; n < max; n++ )
916 {
917 l += n;
918 }
919
920 printf("Summing longs took %ld milliseconds.\n", sw.Time());
921 }
922
923 #if wxUSE_LONGLONG_NATIVE
924 {
925 wxStopWatch sw;
926
927 wxLongLong_t l = 0;
928 for ( n = 0; n < max; n++ )
929 {
930 l += n;
931 }
932
933 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
934 }
935 #endif // wxUSE_LONGLONG_NATIVE
936
937 {
938 wxStopWatch sw;
939
940 wxLongLong l;
941 for ( n = 0; n < max; n++ )
942 {
943 l += n;
944 }
945
946 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
947 }
948 }
949
950 static void TestLongLongConversion()
951 {
952 puts("*** Testing wxLongLong conversions ***\n");
953
954 wxLongLong a;
955 size_t nTested = 0;
956 for ( size_t n = 0; n < 100000; n++ )
957 {
958 a = RAND_LL();
959
960 #if wxUSE_LONGLONG_NATIVE
961 wxLongLongNative b(a.GetHi(), a.GetLo());
962
963 wxASSERT_MSG( a == b, "conversions failure" );
964 #else
965 puts("Can't do it without native long long type, test skipped.");
966
967 return;
968 #endif // wxUSE_LONGLONG_NATIVE
969
970 if ( !(nTested % 1000) )
971 {
972 putchar('.');
973 fflush(stdout);
974 }
975
976 nTested++;
977 }
978
979 puts(" done!");
980 }
981
982 static void TestMultiplication()
983 {
984 puts("*** Testing wxLongLong multiplication ***\n");
985
986 wxLongLong a, b;
987 size_t nTested = 0;
988 for ( size_t n = 0; n < 100000; n++ )
989 {
990 a = RAND_LL();
991 b = RAND_LL();
992
993 #if wxUSE_LONGLONG_NATIVE
994 wxLongLongNative aa(a.GetHi(), a.GetLo());
995 wxLongLongNative bb(b.GetHi(), b.GetLo());
996
997 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
998 #else // !wxUSE_LONGLONG_NATIVE
999 puts("Can't do it without native long long type, test skipped.");
1000
1001 return;
1002 #endif // wxUSE_LONGLONG_NATIVE
1003
1004 if ( !(nTested % 1000) )
1005 {
1006 putchar('.');
1007 fflush(stdout);
1008 }
1009
1010 nTested++;
1011 }
1012
1013 puts(" done!");
1014 }
1015
1016 static void TestDivision()
1017 {
1018 puts("*** Testing wxLongLong division ***\n");
1019
1020 wxLongLong q, r;
1021 size_t nTested = 0;
1022 for ( size_t n = 0; n < 100000; n++ )
1023 {
1024 // get a random wxLongLong (shifting by 12 the MSB ensures that the
1025 // multiplication will not overflow)
1026 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
1027
1028 // get a random long (not wxLongLong for now) to divide it with
1029 long l = rand();
1030 q = ll / l;
1031 r = ll % l;
1032
1033 #if wxUSE_LONGLONG_NATIVE
1034 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1035
1036 wxLongLongNative p = m / l, s = m % l;
1037 wxASSERT_MSG( q == p && r == s, "division failure" );
1038 #else // !wxUSE_LONGLONG_NATIVE
1039 // verify the result
1040 wxASSERT_MSG( ll == q*l + r, "division failure" );
1041 #endif // wxUSE_LONGLONG_NATIVE
1042
1043 if ( !(nTested % 1000) )
1044 {
1045 putchar('.');
1046 fflush(stdout);
1047 }
1048
1049 nTested++;
1050 }
1051
1052 puts(" done!");
1053 }
1054
1055 static void TestAddition()
1056 {
1057 puts("*** Testing wxLongLong addition ***\n");
1058
1059 wxLongLong a, b, c;
1060 size_t nTested = 0;
1061 for ( size_t n = 0; n < 100000; n++ )
1062 {
1063 a = RAND_LL();
1064 b = RAND_LL();
1065 c = a + b;
1066
1067 #if wxUSE_LONGLONG_NATIVE
1068 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1069 wxLongLongNative(b.GetHi(), b.GetLo()),
1070 "addition failure" );
1071 #else // !wxUSE_LONGLONG_NATIVE
1072 wxASSERT_MSG( c - b == a, "addition failure" );
1073 #endif // wxUSE_LONGLONG_NATIVE
1074
1075 if ( !(nTested % 1000) )
1076 {
1077 putchar('.');
1078 fflush(stdout);
1079 }
1080
1081 nTested++;
1082 }
1083
1084 puts(" done!");
1085 }
1086
1087 static void TestBitOperations()
1088 {
1089 puts("*** Testing wxLongLong bit operation ***\n");
1090
1091 wxLongLong ll;
1092 size_t nTested = 0;
1093 for ( size_t n = 0; n < 100000; n++ )
1094 {
1095 ll = RAND_LL();
1096
1097 #if wxUSE_LONGLONG_NATIVE
1098 for ( size_t n = 0; n < 33; n++ )
1099 {
1100 }
1101 #else // !wxUSE_LONGLONG_NATIVE
1102 puts("Can't do it without native long long type, test skipped.");
1103
1104 return;
1105 #endif // wxUSE_LONGLONG_NATIVE
1106
1107 if ( !(nTested % 1000) )
1108 {
1109 putchar('.');
1110 fflush(stdout);
1111 }
1112
1113 nTested++;
1114 }
1115
1116 puts(" done!");
1117 }
1118
1119 static void TestLongLongComparison()
1120 {
1121 puts("*** Testing wxLongLong comparison ***\n");
1122
1123 static const long testLongs[] =
1124 {
1125 0,
1126 1,
1127 -1,
1128 LONG_MAX,
1129 LONG_MIN,
1130 0x1234,
1131 -0x1234
1132 };
1133
1134 static const long ls[2] =
1135 {
1136 0x1234,
1137 -0x1234,
1138 };
1139
1140 wxLongLongWx lls[2];
1141 lls[0] = ls[0];
1142 lls[1] = ls[1];
1143
1144 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1145 {
1146 bool res;
1147
1148 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
1149 {
1150 res = lls[m] > testLongs[n];
1151 printf("0x%lx > 0x%lx is %s (%s)\n",
1152 ls[m], testLongs[n], res ? "true" : "false",
1153 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
1154
1155 res = lls[m] < testLongs[n];
1156 printf("0x%lx < 0x%lx is %s (%s)\n",
1157 ls[m], testLongs[n], res ? "true" : "false",
1158 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
1159
1160 res = lls[m] == testLongs[n];
1161 printf("0x%lx == 0x%lx is %s (%s)\n",
1162 ls[m], testLongs[n], res ? "true" : "false",
1163 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
1164 }
1165 }
1166 }
1167
1168 #undef MAKE_LL
1169 #undef RAND_LL
1170
1171 #endif // TEST_LONGLONG
1172
1173 // ----------------------------------------------------------------------------
1174 // registry
1175 // ----------------------------------------------------------------------------
1176
1177 // this is for MSW only
1178 #ifndef __WXMSW__
1179 #undef TEST_REGISTRY
1180 #endif
1181
1182 #ifdef TEST_REGISTRY
1183
1184 #include <wx/msw/registry.h>
1185
1186 // I chose this one because I liked its name, but it probably only exists under
1187 // NT
1188 static const wxChar *TESTKEY =
1189 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
1190
1191 static void TestRegistryRead()
1192 {
1193 puts("*** testing registry reading ***");
1194
1195 wxRegKey key(TESTKEY);
1196 printf("The test key name is '%s'.\n", key.GetName().c_str());
1197 if ( !key.Open() )
1198 {
1199 puts("ERROR: test key can't be opened, aborting test.");
1200
1201 return;
1202 }
1203
1204 size_t nSubKeys, nValues;
1205 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
1206 {
1207 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
1208 }
1209
1210 printf("Enumerating values:\n");
1211
1212 long dummy;
1213 wxString value;
1214 bool cont = key.GetFirstValue(value, dummy);
1215 while ( cont )
1216 {
1217 printf("Value '%s': type ", value.c_str());
1218 switch ( key.GetValueType(value) )
1219 {
1220 case wxRegKey::Type_None: printf("ERROR (none)"); break;
1221 case wxRegKey::Type_String: printf("SZ"); break;
1222 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
1223 case wxRegKey::Type_Binary: printf("BINARY"); break;
1224 case wxRegKey::Type_Dword: printf("DWORD"); break;
1225 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
1226 default: printf("other (unknown)"); break;
1227 }
1228
1229 printf(", value = ");
1230 if ( key.IsNumericValue(value) )
1231 {
1232 long val;
1233 key.QueryValue(value, &val);
1234 printf("%ld", val);
1235 }
1236 else // string
1237 {
1238 wxString val;
1239 key.QueryValue(value, val);
1240 printf("'%s'", val.c_str());
1241
1242 key.QueryRawValue(value, val);
1243 printf(" (raw value '%s')", val.c_str());
1244 }
1245
1246 putchar('\n');
1247
1248 cont = key.GetNextValue(value, dummy);
1249 }
1250 }
1251
1252 static void TestRegistryAssociation()
1253 {
1254 /*
1255 The second call to deleteself genertaes an error message, with a
1256 messagebox saying .flo is crucial to system operation, while the .ddf
1257 call also fails, but with no error message
1258 */
1259
1260 wxRegKey key;
1261
1262 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
1263 key.Create();
1264 key = "ddxf_auto_file" ;
1265 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
1266 key.Create();
1267 key = "ddxf_auto_file" ;
1268 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
1269 key.Create();
1270 key = "program,0" ;
1271 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
1272 key.Create();
1273 key = "program \"%1\"" ;
1274
1275 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
1276 key.DeleteSelf();
1277 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
1278 key.DeleteSelf();
1279 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
1280 key.DeleteSelf();
1281 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
1282 key.DeleteSelf();
1283 }
1284
1285 #endif // TEST_REGISTRY
1286
1287 // ----------------------------------------------------------------------------
1288 // sockets
1289 // ----------------------------------------------------------------------------
1290
1291 #ifdef TEST_SOCKETS
1292
1293 #include <wx/socket.h>
1294 #include <wx/protocol/protocol.h>
1295 #include <wx/protocol/http.h>
1296
1297 static void TestSocketServer()
1298 {
1299 puts("*** Testing wxSocketServer ***\n");
1300
1301 static const int PORT = 3000;
1302
1303 wxIPV4address addr;
1304 addr.Service(PORT);
1305
1306 wxSocketServer *server = new wxSocketServer(addr);
1307 if ( !server->Ok() )
1308 {
1309 puts("ERROR: failed to bind");
1310
1311 return;
1312 }
1313
1314 for ( ;; )
1315 {
1316 printf("Server: waiting for connection on port %d...\n", PORT);
1317
1318 wxSocketBase *socket = server->Accept();
1319 if ( !socket )
1320 {
1321 puts("ERROR: wxSocketServer::Accept() failed.");
1322 break;
1323 }
1324
1325 puts("Server: got a client.");
1326
1327 server->SetTimeout(60); // 1 min
1328
1329 while ( socket->IsConnected() )
1330 {
1331 wxString s;
1332 char ch = '\0';
1333 for ( ;; )
1334 {
1335 if ( socket->Read(&ch, sizeof(ch)).Error() )
1336 {
1337 // don't log error if the client just close the connection
1338 if ( socket->IsConnected() )
1339 {
1340 puts("ERROR: in wxSocket::Read.");
1341 }
1342
1343 break;
1344 }
1345
1346 if ( ch == '\r' )
1347 continue;
1348
1349 if ( ch == '\n' )
1350 break;
1351
1352 s += ch;
1353 }
1354
1355 if ( ch != '\n' )
1356 {
1357 break;
1358 }
1359
1360 printf("Server: got '%s'.\n", s.c_str());
1361 if ( s == _T("bye") )
1362 {
1363 delete socket;
1364
1365 break;
1366 }
1367
1368 socket->Write(s.MakeUpper().c_str(), s.length());
1369 socket->Write("\r\n", 2);
1370 printf("Server: wrote '%s'.\n", s.c_str());
1371 }
1372
1373 puts("Server: lost a client.");
1374
1375 socket->Destroy();
1376 }
1377
1378 // same as "delete server" but is consistent with GUI programs
1379 server->Destroy();
1380 }
1381
1382 static void TestSocketClient()
1383 {
1384 puts("*** Testing wxSocketClient ***\n");
1385
1386 static const char *hostname = "www.wxwindows.org";
1387
1388 wxIPV4address addr;
1389 addr.Hostname(hostname);
1390 addr.Service(80);
1391
1392 printf("--- Attempting to connect to %s:80...\n", hostname);
1393
1394 wxSocketClient client;
1395 if ( !client.Connect(addr) )
1396 {
1397 printf("ERROR: failed to connect to %s\n", hostname);
1398 }
1399 else
1400 {
1401 printf("--- Connected to %s:%u...\n",
1402 addr.Hostname().c_str(), addr.Service());
1403
1404 char buf[8192];
1405
1406 // could use simply "GET" here I suppose
1407 wxString cmdGet =
1408 wxString::Format("GET http://%s/\r\n", hostname);
1409 client.Write(cmdGet, cmdGet.length());
1410 printf("--- Sent command '%s' to the server\n",
1411 MakePrintable(cmdGet).c_str());
1412 client.Read(buf, WXSIZEOF(buf));
1413 printf("--- Server replied:\n%s", buf);
1414 }
1415 }
1416
1417 #endif // TEST_SOCKETS
1418
1419 #ifdef TEST_FTP
1420
1421 #include <wx/protocol/ftp.h>
1422
1423 static void TestProtocolFtp()
1424 {
1425 puts("*** Testing wxFTP download ***\n");
1426
1427 wxFTP ftp;
1428 #if 1
1429 static const char *hostname = "ftp.wxwindows.org";
1430 static const char *directory = "pub";
1431
1432 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
1433 #else
1434 static const char *hostname = "localhost";
1435 static const char *user = "zeitlin";
1436 static const char *directory = "/tmp";
1437
1438 ftp.SetUser(user);
1439 ftp.SetPassword("password");
1440
1441 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
1442 #endif
1443
1444 if ( !ftp.Connect(hostname) )
1445 {
1446 printf("ERROR: failed to connect to %s\n", hostname);
1447 }
1448 else
1449 {
1450 printf("--- Connected to %s, current directory is '%s'\n",
1451 hostname, ftp.Pwd().c_str());
1452
1453 // test CWD
1454 if ( !ftp.ChDir(directory) )
1455 {
1456 printf("ERROR: failed to cd to %s\n", directory);
1457 }
1458
1459 // test NLIST and LIST
1460 wxArrayString files;
1461 if ( !ftp.GetFilesList(files) )
1462 {
1463 puts("ERROR: failed to get NLIST of files");
1464 }
1465 else
1466 {
1467 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
1468 size_t count = files.GetCount();
1469 for ( size_t n = 0; n < count; n++ )
1470 {
1471 printf("\t%s\n", files[n].c_str());
1472 }
1473 puts("End of the file list");
1474 }
1475
1476 if ( !ftp.GetDirList(files) )
1477 {
1478 puts("ERROR: failed to get LIST of files");
1479 }
1480 else
1481 {
1482 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
1483 size_t count = files.GetCount();
1484 for ( size_t n = 0; n < count; n++ )
1485 {
1486 printf("\t%s\n", files[n].c_str());
1487 }
1488 puts("End of the file list");
1489 }
1490
1491 if ( !ftp.ChDir(_T("..")) )
1492 {
1493 puts("ERROR: failed to cd to ..");
1494 }
1495
1496 // test RETR
1497 static const char *filename = "welcome.msg";
1498 wxInputStream *in = ftp.GetInputStream(filename);
1499 if ( !in )
1500 {
1501 printf("ERROR: couldn't get input stream for %s\n", filename);
1502 }
1503 else
1504 {
1505 size_t size = in->StreamSize();
1506 printf("Reading file %s (%u bytes)...", filename, size);
1507
1508 char *data = new char[size];
1509 if ( !in->Read(data, size) )
1510 {
1511 puts("ERROR: read error");
1512 }
1513 else
1514 {
1515 printf("\nContents of %s:\n%s\n", filename, data);
1516 }
1517
1518 delete [] data;
1519 delete in;
1520 }
1521
1522 // test some other FTP commands
1523 if ( ftp.SendCommand("STAT") != '2' )
1524 {
1525 puts("ERROR: STAT failed");
1526 }
1527 else
1528 {
1529 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
1530 }
1531
1532 if ( ftp.SendCommand("HELP SITE") != '2' )
1533 {
1534 puts("ERROR: HELP SITE failed");
1535 }
1536 else
1537 {
1538 printf("The list of site-specific commands:\n\n%s\n",
1539 ftp.GetLastResult().c_str());
1540 }
1541 }
1542 }
1543
1544 static void TestProtocolFtpUpload()
1545 {
1546 puts("*** Testing wxFTP uploading ***\n");
1547
1548 static const char *hostname = "localhost";
1549
1550 printf("--- Attempting to connect to %s:21...\n", hostname);
1551
1552 wxFTP ftp;
1553 ftp.SetUser("zeitlin");
1554 ftp.SetPassword("password");
1555 if ( !ftp.Connect(hostname) )
1556 {
1557 printf("ERROR: failed to connect to %s\n", hostname);
1558 }
1559 else
1560 {
1561 printf("--- Connected to %s, current directory is '%s'\n",
1562 hostname, ftp.Pwd().c_str());
1563
1564 // upload a file
1565 static const char *file1 = "test1";
1566 static const char *file2 = "test2";
1567 wxOutputStream *out = ftp.GetOutputStream(file1);
1568 if ( out )
1569 {
1570 printf("--- Uploading to %s ---\n", file1);
1571 out->Write("First hello", 11);
1572 delete out;
1573 }
1574
1575 // send a command to check the remote file
1576 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
1577 {
1578 printf("ERROR: STAT %s failed\n", file1);
1579 }
1580 else
1581 {
1582 printf("STAT %s returned:\n\n%s\n",
1583 file1, ftp.GetLastResult().c_str());
1584 }
1585
1586 out = ftp.GetOutputStream(file2);
1587 if ( out )
1588 {
1589 printf("--- Uploading to %s ---\n", file1);
1590 out->Write("Second hello", 12);
1591 delete out;
1592 }
1593 }
1594 }
1595
1596 #endif // TEST_FTP
1597
1598 // ----------------------------------------------------------------------------
1599 // streams
1600 // ----------------------------------------------------------------------------
1601
1602 #ifdef TEST_STREAMS
1603
1604 #include <wx/mstream.h>
1605
1606 static void TestMemoryStream()
1607 {
1608 puts("*** Testing wxMemoryInputStream ***");
1609
1610 wxChar buf[1024];
1611 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
1612
1613 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
1614 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
1615 while ( !memInpStream.Eof() )
1616 {
1617 putchar(memInpStream.GetC());
1618 }
1619
1620 puts("\n*** wxMemoryInputStream test done ***");
1621 }
1622
1623 #endif // TEST_STREAMS
1624
1625 // ----------------------------------------------------------------------------
1626 // timers
1627 // ----------------------------------------------------------------------------
1628
1629 #ifdef TEST_TIMER
1630
1631 #include <wx/timer.h>
1632 #include <wx/utils.h>
1633
1634 static void TestStopWatch()
1635 {
1636 puts("*** Testing wxStopWatch ***\n");
1637
1638 wxStopWatch sw;
1639 printf("Sleeping 3 seconds...");
1640 wxSleep(3);
1641 printf("\telapsed time: %ldms\n", sw.Time());
1642
1643 sw.Pause();
1644 printf("Sleeping 2 more seconds...");
1645 wxSleep(2);
1646 printf("\telapsed time: %ldms\n", sw.Time());
1647
1648 sw.Resume();
1649 printf("And 3 more seconds...");
1650 wxSleep(3);
1651 printf("\telapsed time: %ldms\n", sw.Time());
1652
1653 wxStopWatch sw2;
1654 puts("\nChecking for 'backwards clock' bug...");
1655 for ( size_t n = 0; n < 70; n++ )
1656 {
1657 sw2.Start();
1658
1659 for ( size_t m = 0; m < 100000; m++ )
1660 {
1661 if ( sw.Time() < 0 || sw2.Time() < 0 )
1662 {
1663 puts("\ntime is negative - ERROR!");
1664 }
1665 }
1666
1667 putchar('.');
1668 }
1669
1670 puts(", ok.");
1671 }
1672
1673 #endif // TEST_TIMER
1674
1675 // ----------------------------------------------------------------------------
1676 // vCard support
1677 // ----------------------------------------------------------------------------
1678
1679 #ifdef TEST_VCARD
1680
1681 #include <wx/vcard.h>
1682
1683 static void DumpVObject(size_t level, const wxVCardObject& vcard)
1684 {
1685 void *cookie;
1686 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
1687 while ( vcObj )
1688 {
1689 printf("%s%s",
1690 wxString(_T('\t'), level).c_str(),
1691 vcObj->GetName().c_str());
1692
1693 wxString value;
1694 switch ( vcObj->GetType() )
1695 {
1696 case wxVCardObject::String:
1697 case wxVCardObject::UString:
1698 {
1699 wxString val;
1700 vcObj->GetValue(&val);
1701 value << _T('"') << val << _T('"');
1702 }
1703 break;
1704
1705 case wxVCardObject::Int:
1706 {
1707 unsigned int i;
1708 vcObj->GetValue(&i);
1709 value.Printf(_T("%u"), i);
1710 }
1711 break;
1712
1713 case wxVCardObject::Long:
1714 {
1715 unsigned long l;
1716 vcObj->GetValue(&l);
1717 value.Printf(_T("%lu"), l);
1718 }
1719 break;
1720
1721 case wxVCardObject::None:
1722 break;
1723
1724 case wxVCardObject::Object:
1725 value = _T("<node>");
1726 break;
1727
1728 default:
1729 value = _T("<unknown value type>");
1730 }
1731
1732 if ( !!value )
1733 printf(" = %s", value.c_str());
1734 putchar('\n');
1735
1736 DumpVObject(level + 1, *vcObj);
1737
1738 delete vcObj;
1739 vcObj = vcard.GetNextProp(&cookie);
1740 }
1741 }
1742
1743 static void DumpVCardAddresses(const wxVCard& vcard)
1744 {
1745 puts("\nShowing all addresses from vCard:\n");
1746
1747 size_t nAdr = 0;
1748 void *cookie;
1749 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
1750 while ( addr )
1751 {
1752 wxString flagsStr;
1753 int flags = addr->GetFlags();
1754 if ( flags & wxVCardAddress::Domestic )
1755 {
1756 flagsStr << _T("domestic ");
1757 }
1758 if ( flags & wxVCardAddress::Intl )
1759 {
1760 flagsStr << _T("international ");
1761 }
1762 if ( flags & wxVCardAddress::Postal )
1763 {
1764 flagsStr << _T("postal ");
1765 }
1766 if ( flags & wxVCardAddress::Parcel )
1767 {
1768 flagsStr << _T("parcel ");
1769 }
1770 if ( flags & wxVCardAddress::Home )
1771 {
1772 flagsStr << _T("home ");
1773 }
1774 if ( flags & wxVCardAddress::Work )
1775 {
1776 flagsStr << _T("work ");
1777 }
1778
1779 printf("Address %u:\n"
1780 "\tflags = %s\n"
1781 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
1782 ++nAdr,
1783 flagsStr.c_str(),
1784 addr->GetPostOffice().c_str(),
1785 addr->GetExtAddress().c_str(),
1786 addr->GetStreet().c_str(),
1787 addr->GetLocality().c_str(),
1788 addr->GetRegion().c_str(),
1789 addr->GetPostalCode().c_str(),
1790 addr->GetCountry().c_str()
1791 );
1792
1793 delete addr;
1794 addr = vcard.GetNextAddress(&cookie);
1795 }
1796 }
1797
1798 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
1799 {
1800 puts("\nShowing all phone numbers from vCard:\n");
1801
1802 size_t nPhone = 0;
1803 void *cookie;
1804 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
1805 while ( phone )
1806 {
1807 wxString flagsStr;
1808 int flags = phone->GetFlags();
1809 if ( flags & wxVCardPhoneNumber::Voice )
1810 {
1811 flagsStr << _T("voice ");
1812 }
1813 if ( flags & wxVCardPhoneNumber::Fax )
1814 {
1815 flagsStr << _T("fax ");
1816 }
1817 if ( flags & wxVCardPhoneNumber::Cellular )
1818 {
1819 flagsStr << _T("cellular ");
1820 }
1821 if ( flags & wxVCardPhoneNumber::Modem )
1822 {
1823 flagsStr << _T("modem ");
1824 }
1825 if ( flags & wxVCardPhoneNumber::Home )
1826 {
1827 flagsStr << _T("home ");
1828 }
1829 if ( flags & wxVCardPhoneNumber::Work )
1830 {
1831 flagsStr << _T("work ");
1832 }
1833
1834 printf("Phone number %u:\n"
1835 "\tflags = %s\n"
1836 "\tvalue = %s\n",
1837 ++nPhone,
1838 flagsStr.c_str(),
1839 phone->GetNumber().c_str()
1840 );
1841
1842 delete phone;
1843 phone = vcard.GetNextPhoneNumber(&cookie);
1844 }
1845 }
1846
1847 static void TestVCardRead()
1848 {
1849 puts("*** Testing wxVCard reading ***\n");
1850
1851 wxVCard vcard(_T("vcard.vcf"));
1852 if ( !vcard.IsOk() )
1853 {
1854 puts("ERROR: couldn't load vCard.");
1855 }
1856 else
1857 {
1858 // read individual vCard properties
1859 wxVCardObject *vcObj = vcard.GetProperty("FN");
1860 wxString value;
1861 if ( vcObj )
1862 {
1863 vcObj->GetValue(&value);
1864 delete vcObj;
1865 }
1866 else
1867 {
1868 value = _T("<none>");
1869 }
1870
1871 printf("Full name retrieved directly: %s\n", value.c_str());
1872
1873
1874 if ( !vcard.GetFullName(&value) )
1875 {
1876 value = _T("<none>");
1877 }
1878
1879 printf("Full name from wxVCard API: %s\n", value.c_str());
1880
1881 // now show how to deal with multiply occuring properties
1882 DumpVCardAddresses(vcard);
1883 DumpVCardPhoneNumbers(vcard);
1884
1885 // and finally show all
1886 puts("\nNow dumping the entire vCard:\n"
1887 "-----------------------------\n");
1888
1889 DumpVObject(0, vcard);
1890 }
1891 }
1892
1893 static void TestVCardWrite()
1894 {
1895 puts("*** Testing wxVCard writing ***\n");
1896
1897 wxVCard vcard;
1898 if ( !vcard.IsOk() )
1899 {
1900 puts("ERROR: couldn't create vCard.");
1901 }
1902 else
1903 {
1904 // set some fields
1905 vcard.SetName("Zeitlin", "Vadim");
1906 vcard.SetFullName("Vadim Zeitlin");
1907 vcard.SetOrganization("wxWindows", "R&D");
1908
1909 // just dump the vCard back
1910 puts("Entire vCard follows:\n");
1911 puts(vcard.Write());
1912 }
1913 }
1914
1915 #endif // TEST_VCARD
1916
1917 // ----------------------------------------------------------------------------
1918 // wide char (Unicode) support
1919 // ----------------------------------------------------------------------------
1920
1921 #ifdef TEST_WCHAR
1922
1923 #include <wx/strconv.h>
1924 #include <wx/buffer.h>
1925
1926 static void TestUtf8()
1927 {
1928 puts("*** Testing UTF8 support ***\n");
1929
1930 wxString testString = "français";
1931 #if 0
1932 "************ French - Français ****************"
1933 "Juste un petit exemple pour dire que les français aussi"
1934 "ont à cœur de pouvoir utiliser tous leurs caractères ! :)";
1935 #endif
1936
1937 wxWCharBuffer wchBuf = testString.wc_str(wxConvUTF8);
1938 const wchar_t *pwz = (const wchar_t *)wchBuf;
1939 wxString testString2(pwz, wxConvLocal);
1940
1941 printf("Decoding '%s' => '%s'\n", testString.c_str(), testString2.c_str());
1942
1943 char *psz = "fran" "\xe7" "ais";
1944 size_t len = strlen(psz);
1945 wchar_t *pwz2 = new wchar_t[len + 1];
1946 for ( size_t n = 0; n <= len; n++ )
1947 {
1948 pwz2[n] = (wchar_t)(unsigned char)psz[n];
1949 }
1950
1951 wxString testString3(pwz2, wxConvUTF8);
1952 delete [] pwz2;
1953
1954 printf("Encoding '%s' -> '%s'\n", psz, testString3.c_str());
1955 }
1956
1957 #endif // TEST_WCHAR
1958
1959 // ----------------------------------------------------------------------------
1960 // ZIP stream
1961 // ----------------------------------------------------------------------------
1962
1963 #ifdef TEST_ZIP
1964
1965 #include "wx/zipstrm.h"
1966
1967 static void TestZipStreamRead()
1968 {
1969 puts("*** Testing ZIP reading ***\n");
1970
1971 wxZipInputStream istr(_T("idx.zip"), _T("IDX.txt"));
1972 printf("Archive size: %u\n", istr.GetSize());
1973
1974 puts("Dumping the file:");
1975 while ( !istr.Eof() )
1976 {
1977 putchar(istr.GetC());
1978 fflush(stdout);
1979 }
1980
1981 puts("\n----- done ------");
1982 }
1983
1984 #endif // TEST_ZIP
1985
1986 // ----------------------------------------------------------------------------
1987 // ZLIB stream
1988 // ----------------------------------------------------------------------------
1989
1990 #ifdef TEST_ZLIB
1991
1992 #include <wx/zstream.h>
1993 #include <wx/wfstream.h>
1994
1995 static const wxChar *FILENAME_GZ = _T("test.gz");
1996 static const char *TEST_DATA = "hello and hello again";
1997
1998 static void TestZlibStreamWrite()
1999 {
2000 puts("*** Testing Zlib stream reading ***\n");
2001
2002 wxFileOutputStream fileOutStream(FILENAME_GZ);
2003 wxZlibOutputStream ostr(fileOutStream, 0);
2004 printf("Compressing the test string... ");
2005 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
2006 if ( !ostr )
2007 {
2008 puts("(ERROR: failed)");
2009 }
2010 else
2011 {
2012 puts("(ok)");
2013 }
2014
2015 puts("\n----- done ------");
2016 }
2017
2018 static void TestZlibStreamRead()
2019 {
2020 puts("*** Testing Zlib stream reading ***\n");
2021
2022 wxFileInputStream fileInStream(FILENAME_GZ);
2023 wxZlibInputStream istr(fileInStream);
2024 printf("Archive size: %u\n", istr.GetSize());
2025
2026 puts("Dumping the file:");
2027 while ( !istr.Eof() )
2028 {
2029 putchar(istr.GetC());
2030 fflush(stdout);
2031 }
2032
2033 puts("\n----- done ------");
2034 }
2035
2036 #endif // TEST_ZLIB
2037
2038 // ----------------------------------------------------------------------------
2039 // date time
2040 // ----------------------------------------------------------------------------
2041
2042 #ifdef TEST_DATETIME
2043
2044 #include <wx/date.h>
2045
2046 #include <wx/datetime.h>
2047
2048 // the test data
2049 struct Date
2050 {
2051 wxDateTime::wxDateTime_t day;
2052 wxDateTime::Month month;
2053 int year;
2054 wxDateTime::wxDateTime_t hour, min, sec;
2055 double jdn;
2056 wxDateTime::WeekDay wday;
2057 time_t gmticks, ticks;
2058
2059 void Init(const wxDateTime::Tm& tm)
2060 {
2061 day = tm.mday;
2062 month = tm.mon;
2063 year = tm.year;
2064 hour = tm.hour;
2065 min = tm.min;
2066 sec = tm.sec;
2067 jdn = 0.0;
2068 gmticks = ticks = -1;
2069 }
2070
2071 wxDateTime DT() const
2072 { return wxDateTime(day, month, year, hour, min, sec); }
2073
2074 bool SameDay(const wxDateTime::Tm& tm) const
2075 {
2076 return day == tm.mday && month == tm.mon && year == tm.year;
2077 }
2078
2079 wxString Format() const
2080 {
2081 wxString s;
2082 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
2083 hour, min, sec,
2084 wxDateTime::GetMonthName(month).c_str(),
2085 day,
2086 abs(wxDateTime::ConvertYearToBC(year)),
2087 year > 0 ? "AD" : "BC");
2088 return s;
2089 }
2090
2091 wxString FormatDate() const
2092 {
2093 wxString s;
2094 s.Printf("%02d-%s-%4d%s",
2095 day,
2096 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2097 abs(wxDateTime::ConvertYearToBC(year)),
2098 year > 0 ? "AD" : "BC");
2099 return s;
2100 }
2101 };
2102
2103 static const Date testDates[] =
2104 {
2105 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
2106 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
2107 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
2108 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
2109 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
2110 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
2111 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
2112 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
2113 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
2114 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
2115 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
2116 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
2117 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
2118 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
2119 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
2120 };
2121
2122 // this test miscellaneous static wxDateTime functions
2123 static void TestTimeStatic()
2124 {
2125 puts("\n*** wxDateTime static methods test ***");
2126
2127 // some info about the current date
2128 int year = wxDateTime::GetCurrentYear();
2129 printf("Current year %d is %sa leap one and has %d days.\n",
2130 year,
2131 wxDateTime::IsLeapYear(year) ? "" : "not ",
2132 wxDateTime::GetNumberOfDays(year));
2133
2134 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
2135 printf("Current month is '%s' ('%s') and it has %d days\n",
2136 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2137 wxDateTime::GetMonthName(month).c_str(),
2138 wxDateTime::GetNumberOfDays(month));
2139
2140 // leap year logic
2141 static const size_t nYears = 5;
2142 static const size_t years[2][nYears] =
2143 {
2144 // first line: the years to test
2145 { 1990, 1976, 2000, 2030, 1984, },
2146
2147 // second line: TRUE if leap, FALSE otherwise
2148 { FALSE, TRUE, TRUE, FALSE, TRUE }
2149 };
2150
2151 for ( size_t n = 0; n < nYears; n++ )
2152 {
2153 int year = years[0][n];
2154 bool should = years[1][n] != 0,
2155 is = wxDateTime::IsLeapYear(year);
2156
2157 printf("Year %d is %sa leap year (%s)\n",
2158 year,
2159 is ? "" : "not ",
2160 should == is ? "ok" : "ERROR");
2161
2162 wxASSERT( should == wxDateTime::IsLeapYear(year) );
2163 }
2164 }
2165
2166 // test constructing wxDateTime objects
2167 static void TestTimeSet()
2168 {
2169 puts("\n*** wxDateTime construction test ***");
2170
2171 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2172 {
2173 const Date& d1 = testDates[n];
2174 wxDateTime dt = d1.DT();
2175
2176 Date d2;
2177 d2.Init(dt.GetTm());
2178
2179 wxString s1 = d1.Format(),
2180 s2 = d2.Format();
2181
2182 printf("Date: %s == %s (%s)\n",
2183 s1.c_str(), s2.c_str(),
2184 s1 == s2 ? "ok" : "ERROR");
2185 }
2186 }
2187
2188 // test time zones stuff
2189 static void TestTimeZones()
2190 {
2191 puts("\n*** wxDateTime timezone test ***");
2192
2193 wxDateTime now = wxDateTime::Now();
2194
2195 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
2196 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
2197 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
2198 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
2199 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
2200 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
2201
2202 wxDateTime::Tm tm = now.GetTm();
2203 if ( wxDateTime(tm) != now )
2204 {
2205 printf("ERROR: got %s instead of %s\n",
2206 wxDateTime(tm).Format().c_str(), now.Format().c_str());
2207 }
2208 }
2209
2210 // test some minimal support for the dates outside the standard range
2211 static void TestTimeRange()
2212 {
2213 puts("\n*** wxDateTime out-of-standard-range dates test ***");
2214
2215 static const char *fmt = "%d-%b-%Y %H:%M:%S";
2216
2217 printf("Unix epoch:\t%s\n",
2218 wxDateTime(2440587.5).Format(fmt).c_str());
2219 printf("Feb 29, 0: \t%s\n",
2220 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
2221 printf("JDN 0: \t%s\n",
2222 wxDateTime(0.0).Format(fmt).c_str());
2223 printf("Jan 1, 1AD:\t%s\n",
2224 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
2225 printf("May 29, 2099:\t%s\n",
2226 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
2227 }
2228
2229 static void TestTimeTicks()
2230 {
2231 puts("\n*** wxDateTime ticks test ***");
2232
2233 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2234 {
2235 const Date& d = testDates[n];
2236 if ( d.ticks == -1 )
2237 continue;
2238
2239 wxDateTime dt = d.DT();
2240 long ticks = (dt.GetValue() / 1000).ToLong();
2241 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
2242 if ( ticks == d.ticks )
2243 {
2244 puts(" (ok)");
2245 }
2246 else
2247 {
2248 printf(" (ERROR: should be %ld, delta = %ld)\n",
2249 d.ticks, ticks - d.ticks);
2250 }
2251
2252 dt = d.DT().ToTimezone(wxDateTime::GMT0);
2253 ticks = (dt.GetValue() / 1000).ToLong();
2254 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
2255 if ( ticks == d.gmticks )
2256 {
2257 puts(" (ok)");
2258 }
2259 else
2260 {
2261 printf(" (ERROR: should be %ld, delta = %ld)\n",
2262 d.gmticks, ticks - d.gmticks);
2263 }
2264 }
2265
2266 puts("");
2267 }
2268
2269 // test conversions to JDN &c
2270 static void TestTimeJDN()
2271 {
2272 puts("\n*** wxDateTime to JDN test ***");
2273
2274 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2275 {
2276 const Date& d = testDates[n];
2277 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
2278 double jdn = dt.GetJulianDayNumber();
2279
2280 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
2281 if ( jdn == d.jdn )
2282 {
2283 puts(" (ok)");
2284 }
2285 else
2286 {
2287 printf(" (ERROR: should be %f, delta = %f)\n",
2288 d.jdn, jdn - d.jdn);
2289 }
2290 }
2291 }
2292
2293 // test week days computation
2294 static void TestTimeWDays()
2295 {
2296 puts("\n*** wxDateTime weekday test ***");
2297
2298 // test GetWeekDay()
2299 size_t n;
2300 for ( n = 0; n < WXSIZEOF(testDates); n++ )
2301 {
2302 const Date& d = testDates[n];
2303 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
2304
2305 wxDateTime::WeekDay wday = dt.GetWeekDay();
2306 printf("%s is: %s",
2307 d.Format().c_str(),
2308 wxDateTime::GetWeekDayName(wday).c_str());
2309 if ( wday == d.wday )
2310 {
2311 puts(" (ok)");
2312 }
2313 else
2314 {
2315 printf(" (ERROR: should be %s)\n",
2316 wxDateTime::GetWeekDayName(d.wday).c_str());
2317 }
2318 }
2319
2320 puts("");
2321
2322 // test SetToWeekDay()
2323 struct WeekDateTestData
2324 {
2325 Date date; // the real date (precomputed)
2326 int nWeek; // its week index in the month
2327 wxDateTime::WeekDay wday; // the weekday
2328 wxDateTime::Month month; // the month
2329 int year; // and the year
2330
2331 wxString Format() const
2332 {
2333 wxString s, which;
2334 switch ( nWeek < -1 ? -nWeek : nWeek )
2335 {
2336 case 1: which = "first"; break;
2337 case 2: which = "second"; break;
2338 case 3: which = "third"; break;
2339 case 4: which = "fourth"; break;
2340 case 5: which = "fifth"; break;
2341
2342 case -1: which = "last"; break;
2343 }
2344
2345 if ( nWeek < -1 )
2346 {
2347 which += " from end";
2348 }
2349
2350 s.Printf("The %s %s of %s in %d",
2351 which.c_str(),
2352 wxDateTime::GetWeekDayName(wday).c_str(),
2353 wxDateTime::GetMonthName(month).c_str(),
2354 year);
2355
2356 return s;
2357 }
2358 };
2359
2360 // the array data was generated by the following python program
2361 /*
2362 from DateTime import *
2363 from whrandom import *
2364 from string import *
2365
2366 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
2367 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
2368
2369 week = DateTimeDelta(7)
2370
2371 for n in range(20):
2372 year = randint(1900, 2100)
2373 month = randint(1, 12)
2374 day = randint(1, 28)
2375 dt = DateTime(year, month, day)
2376 wday = dt.day_of_week
2377
2378 countFromEnd = choice([-1, 1])
2379 weekNum = 0;
2380
2381 while dt.month is month:
2382 dt = dt - countFromEnd * week
2383 weekNum = weekNum + countFromEnd
2384
2385 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
2386
2387 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
2388 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
2389 */
2390
2391 static const WeekDateTestData weekDatesTestData[] =
2392 {
2393 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
2394 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
2395 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
2396 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
2397 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
2398 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
2399 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
2400 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
2401 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
2402 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
2403 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
2404 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
2405 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
2406 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
2407 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
2408 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
2409 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
2410 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
2411 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
2412 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
2413 };
2414
2415 static const char *fmt = "%d-%b-%Y";
2416
2417 wxDateTime dt;
2418 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
2419 {
2420 const WeekDateTestData& wd = weekDatesTestData[n];
2421
2422 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
2423
2424 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
2425
2426 const Date& d = wd.date;
2427 if ( d.SameDay(dt.GetTm()) )
2428 {
2429 puts(" (ok)");
2430 }
2431 else
2432 {
2433 dt.Set(d.day, d.month, d.year);
2434
2435 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
2436 }
2437 }
2438 }
2439
2440 // test the computation of (ISO) week numbers
2441 static void TestTimeWNumber()
2442 {
2443 puts("\n*** wxDateTime week number test ***");
2444
2445 struct WeekNumberTestData
2446 {
2447 Date date; // the date
2448 wxDateTime::wxDateTime_t week; // the week number in the year
2449 wxDateTime::wxDateTime_t wmon; // the week number in the month
2450 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
2451 wxDateTime::wxDateTime_t dnum; // day number in the year
2452 };
2453
2454 // data generated with the following python script:
2455 /*
2456 from DateTime import *
2457 from whrandom import *
2458 from string import *
2459
2460 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
2461 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
2462
2463 def GetMonthWeek(dt):
2464 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
2465 if weekNumMonth < 0:
2466 weekNumMonth = weekNumMonth + 53
2467 return weekNumMonth
2468
2469 def GetLastSundayBefore(dt):
2470 if dt.iso_week[2] == 7:
2471 return dt
2472 else:
2473 return dt - DateTimeDelta(dt.iso_week[2])
2474
2475 for n in range(20):
2476 year = randint(1900, 2100)
2477 month = randint(1, 12)
2478 day = randint(1, 28)
2479 dt = DateTime(year, month, day)
2480 dayNum = dt.day_of_year
2481 weekNum = dt.iso_week[1]
2482 weekNumMonth = GetMonthWeek(dt)
2483
2484 weekNumMonth2 = 0
2485 dtSunday = GetLastSundayBefore(dt)
2486
2487 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
2488 weekNumMonth2 = weekNumMonth2 + 1
2489 dtSunday = dtSunday - DateTimeDelta(7)
2490
2491 data = { 'day': rjust(`day`, 2), \
2492 'month': monthNames[month - 1], \
2493 'year': year, \
2494 'weekNum': rjust(`weekNum`, 2), \
2495 'weekNumMonth': weekNumMonth, \
2496 'weekNumMonth2': weekNumMonth2, \
2497 'dayNum': rjust(`dayNum`, 3) }
2498
2499 print " { { %(day)s, "\
2500 "wxDateTime::%(month)s, "\
2501 "%(year)d }, "\
2502 "%(weekNum)s, "\
2503 "%(weekNumMonth)s, "\
2504 "%(weekNumMonth2)s, "\
2505 "%(dayNum)s }," % data
2506
2507 */
2508 static const WeekNumberTestData weekNumberTestDates[] =
2509 {
2510 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
2511 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
2512 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
2513 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
2514 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
2515 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
2516 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
2517 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
2518 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
2519 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
2520 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
2521 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
2522 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
2523 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
2524 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
2525 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
2526 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
2527 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
2528 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
2529 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
2530 };
2531
2532 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
2533 {
2534 const WeekNumberTestData& wn = weekNumberTestDates[n];
2535 const Date& d = wn.date;
2536
2537 wxDateTime dt = d.DT();
2538
2539 wxDateTime::wxDateTime_t
2540 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
2541 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
2542 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
2543 dnum = dt.GetDayOfYear();
2544
2545 printf("%s: the day number is %d",
2546 d.FormatDate().c_str(), dnum);
2547 if ( dnum == wn.dnum )
2548 {
2549 printf(" (ok)");
2550 }
2551 else
2552 {
2553 printf(" (ERROR: should be %d)", wn.dnum);
2554 }
2555
2556 printf(", week in month is %d", wmon);
2557 if ( wmon == wn.wmon )
2558 {
2559 printf(" (ok)");
2560 }
2561 else
2562 {
2563 printf(" (ERROR: should be %d)", wn.wmon);
2564 }
2565
2566 printf(" or %d", wmon2);
2567 if ( wmon2 == wn.wmon2 )
2568 {
2569 printf(" (ok)");
2570 }
2571 else
2572 {
2573 printf(" (ERROR: should be %d)", wn.wmon2);
2574 }
2575
2576 printf(", week in year is %d", week);
2577 if ( week == wn.week )
2578 {
2579 puts(" (ok)");
2580 }
2581 else
2582 {
2583 printf(" (ERROR: should be %d)\n", wn.week);
2584 }
2585 }
2586 }
2587
2588 // test DST calculations
2589 static void TestTimeDST()
2590 {
2591 puts("\n*** wxDateTime DST test ***");
2592
2593 printf("DST is%s in effect now.\n\n",
2594 wxDateTime::Now().IsDST() ? "" : " not");
2595
2596 // taken from http://www.energy.ca.gov/daylightsaving.html
2597 static const Date datesDST[2][2004 - 1900 + 1] =
2598 {
2599 {
2600 { 1, wxDateTime::Apr, 1990 },
2601 { 7, wxDateTime::Apr, 1991 },
2602 { 5, wxDateTime::Apr, 1992 },
2603 { 4, wxDateTime::Apr, 1993 },
2604 { 3, wxDateTime::Apr, 1994 },
2605 { 2, wxDateTime::Apr, 1995 },
2606 { 7, wxDateTime::Apr, 1996 },
2607 { 6, wxDateTime::Apr, 1997 },
2608 { 5, wxDateTime::Apr, 1998 },
2609 { 4, wxDateTime::Apr, 1999 },
2610 { 2, wxDateTime::Apr, 2000 },
2611 { 1, wxDateTime::Apr, 2001 },
2612 { 7, wxDateTime::Apr, 2002 },
2613 { 6, wxDateTime::Apr, 2003 },
2614 { 4, wxDateTime::Apr, 2004 },
2615 },
2616 {
2617 { 28, wxDateTime::Oct, 1990 },
2618 { 27, wxDateTime::Oct, 1991 },
2619 { 25, wxDateTime::Oct, 1992 },
2620 { 31, wxDateTime::Oct, 1993 },
2621 { 30, wxDateTime::Oct, 1994 },
2622 { 29, wxDateTime::Oct, 1995 },
2623 { 27, wxDateTime::Oct, 1996 },
2624 { 26, wxDateTime::Oct, 1997 },
2625 { 25, wxDateTime::Oct, 1998 },
2626 { 31, wxDateTime::Oct, 1999 },
2627 { 29, wxDateTime::Oct, 2000 },
2628 { 28, wxDateTime::Oct, 2001 },
2629 { 27, wxDateTime::Oct, 2002 },
2630 { 26, wxDateTime::Oct, 2003 },
2631 { 31, wxDateTime::Oct, 2004 },
2632 }
2633 };
2634
2635 int year;
2636 for ( year = 1990; year < 2005; year++ )
2637 {
2638 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
2639 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
2640
2641 printf("DST period in the US for year %d: from %s to %s",
2642 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
2643
2644 size_t n = year - 1990;
2645 const Date& dBegin = datesDST[0][n];
2646 const Date& dEnd = datesDST[1][n];
2647
2648 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
2649 {
2650 puts(" (ok)");
2651 }
2652 else
2653 {
2654 printf(" (ERROR: should be %s %d to %s %d)\n",
2655 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
2656 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
2657 }
2658 }
2659
2660 puts("");
2661
2662 for ( year = 1990; year < 2005; year++ )
2663 {
2664 printf("DST period in Europe for year %d: from %s to %s\n",
2665 year,
2666 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
2667 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
2668 }
2669 }
2670
2671 // test wxDateTime -> text conversion
2672 static void TestTimeFormat()
2673 {
2674 puts("\n*** wxDateTime formatting test ***");
2675
2676 // some information may be lost during conversion, so store what kind
2677 // of info should we recover after a round trip
2678 enum CompareKind
2679 {
2680 CompareNone, // don't try comparing
2681 CompareBoth, // dates and times should be identical
2682 CompareDate, // dates only
2683 CompareTime // time only
2684 };
2685
2686 static const struct
2687 {
2688 CompareKind compareKind;
2689 const char *format;
2690 } formatTestFormats[] =
2691 {
2692 { CompareBoth, "---> %c" },
2693 { CompareDate, "Date is %A, %d of %B, in year %Y" },
2694 { CompareBoth, "Date is %x, time is %X" },
2695 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
2696 { CompareNone, "The day of year: %j, the week of year: %W" },
2697 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
2698 };
2699
2700 static const Date formatTestDates[] =
2701 {
2702 { 29, wxDateTime::May, 1976, 18, 30, 00 },
2703 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
2704 #if 0
2705 // this test can't work for other centuries because it uses two digit
2706 // years in formats, so don't even try it
2707 { 29, wxDateTime::May, 2076, 18, 30, 00 },
2708 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
2709 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
2710 #endif
2711 };
2712
2713 // an extra test (as it doesn't depend on date, don't do it in the loop)
2714 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
2715
2716 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
2717 {
2718 puts("");
2719
2720 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
2721 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
2722 {
2723 wxString s = dt.Format(formatTestFormats[n].format);
2724 printf("%s", s.c_str());
2725
2726 // what can we recover?
2727 int kind = formatTestFormats[n].compareKind;
2728
2729 // convert back
2730 wxDateTime dt2;
2731 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
2732 if ( !result )
2733 {
2734 // converion failed - should it have?
2735 if ( kind == CompareNone )
2736 puts(" (ok)");
2737 else
2738 puts(" (ERROR: conversion back failed)");
2739 }
2740 else if ( *result )
2741 {
2742 // should have parsed the entire string
2743 puts(" (ERROR: conversion back stopped too soon)");
2744 }
2745 else
2746 {
2747 bool equal = FALSE; // suppress compilaer warning
2748 switch ( kind )
2749 {
2750 case CompareBoth:
2751 equal = dt2 == dt;
2752 break;
2753
2754 case CompareDate:
2755 equal = dt.IsSameDate(dt2);
2756 break;
2757
2758 case CompareTime:
2759 equal = dt.IsSameTime(dt2);
2760 break;
2761 }
2762
2763 if ( !equal )
2764 {
2765 printf(" (ERROR: got back '%s' instead of '%s')\n",
2766 dt2.Format().c_str(), dt.Format().c_str());
2767 }
2768 else
2769 {
2770 puts(" (ok)");
2771 }
2772 }
2773 }
2774 }
2775 }
2776
2777 // test text -> wxDateTime conversion
2778 static void TestTimeParse()
2779 {
2780 puts("\n*** wxDateTime parse test ***");
2781
2782 struct ParseTestData
2783 {
2784 const char *format;
2785 Date date;
2786 bool good;
2787 };
2788
2789 static const ParseTestData parseTestDates[] =
2790 {
2791 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
2792 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
2793 };
2794
2795 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
2796 {
2797 const char *format = parseTestDates[n].format;
2798
2799 printf("%s => ", format);
2800
2801 wxDateTime dt;
2802 if ( dt.ParseRfc822Date(format) )
2803 {
2804 printf("%s ", dt.Format().c_str());
2805
2806 if ( parseTestDates[n].good )
2807 {
2808 wxDateTime dtReal = parseTestDates[n].date.DT();
2809 if ( dt == dtReal )
2810 {
2811 puts("(ok)");
2812 }
2813 else
2814 {
2815 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
2816 }
2817 }
2818 else
2819 {
2820 puts("(ERROR: bad format)");
2821 }
2822 }
2823 else
2824 {
2825 printf("bad format (%s)\n",
2826 parseTestDates[n].good ? "ERROR" : "ok");
2827 }
2828 }
2829 }
2830
2831 static void TestInteractive()
2832 {
2833 puts("\n*** interactive wxDateTime tests ***");
2834
2835 char buf[128];
2836
2837 for ( ;; )
2838 {
2839 printf("Enter a date: ");
2840 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2841 break;
2842
2843 // kill the last '\n'
2844 buf[strlen(buf) - 1] = 0;
2845
2846 wxDateTime dt;
2847 const char *p = dt.ParseDate(buf);
2848 if ( !p )
2849 {
2850 printf("ERROR: failed to parse the date '%s'.\n", buf);
2851
2852 continue;
2853 }
2854 else if ( *p )
2855 {
2856 printf("WARNING: parsed only first %u characters.\n", p - buf);
2857 }
2858
2859 printf("%s: day %u, week of month %u/%u, week of year %u\n",
2860 dt.Format("%b %d, %Y").c_str(),
2861 dt.GetDayOfYear(),
2862 dt.GetWeekOfMonth(wxDateTime::Monday_First),
2863 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
2864 dt.GetWeekOfYear(wxDateTime::Monday_First));
2865 }
2866
2867 puts("\n*** done ***");
2868 }
2869
2870 static void TestTimeMS()
2871 {
2872 puts("*** testing millisecond-resolution support in wxDateTime ***");
2873
2874 wxDateTime dt1 = wxDateTime::Now(),
2875 dt2 = wxDateTime::UNow();
2876
2877 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
2878 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
2879 printf("Dummy loop: ");
2880 for ( int i = 0; i < 6000; i++ )
2881 {
2882 //for ( int j = 0; j < 10; j++ )
2883 {
2884 wxString s;
2885 s.Printf("%g", sqrt(i));
2886 }
2887
2888 if ( !(i % 100) )
2889 putchar('.');
2890 }
2891 puts(", done");
2892
2893 dt1 = dt2;
2894 dt2 = wxDateTime::UNow();
2895 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
2896
2897 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
2898
2899 puts("\n*** done ***");
2900 }
2901
2902 static void TestTimeArithmetics()
2903 {
2904 puts("\n*** testing arithmetic operations on wxDateTime ***");
2905
2906 static const struct ArithmData
2907 {
2908 ArithmData(const wxDateSpan& sp, const char *nam)
2909 : span(sp), name(nam) { }
2910
2911 wxDateSpan span;
2912 const char *name;
2913 } testArithmData[] =
2914 {
2915 ArithmData(wxDateSpan::Day(), "day"),
2916 ArithmData(wxDateSpan::Week(), "week"),
2917 ArithmData(wxDateSpan::Month(), "month"),
2918 ArithmData(wxDateSpan::Year(), "year"),
2919 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
2920 };
2921
2922 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
2923
2924 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
2925 {
2926 wxDateSpan span = testArithmData[n].span;
2927 dt1 = dt + span;
2928 dt2 = dt - span;
2929
2930 const char *name = testArithmData[n].name;
2931 printf("%s + %s = %s, %s - %s = %s\n",
2932 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
2933 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
2934
2935 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
2936 if ( dt1 - span == dt )
2937 {
2938 puts(" (ok)");
2939 }
2940 else
2941 {
2942 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
2943 }
2944
2945 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
2946 if ( dt2 + span == dt )
2947 {
2948 puts(" (ok)");
2949 }
2950 else
2951 {
2952 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
2953 }
2954
2955 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
2956 if ( dt2 + 2*span == dt1 )
2957 {
2958 puts(" (ok)");
2959 }
2960 else
2961 {
2962 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
2963 }
2964
2965 puts("");
2966 }
2967 }
2968
2969 static void TestTimeHolidays()
2970 {
2971 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
2972
2973 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
2974 wxDateTime dtStart(1, tm.mon, tm.year),
2975 dtEnd = dtStart.GetLastMonthDay();
2976
2977 wxDateTimeArray hol;
2978 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
2979
2980 const wxChar *format = "%d-%b-%Y (%a)";
2981
2982 printf("All holidays between %s and %s:\n",
2983 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
2984
2985 size_t count = hol.GetCount();
2986 for ( size_t n = 0; n < count; n++ )
2987 {
2988 printf("\t%s\n", hol[n].Format(format).c_str());
2989 }
2990
2991 puts("");
2992 }
2993
2994 static void TestTimeZoneBug()
2995 {
2996 puts("\n*** testing for DST/timezone bug ***\n");
2997
2998 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
2999 for ( int i = 0; i < 31; i++ )
3000 {
3001 printf("Date %s: week day %s.\n",
3002 date.Format(_T("%d-%m-%Y")).c_str(),
3003 date.GetWeekDayName(date.GetWeekDay()).c_str());
3004
3005 date += wxDateSpan::Day();
3006 }
3007
3008 puts("");
3009 }
3010
3011 #if 0
3012
3013 // test compatibility with the old wxDate/wxTime classes
3014 static void TestTimeCompatibility()
3015 {
3016 puts("\n*** wxDateTime compatibility test ***");
3017
3018 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
3019 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
3020
3021 double jdnNow = wxDateTime::Now().GetJDN();
3022 long jdnMidnight = (long)(jdnNow - 0.5);
3023 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
3024
3025 jdnMidnight = wxDate().Set().GetJulianDate();
3026 printf("wxDateTime for today: %s\n",
3027 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
3028
3029 int flags = wxEUROPEAN;//wxFULL;
3030 wxDate date;
3031 date.Set();
3032 printf("Today is %s\n", date.FormatDate(flags).c_str());
3033 for ( int n = 0; n < 7; n++ )
3034 {
3035 printf("Previous %s is %s\n",
3036 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
3037 date.Previous(n + 1).FormatDate(flags).c_str());
3038 }
3039 }
3040
3041 #endif // 0
3042
3043 #endif // TEST_DATETIME
3044
3045 // ----------------------------------------------------------------------------
3046 // threads
3047 // ----------------------------------------------------------------------------
3048
3049 #ifdef TEST_THREADS
3050
3051 #include <wx/thread.h>
3052
3053 static size_t gs_counter = (size_t)-1;
3054 static wxCriticalSection gs_critsect;
3055 static wxCondition gs_cond;
3056
3057 class MyJoinableThread : public wxThread
3058 {
3059 public:
3060 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3061 { m_n = n; Create(); }
3062
3063 // thread execution starts here
3064 virtual ExitCode Entry();
3065
3066 private:
3067 size_t m_n;
3068 };
3069
3070 wxThread::ExitCode MyJoinableThread::Entry()
3071 {
3072 unsigned long res = 1;
3073 for ( size_t n = 1; n < m_n; n++ )
3074 {
3075 res *= n;
3076
3077 // it's a loooong calculation :-)
3078 Sleep(100);
3079 }
3080
3081 return (ExitCode)res;
3082 }
3083
3084 class MyDetachedThread : public wxThread
3085 {
3086 public:
3087 MyDetachedThread(size_t n, char ch)
3088 {
3089 m_n = n;
3090 m_ch = ch;
3091 m_cancelled = FALSE;
3092
3093 Create();
3094 }
3095
3096 // thread execution starts here
3097 virtual ExitCode Entry();
3098
3099 // and stops here
3100 virtual void OnExit();
3101
3102 private:
3103 size_t m_n; // number of characters to write
3104 char m_ch; // character to write
3105
3106 bool m_cancelled; // FALSE if we exit normally
3107 };
3108
3109 wxThread::ExitCode MyDetachedThread::Entry()
3110 {
3111 {
3112 wxCriticalSectionLocker lock(gs_critsect);
3113 if ( gs_counter == (size_t)-1 )
3114 gs_counter = 1;
3115 else
3116 gs_counter++;
3117 }
3118
3119 for ( size_t n = 0; n < m_n; n++ )
3120 {
3121 if ( TestDestroy() )
3122 {
3123 m_cancelled = TRUE;
3124
3125 break;
3126 }
3127
3128 putchar(m_ch);
3129 fflush(stdout);
3130
3131 wxThread::Sleep(100);
3132 }
3133
3134 return 0;
3135 }
3136
3137 void MyDetachedThread::OnExit()
3138 {
3139 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
3140
3141 wxCriticalSectionLocker lock(gs_critsect);
3142 if ( !--gs_counter && !m_cancelled )
3143 gs_cond.Signal();
3144 }
3145
3146 void TestDetachedThreads()
3147 {
3148 puts("\n*** Testing detached threads ***");
3149
3150 static const size_t nThreads = 3;
3151 MyDetachedThread *threads[nThreads];
3152 size_t n;
3153 for ( n = 0; n < nThreads; n++ )
3154 {
3155 threads[n] = new MyDetachedThread(10, 'A' + n);
3156 }
3157
3158 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3159 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3160
3161 for ( n = 0; n < nThreads; n++ )
3162 {
3163 threads[n]->Run();
3164 }
3165
3166 // wait until all threads terminate
3167 gs_cond.Wait();
3168
3169 puts("");
3170 }
3171
3172 void TestJoinableThreads()
3173 {
3174 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
3175
3176 // calc 10! in the background
3177 MyJoinableThread thread(10);
3178 thread.Run();
3179
3180 printf("\nThread terminated with exit code %lu.\n",
3181 (unsigned long)thread.Wait());
3182 }
3183
3184 void TestThreadSuspend()
3185 {
3186 puts("\n*** Testing thread suspend/resume functions ***");
3187
3188 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3189
3190 thread->Run();
3191
3192 // this is for this demo only, in a real life program we'd use another
3193 // condition variable which would be signaled from wxThread::Entry() to
3194 // tell us that the thread really started running - but here just wait a
3195 // bit and hope that it will be enough (the problem is, of course, that
3196 // the thread might still not run when we call Pause() which will result
3197 // in an error)
3198 wxThread::Sleep(300);
3199
3200 for ( size_t n = 0; n < 3; n++ )
3201 {
3202 thread->Pause();
3203
3204 puts("\nThread suspended");
3205 if ( n > 0 )
3206 {
3207 // don't sleep but resume immediately the first time
3208 wxThread::Sleep(300);
3209 }
3210 puts("Going to resume the thread");
3211
3212 thread->Resume();
3213 }
3214
3215 puts("Waiting until it terminates now");
3216
3217 // wait until the thread terminates
3218 gs_cond.Wait();
3219
3220 puts("");
3221 }
3222
3223 void TestThreadDelete()
3224 {
3225 // As above, using Sleep() is only for testing here - we must use some
3226 // synchronisation object instead to ensure that the thread is still
3227 // running when we delete it - deleting a detached thread which already
3228 // terminated will lead to a crash!
3229
3230 puts("\n*** Testing thread delete function ***");
3231
3232 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
3233
3234 thread0->Delete();
3235
3236 puts("\nDeleted a thread which didn't start to run yet.");
3237
3238 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
3239
3240 thread1->Run();
3241
3242 wxThread::Sleep(300);
3243
3244 thread1->Delete();
3245
3246 puts("\nDeleted a running thread.");
3247
3248 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
3249
3250 thread2->Run();
3251
3252 wxThread::Sleep(300);
3253
3254 thread2->Pause();
3255
3256 thread2->Delete();
3257
3258 puts("\nDeleted a sleeping thread.");
3259
3260 MyJoinableThread thread3(20);
3261 thread3.Run();
3262
3263 thread3.Delete();
3264
3265 puts("\nDeleted a joinable thread.");
3266
3267 MyJoinableThread thread4(2);
3268 thread4.Run();
3269
3270 wxThread::Sleep(300);
3271
3272 thread4.Delete();
3273
3274 puts("\nDeleted a joinable thread which already terminated.");
3275
3276 puts("");
3277 }
3278
3279 #endif // TEST_THREADS
3280
3281 // ----------------------------------------------------------------------------
3282 // arrays
3283 // ----------------------------------------------------------------------------
3284
3285 #ifdef TEST_ARRAYS
3286
3287 static void PrintArray(const char* name, const wxArrayString& array)
3288 {
3289 printf("Dump of the array '%s'\n", name);
3290
3291 size_t nCount = array.GetCount();
3292 for ( size_t n = 0; n < nCount; n++ )
3293 {
3294 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
3295 }
3296 }
3297
3298 static void PrintArray(const char* name, const wxArrayInt& array)
3299 {
3300 printf("Dump of the array '%s'\n", name);
3301
3302 size_t nCount = array.GetCount();
3303 for ( size_t n = 0; n < nCount; n++ )
3304 {
3305 printf("\t%s[%u] = %d\n", name, n, array[n]);
3306 }
3307 }
3308
3309 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
3310 const wxString& second)
3311 {
3312 return first.length() - second.length();
3313 }
3314
3315 int wxCMPFUNC_CONV IntCompare(int *first,
3316 int *second)
3317 {
3318 return *first - *second;
3319 }
3320
3321 int wxCMPFUNC_CONV IntRevCompare(int *first,
3322 int *second)
3323 {
3324 return *second - *first;
3325 }
3326
3327 static void TestArrayOfInts()
3328 {
3329 puts("*** Testing wxArrayInt ***\n");
3330
3331 wxArrayInt a;
3332 a.Add(1);
3333 a.Add(17);
3334 a.Add(5);
3335 a.Add(3);
3336
3337 puts("Initially:");
3338 PrintArray("a", a);
3339
3340 puts("After sort:");
3341 a.Sort(IntCompare);
3342 PrintArray("a", a);
3343
3344 puts("After reverse sort:");
3345 a.Sort(IntRevCompare);
3346 PrintArray("a", a);
3347 }
3348
3349 #include "wx/dynarray.h"
3350
3351 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
3352 #include "wx/arrimpl.cpp"
3353 WX_DEFINE_OBJARRAY(ArrayBars);
3354
3355 static void TestArrayOfObjects()
3356 {
3357 puts("*** Testing wxObjArray ***\n");
3358
3359 {
3360 ArrayBars bars;
3361 Bar bar("second bar");
3362
3363 printf("Initially: %u objects in the array, %u objects total.\n",
3364 bars.GetCount(), Bar::GetNumber());
3365
3366 bars.Add(new Bar("first bar"));
3367 bars.Add(bar);
3368
3369 printf("Now: %u objects in the array, %u objects total.\n",
3370 bars.GetCount(), Bar::GetNumber());
3371
3372 bars.Empty();
3373
3374 printf("After Empty(): %u objects in the array, %u objects total.\n",
3375 bars.GetCount(), Bar::GetNumber());
3376 }
3377
3378 printf("Finally: no more objects in the array, %u objects total.\n",
3379 Bar::GetNumber());
3380 }
3381
3382 #endif // TEST_ARRAYS
3383
3384 // ----------------------------------------------------------------------------
3385 // strings
3386 // ----------------------------------------------------------------------------
3387
3388 #ifdef TEST_STRINGS
3389
3390 #include "wx/timer.h"
3391 #include "wx/tokenzr.h"
3392
3393 static void TestStringConstruction()
3394 {
3395 puts("*** Testing wxString constructores ***");
3396
3397 #define TEST_CTOR(args, res) \
3398 { \
3399 wxString s args ; \
3400 printf("wxString%s = %s ", #args, s.c_str()); \
3401 if ( s == res ) \
3402 { \
3403 puts("(ok)"); \
3404 } \
3405 else \
3406 { \
3407 printf("(ERROR: should be %s)\n", res); \
3408 } \
3409 }
3410
3411 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
3412 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
3413 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
3414 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
3415
3416 static const wxChar *s = _T("?really!");
3417 const wxChar *start = wxStrchr(s, _T('r'));
3418 const wxChar *end = wxStrchr(s, _T('!'));
3419 TEST_CTOR((start, end), _T("really"));
3420
3421 puts("");
3422 }
3423
3424 static void TestString()
3425 {
3426 wxStopWatch sw;
3427
3428 wxString a, b, c;
3429
3430 a.reserve (128);
3431 b.reserve (128);
3432 c.reserve (128);
3433
3434 for (int i = 0; i < 1000000; ++i)
3435 {
3436 a = "Hello";
3437 b = " world";
3438 c = "! How'ya doin'?";
3439 a += b;
3440 a += c;
3441 c = "Hello world! What's up?";
3442 if (c != a)
3443 c = "Doh!";
3444 }
3445
3446 printf ("TestString elapsed time: %ld\n", sw.Time());
3447 }
3448
3449 static void TestPChar()
3450 {
3451 wxStopWatch sw;
3452
3453 char a [128];
3454 char b [128];
3455 char c [128];
3456
3457 for (int i = 0; i < 1000000; ++i)
3458 {
3459 strcpy (a, "Hello");
3460 strcpy (b, " world");
3461 strcpy (c, "! How'ya doin'?");
3462 strcat (a, b);
3463 strcat (a, c);
3464 strcpy (c, "Hello world! What's up?");
3465 if (strcmp (c, a) == 0)
3466 strcpy (c, "Doh!");
3467 }
3468
3469 printf ("TestPChar elapsed time: %ld\n", sw.Time());
3470 }
3471
3472 static void TestStringSub()
3473 {
3474 wxString s("Hello, world!");
3475
3476 puts("*** Testing wxString substring extraction ***");
3477
3478 printf("String = '%s'\n", s.c_str());
3479 printf("Left(5) = '%s'\n", s.Left(5).c_str());
3480 printf("Right(6) = '%s'\n", s.Right(6).c_str());
3481 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
3482 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
3483 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
3484 printf("substr(3) = '%s'\n", s.substr(3).c_str());
3485
3486 static const wxChar *prefixes[] =
3487 {
3488 _T("Hello"),
3489 _T("Hello, "),
3490 _T("Hello, world!"),
3491 _T("Hello, world!!!"),
3492 _T(""),
3493 _T("Goodbye"),
3494 _T("Hi"),
3495 };
3496
3497 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
3498 {
3499 wxString prefix = prefixes[n], rest;
3500 bool rc = s.StartsWith(prefix, &rest);
3501 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
3502 if ( rc )
3503 {
3504 printf(" (the rest is '%s')\n", rest.c_str());
3505 }
3506 else
3507 {
3508 putchar('\n');
3509 }
3510 }
3511
3512 puts("");
3513 }
3514
3515 static void TestStringFormat()
3516 {
3517 puts("*** Testing wxString formatting ***");
3518
3519 wxString s;
3520 s.Printf("%03d", 18);
3521
3522 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
3523 printf("Number 18: %s\n", s.c_str());
3524
3525 puts("");
3526 }
3527
3528 // returns "not found" for npos, value for all others
3529 static wxString PosToString(size_t res)
3530 {
3531 wxString s = res == wxString::npos ? wxString(_T("not found"))
3532 : wxString::Format(_T("%u"), res);
3533 return s;
3534 }
3535
3536 static void TestStringFind()
3537 {
3538 puts("*** Testing wxString find() functions ***");
3539
3540 static const wxChar *strToFind = _T("ell");
3541 static const struct StringFindTest
3542 {
3543 const wxChar *str;
3544 size_t start,
3545 result; // of searching "ell" in str
3546 } findTestData[] =
3547 {
3548 { _T("Well, hello world"), 0, 1 },
3549 { _T("Well, hello world"), 6, 7 },
3550 { _T("Well, hello world"), 9, wxString::npos },
3551 };
3552
3553 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
3554 {
3555 const StringFindTest& ft = findTestData[n];
3556 size_t res = wxString(ft.str).find(strToFind, ft.start);
3557
3558 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
3559 strToFind, ft.str, ft.start, PosToString(res).c_str());
3560
3561 size_t resTrue = ft.result;
3562 if ( res == resTrue )
3563 {
3564 puts(_T("(ok)"));
3565 }
3566 else
3567 {
3568 printf(_T("(ERROR: should be %s)\n"),
3569 PosToString(resTrue).c_str());
3570 }
3571 }
3572
3573 puts("");
3574 }
3575
3576 static void TestStringTokenizer()
3577 {
3578 puts("*** Testing wxStringTokenizer ***");
3579
3580 static const wxChar *modeNames[] =
3581 {
3582 _T("default"),
3583 _T("return empty"),
3584 _T("return all empty"),
3585 _T("with delims"),
3586 _T("like strtok"),
3587 };
3588
3589 static const struct StringTokenizerTest
3590 {
3591 const wxChar *str; // string to tokenize
3592 const wxChar *delims; // delimiters to use
3593 size_t count; // count of token
3594 wxStringTokenizerMode mode; // how should we tokenize it
3595 } tokenizerTestData[] =
3596 {
3597 { _T(""), _T(" "), 0 },
3598 { _T("Hello, world"), _T(" "), 2 },
3599 { _T("Hello, world "), _T(" "), 2 },
3600 { _T("Hello, world"), _T(","), 2 },
3601 { _T("Hello, world!"), _T(",!"), 2 },
3602 { _T("Hello,, world!"), _T(",!"), 3 },
3603 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
3604 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
3605 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
3606 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
3607 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
3608 { _T("01/02/99"), _T("/-"), 3 },
3609 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
3610 };
3611
3612 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
3613 {
3614 const StringTokenizerTest& tt = tokenizerTestData[n];
3615 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
3616
3617 size_t count = tkz.CountTokens();
3618 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
3619 MakePrintable(tt.str).c_str(),
3620 count,
3621 MakePrintable(tt.delims).c_str(),
3622 modeNames[tkz.GetMode()]);
3623 if ( count == tt.count )
3624 {
3625 puts(_T("(ok)"));
3626 }
3627 else
3628 {
3629 printf(_T("(ERROR: should be %u)\n"), tt.count);
3630
3631 continue;
3632 }
3633
3634 // if we emulate strtok(), check that we do it correctly
3635 wxChar *buf, *s = NULL, *last;
3636
3637 if ( tkz.GetMode() == wxTOKEN_STRTOK )
3638 {
3639 buf = new wxChar[wxStrlen(tt.str) + 1];
3640 wxStrcpy(buf, tt.str);
3641
3642 s = wxStrtok(buf, tt.delims, &last);
3643 }
3644 else
3645 {
3646 buf = NULL;
3647 }
3648
3649 // now show the tokens themselves
3650 size_t count2 = 0;
3651 while ( tkz.HasMoreTokens() )
3652 {
3653 wxString token = tkz.GetNextToken();
3654
3655 printf(_T("\ttoken %u: '%s'"),
3656 ++count2,
3657 MakePrintable(token).c_str());
3658
3659 if ( buf )
3660 {
3661 if ( token == s )
3662 {
3663 puts(" (ok)");
3664 }
3665 else
3666 {
3667 printf(" (ERROR: should be %s)\n", s);
3668 }
3669
3670 s = wxStrtok(NULL, tt.delims, &last);
3671 }
3672 else
3673 {
3674 // nothing to compare with
3675 puts("");
3676 }
3677 }
3678
3679 if ( count2 != count )
3680 {
3681 puts(_T("\tERROR: token count mismatch"));
3682 }
3683
3684 delete [] buf;
3685 }
3686
3687 puts("");
3688 }
3689
3690 static void TestStringReplace()
3691 {
3692 puts("*** Testing wxString::replace ***");
3693
3694 static const struct StringReplaceTestData
3695 {
3696 const wxChar *original; // original test string
3697 size_t start, len; // the part to replace
3698 const wxChar *replacement; // the replacement string
3699 const wxChar *result; // and the expected result
3700 } stringReplaceTestData[] =
3701 {
3702 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
3703 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
3704 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
3705 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
3706 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
3707 };
3708
3709 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
3710 {
3711 const StringReplaceTestData data = stringReplaceTestData[n];
3712
3713 wxString original = data.original;
3714 original.replace(data.start, data.len, data.replacement);
3715
3716 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
3717 data.original, data.start, data.len, data.replacement,
3718 original.c_str());
3719
3720 if ( original == data.result )
3721 {
3722 puts("(ok)");
3723 }
3724 else
3725 {
3726 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
3727 }
3728 }
3729
3730 puts("");
3731 }
3732
3733 #endif // TEST_STRINGS
3734
3735 // ----------------------------------------------------------------------------
3736 // entry point
3737 // ----------------------------------------------------------------------------
3738
3739 int main(int argc, char **argv)
3740 {
3741 if ( !wxInitialize() )
3742 {
3743 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
3744 }
3745
3746 #ifdef TEST_USLEEP
3747 puts("Sleeping for 3 seconds... z-z-z-z-z...");
3748 wxUsleep(3000);
3749 #endif // TEST_USLEEP
3750
3751 #ifdef TEST_CMDLINE
3752 static const wxCmdLineEntryDesc cmdLineDesc[] =
3753 {
3754 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
3755 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
3756
3757 { wxCMD_LINE_OPTION, "o", "output", "output file" },
3758 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
3759 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
3760 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
3761
3762 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
3763 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
3764
3765 { wxCMD_LINE_NONE }
3766 };
3767
3768 wxCmdLineParser parser(cmdLineDesc, argc, argv);
3769
3770 parser.AddOption("project_name", "", "full path to project file",
3771 wxCMD_LINE_VAL_STRING,
3772 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
3773
3774 switch ( parser.Parse() )
3775 {
3776 case -1:
3777 wxLogMessage("Help was given, terminating.");
3778 break;
3779
3780 case 0:
3781 ShowCmdLine(parser);
3782 break;
3783
3784 default:
3785 wxLogMessage("Syntax error detected, aborting.");
3786 break;
3787 }
3788 #endif // TEST_CMDLINE
3789
3790 #ifdef TEST_STRINGS
3791 if ( 0 )
3792 {
3793 TestPChar();
3794 TestString();
3795 }
3796 TestStringSub();
3797 if ( 0 )
3798 {
3799 TestStringConstruction();
3800 TestStringFormat();
3801 TestStringFind();
3802 TestStringTokenizer();
3803 TestStringReplace();
3804 }
3805 #endif // TEST_STRINGS
3806
3807 #ifdef TEST_ARRAYS
3808 if ( 0 )
3809 {
3810 wxArrayString a1;
3811 a1.Add("tiger");
3812 a1.Add("cat");
3813 a1.Add("lion");
3814 a1.Add("dog");
3815 a1.Add("human");
3816 a1.Add("ape");
3817
3818 puts("*** Initially:");
3819
3820 PrintArray("a1", a1);
3821
3822 wxArrayString a2(a1);
3823 PrintArray("a2", a2);
3824
3825 wxSortedArrayString a3(a1);
3826 PrintArray("a3", a3);
3827
3828 puts("*** After deleting a string from a1");
3829 a1.Remove(2);
3830
3831 PrintArray("a1", a1);
3832 PrintArray("a2", a2);
3833 PrintArray("a3", a3);
3834
3835 puts("*** After reassigning a1 to a2 and a3");
3836 a3 = a2 = a1;
3837 PrintArray("a2", a2);
3838 PrintArray("a3", a3);
3839
3840 puts("*** After sorting a1");
3841 a1.Sort();
3842 PrintArray("a1", a1);
3843
3844 puts("*** After sorting a1 in reverse order");
3845 a1.Sort(TRUE);
3846 PrintArray("a1", a1);
3847
3848 puts("*** After sorting a1 by the string length");
3849 a1.Sort(StringLenCompare);
3850 PrintArray("a1", a1);
3851
3852 TestArrayOfObjects();
3853 }
3854 TestArrayOfInts();
3855 #endif // TEST_ARRAYS
3856
3857 #ifdef TEST_DIR
3858 TestDirEnum();
3859 #endif // TEST_DIR
3860
3861 #ifdef TEST_DLLLOADER
3862 TestDllLoad();
3863 #endif // TEST_DLLLOADER
3864
3865 #ifdef TEST_ENVIRON
3866 TestEnvironment();
3867 #endif // TEST_ENVIRON
3868
3869 #ifdef TEST_EXECUTE
3870 TestExecute();
3871 #endif // TEST_EXECUTE
3872
3873 #ifdef TEST_FILECONF
3874 TestFileConfRead();
3875 #endif // TEST_FILECONF
3876
3877 #ifdef TEST_LIST
3878 TestListCtor();
3879 #endif // TEST_LIST
3880
3881 #ifdef TEST_LOG
3882 wxString s;
3883 for ( size_t n = 0; n < 8000; n++ )
3884 {
3885 s << (char)('A' + (n % 26));
3886 }
3887
3888 wxString msg;
3889 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
3890
3891 // this one shouldn't be truncated
3892 printf(msg);
3893
3894 // but this one will because log functions use fixed size buffer
3895 // (note that it doesn't need '\n' at the end neither - will be added
3896 // by wxLog anyhow)
3897 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
3898 #endif // TEST_LOG
3899
3900 #ifdef TEST_FILE
3901 if ( 0 )
3902 {
3903 TestFileRead();
3904 TestTextFileRead();
3905 }
3906 TestFileCopy();
3907 #endif // TEST_FILE
3908
3909 #ifdef TEST_THREADS
3910 int nCPUs = wxThread::GetCPUCount();
3911 printf("This system has %d CPUs\n", nCPUs);
3912 if ( nCPUs != -1 )
3913 wxThread::SetConcurrency(nCPUs);
3914
3915 if ( argc > 1 && argv[1][0] == 't' )
3916 wxLog::AddTraceMask("thread");
3917
3918 if ( 1 )
3919 TestDetachedThreads();
3920 if ( 1 )
3921 TestJoinableThreads();
3922 if ( 1 )
3923 TestThreadSuspend();
3924 if ( 1 )
3925 TestThreadDelete();
3926
3927 #endif // TEST_THREADS
3928
3929 #ifdef TEST_LONGLONG
3930 // seed pseudo random generator
3931 srand((unsigned)time(NULL));
3932
3933 if ( 0 )
3934 {
3935 TestSpeed();
3936 }
3937 if ( 0 )
3938 {
3939 TestMultiplication();
3940 TestDivision();
3941 TestAddition();
3942 TestLongLongConversion();
3943 TestBitOperations();
3944 }
3945 TestLongLongComparison();
3946 #endif // TEST_LONGLONG
3947
3948 #ifdef TEST_HASH
3949 TestHash();
3950 #endif // TEST_HASH
3951
3952 #ifdef TEST_MIME
3953 wxLog::AddTraceMask(_T("mime"));
3954 if ( 0 )
3955 {
3956 TestMimeEnum();
3957 TestMimeOverride();
3958 TestMimeFilename();
3959 }
3960 TestMimeAssociate();
3961 #endif // TEST_MIME
3962
3963 #ifdef TEST_INFO_FUNCTIONS
3964 TestOsInfo();
3965 TestUserInfo();
3966 #endif // TEST_INFO_FUNCTIONS
3967
3968 #ifdef TEST_REGISTRY
3969 if ( 0 )
3970 TestRegistryRead();
3971 TestRegistryAssociation();
3972 #endif // TEST_REGISTRY
3973
3974 #ifdef TEST_SOCKETS
3975 if ( 0 )
3976 {
3977 TestSocketServer();
3978 }
3979 TestSocketClient();
3980 #endif // TEST_SOCKETS
3981
3982 #ifdef TEST_FTP
3983 wxLog::AddTraceMask(_T("ftp"));
3984 TestProtocolFtp();
3985 if ( 0 )
3986 TestProtocolFtpUpload();
3987 #endif // TEST_FTP
3988
3989 #ifdef TEST_STREAMS
3990 TestMemoryStream();
3991 #endif // TEST_STREAMS
3992
3993 #ifdef TEST_TIMER
3994 TestStopWatch();
3995 #endif // TEST_TIMER
3996
3997 #ifdef TEST_DATETIME
3998 if ( 0 )
3999 {
4000 TestTimeSet();
4001 TestTimeStatic();
4002 TestTimeRange();
4003 TestTimeZones();
4004 TestTimeTicks();
4005 TestTimeJDN();
4006 TestTimeDST();
4007 TestTimeWDays();
4008 TestTimeWNumber();
4009 TestTimeParse();
4010 TestTimeArithmetics();
4011 TestTimeHolidays();
4012 TestTimeFormat();
4013 TestTimeMS();
4014
4015 TestTimeZoneBug();
4016 }
4017 if ( 0 )
4018 TestInteractive();
4019 #endif // TEST_DATETIME
4020
4021 #ifdef TEST_VCARD
4022 if ( 0 )
4023 TestVCardRead();
4024 TestVCardWrite();
4025 #endif // TEST_VCARD
4026
4027 #ifdef TEST_WCHAR
4028 TestUtf8();
4029 #endif // TEST_WCHAR
4030
4031 #ifdef TEST_ZIP
4032 TestZipStreamRead();
4033 #endif // TEST_ZIP
4034
4035 #ifdef TEST_ZLIB
4036 if ( 0 )
4037 TestZlibStreamWrite();
4038 TestZlibStreamRead();
4039 #endif // TEST_ZLIB
4040
4041 wxUninitialize();
4042
4043 return 0;
4044 }
4045