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