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