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