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