]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
c89655a18106bc7d4347cf18dfec55036b82bdb9
[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 for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ )
1177 {
1178 const char *langStr = langStrings[n];
1179 if ( langStr )
1180 wxSetEnv(_T("LC_ALL"), langStr);
1181
1182 int lang = gs_localeDefault.GetSystemLanguage();
1183 printf("Locale for '%s' is %s.\n",
1184 langStr ? langStr : "system default", GetLangName(lang));
1185 }
1186 }
1187
1188 #endif // TEST_LOCALE
1189
1190 // ----------------------------------------------------------------------------
1191 // MIME types
1192 // ----------------------------------------------------------------------------
1193
1194 #ifdef TEST_MIME
1195
1196 #include <wx/mimetype.h>
1197
1198 static void TestMimeEnum()
1199 {
1200 wxPuts(_T("*** Testing wxMimeTypesManager::EnumAllFileTypes() ***\n"));
1201
1202 wxArrayString mimetypes;
1203
1204 size_t count = wxTheMimeTypesManager->EnumAllFileTypes(mimetypes);
1205
1206 printf("*** All %u known filetypes: ***\n", count);
1207
1208 wxArrayString exts;
1209 wxString desc;
1210
1211 for ( size_t n = 0; n < count; n++ )
1212 {
1213 wxFileType *filetype =
1214 wxTheMimeTypesManager->GetFileTypeFromMimeType(mimetypes[n]);
1215 if ( !filetype )
1216 {
1217 printf("nothing known about the filetype '%s'!\n",
1218 mimetypes[n].c_str());
1219 continue;
1220 }
1221
1222 filetype->GetDescription(&desc);
1223 filetype->GetExtensions(exts);
1224
1225 filetype->GetIcon(NULL);
1226
1227 wxString extsAll;
1228 for ( size_t e = 0; e < exts.GetCount(); e++ )
1229 {
1230 if ( e > 0 )
1231 extsAll << _T(", ");
1232 extsAll += exts[e];
1233 }
1234
1235 printf("\t%s: %s (%s)\n",
1236 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
1237 }
1238
1239 puts("");
1240 }
1241
1242 static void TestMimeOverride()
1243 {
1244 wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
1245
1246 static const wxChar *mailcap = _T("/tmp/mailcap");
1247 static const wxChar *mimetypes = _T("/tmp/mime.types");
1248
1249 if ( wxFile::Exists(mailcap) )
1250 wxPrintf(_T("Loading mailcap from '%s': %s\n"),
1251 mailcap,
1252 wxTheMimeTypesManager->ReadMailcap(mailcap) ? _T("ok") : _T("ERROR"));
1253 else
1254 wxPrintf(_T("WARN: mailcap file '%s' doesn't exist, not loaded.\n"),
1255 mailcap);
1256
1257 if ( wxFile::Exists(mimetypes) )
1258 wxPrintf(_T("Loading mime.types from '%s': %s\n"),
1259 mimetypes,
1260 wxTheMimeTypesManager->ReadMimeTypes(mimetypes) ? _T("ok") : _T("ERROR"));
1261 else
1262 wxPrintf(_T("WARN: mime.types file '%s' doesn't exist, not loaded.\n"),
1263 mimetypes);
1264
1265 puts("");
1266 }
1267
1268 static void TestMimeFilename()
1269 {
1270 wxPuts(_T("*** Testing MIME type from filename query ***\n"));
1271
1272 static const wxChar *filenames[] =
1273 {
1274 _T("readme.txt"),
1275 _T("document.pdf"),
1276 _T("image.gif"),
1277 };
1278
1279 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
1280 {
1281 const wxString fname = filenames[n];
1282 wxString ext = fname.AfterLast(_T('.'));
1283 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
1284 if ( !ft )
1285 {
1286 wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext.c_str());
1287 }
1288 else
1289 {
1290 wxString desc;
1291 if ( !ft->GetDescription(&desc) )
1292 desc = _T("<no description>");
1293
1294 wxString cmd;
1295 if ( !ft->GetOpenCommand(&cmd,
1296 wxFileType::MessageParameters(fname, _T(""))) )
1297 cmd = _T("<no command available>");
1298
1299 wxPrintf(_T("To open %s (%s) do '%s'.\n"),
1300 fname.c_str(), desc.c_str(), cmd.c_str());
1301
1302 delete ft;
1303 }
1304 }
1305
1306 puts("");
1307 }
1308
1309 static void TestMimeAssociate()
1310 {
1311 wxPuts(_T("*** Testing creation of filetype association ***\n"));
1312
1313 wxFileTypeInfo ftInfo(
1314 _T("application/x-xyz"),
1315 _T("xyzview '%s'"), // open cmd
1316 _T(""), // print cmd
1317 _T("XYZ File") // description
1318 _T(".xyz"), // extensions
1319 NULL // end of extensions
1320 );
1321 ftInfo.SetShortDesc(_T("XYZFile")); // used under Win32 only
1322
1323 wxFileType *ft = wxTheMimeTypesManager->Associate(ftInfo);
1324 if ( !ft )
1325 {
1326 wxPuts(_T("ERROR: failed to create association!"));
1327 }
1328 else
1329 {
1330 // TODO: read it back
1331 delete ft;
1332 }
1333
1334 puts("");
1335 }
1336
1337 #endif // TEST_MIME
1338
1339 // ----------------------------------------------------------------------------
1340 // misc information functions
1341 // ----------------------------------------------------------------------------
1342
1343 #ifdef TEST_INFO_FUNCTIONS
1344
1345 #include <wx/utils.h>
1346
1347 static void TestOsInfo()
1348 {
1349 puts("*** Testing OS info functions ***\n");
1350
1351 int major, minor;
1352 wxGetOsVersion(&major, &minor);
1353 printf("Running under: %s, version %d.%d\n",
1354 wxGetOsDescription().c_str(), major, minor);
1355
1356 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
1357
1358 printf("Host name is %s (%s).\n",
1359 wxGetHostName().c_str(), wxGetFullHostName().c_str());
1360
1361 puts("");
1362 }
1363
1364 static void TestUserInfo()
1365 {
1366 puts("*** Testing user info functions ***\n");
1367
1368 printf("User id is:\t%s\n", wxGetUserId().c_str());
1369 printf("User name is:\t%s\n", wxGetUserName().c_str());
1370 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
1371 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
1372
1373 puts("");
1374 }
1375
1376 #endif // TEST_INFO_FUNCTIONS
1377
1378 // ----------------------------------------------------------------------------
1379 // long long
1380 // ----------------------------------------------------------------------------
1381
1382 #ifdef TEST_LONGLONG
1383
1384 #include <wx/longlong.h>
1385 #include <wx/timer.h>
1386
1387 // make a 64 bit number from 4 16 bit ones
1388 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1389
1390 // get a random 64 bit number
1391 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1392
1393 #if wxUSE_LONGLONG_WX
1394 inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
1395 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1396 inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
1397 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1398 #endif // wxUSE_LONGLONG_WX
1399
1400 static void TestSpeed()
1401 {
1402 static const long max = 100000000;
1403 long n;
1404
1405 {
1406 wxStopWatch sw;
1407
1408 long l = 0;
1409 for ( n = 0; n < max; n++ )
1410 {
1411 l += n;
1412 }
1413
1414 printf("Summing longs took %ld milliseconds.\n", sw.Time());
1415 }
1416
1417 #if wxUSE_LONGLONG_NATIVE
1418 {
1419 wxStopWatch sw;
1420
1421 wxLongLong_t l = 0;
1422 for ( n = 0; n < max; n++ )
1423 {
1424 l += n;
1425 }
1426
1427 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
1428 }
1429 #endif // wxUSE_LONGLONG_NATIVE
1430
1431 {
1432 wxStopWatch sw;
1433
1434 wxLongLong l;
1435 for ( n = 0; n < max; n++ )
1436 {
1437 l += n;
1438 }
1439
1440 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
1441 }
1442 }
1443
1444 static void TestLongLongConversion()
1445 {
1446 puts("*** Testing wxLongLong conversions ***\n");
1447
1448 wxLongLong a;
1449 size_t nTested = 0;
1450 for ( size_t n = 0; n < 100000; n++ )
1451 {
1452 a = RAND_LL();
1453
1454 #if wxUSE_LONGLONG_NATIVE
1455 wxLongLongNative b(a.GetHi(), a.GetLo());
1456
1457 wxASSERT_MSG( a == b, "conversions failure" );
1458 #else
1459 puts("Can't do it without native long long type, test skipped.");
1460
1461 return;
1462 #endif // wxUSE_LONGLONG_NATIVE
1463
1464 if ( !(nTested % 1000) )
1465 {
1466 putchar('.');
1467 fflush(stdout);
1468 }
1469
1470 nTested++;
1471 }
1472
1473 puts(" done!");
1474 }
1475
1476 static void TestMultiplication()
1477 {
1478 puts("*** Testing wxLongLong multiplication ***\n");
1479
1480 wxLongLong a, b;
1481 size_t nTested = 0;
1482 for ( size_t n = 0; n < 100000; n++ )
1483 {
1484 a = RAND_LL();
1485 b = RAND_LL();
1486
1487 #if wxUSE_LONGLONG_NATIVE
1488 wxLongLongNative aa(a.GetHi(), a.GetLo());
1489 wxLongLongNative bb(b.GetHi(), b.GetLo());
1490
1491 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
1492 #else // !wxUSE_LONGLONG_NATIVE
1493 puts("Can't do it without native long long type, test skipped.");
1494
1495 return;
1496 #endif // wxUSE_LONGLONG_NATIVE
1497
1498 if ( !(nTested % 1000) )
1499 {
1500 putchar('.');
1501 fflush(stdout);
1502 }
1503
1504 nTested++;
1505 }
1506
1507 puts(" done!");
1508 }
1509
1510 static void TestDivision()
1511 {
1512 puts("*** Testing wxLongLong division ***\n");
1513
1514 wxLongLong q, r;
1515 size_t nTested = 0;
1516 for ( size_t n = 0; n < 100000; n++ )
1517 {
1518 // get a random wxLongLong (shifting by 12 the MSB ensures that the
1519 // multiplication will not overflow)
1520 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
1521
1522 // get a random long (not wxLongLong for now) to divide it with
1523 long l = rand();
1524 q = ll / l;
1525 r = ll % l;
1526
1527 #if wxUSE_LONGLONG_NATIVE
1528 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1529
1530 wxLongLongNative p = m / l, s = m % l;
1531 wxASSERT_MSG( q == p && r == s, "division failure" );
1532 #else // !wxUSE_LONGLONG_NATIVE
1533 // verify the result
1534 wxASSERT_MSG( ll == q*l + r, "division failure" );
1535 #endif // wxUSE_LONGLONG_NATIVE
1536
1537 if ( !(nTested % 1000) )
1538 {
1539 putchar('.');
1540 fflush(stdout);
1541 }
1542
1543 nTested++;
1544 }
1545
1546 puts(" done!");
1547 }
1548
1549 static void TestAddition()
1550 {
1551 puts("*** Testing wxLongLong addition ***\n");
1552
1553 wxLongLong a, b, c;
1554 size_t nTested = 0;
1555 for ( size_t n = 0; n < 100000; n++ )
1556 {
1557 a = RAND_LL();
1558 b = RAND_LL();
1559 c = a + b;
1560
1561 #if wxUSE_LONGLONG_NATIVE
1562 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1563 wxLongLongNative(b.GetHi(), b.GetLo()),
1564 "addition failure" );
1565 #else // !wxUSE_LONGLONG_NATIVE
1566 wxASSERT_MSG( c - b == a, "addition failure" );
1567 #endif // wxUSE_LONGLONG_NATIVE
1568
1569 if ( !(nTested % 1000) )
1570 {
1571 putchar('.');
1572 fflush(stdout);
1573 }
1574
1575 nTested++;
1576 }
1577
1578 puts(" done!");
1579 }
1580
1581 static void TestBitOperations()
1582 {
1583 puts("*** Testing wxLongLong bit operation ***\n");
1584
1585 wxLongLong ll;
1586 size_t nTested = 0;
1587 for ( size_t n = 0; n < 100000; n++ )
1588 {
1589 ll = RAND_LL();
1590
1591 #if wxUSE_LONGLONG_NATIVE
1592 for ( size_t n = 0; n < 33; n++ )
1593 {
1594 }
1595 #else // !wxUSE_LONGLONG_NATIVE
1596 puts("Can't do it without native long long type, test skipped.");
1597
1598 return;
1599 #endif // wxUSE_LONGLONG_NATIVE
1600
1601 if ( !(nTested % 1000) )
1602 {
1603 putchar('.');
1604 fflush(stdout);
1605 }
1606
1607 nTested++;
1608 }
1609
1610 puts(" done!");
1611 }
1612
1613 static void TestLongLongComparison()
1614 {
1615 puts("*** Testing wxLongLong comparison ***\n");
1616
1617 static const long testLongs[] =
1618 {
1619 0,
1620 1,
1621 -1,
1622 LONG_MAX,
1623 LONG_MIN,
1624 0x1234,
1625 -0x1234
1626 };
1627
1628 static const long ls[2] =
1629 {
1630 0x1234,
1631 -0x1234,
1632 };
1633
1634 wxLongLongWx lls[2];
1635 lls[0] = ls[0];
1636 lls[1] = ls[1];
1637
1638 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1639 {
1640 bool res;
1641
1642 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
1643 {
1644 res = lls[m] > testLongs[n];
1645 printf("0x%lx > 0x%lx is %s (%s)\n",
1646 ls[m], testLongs[n], res ? "true" : "false",
1647 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
1648
1649 res = lls[m] < testLongs[n];
1650 printf("0x%lx < 0x%lx is %s (%s)\n",
1651 ls[m], testLongs[n], res ? "true" : "false",
1652 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
1653
1654 res = lls[m] == testLongs[n];
1655 printf("0x%lx == 0x%lx is %s (%s)\n",
1656 ls[m], testLongs[n], res ? "true" : "false",
1657 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
1658 }
1659 }
1660 }
1661
1662 #undef MAKE_LL
1663 #undef RAND_LL
1664
1665 #endif // TEST_LONGLONG
1666
1667 // ----------------------------------------------------------------------------
1668 // path list
1669 // ----------------------------------------------------------------------------
1670
1671 #ifdef TEST_PATHLIST
1672
1673 static void TestPathList()
1674 {
1675 puts("*** Testing wxPathList ***\n");
1676
1677 wxPathList pathlist;
1678 pathlist.AddEnvList("PATH");
1679 wxString path = pathlist.FindValidPath("ls");
1680 if ( path.empty() )
1681 {
1682 printf("ERROR: command not found in the path.\n");
1683 }
1684 else
1685 {
1686 printf("Command found in the path as '%s'.\n", path.c_str());
1687 }
1688 }
1689
1690 #endif // TEST_PATHLIST
1691
1692 // ----------------------------------------------------------------------------
1693 // registry and related stuff
1694 // ----------------------------------------------------------------------------
1695
1696 // this is for MSW only
1697 #ifndef __WXMSW__
1698 #undef TEST_REGCONF
1699 #undef TEST_REGISTRY
1700 #endif
1701
1702 #ifdef TEST_REGCONF
1703
1704 #include <wx/confbase.h>
1705 #include <wx/msw/regconf.h>
1706
1707 static void TestRegConfWrite()
1708 {
1709 wxRegConfig regconf(_T("console"), _T("wxwindows"));
1710 regconf.Write(_T("Hello"), wxString(_T("world")));
1711 }
1712
1713 #endif // TEST_REGCONF
1714
1715 #ifdef TEST_REGISTRY
1716
1717 #include <wx/msw/registry.h>
1718
1719 // I chose this one because I liked its name, but it probably only exists under
1720 // NT
1721 static const wxChar *TESTKEY =
1722 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
1723
1724 static void TestRegistryRead()
1725 {
1726 puts("*** testing registry reading ***");
1727
1728 wxRegKey key(TESTKEY);
1729 printf("The test key name is '%s'.\n", key.GetName().c_str());
1730 if ( !key.Open() )
1731 {
1732 puts("ERROR: test key can't be opened, aborting test.");
1733
1734 return;
1735 }
1736
1737 size_t nSubKeys, nValues;
1738 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
1739 {
1740 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
1741 }
1742
1743 printf("Enumerating values:\n");
1744
1745 long dummy;
1746 wxString value;
1747 bool cont = key.GetFirstValue(value, dummy);
1748 while ( cont )
1749 {
1750 printf("Value '%s': type ", value.c_str());
1751 switch ( key.GetValueType(value) )
1752 {
1753 case wxRegKey::Type_None: printf("ERROR (none)"); break;
1754 case wxRegKey::Type_String: printf("SZ"); break;
1755 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
1756 case wxRegKey::Type_Binary: printf("BINARY"); break;
1757 case wxRegKey::Type_Dword: printf("DWORD"); break;
1758 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
1759 default: printf("other (unknown)"); break;
1760 }
1761
1762 printf(", value = ");
1763 if ( key.IsNumericValue(value) )
1764 {
1765 long val;
1766 key.QueryValue(value, &val);
1767 printf("%ld", val);
1768 }
1769 else // string
1770 {
1771 wxString val;
1772 key.QueryValue(value, val);
1773 printf("'%s'", val.c_str());
1774
1775 key.QueryRawValue(value, val);
1776 printf(" (raw value '%s')", val.c_str());
1777 }
1778
1779 putchar('\n');
1780
1781 cont = key.GetNextValue(value, dummy);
1782 }
1783 }
1784
1785 static void TestRegistryAssociation()
1786 {
1787 /*
1788 The second call to deleteself genertaes an error message, with a
1789 messagebox saying .flo is crucial to system operation, while the .ddf
1790 call also fails, but with no error message
1791 */
1792
1793 wxRegKey key;
1794
1795 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
1796 key.Create();
1797 key = "ddxf_auto_file" ;
1798 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
1799 key.Create();
1800 key = "ddxf_auto_file" ;
1801 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
1802 key.Create();
1803 key = "program,0" ;
1804 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
1805 key.Create();
1806 key = "program \"%1\"" ;
1807
1808 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
1809 key.DeleteSelf();
1810 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
1811 key.DeleteSelf();
1812 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
1813 key.DeleteSelf();
1814 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
1815 key.DeleteSelf();
1816 }
1817
1818 #endif // TEST_REGISTRY
1819
1820 // ----------------------------------------------------------------------------
1821 // sockets
1822 // ----------------------------------------------------------------------------
1823
1824 #ifdef TEST_SOCKETS
1825
1826 #include <wx/socket.h>
1827 #include <wx/protocol/protocol.h>
1828 #include <wx/protocol/http.h>
1829
1830 static void TestSocketServer()
1831 {
1832 puts("*** Testing wxSocketServer ***\n");
1833
1834 static const int PORT = 3000;
1835
1836 wxIPV4address addr;
1837 addr.Service(PORT);
1838
1839 wxSocketServer *server = new wxSocketServer(addr);
1840 if ( !server->Ok() )
1841 {
1842 puts("ERROR: failed to bind");
1843
1844 return;
1845 }
1846
1847 for ( ;; )
1848 {
1849 printf("Server: waiting for connection on port %d...\n", PORT);
1850
1851 wxSocketBase *socket = server->Accept();
1852 if ( !socket )
1853 {
1854 puts("ERROR: wxSocketServer::Accept() failed.");
1855 break;
1856 }
1857
1858 puts("Server: got a client.");
1859
1860 server->SetTimeout(60); // 1 min
1861
1862 while ( socket->IsConnected() )
1863 {
1864 wxString s;
1865 char ch = '\0';
1866 for ( ;; )
1867 {
1868 if ( socket->Read(&ch, sizeof(ch)).Error() )
1869 {
1870 // don't log error if the client just close the connection
1871 if ( socket->IsConnected() )
1872 {
1873 puts("ERROR: in wxSocket::Read.");
1874 }
1875
1876 break;
1877 }
1878
1879 if ( ch == '\r' )
1880 continue;
1881
1882 if ( ch == '\n' )
1883 break;
1884
1885 s += ch;
1886 }
1887
1888 if ( ch != '\n' )
1889 {
1890 break;
1891 }
1892
1893 printf("Server: got '%s'.\n", s.c_str());
1894 if ( s == _T("bye") )
1895 {
1896 delete socket;
1897
1898 break;
1899 }
1900
1901 socket->Write(s.MakeUpper().c_str(), s.length());
1902 socket->Write("\r\n", 2);
1903 printf("Server: wrote '%s'.\n", s.c_str());
1904 }
1905
1906 puts("Server: lost a client.");
1907
1908 socket->Destroy();
1909 }
1910
1911 // same as "delete server" but is consistent with GUI programs
1912 server->Destroy();
1913 }
1914
1915 static void TestSocketClient()
1916 {
1917 puts("*** Testing wxSocketClient ***\n");
1918
1919 static const char *hostname = "www.wxwindows.org";
1920
1921 wxIPV4address addr;
1922 addr.Hostname(hostname);
1923 addr.Service(80);
1924
1925 printf("--- Attempting to connect to %s:80...\n", hostname);
1926
1927 wxSocketClient client;
1928 if ( !client.Connect(addr) )
1929 {
1930 printf("ERROR: failed to connect to %s\n", hostname);
1931 }
1932 else
1933 {
1934 printf("--- Connected to %s:%u...\n",
1935 addr.Hostname().c_str(), addr.Service());
1936
1937 char buf[8192];
1938
1939 // could use simply "GET" here I suppose
1940 wxString cmdGet =
1941 wxString::Format("GET http://%s/\r\n", hostname);
1942 client.Write(cmdGet, cmdGet.length());
1943 printf("--- Sent command '%s' to the server\n",
1944 MakePrintable(cmdGet).c_str());
1945 client.Read(buf, WXSIZEOF(buf));
1946 printf("--- Server replied:\n%s", buf);
1947 }
1948 }
1949
1950 #endif // TEST_SOCKETS
1951
1952 // ----------------------------------------------------------------------------
1953 // FTP
1954 // ----------------------------------------------------------------------------
1955
1956 #ifdef TEST_FTP
1957
1958 #include <wx/protocol/ftp.h>
1959
1960 static wxFTP ftp;
1961
1962 #define FTP_ANONYMOUS
1963
1964 #ifdef FTP_ANONYMOUS
1965 static const char *directory = "/pub";
1966 static const char *filename = "welcome.msg";
1967 #else
1968 static const char *directory = "/etc";
1969 static const char *filename = "issue";
1970 #endif
1971
1972 static bool TestFtpConnect()
1973 {
1974 puts("*** Testing FTP connect ***");
1975
1976 #ifdef FTP_ANONYMOUS
1977 static const char *hostname = "ftp.wxwindows.org";
1978
1979 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
1980 #else // !FTP_ANONYMOUS
1981 static const char *hostname = "localhost";
1982
1983 char user[256];
1984 fgets(user, WXSIZEOF(user), stdin);
1985 user[strlen(user) - 1] = '\0'; // chop off '\n'
1986 ftp.SetUser(user);
1987
1988 char password[256];
1989 printf("Password for %s: ", password);
1990 fgets(password, WXSIZEOF(password), stdin);
1991 password[strlen(password) - 1] = '\0'; // chop off '\n'
1992 ftp.SetPassword(password);
1993
1994 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
1995 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
1996
1997 if ( !ftp.Connect(hostname) )
1998 {
1999 printf("ERROR: failed to connect to %s\n", hostname);
2000
2001 return FALSE;
2002 }
2003 else
2004 {
2005 printf("--- Connected to %s, current directory is '%s'\n",
2006 hostname, ftp.Pwd().c_str());
2007 }
2008
2009 return TRUE;
2010 }
2011
2012 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2013 static void TestFtpWuFtpd()
2014 {
2015 wxFTP ftp;
2016 static const char *hostname = "ftp.eudora.com";
2017 if ( !ftp.Connect(hostname) )
2018 {
2019 printf("ERROR: failed to connect to %s\n", hostname);
2020 }
2021 else
2022 {
2023 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2024 wxInputStream *in = ftp.GetInputStream(filename);
2025 if ( !in )
2026 {
2027 printf("ERROR: couldn't get input stream for %s\n", filename);
2028 }
2029 else
2030 {
2031 size_t size = in->StreamSize();
2032 printf("Reading file %s (%u bytes)...", filename, size);
2033
2034 char *data = new char[size];
2035 if ( !in->Read(data, size) )
2036 {
2037 puts("ERROR: read error");
2038 }
2039 else
2040 {
2041 printf("Successfully retrieved the file.\n");
2042 }
2043
2044 delete [] data;
2045 delete in;
2046 }
2047 }
2048 }
2049
2050 static void TestFtpList()
2051 {
2052 puts("*** Testing wxFTP file listing ***\n");
2053
2054 // test CWD
2055 if ( !ftp.ChDir(directory) )
2056 {
2057 printf("ERROR: failed to cd to %s\n", directory);
2058 }
2059
2060 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2061
2062 // test NLIST and LIST
2063 wxArrayString files;
2064 if ( !ftp.GetFilesList(files) )
2065 {
2066 puts("ERROR: failed to get NLIST of files");
2067 }
2068 else
2069 {
2070 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2071 size_t count = files.GetCount();
2072 for ( size_t n = 0; n < count; n++ )
2073 {
2074 printf("\t%s\n", files[n].c_str());
2075 }
2076 puts("End of the file list");
2077 }
2078
2079 if ( !ftp.GetDirList(files) )
2080 {
2081 puts("ERROR: failed to get LIST of files");
2082 }
2083 else
2084 {
2085 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2086 size_t count = files.GetCount();
2087 for ( size_t n = 0; n < count; n++ )
2088 {
2089 printf("\t%s\n", files[n].c_str());
2090 }
2091 puts("End of the file list");
2092 }
2093
2094 if ( !ftp.ChDir(_T("..")) )
2095 {
2096 puts("ERROR: failed to cd to ..");
2097 }
2098
2099 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2100 }
2101
2102 static void TestFtpDownload()
2103 {
2104 puts("*** Testing wxFTP download ***\n");
2105
2106 // test RETR
2107 wxInputStream *in = ftp.GetInputStream(filename);
2108 if ( !in )
2109 {
2110 printf("ERROR: couldn't get input stream for %s\n", filename);
2111 }
2112 else
2113 {
2114 size_t size = in->StreamSize();
2115 printf("Reading file %s (%u bytes)...", filename, size);
2116 fflush(stdout);
2117
2118 char *data = new char[size];
2119 if ( !in->Read(data, size) )
2120 {
2121 puts("ERROR: read error");
2122 }
2123 else
2124 {
2125 printf("\nContents of %s:\n%s\n", filename, data);
2126 }
2127
2128 delete [] data;
2129 delete in;
2130 }
2131 }
2132
2133 static void TestFtpFileSize()
2134 {
2135 puts("*** Testing FTP SIZE command ***");
2136
2137 if ( !ftp.ChDir(directory) )
2138 {
2139 printf("ERROR: failed to cd to %s\n", directory);
2140 }
2141
2142 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2143
2144 if ( ftp.FileExists(filename) )
2145 {
2146 int size = ftp.GetFileSize(filename);
2147 if ( size == -1 )
2148 printf("ERROR: couldn't get size of '%s'\n", filename);
2149 else
2150 printf("Size of '%s' is %d bytes.\n", filename, size);
2151 }
2152 else
2153 {
2154 printf("ERROR: '%s' doesn't exist\n", filename);
2155 }
2156 }
2157
2158 static void TestFtpMisc()
2159 {
2160 puts("*** Testing miscellaneous wxFTP functions ***");
2161
2162 if ( ftp.SendCommand("STAT") != '2' )
2163 {
2164 puts("ERROR: STAT failed");
2165 }
2166 else
2167 {
2168 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2169 }
2170
2171 if ( ftp.SendCommand("HELP SITE") != '2' )
2172 {
2173 puts("ERROR: HELP SITE failed");
2174 }
2175 else
2176 {
2177 printf("The list of site-specific commands:\n\n%s\n",
2178 ftp.GetLastResult().c_str());
2179 }
2180 }
2181
2182 static void TestFtpInteractive()
2183 {
2184 puts("\n*** Interactive wxFTP test ***");
2185
2186 char buf[128];
2187
2188 for ( ;; )
2189 {
2190 printf("Enter FTP command: ");
2191 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2192 break;
2193
2194 // kill the last '\n'
2195 buf[strlen(buf) - 1] = 0;
2196
2197 // special handling of LIST and NLST as they require data connection
2198 wxString start(buf, 4);
2199 start.MakeUpper();
2200 if ( start == "LIST" || start == "NLST" )
2201 {
2202 wxString wildcard;
2203 if ( strlen(buf) > 4 )
2204 wildcard = buf + 5;
2205
2206 wxArrayString files;
2207 if ( !ftp.GetList(files, wildcard, start == "LIST") )
2208 {
2209 printf("ERROR: failed to get %s of files\n", start.c_str());
2210 }
2211 else
2212 {
2213 printf("--- %s of '%s' under '%s':\n",
2214 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2215 size_t count = files.GetCount();
2216 for ( size_t n = 0; n < count; n++ )
2217 {
2218 printf("\t%s\n", files[n].c_str());
2219 }
2220 puts("--- End of the file list");
2221 }
2222 }
2223 else // !list
2224 {
2225 char ch = ftp.SendCommand(buf);
2226 printf("Command %s", ch ? "succeeded" : "failed");
2227 if ( ch )
2228 {
2229 printf(" (return code %c)", ch);
2230 }
2231
2232 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2233 }
2234 }
2235
2236 puts("\n*** done ***");
2237 }
2238
2239 static void TestFtpUpload()
2240 {
2241 puts("*** Testing wxFTP uploading ***\n");
2242
2243 // upload a file
2244 static const char *file1 = "test1";
2245 static const char *file2 = "test2";
2246 wxOutputStream *out = ftp.GetOutputStream(file1);
2247 if ( out )
2248 {
2249 printf("--- Uploading to %s ---\n", file1);
2250 out->Write("First hello", 11);
2251 delete out;
2252 }
2253
2254 // send a command to check the remote file
2255 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
2256 {
2257 printf("ERROR: STAT %s failed\n", file1);
2258 }
2259 else
2260 {
2261 printf("STAT %s returned:\n\n%s\n",
2262 file1, ftp.GetLastResult().c_str());
2263 }
2264
2265 out = ftp.GetOutputStream(file2);
2266 if ( out )
2267 {
2268 printf("--- Uploading to %s ---\n", file1);
2269 out->Write("Second hello", 12);
2270 delete out;
2271 }
2272 }
2273
2274 #endif // TEST_FTP
2275
2276 // ----------------------------------------------------------------------------
2277 // streams
2278 // ----------------------------------------------------------------------------
2279
2280 #ifdef TEST_STREAMS
2281
2282 #include <wx/wfstream.h>
2283 #include <wx/mstream.h>
2284
2285 static void TestFileStream()
2286 {
2287 puts("*** Testing wxFileInputStream ***");
2288
2289 static const wxChar *filename = _T("testdata.fs");
2290 {
2291 wxFileOutputStream fsOut(filename);
2292 fsOut.Write("foo", 3);
2293 }
2294
2295 wxFileInputStream fsIn(filename);
2296 printf("File stream size: %u\n", fsIn.GetSize());
2297 while ( !fsIn.Eof() )
2298 {
2299 putchar(fsIn.GetC());
2300 }
2301
2302 if ( !wxRemoveFile(filename) )
2303 {
2304 printf("ERROR: failed to remove the file '%s'.\n", filename);
2305 }
2306
2307 puts("\n*** wxFileInputStream test done ***");
2308 }
2309
2310 static void TestMemoryStream()
2311 {
2312 puts("*** Testing wxMemoryInputStream ***");
2313
2314 wxChar buf[1024];
2315 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2316
2317 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2318 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2319 while ( !memInpStream.Eof() )
2320 {
2321 putchar(memInpStream.GetC());
2322 }
2323
2324 puts("\n*** wxMemoryInputStream test done ***");
2325 }
2326
2327 #endif // TEST_STREAMS
2328
2329 // ----------------------------------------------------------------------------
2330 // timers
2331 // ----------------------------------------------------------------------------
2332
2333 #ifdef TEST_TIMER
2334
2335 #include <wx/timer.h>
2336 #include <wx/utils.h>
2337
2338 static void TestStopWatch()
2339 {
2340 puts("*** Testing wxStopWatch ***\n");
2341
2342 wxStopWatch sw;
2343 printf("Sleeping 3 seconds...");
2344 wxSleep(3);
2345 printf("\telapsed time: %ldms\n", sw.Time());
2346
2347 sw.Pause();
2348 printf("Sleeping 2 more seconds...");
2349 wxSleep(2);
2350 printf("\telapsed time: %ldms\n", sw.Time());
2351
2352 sw.Resume();
2353 printf("And 3 more seconds...");
2354 wxSleep(3);
2355 printf("\telapsed time: %ldms\n", sw.Time());
2356
2357 wxStopWatch sw2;
2358 puts("\nChecking for 'backwards clock' bug...");
2359 for ( size_t n = 0; n < 70; n++ )
2360 {
2361 sw2.Start();
2362
2363 for ( size_t m = 0; m < 100000; m++ )
2364 {
2365 if ( sw.Time() < 0 || sw2.Time() < 0 )
2366 {
2367 puts("\ntime is negative - ERROR!");
2368 }
2369 }
2370
2371 putchar('.');
2372 }
2373
2374 puts(", ok.");
2375 }
2376
2377 #endif // TEST_TIMER
2378
2379 // ----------------------------------------------------------------------------
2380 // vCard support
2381 // ----------------------------------------------------------------------------
2382
2383 #ifdef TEST_VCARD
2384
2385 #include <wx/vcard.h>
2386
2387 static void DumpVObject(size_t level, const wxVCardObject& vcard)
2388 {
2389 void *cookie;
2390 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2391 while ( vcObj )
2392 {
2393 printf("%s%s",
2394 wxString(_T('\t'), level).c_str(),
2395 vcObj->GetName().c_str());
2396
2397 wxString value;
2398 switch ( vcObj->GetType() )
2399 {
2400 case wxVCardObject::String:
2401 case wxVCardObject::UString:
2402 {
2403 wxString val;
2404 vcObj->GetValue(&val);
2405 value << _T('"') << val << _T('"');
2406 }
2407 break;
2408
2409 case wxVCardObject::Int:
2410 {
2411 unsigned int i;
2412 vcObj->GetValue(&i);
2413 value.Printf(_T("%u"), i);
2414 }
2415 break;
2416
2417 case wxVCardObject::Long:
2418 {
2419 unsigned long l;
2420 vcObj->GetValue(&l);
2421 value.Printf(_T("%lu"), l);
2422 }
2423 break;
2424
2425 case wxVCardObject::None:
2426 break;
2427
2428 case wxVCardObject::Object:
2429 value = _T("<node>");
2430 break;
2431
2432 default:
2433 value = _T("<unknown value type>");
2434 }
2435
2436 if ( !!value )
2437 printf(" = %s", value.c_str());
2438 putchar('\n');
2439
2440 DumpVObject(level + 1, *vcObj);
2441
2442 delete vcObj;
2443 vcObj = vcard.GetNextProp(&cookie);
2444 }
2445 }
2446
2447 static void DumpVCardAddresses(const wxVCard& vcard)
2448 {
2449 puts("\nShowing all addresses from vCard:\n");
2450
2451 size_t nAdr = 0;
2452 void *cookie;
2453 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
2454 while ( addr )
2455 {
2456 wxString flagsStr;
2457 int flags = addr->GetFlags();
2458 if ( flags & wxVCardAddress::Domestic )
2459 {
2460 flagsStr << _T("domestic ");
2461 }
2462 if ( flags & wxVCardAddress::Intl )
2463 {
2464 flagsStr << _T("international ");
2465 }
2466 if ( flags & wxVCardAddress::Postal )
2467 {
2468 flagsStr << _T("postal ");
2469 }
2470 if ( flags & wxVCardAddress::Parcel )
2471 {
2472 flagsStr << _T("parcel ");
2473 }
2474 if ( flags & wxVCardAddress::Home )
2475 {
2476 flagsStr << _T("home ");
2477 }
2478 if ( flags & wxVCardAddress::Work )
2479 {
2480 flagsStr << _T("work ");
2481 }
2482
2483 printf("Address %u:\n"
2484 "\tflags = %s\n"
2485 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
2486 ++nAdr,
2487 flagsStr.c_str(),
2488 addr->GetPostOffice().c_str(),
2489 addr->GetExtAddress().c_str(),
2490 addr->GetStreet().c_str(),
2491 addr->GetLocality().c_str(),
2492 addr->GetRegion().c_str(),
2493 addr->GetPostalCode().c_str(),
2494 addr->GetCountry().c_str()
2495 );
2496
2497 delete addr;
2498 addr = vcard.GetNextAddress(&cookie);
2499 }
2500 }
2501
2502 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
2503 {
2504 puts("\nShowing all phone numbers from vCard:\n");
2505
2506 size_t nPhone = 0;
2507 void *cookie;
2508 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
2509 while ( phone )
2510 {
2511 wxString flagsStr;
2512 int flags = phone->GetFlags();
2513 if ( flags & wxVCardPhoneNumber::Voice )
2514 {
2515 flagsStr << _T("voice ");
2516 }
2517 if ( flags & wxVCardPhoneNumber::Fax )
2518 {
2519 flagsStr << _T("fax ");
2520 }
2521 if ( flags & wxVCardPhoneNumber::Cellular )
2522 {
2523 flagsStr << _T("cellular ");
2524 }
2525 if ( flags & wxVCardPhoneNumber::Modem )
2526 {
2527 flagsStr << _T("modem ");
2528 }
2529 if ( flags & wxVCardPhoneNumber::Home )
2530 {
2531 flagsStr << _T("home ");
2532 }
2533 if ( flags & wxVCardPhoneNumber::Work )
2534 {
2535 flagsStr << _T("work ");
2536 }
2537
2538 printf("Phone number %u:\n"
2539 "\tflags = %s\n"
2540 "\tvalue = %s\n",
2541 ++nPhone,
2542 flagsStr.c_str(),
2543 phone->GetNumber().c_str()
2544 );
2545
2546 delete phone;
2547 phone = vcard.GetNextPhoneNumber(&cookie);
2548 }
2549 }
2550
2551 static void TestVCardRead()
2552 {
2553 puts("*** Testing wxVCard reading ***\n");
2554
2555 wxVCard vcard(_T("vcard.vcf"));
2556 if ( !vcard.IsOk() )
2557 {
2558 puts("ERROR: couldn't load vCard.");
2559 }
2560 else
2561 {
2562 // read individual vCard properties
2563 wxVCardObject *vcObj = vcard.GetProperty("FN");
2564 wxString value;
2565 if ( vcObj )
2566 {
2567 vcObj->GetValue(&value);
2568 delete vcObj;
2569 }
2570 else
2571 {
2572 value = _T("<none>");
2573 }
2574
2575 printf("Full name retrieved directly: %s\n", value.c_str());
2576
2577
2578 if ( !vcard.GetFullName(&value) )
2579 {
2580 value = _T("<none>");
2581 }
2582
2583 printf("Full name from wxVCard API: %s\n", value.c_str());
2584
2585 // now show how to deal with multiply occuring properties
2586 DumpVCardAddresses(vcard);
2587 DumpVCardPhoneNumbers(vcard);
2588
2589 // and finally show all
2590 puts("\nNow dumping the entire vCard:\n"
2591 "-----------------------------\n");
2592
2593 DumpVObject(0, vcard);
2594 }
2595 }
2596
2597 static void TestVCardWrite()
2598 {
2599 puts("*** Testing wxVCard writing ***\n");
2600
2601 wxVCard vcard;
2602 if ( !vcard.IsOk() )
2603 {
2604 puts("ERROR: couldn't create vCard.");
2605 }
2606 else
2607 {
2608 // set some fields
2609 vcard.SetName("Zeitlin", "Vadim");
2610 vcard.SetFullName("Vadim Zeitlin");
2611 vcard.SetOrganization("wxWindows", "R&D");
2612
2613 // just dump the vCard back
2614 puts("Entire vCard follows:\n");
2615 puts(vcard.Write());
2616 }
2617 }
2618
2619 #endif // TEST_VCARD
2620
2621 // ----------------------------------------------------------------------------
2622 // wide char (Unicode) support
2623 // ----------------------------------------------------------------------------
2624
2625 #ifdef TEST_WCHAR
2626
2627 #include <wx/strconv.h>
2628 #include <wx/fontenc.h>
2629 #include <wx/encconv.h>
2630 #include <wx/buffer.h>
2631
2632 static void TestUtf8()
2633 {
2634 puts("*** Testing UTF8 support ***\n");
2635
2636 static const char textInUtf8[] =
2637 {
2638 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
2639 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
2640 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
2641 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
2642 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
2643 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
2644 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
2645 };
2646
2647 char buf[1024];
2648 wchar_t wbuf[1024];
2649 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
2650 {
2651 puts("ERROR: UTF-8 decoding failed.");
2652 }
2653 else
2654 {
2655 // using wxEncodingConverter
2656 #if 0
2657 wxEncodingConverter ec;
2658 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
2659 ec.Convert(wbuf, buf);
2660 #else // using wxCSConv
2661 wxCSConv conv(_T("koi8-r"));
2662 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
2663 {
2664 puts("ERROR: conversion to KOI8-R failed.");
2665 }
2666 else
2667 #endif
2668
2669 printf("The resulting string (in koi8-r): %s\n", buf);
2670 }
2671 }
2672
2673 #endif // TEST_WCHAR
2674
2675 // ----------------------------------------------------------------------------
2676 // ZIP stream
2677 // ----------------------------------------------------------------------------
2678
2679 #ifdef TEST_ZIP
2680
2681 #include "wx/filesys.h"
2682 #include "wx/fs_zip.h"
2683 #include "wx/zipstrm.h"
2684
2685 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
2686
2687 static void TestZipStreamRead()
2688 {
2689 puts("*** Testing ZIP reading ***\n");
2690
2691 static const wxChar *filename = _T("foo");
2692 wxZipInputStream istr(TESTFILE_ZIP, filename);
2693 printf("Archive size: %u\n", istr.GetSize());
2694
2695 printf("Dumping the file '%s':\n", filename);
2696 while ( !istr.Eof() )
2697 {
2698 putchar(istr.GetC());
2699 fflush(stdout);
2700 }
2701
2702 puts("\n----- done ------");
2703 }
2704
2705 static void DumpZipDirectory(wxFileSystem& fs,
2706 const wxString& dir,
2707 const wxString& indent)
2708 {
2709 wxString prefix = wxString::Format(_T("%s#zip:%s"),
2710 TESTFILE_ZIP, dir.c_str());
2711 wxString wildcard = prefix + _T("/*");
2712
2713 wxString dirname = fs.FindFirst(wildcard, wxDIR);
2714 while ( !dirname.empty() )
2715 {
2716 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
2717 {
2718 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2719
2720 break;
2721 }
2722
2723 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
2724
2725 DumpZipDirectory(fs, dirname,
2726 indent + wxString(_T(' '), 4));
2727
2728 dirname = fs.FindNext();
2729 }
2730
2731 wxString filename = fs.FindFirst(wildcard, wxFILE);
2732 while ( !filename.empty() )
2733 {
2734 if ( !filename.StartsWith(prefix, &filename) )
2735 {
2736 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2737
2738 break;
2739 }
2740
2741 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
2742
2743 filename = fs.FindNext();
2744 }
2745 }
2746
2747 static void TestZipFileSystem()
2748 {
2749 puts("*** Testing ZIP file system ***\n");
2750
2751 wxFileSystem::AddHandler(new wxZipFSHandler);
2752 wxFileSystem fs;
2753 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
2754
2755 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
2756 }
2757
2758 #endif // TEST_ZIP
2759
2760 // ----------------------------------------------------------------------------
2761 // ZLIB stream
2762 // ----------------------------------------------------------------------------
2763
2764 #ifdef TEST_ZLIB
2765
2766 #include <wx/zstream.h>
2767 #include <wx/wfstream.h>
2768
2769 static const wxChar *FILENAME_GZ = _T("test.gz");
2770 static const char *TEST_DATA = "hello and hello again";
2771
2772 static void TestZlibStreamWrite()
2773 {
2774 puts("*** Testing Zlib stream reading ***\n");
2775
2776 wxFileOutputStream fileOutStream(FILENAME_GZ);
2777 wxZlibOutputStream ostr(fileOutStream, 0);
2778 printf("Compressing the test string... ");
2779 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
2780 if ( !ostr )
2781 {
2782 puts("(ERROR: failed)");
2783 }
2784 else
2785 {
2786 puts("(ok)");
2787 }
2788
2789 puts("\n----- done ------");
2790 }
2791
2792 static void TestZlibStreamRead()
2793 {
2794 puts("*** Testing Zlib stream reading ***\n");
2795
2796 wxFileInputStream fileInStream(FILENAME_GZ);
2797 wxZlibInputStream istr(fileInStream);
2798 printf("Archive size: %u\n", istr.GetSize());
2799
2800 puts("Dumping the file:");
2801 while ( !istr.Eof() )
2802 {
2803 putchar(istr.GetC());
2804 fflush(stdout);
2805 }
2806
2807 puts("\n----- done ------");
2808 }
2809
2810 #endif // TEST_ZLIB
2811
2812 // ----------------------------------------------------------------------------
2813 // date time
2814 // ----------------------------------------------------------------------------
2815
2816 #ifdef TEST_DATETIME
2817
2818 #include <math.h>
2819
2820 #include <wx/date.h>
2821
2822 #include <wx/datetime.h>
2823
2824 // the test data
2825 struct Date
2826 {
2827 wxDateTime::wxDateTime_t day;
2828 wxDateTime::Month month;
2829 int year;
2830 wxDateTime::wxDateTime_t hour, min, sec;
2831 double jdn;
2832 wxDateTime::WeekDay wday;
2833 time_t gmticks, ticks;
2834
2835 void Init(const wxDateTime::Tm& tm)
2836 {
2837 day = tm.mday;
2838 month = tm.mon;
2839 year = tm.year;
2840 hour = tm.hour;
2841 min = tm.min;
2842 sec = tm.sec;
2843 jdn = 0.0;
2844 gmticks = ticks = -1;
2845 }
2846
2847 wxDateTime DT() const
2848 { return wxDateTime(day, month, year, hour, min, sec); }
2849
2850 bool SameDay(const wxDateTime::Tm& tm) const
2851 {
2852 return day == tm.mday && month == tm.mon && year == tm.year;
2853 }
2854
2855 wxString Format() const
2856 {
2857 wxString s;
2858 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
2859 hour, min, sec,
2860 wxDateTime::GetMonthName(month).c_str(),
2861 day,
2862 abs(wxDateTime::ConvertYearToBC(year)),
2863 year > 0 ? "AD" : "BC");
2864 return s;
2865 }
2866
2867 wxString FormatDate() const
2868 {
2869 wxString s;
2870 s.Printf("%02d-%s-%4d%s",
2871 day,
2872 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2873 abs(wxDateTime::ConvertYearToBC(year)),
2874 year > 0 ? "AD" : "BC");
2875 return s;
2876 }
2877 };
2878
2879 static const Date testDates[] =
2880 {
2881 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
2882 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
2883 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
2884 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
2885 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
2886 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
2887 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
2888 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
2889 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
2890 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
2891 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
2892 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
2893 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
2894 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
2895 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
2896 };
2897
2898 // this test miscellaneous static wxDateTime functions
2899 static void TestTimeStatic()
2900 {
2901 puts("\n*** wxDateTime static methods test ***");
2902
2903 // some info about the current date
2904 int year = wxDateTime::GetCurrentYear();
2905 printf("Current year %d is %sa leap one and has %d days.\n",
2906 year,
2907 wxDateTime::IsLeapYear(year) ? "" : "not ",
2908 wxDateTime::GetNumberOfDays(year));
2909
2910 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
2911 printf("Current month is '%s' ('%s') and it has %d days\n",
2912 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2913 wxDateTime::GetMonthName(month).c_str(),
2914 wxDateTime::GetNumberOfDays(month));
2915
2916 // leap year logic
2917 static const size_t nYears = 5;
2918 static const size_t years[2][nYears] =
2919 {
2920 // first line: the years to test
2921 { 1990, 1976, 2000, 2030, 1984, },
2922
2923 // second line: TRUE if leap, FALSE otherwise
2924 { FALSE, TRUE, TRUE, FALSE, TRUE }
2925 };
2926
2927 for ( size_t n = 0; n < nYears; n++ )
2928 {
2929 int year = years[0][n];
2930 bool should = years[1][n] != 0,
2931 is = wxDateTime::IsLeapYear(year);
2932
2933 printf("Year %d is %sa leap year (%s)\n",
2934 year,
2935 is ? "" : "not ",
2936 should == is ? "ok" : "ERROR");
2937
2938 wxASSERT( should == wxDateTime::IsLeapYear(year) );
2939 }
2940 }
2941
2942 // test constructing wxDateTime objects
2943 static void TestTimeSet()
2944 {
2945 puts("\n*** wxDateTime construction test ***");
2946
2947 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2948 {
2949 const Date& d1 = testDates[n];
2950 wxDateTime dt = d1.DT();
2951
2952 Date d2;
2953 d2.Init(dt.GetTm());
2954
2955 wxString s1 = d1.Format(),
2956 s2 = d2.Format();
2957
2958 printf("Date: %s == %s (%s)\n",
2959 s1.c_str(), s2.c_str(),
2960 s1 == s2 ? "ok" : "ERROR");
2961 }
2962 }
2963
2964 // test time zones stuff
2965 static void TestTimeZones()
2966 {
2967 puts("\n*** wxDateTime timezone test ***");
2968
2969 wxDateTime now = wxDateTime::Now();
2970
2971 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
2972 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
2973 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
2974 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
2975 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
2976 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
2977
2978 wxDateTime::Tm tm = now.GetTm();
2979 if ( wxDateTime(tm) != now )
2980 {
2981 printf("ERROR: got %s instead of %s\n",
2982 wxDateTime(tm).Format().c_str(), now.Format().c_str());
2983 }
2984 }
2985
2986 // test some minimal support for the dates outside the standard range
2987 static void TestTimeRange()
2988 {
2989 puts("\n*** wxDateTime out-of-standard-range dates test ***");
2990
2991 static const char *fmt = "%d-%b-%Y %H:%M:%S";
2992
2993 printf("Unix epoch:\t%s\n",
2994 wxDateTime(2440587.5).Format(fmt).c_str());
2995 printf("Feb 29, 0: \t%s\n",
2996 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
2997 printf("JDN 0: \t%s\n",
2998 wxDateTime(0.0).Format(fmt).c_str());
2999 printf("Jan 1, 1AD:\t%s\n",
3000 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3001 printf("May 29, 2099:\t%s\n",
3002 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3003 }
3004
3005 static void TestTimeTicks()
3006 {
3007 puts("\n*** wxDateTime ticks test ***");
3008
3009 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3010 {
3011 const Date& d = testDates[n];
3012 if ( d.ticks == -1 )
3013 continue;
3014
3015 wxDateTime dt = d.DT();
3016 long ticks = (dt.GetValue() / 1000).ToLong();
3017 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3018 if ( ticks == d.ticks )
3019 {
3020 puts(" (ok)");
3021 }
3022 else
3023 {
3024 printf(" (ERROR: should be %ld, delta = %ld)\n",
3025 d.ticks, ticks - d.ticks);
3026 }
3027
3028 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3029 ticks = (dt.GetValue() / 1000).ToLong();
3030 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3031 if ( ticks == d.gmticks )
3032 {
3033 puts(" (ok)");
3034 }
3035 else
3036 {
3037 printf(" (ERROR: should be %ld, delta = %ld)\n",
3038 d.gmticks, ticks - d.gmticks);
3039 }
3040 }
3041
3042 puts("");
3043 }
3044
3045 // test conversions to JDN &c
3046 static void TestTimeJDN()
3047 {
3048 puts("\n*** wxDateTime to JDN test ***");
3049
3050 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3051 {
3052 const Date& d = testDates[n];
3053 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3054 double jdn = dt.GetJulianDayNumber();
3055
3056 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
3057 if ( jdn == d.jdn )
3058 {
3059 puts(" (ok)");
3060 }
3061 else
3062 {
3063 printf(" (ERROR: should be %f, delta = %f)\n",
3064 d.jdn, jdn - d.jdn);
3065 }
3066 }
3067 }
3068
3069 // test week days computation
3070 static void TestTimeWDays()
3071 {
3072 puts("\n*** wxDateTime weekday test ***");
3073
3074 // test GetWeekDay()
3075 size_t n;
3076 for ( n = 0; n < WXSIZEOF(testDates); n++ )
3077 {
3078 const Date& d = testDates[n];
3079 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3080
3081 wxDateTime::WeekDay wday = dt.GetWeekDay();
3082 printf("%s is: %s",
3083 d.Format().c_str(),
3084 wxDateTime::GetWeekDayName(wday).c_str());
3085 if ( wday == d.wday )
3086 {
3087 puts(" (ok)");
3088 }
3089 else
3090 {
3091 printf(" (ERROR: should be %s)\n",
3092 wxDateTime::GetWeekDayName(d.wday).c_str());
3093 }
3094 }
3095
3096 puts("");
3097
3098 // test SetToWeekDay()
3099 struct WeekDateTestData
3100 {
3101 Date date; // the real date (precomputed)
3102 int nWeek; // its week index in the month
3103 wxDateTime::WeekDay wday; // the weekday
3104 wxDateTime::Month month; // the month
3105 int year; // and the year
3106
3107 wxString Format() const
3108 {
3109 wxString s, which;
3110 switch ( nWeek < -1 ? -nWeek : nWeek )
3111 {
3112 case 1: which = "first"; break;
3113 case 2: which = "second"; break;
3114 case 3: which = "third"; break;
3115 case 4: which = "fourth"; break;
3116 case 5: which = "fifth"; break;
3117
3118 case -1: which = "last"; break;
3119 }
3120
3121 if ( nWeek < -1 )
3122 {
3123 which += " from end";
3124 }
3125
3126 s.Printf("The %s %s of %s in %d",
3127 which.c_str(),
3128 wxDateTime::GetWeekDayName(wday).c_str(),
3129 wxDateTime::GetMonthName(month).c_str(),
3130 year);
3131
3132 return s;
3133 }
3134 };
3135
3136 // the array data was generated by the following python program
3137 /*
3138 from DateTime import *
3139 from whrandom import *
3140 from string import *
3141
3142 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3143 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3144
3145 week = DateTimeDelta(7)
3146
3147 for n in range(20):
3148 year = randint(1900, 2100)
3149 month = randint(1, 12)
3150 day = randint(1, 28)
3151 dt = DateTime(year, month, day)
3152 wday = dt.day_of_week
3153
3154 countFromEnd = choice([-1, 1])
3155 weekNum = 0;
3156
3157 while dt.month is month:
3158 dt = dt - countFromEnd * week
3159 weekNum = weekNum + countFromEnd
3160
3161 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
3162
3163 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3164 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
3165 */
3166
3167 static const WeekDateTestData weekDatesTestData[] =
3168 {
3169 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3170 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3171 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3172 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3173 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3174 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3175 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3176 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3177 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3178 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3179 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3180 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3181 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3182 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3183 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3184 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3185 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3186 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3187 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3188 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3189 };
3190
3191 static const char *fmt = "%d-%b-%Y";
3192
3193 wxDateTime dt;
3194 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3195 {
3196 const WeekDateTestData& wd = weekDatesTestData[n];
3197
3198 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3199
3200 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3201
3202 const Date& d = wd.date;
3203 if ( d.SameDay(dt.GetTm()) )
3204 {
3205 puts(" (ok)");
3206 }
3207 else
3208 {
3209 dt.Set(d.day, d.month, d.year);
3210
3211 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
3212 }
3213 }
3214 }
3215
3216 // test the computation of (ISO) week numbers
3217 static void TestTimeWNumber()
3218 {
3219 puts("\n*** wxDateTime week number test ***");
3220
3221 struct WeekNumberTestData
3222 {
3223 Date date; // the date
3224 wxDateTime::wxDateTime_t week; // the week number in the year
3225 wxDateTime::wxDateTime_t wmon; // the week number in the month
3226 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
3227 wxDateTime::wxDateTime_t dnum; // day number in the year
3228 };
3229
3230 // data generated with the following python script:
3231 /*
3232 from DateTime import *
3233 from whrandom import *
3234 from string import *
3235
3236 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3237 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3238
3239 def GetMonthWeek(dt):
3240 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3241 if weekNumMonth < 0:
3242 weekNumMonth = weekNumMonth + 53
3243 return weekNumMonth
3244
3245 def GetLastSundayBefore(dt):
3246 if dt.iso_week[2] == 7:
3247 return dt
3248 else:
3249 return dt - DateTimeDelta(dt.iso_week[2])
3250
3251 for n in range(20):
3252 year = randint(1900, 2100)
3253 month = randint(1, 12)
3254 day = randint(1, 28)
3255 dt = DateTime(year, month, day)
3256 dayNum = dt.day_of_year
3257 weekNum = dt.iso_week[1]
3258 weekNumMonth = GetMonthWeek(dt)
3259
3260 weekNumMonth2 = 0
3261 dtSunday = GetLastSundayBefore(dt)
3262
3263 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3264 weekNumMonth2 = weekNumMonth2 + 1
3265 dtSunday = dtSunday - DateTimeDelta(7)
3266
3267 data = { 'day': rjust(`day`, 2), \
3268 'month': monthNames[month - 1], \
3269 'year': year, \
3270 'weekNum': rjust(`weekNum`, 2), \
3271 'weekNumMonth': weekNumMonth, \
3272 'weekNumMonth2': weekNumMonth2, \
3273 'dayNum': rjust(`dayNum`, 3) }
3274
3275 print " { { %(day)s, "\
3276 "wxDateTime::%(month)s, "\
3277 "%(year)d }, "\
3278 "%(weekNum)s, "\
3279 "%(weekNumMonth)s, "\
3280 "%(weekNumMonth2)s, "\
3281 "%(dayNum)s }," % data
3282
3283 */
3284 static const WeekNumberTestData weekNumberTestDates[] =
3285 {
3286 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3287 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3288 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3289 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3290 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3291 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3292 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3293 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3294 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3295 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3296 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3297 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3298 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3299 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3300 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3301 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3302 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3303 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3304 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3305 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
3306 };
3307
3308 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3309 {
3310 const WeekNumberTestData& wn = weekNumberTestDates[n];
3311 const Date& d = wn.date;
3312
3313 wxDateTime dt = d.DT();
3314
3315 wxDateTime::wxDateTime_t
3316 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3317 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3318 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3319 dnum = dt.GetDayOfYear();
3320
3321 printf("%s: the day number is %d",
3322 d.FormatDate().c_str(), dnum);
3323 if ( dnum == wn.dnum )
3324 {
3325 printf(" (ok)");
3326 }
3327 else
3328 {
3329 printf(" (ERROR: should be %d)", wn.dnum);
3330 }
3331
3332 printf(", week in month is %d", wmon);
3333 if ( wmon == wn.wmon )
3334 {
3335 printf(" (ok)");
3336 }
3337 else
3338 {
3339 printf(" (ERROR: should be %d)", wn.wmon);
3340 }
3341
3342 printf(" or %d", wmon2);
3343 if ( wmon2 == wn.wmon2 )
3344 {
3345 printf(" (ok)");
3346 }
3347 else
3348 {
3349 printf(" (ERROR: should be %d)", wn.wmon2);
3350 }
3351
3352 printf(", week in year is %d", week);
3353 if ( week == wn.week )
3354 {
3355 puts(" (ok)");
3356 }
3357 else
3358 {
3359 printf(" (ERROR: should be %d)\n", wn.week);
3360 }
3361 }
3362 }
3363
3364 // test DST calculations
3365 static void TestTimeDST()
3366 {
3367 puts("\n*** wxDateTime DST test ***");
3368
3369 printf("DST is%s in effect now.\n\n",
3370 wxDateTime::Now().IsDST() ? "" : " not");
3371
3372 // taken from http://www.energy.ca.gov/daylightsaving.html
3373 static const Date datesDST[2][2004 - 1900 + 1] =
3374 {
3375 {
3376 { 1, wxDateTime::Apr, 1990 },
3377 { 7, wxDateTime::Apr, 1991 },
3378 { 5, wxDateTime::Apr, 1992 },
3379 { 4, wxDateTime::Apr, 1993 },
3380 { 3, wxDateTime::Apr, 1994 },
3381 { 2, wxDateTime::Apr, 1995 },
3382 { 7, wxDateTime::Apr, 1996 },
3383 { 6, wxDateTime::Apr, 1997 },
3384 { 5, wxDateTime::Apr, 1998 },
3385 { 4, wxDateTime::Apr, 1999 },
3386 { 2, wxDateTime::Apr, 2000 },
3387 { 1, wxDateTime::Apr, 2001 },
3388 { 7, wxDateTime::Apr, 2002 },
3389 { 6, wxDateTime::Apr, 2003 },
3390 { 4, wxDateTime::Apr, 2004 },
3391 },
3392 {
3393 { 28, wxDateTime::Oct, 1990 },
3394 { 27, wxDateTime::Oct, 1991 },
3395 { 25, wxDateTime::Oct, 1992 },
3396 { 31, wxDateTime::Oct, 1993 },
3397 { 30, wxDateTime::Oct, 1994 },
3398 { 29, wxDateTime::Oct, 1995 },
3399 { 27, wxDateTime::Oct, 1996 },
3400 { 26, wxDateTime::Oct, 1997 },
3401 { 25, wxDateTime::Oct, 1998 },
3402 { 31, wxDateTime::Oct, 1999 },
3403 { 29, wxDateTime::Oct, 2000 },
3404 { 28, wxDateTime::Oct, 2001 },
3405 { 27, wxDateTime::Oct, 2002 },
3406 { 26, wxDateTime::Oct, 2003 },
3407 { 31, wxDateTime::Oct, 2004 },
3408 }
3409 };
3410
3411 int year;
3412 for ( year = 1990; year < 2005; year++ )
3413 {
3414 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
3415 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
3416
3417 printf("DST period in the US for year %d: from %s to %s",
3418 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
3419
3420 size_t n = year - 1990;
3421 const Date& dBegin = datesDST[0][n];
3422 const Date& dEnd = datesDST[1][n];
3423
3424 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
3425 {
3426 puts(" (ok)");
3427 }
3428 else
3429 {
3430 printf(" (ERROR: should be %s %d to %s %d)\n",
3431 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
3432 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
3433 }
3434 }
3435
3436 puts("");
3437
3438 for ( year = 1990; year < 2005; year++ )
3439 {
3440 printf("DST period in Europe for year %d: from %s to %s\n",
3441 year,
3442 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3443 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3444 }
3445 }
3446
3447 // test wxDateTime -> text conversion
3448 static void TestTimeFormat()
3449 {
3450 puts("\n*** wxDateTime formatting test ***");
3451
3452 // some information may be lost during conversion, so store what kind
3453 // of info should we recover after a round trip
3454 enum CompareKind
3455 {
3456 CompareNone, // don't try comparing
3457 CompareBoth, // dates and times should be identical
3458 CompareDate, // dates only
3459 CompareTime // time only
3460 };
3461
3462 static const struct
3463 {
3464 CompareKind compareKind;
3465 const char *format;
3466 } formatTestFormats[] =
3467 {
3468 { CompareBoth, "---> %c" },
3469 { CompareDate, "Date is %A, %d of %B, in year %Y" },
3470 { CompareBoth, "Date is %x, time is %X" },
3471 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
3472 { CompareNone, "The day of year: %j, the week of year: %W" },
3473 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
3474 };
3475
3476 static const Date formatTestDates[] =
3477 {
3478 { 29, wxDateTime::May, 1976, 18, 30, 00 },
3479 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
3480 #if 0
3481 // this test can't work for other centuries because it uses two digit
3482 // years in formats, so don't even try it
3483 { 29, wxDateTime::May, 2076, 18, 30, 00 },
3484 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
3485 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
3486 #endif
3487 };
3488
3489 // an extra test (as it doesn't depend on date, don't do it in the loop)
3490 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
3491
3492 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
3493 {
3494 puts("");
3495
3496 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
3497 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
3498 {
3499 wxString s = dt.Format(formatTestFormats[n].format);
3500 printf("%s", s.c_str());
3501
3502 // what can we recover?
3503 int kind = formatTestFormats[n].compareKind;
3504
3505 // convert back
3506 wxDateTime dt2;
3507 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
3508 if ( !result )
3509 {
3510 // converion failed - should it have?
3511 if ( kind == CompareNone )
3512 puts(" (ok)");
3513 else
3514 puts(" (ERROR: conversion back failed)");
3515 }
3516 else if ( *result )
3517 {
3518 // should have parsed the entire string
3519 puts(" (ERROR: conversion back stopped too soon)");
3520 }
3521 else
3522 {
3523 bool equal = FALSE; // suppress compilaer warning
3524 switch ( kind )
3525 {
3526 case CompareBoth:
3527 equal = dt2 == dt;
3528 break;
3529
3530 case CompareDate:
3531 equal = dt.IsSameDate(dt2);
3532 break;
3533
3534 case CompareTime:
3535 equal = dt.IsSameTime(dt2);
3536 break;
3537 }
3538
3539 if ( !equal )
3540 {
3541 printf(" (ERROR: got back '%s' instead of '%s')\n",
3542 dt2.Format().c_str(), dt.Format().c_str());
3543 }
3544 else
3545 {
3546 puts(" (ok)");
3547 }
3548 }
3549 }
3550 }
3551 }
3552
3553 // test text -> wxDateTime conversion
3554 static void TestTimeParse()
3555 {
3556 puts("\n*** wxDateTime parse test ***");
3557
3558 struct ParseTestData
3559 {
3560 const char *format;
3561 Date date;
3562 bool good;
3563 };
3564
3565 static const ParseTestData parseTestDates[] =
3566 {
3567 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
3568 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
3569 };
3570
3571 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
3572 {
3573 const char *format = parseTestDates[n].format;
3574
3575 printf("%s => ", format);
3576
3577 wxDateTime dt;
3578 if ( dt.ParseRfc822Date(format) )
3579 {
3580 printf("%s ", dt.Format().c_str());
3581
3582 if ( parseTestDates[n].good )
3583 {
3584 wxDateTime dtReal = parseTestDates[n].date.DT();
3585 if ( dt == dtReal )
3586 {
3587 puts("(ok)");
3588 }
3589 else
3590 {
3591 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
3592 }
3593 }
3594 else
3595 {
3596 puts("(ERROR: bad format)");
3597 }
3598 }
3599 else
3600 {
3601 printf("bad format (%s)\n",
3602 parseTestDates[n].good ? "ERROR" : "ok");
3603 }
3604 }
3605 }
3606
3607 static void TestDateTimeInteractive()
3608 {
3609 puts("\n*** interactive wxDateTime tests ***");
3610
3611 char buf[128];
3612
3613 for ( ;; )
3614 {
3615 printf("Enter a date: ");
3616 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
3617 break;
3618
3619 // kill the last '\n'
3620 buf[strlen(buf) - 1] = 0;
3621
3622 wxDateTime dt;
3623 const char *p = dt.ParseDate(buf);
3624 if ( !p )
3625 {
3626 printf("ERROR: failed to parse the date '%s'.\n", buf);
3627
3628 continue;
3629 }
3630 else if ( *p )
3631 {
3632 printf("WARNING: parsed only first %u characters.\n", p - buf);
3633 }
3634
3635 printf("%s: day %u, week of month %u/%u, week of year %u\n",
3636 dt.Format("%b %d, %Y").c_str(),
3637 dt.GetDayOfYear(),
3638 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3639 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3640 dt.GetWeekOfYear(wxDateTime::Monday_First));
3641 }
3642
3643 puts("\n*** done ***");
3644 }
3645
3646 static void TestTimeMS()
3647 {
3648 puts("*** testing millisecond-resolution support in wxDateTime ***");
3649
3650 wxDateTime dt1 = wxDateTime::Now(),
3651 dt2 = wxDateTime::UNow();
3652
3653 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
3654 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3655 printf("Dummy loop: ");
3656 for ( int i = 0; i < 6000; i++ )
3657 {
3658 //for ( int j = 0; j < 10; j++ )
3659 {
3660 wxString s;
3661 s.Printf("%g", sqrt(i));
3662 }
3663
3664 if ( !(i % 100) )
3665 putchar('.');
3666 }
3667 puts(", done");
3668
3669 dt1 = dt2;
3670 dt2 = wxDateTime::UNow();
3671 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3672
3673 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
3674
3675 puts("\n*** done ***");
3676 }
3677
3678 static void TestTimeArithmetics()
3679 {
3680 puts("\n*** testing arithmetic operations on wxDateTime ***");
3681
3682 static const struct ArithmData
3683 {
3684 ArithmData(const wxDateSpan& sp, const char *nam)
3685 : span(sp), name(nam) { }
3686
3687 wxDateSpan span;
3688 const char *name;
3689 } testArithmData[] =
3690 {
3691 ArithmData(wxDateSpan::Day(), "day"),
3692 ArithmData(wxDateSpan::Week(), "week"),
3693 ArithmData(wxDateSpan::Month(), "month"),
3694 ArithmData(wxDateSpan::Year(), "year"),
3695 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
3696 };
3697
3698 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
3699
3700 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
3701 {
3702 wxDateSpan span = testArithmData[n].span;
3703 dt1 = dt + span;
3704 dt2 = dt - span;
3705
3706 const char *name = testArithmData[n].name;
3707 printf("%s + %s = %s, %s - %s = %s\n",
3708 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
3709 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
3710
3711 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
3712 if ( dt1 - span == dt )
3713 {
3714 puts(" (ok)");
3715 }
3716 else
3717 {
3718 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3719 }
3720
3721 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
3722 if ( dt2 + span == dt )
3723 {
3724 puts(" (ok)");
3725 }
3726 else
3727 {
3728 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3729 }
3730
3731 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
3732 if ( dt2 + 2*span == dt1 )
3733 {
3734 puts(" (ok)");
3735 }
3736 else
3737 {
3738 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
3739 }
3740
3741 puts("");
3742 }
3743 }
3744
3745 static void TestTimeHolidays()
3746 {
3747 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
3748
3749 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3750 wxDateTime dtStart(1, tm.mon, tm.year),
3751 dtEnd = dtStart.GetLastMonthDay();
3752
3753 wxDateTimeArray hol;
3754 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3755
3756 const wxChar *format = "%d-%b-%Y (%a)";
3757
3758 printf("All holidays between %s and %s:\n",
3759 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
3760
3761 size_t count = hol.GetCount();
3762 for ( size_t n = 0; n < count; n++ )
3763 {
3764 printf("\t%s\n", hol[n].Format(format).c_str());
3765 }
3766
3767 puts("");
3768 }
3769
3770 static void TestTimeZoneBug()
3771 {
3772 puts("\n*** testing for DST/timezone bug ***\n");
3773
3774 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
3775 for ( int i = 0; i < 31; i++ )
3776 {
3777 printf("Date %s: week day %s.\n",
3778 date.Format(_T("%d-%m-%Y")).c_str(),
3779 date.GetWeekDayName(date.GetWeekDay()).c_str());
3780
3781 date += wxDateSpan::Day();
3782 }
3783
3784 puts("");
3785 }
3786
3787 static void TestTimeSpanFormat()
3788 {
3789 puts("\n*** wxTimeSpan tests ***");
3790
3791 static const char *formats[] =
3792 {
3793 _T("(default) %H:%M:%S"),
3794 _T("%E weeks and %D days"),
3795 _T("%l milliseconds"),
3796 _T("(with ms) %H:%M:%S:%l"),
3797 _T("100%% of minutes is %M"), // test "%%"
3798 _T("%D days and %H hours"),
3799 };
3800
3801 wxTimeSpan ts1(1, 2, 3, 4),
3802 ts2(111, 222, 333);
3803 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
3804 {
3805 printf("ts1 = %s\tts2 = %s\n",
3806 ts1.Format(formats[n]).c_str(),
3807 ts2.Format(formats[n]).c_str());
3808 }
3809
3810 puts("");
3811 }
3812
3813 #if 0
3814
3815 // test compatibility with the old wxDate/wxTime classes
3816 static void TestTimeCompatibility()
3817 {
3818 puts("\n*** wxDateTime compatibility test ***");
3819
3820 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
3821 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
3822
3823 double jdnNow = wxDateTime::Now().GetJDN();
3824 long jdnMidnight = (long)(jdnNow - 0.5);
3825 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
3826
3827 jdnMidnight = wxDate().Set().GetJulianDate();
3828 printf("wxDateTime for today: %s\n",
3829 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
3830
3831 int flags = wxEUROPEAN;//wxFULL;
3832 wxDate date;
3833 date.Set();
3834 printf("Today is %s\n", date.FormatDate(flags).c_str());
3835 for ( int n = 0; n < 7; n++ )
3836 {
3837 printf("Previous %s is %s\n",
3838 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
3839 date.Previous(n + 1).FormatDate(flags).c_str());
3840 }
3841 }
3842
3843 #endif // 0
3844
3845 #endif // TEST_DATETIME
3846
3847 // ----------------------------------------------------------------------------
3848 // threads
3849 // ----------------------------------------------------------------------------
3850
3851 #ifdef TEST_THREADS
3852
3853 #include <wx/thread.h>
3854
3855 static size_t gs_counter = (size_t)-1;
3856 static wxCriticalSection gs_critsect;
3857 static wxCondition gs_cond;
3858
3859 class MyJoinableThread : public wxThread
3860 {
3861 public:
3862 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3863 { m_n = n; Create(); }
3864
3865 // thread execution starts here
3866 virtual ExitCode Entry();
3867
3868 private:
3869 size_t m_n;
3870 };
3871
3872 wxThread::ExitCode MyJoinableThread::Entry()
3873 {
3874 unsigned long res = 1;
3875 for ( size_t n = 1; n < m_n; n++ )
3876 {
3877 res *= n;
3878
3879 // it's a loooong calculation :-)
3880 Sleep(100);
3881 }
3882
3883 return (ExitCode)res;
3884 }
3885
3886 class MyDetachedThread : public wxThread
3887 {
3888 public:
3889 MyDetachedThread(size_t n, char ch)
3890 {
3891 m_n = n;
3892 m_ch = ch;
3893 m_cancelled = FALSE;
3894
3895 Create();
3896 }
3897
3898 // thread execution starts here
3899 virtual ExitCode Entry();
3900
3901 // and stops here
3902 virtual void OnExit();
3903
3904 private:
3905 size_t m_n; // number of characters to write
3906 char m_ch; // character to write
3907
3908 bool m_cancelled; // FALSE if we exit normally
3909 };
3910
3911 wxThread::ExitCode MyDetachedThread::Entry()
3912 {
3913 {
3914 wxCriticalSectionLocker lock(gs_critsect);
3915 if ( gs_counter == (size_t)-1 )
3916 gs_counter = 1;
3917 else
3918 gs_counter++;
3919 }
3920
3921 for ( size_t n = 0; n < m_n; n++ )
3922 {
3923 if ( TestDestroy() )
3924 {
3925 m_cancelled = TRUE;
3926
3927 break;
3928 }
3929
3930 putchar(m_ch);
3931 fflush(stdout);
3932
3933 wxThread::Sleep(100);
3934 }
3935
3936 return 0;
3937 }
3938
3939 void MyDetachedThread::OnExit()
3940 {
3941 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
3942
3943 wxCriticalSectionLocker lock(gs_critsect);
3944 if ( !--gs_counter && !m_cancelled )
3945 gs_cond.Signal();
3946 }
3947
3948 void TestDetachedThreads()
3949 {
3950 puts("\n*** Testing detached threads ***");
3951
3952 static const size_t nThreads = 3;
3953 MyDetachedThread *threads[nThreads];
3954 size_t n;
3955 for ( n = 0; n < nThreads; n++ )
3956 {
3957 threads[n] = new MyDetachedThread(10, 'A' + n);
3958 }
3959
3960 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3961 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3962
3963 for ( n = 0; n < nThreads; n++ )
3964 {
3965 threads[n]->Run();
3966 }
3967
3968 // wait until all threads terminate
3969 gs_cond.Wait();
3970
3971 puts("");
3972 }
3973
3974 void TestJoinableThreads()
3975 {
3976 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
3977
3978 // calc 10! in the background
3979 MyJoinableThread thread(10);
3980 thread.Run();
3981
3982 printf("\nThread terminated with exit code %lu.\n",
3983 (unsigned long)thread.Wait());
3984 }
3985
3986 void TestThreadSuspend()
3987 {
3988 puts("\n*** Testing thread suspend/resume functions ***");
3989
3990 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3991
3992 thread->Run();
3993
3994 // this is for this demo only, in a real life program we'd use another
3995 // condition variable which would be signaled from wxThread::Entry() to
3996 // tell us that the thread really started running - but here just wait a
3997 // bit and hope that it will be enough (the problem is, of course, that
3998 // the thread might still not run when we call Pause() which will result
3999 // in an error)
4000 wxThread::Sleep(300);
4001
4002 for ( size_t n = 0; n < 3; n++ )
4003 {
4004 thread->Pause();
4005
4006 puts("\nThread suspended");
4007 if ( n > 0 )
4008 {
4009 // don't sleep but resume immediately the first time
4010 wxThread::Sleep(300);
4011 }
4012 puts("Going to resume the thread");
4013
4014 thread->Resume();
4015 }
4016
4017 puts("Waiting until it terminates now");
4018
4019 // wait until the thread terminates
4020 gs_cond.Wait();
4021
4022 puts("");
4023 }
4024
4025 void TestThreadDelete()
4026 {
4027 // As above, using Sleep() is only for testing here - we must use some
4028 // synchronisation object instead to ensure that the thread is still
4029 // running when we delete it - deleting a detached thread which already
4030 // terminated will lead to a crash!
4031
4032 puts("\n*** Testing thread delete function ***");
4033
4034 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4035
4036 thread0->Delete();
4037
4038 puts("\nDeleted a thread which didn't start to run yet.");
4039
4040 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4041
4042 thread1->Run();
4043
4044 wxThread::Sleep(300);
4045
4046 thread1->Delete();
4047
4048 puts("\nDeleted a running thread.");
4049
4050 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4051
4052 thread2->Run();
4053
4054 wxThread::Sleep(300);
4055
4056 thread2->Pause();
4057
4058 thread2->Delete();
4059
4060 puts("\nDeleted a sleeping thread.");
4061
4062 MyJoinableThread thread3(20);
4063 thread3.Run();
4064
4065 thread3.Delete();
4066
4067 puts("\nDeleted a joinable thread.");
4068
4069 MyJoinableThread thread4(2);
4070 thread4.Run();
4071
4072 wxThread::Sleep(300);
4073
4074 thread4.Delete();
4075
4076 puts("\nDeleted a joinable thread which already terminated.");
4077
4078 puts("");
4079 }
4080
4081 #endif // TEST_THREADS
4082
4083 // ----------------------------------------------------------------------------
4084 // arrays
4085 // ----------------------------------------------------------------------------
4086
4087 #ifdef TEST_ARRAYS
4088
4089 static void PrintArray(const char* name, const wxArrayString& array)
4090 {
4091 printf("Dump of the array '%s'\n", name);
4092
4093 size_t nCount = array.GetCount();
4094 for ( size_t n = 0; n < nCount; n++ )
4095 {
4096 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4097 }
4098 }
4099
4100 static void PrintArray(const char* name, const wxArrayInt& array)
4101 {
4102 printf("Dump of the array '%s'\n", name);
4103
4104 size_t nCount = array.GetCount();
4105 for ( size_t n = 0; n < nCount; n++ )
4106 {
4107 printf("\t%s[%u] = %d\n", name, n, array[n]);
4108 }
4109 }
4110
4111 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4112 const wxString& second)
4113 {
4114 return first.length() - second.length();
4115 }
4116
4117 int wxCMPFUNC_CONV IntCompare(int *first,
4118 int *second)
4119 {
4120 return *first - *second;
4121 }
4122
4123 int wxCMPFUNC_CONV IntRevCompare(int *first,
4124 int *second)
4125 {
4126 return *second - *first;
4127 }
4128
4129 static void TestArrayOfInts()
4130 {
4131 puts("*** Testing wxArrayInt ***\n");
4132
4133 wxArrayInt a;
4134 a.Add(1);
4135 a.Add(17);
4136 a.Add(5);
4137 a.Add(3);
4138
4139 puts("Initially:");
4140 PrintArray("a", a);
4141
4142 puts("After sort:");
4143 a.Sort(IntCompare);
4144 PrintArray("a", a);
4145
4146 puts("After reverse sort:");
4147 a.Sort(IntRevCompare);
4148 PrintArray("a", a);
4149 }
4150
4151 #include "wx/dynarray.h"
4152
4153 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4154 #include "wx/arrimpl.cpp"
4155 WX_DEFINE_OBJARRAY(ArrayBars);
4156
4157 static void TestArrayOfObjects()
4158 {
4159 puts("*** Testing wxObjArray ***\n");
4160
4161 {
4162 ArrayBars bars;
4163 Bar bar("second bar");
4164
4165 printf("Initially: %u objects in the array, %u objects total.\n",
4166 bars.GetCount(), Bar::GetNumber());
4167
4168 bars.Add(new Bar("first bar"));
4169 bars.Add(bar);
4170
4171 printf("Now: %u objects in the array, %u objects total.\n",
4172 bars.GetCount(), Bar::GetNumber());
4173
4174 bars.Empty();
4175
4176 printf("After Empty(): %u objects in the array, %u objects total.\n",
4177 bars.GetCount(), Bar::GetNumber());
4178 }
4179
4180 printf("Finally: no more objects in the array, %u objects total.\n",
4181 Bar::GetNumber());
4182 }
4183
4184 #endif // TEST_ARRAYS
4185
4186 // ----------------------------------------------------------------------------
4187 // strings
4188 // ----------------------------------------------------------------------------
4189
4190 #ifdef TEST_STRINGS
4191
4192 #include "wx/timer.h"
4193 #include "wx/tokenzr.h"
4194
4195 static void TestStringConstruction()
4196 {
4197 puts("*** Testing wxString constructores ***");
4198
4199 #define TEST_CTOR(args, res) \
4200 { \
4201 wxString s args ; \
4202 printf("wxString%s = %s ", #args, s.c_str()); \
4203 if ( s == res ) \
4204 { \
4205 puts("(ok)"); \
4206 } \
4207 else \
4208 { \
4209 printf("(ERROR: should be %s)\n", res); \
4210 } \
4211 }
4212
4213 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
4214 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
4215 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
4216 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
4217
4218 static const wxChar *s = _T("?really!");
4219 const wxChar *start = wxStrchr(s, _T('r'));
4220 const wxChar *end = wxStrchr(s, _T('!'));
4221 TEST_CTOR((start, end), _T("really"));
4222
4223 puts("");
4224 }
4225
4226 static void TestString()
4227 {
4228 wxStopWatch sw;
4229
4230 wxString a, b, c;
4231
4232 a.reserve (128);
4233 b.reserve (128);
4234 c.reserve (128);
4235
4236 for (int i = 0; i < 1000000; ++i)
4237 {
4238 a = "Hello";
4239 b = " world";
4240 c = "! How'ya doin'?";
4241 a += b;
4242 a += c;
4243 c = "Hello world! What's up?";
4244 if (c != a)
4245 c = "Doh!";
4246 }
4247
4248 printf ("TestString elapsed time: %ld\n", sw.Time());
4249 }
4250
4251 static void TestPChar()
4252 {
4253 wxStopWatch sw;
4254
4255 char a [128];
4256 char b [128];
4257 char c [128];
4258
4259 for (int i = 0; i < 1000000; ++i)
4260 {
4261 strcpy (a, "Hello");
4262 strcpy (b, " world");
4263 strcpy (c, "! How'ya doin'?");
4264 strcat (a, b);
4265 strcat (a, c);
4266 strcpy (c, "Hello world! What's up?");
4267 if (strcmp (c, a) == 0)
4268 strcpy (c, "Doh!");
4269 }
4270
4271 printf ("TestPChar elapsed time: %ld\n", sw.Time());
4272 }
4273
4274 static void TestStringSub()
4275 {
4276 wxString s("Hello, world!");
4277
4278 puts("*** Testing wxString substring extraction ***");
4279
4280 printf("String = '%s'\n", s.c_str());
4281 printf("Left(5) = '%s'\n", s.Left(5).c_str());
4282 printf("Right(6) = '%s'\n", s.Right(6).c_str());
4283 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
4284 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
4285 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
4286 printf("substr(3) = '%s'\n", s.substr(3).c_str());
4287
4288 static const wxChar *prefixes[] =
4289 {
4290 _T("Hello"),
4291 _T("Hello, "),
4292 _T("Hello, world!"),
4293 _T("Hello, world!!!"),
4294 _T(""),
4295 _T("Goodbye"),
4296 _T("Hi"),
4297 };
4298
4299 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
4300 {
4301 wxString prefix = prefixes[n], rest;
4302 bool rc = s.StartsWith(prefix, &rest);
4303 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
4304 if ( rc )
4305 {
4306 printf(" (the rest is '%s')\n", rest.c_str());
4307 }
4308 else
4309 {
4310 putchar('\n');
4311 }
4312 }
4313
4314 puts("");
4315 }
4316
4317 static void TestStringFormat()
4318 {
4319 puts("*** Testing wxString formatting ***");
4320
4321 wxString s;
4322 s.Printf("%03d", 18);
4323
4324 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
4325 printf("Number 18: %s\n", s.c_str());
4326
4327 puts("");
4328 }
4329
4330 // returns "not found" for npos, value for all others
4331 static wxString PosToString(size_t res)
4332 {
4333 wxString s = res == wxString::npos ? wxString(_T("not found"))
4334 : wxString::Format(_T("%u"), res);
4335 return s;
4336 }
4337
4338 static void TestStringFind()
4339 {
4340 puts("*** Testing wxString find() functions ***");
4341
4342 static const wxChar *strToFind = _T("ell");
4343 static const struct StringFindTest
4344 {
4345 const wxChar *str;
4346 size_t start,
4347 result; // of searching "ell" in str
4348 } findTestData[] =
4349 {
4350 { _T("Well, hello world"), 0, 1 },
4351 { _T("Well, hello world"), 6, 7 },
4352 { _T("Well, hello world"), 9, wxString::npos },
4353 };
4354
4355 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
4356 {
4357 const StringFindTest& ft = findTestData[n];
4358 size_t res = wxString(ft.str).find(strToFind, ft.start);
4359
4360 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
4361 strToFind, ft.str, ft.start, PosToString(res).c_str());
4362
4363 size_t resTrue = ft.result;
4364 if ( res == resTrue )
4365 {
4366 puts(_T("(ok)"));
4367 }
4368 else
4369 {
4370 printf(_T("(ERROR: should be %s)\n"),
4371 PosToString(resTrue).c_str());
4372 }
4373 }
4374
4375 puts("");
4376 }
4377
4378 static void TestStringTokenizer()
4379 {
4380 puts("*** Testing wxStringTokenizer ***");
4381
4382 static const wxChar *modeNames[] =
4383 {
4384 _T("default"),
4385 _T("return empty"),
4386 _T("return all empty"),
4387 _T("with delims"),
4388 _T("like strtok"),
4389 };
4390
4391 static const struct StringTokenizerTest
4392 {
4393 const wxChar *str; // string to tokenize
4394 const wxChar *delims; // delimiters to use
4395 size_t count; // count of token
4396 wxStringTokenizerMode mode; // how should we tokenize it
4397 } tokenizerTestData[] =
4398 {
4399 { _T(""), _T(" "), 0 },
4400 { _T("Hello, world"), _T(" "), 2 },
4401 { _T("Hello, world "), _T(" "), 2 },
4402 { _T("Hello, world"), _T(","), 2 },
4403 { _T("Hello, world!"), _T(",!"), 2 },
4404 { _T("Hello,, world!"), _T(",!"), 3 },
4405 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
4406 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
4407 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
4408 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
4409 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
4410 { _T("01/02/99"), _T("/-"), 3 },
4411 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
4412 };
4413
4414 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
4415 {
4416 const StringTokenizerTest& tt = tokenizerTestData[n];
4417 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
4418
4419 size_t count = tkz.CountTokens();
4420 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
4421 MakePrintable(tt.str).c_str(),
4422 count,
4423 MakePrintable(tt.delims).c_str(),
4424 modeNames[tkz.GetMode()]);
4425 if ( count == tt.count )
4426 {
4427 puts(_T("(ok)"));
4428 }
4429 else
4430 {
4431 printf(_T("(ERROR: should be %u)\n"), tt.count);
4432
4433 continue;
4434 }
4435
4436 // if we emulate strtok(), check that we do it correctly
4437 wxChar *buf, *s = NULL, *last;
4438
4439 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4440 {
4441 buf = new wxChar[wxStrlen(tt.str) + 1];
4442 wxStrcpy(buf, tt.str);
4443
4444 s = wxStrtok(buf, tt.delims, &last);
4445 }
4446 else
4447 {
4448 buf = NULL;
4449 }
4450
4451 // now show the tokens themselves
4452 size_t count2 = 0;
4453 while ( tkz.HasMoreTokens() )
4454 {
4455 wxString token = tkz.GetNextToken();
4456
4457 printf(_T("\ttoken %u: '%s'"),
4458 ++count2,
4459 MakePrintable(token).c_str());
4460
4461 if ( buf )
4462 {
4463 if ( token == s )
4464 {
4465 puts(" (ok)");
4466 }
4467 else
4468 {
4469 printf(" (ERROR: should be %s)\n", s);
4470 }
4471
4472 s = wxStrtok(NULL, tt.delims, &last);
4473 }
4474 else
4475 {
4476 // nothing to compare with
4477 puts("");
4478 }
4479 }
4480
4481 if ( count2 != count )
4482 {
4483 puts(_T("\tERROR: token count mismatch"));
4484 }
4485
4486 delete [] buf;
4487 }
4488
4489 puts("");
4490 }
4491
4492 static void TestStringReplace()
4493 {
4494 puts("*** Testing wxString::replace ***");
4495
4496 static const struct StringReplaceTestData
4497 {
4498 const wxChar *original; // original test string
4499 size_t start, len; // the part to replace
4500 const wxChar *replacement; // the replacement string
4501 const wxChar *result; // and the expected result
4502 } stringReplaceTestData[] =
4503 {
4504 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4505 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4506 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4507 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4508 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4509 };
4510
4511 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4512 {
4513 const StringReplaceTestData data = stringReplaceTestData[n];
4514
4515 wxString original = data.original;
4516 original.replace(data.start, data.len, data.replacement);
4517
4518 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4519 data.original, data.start, data.len, data.replacement,
4520 original.c_str());
4521
4522 if ( original == data.result )
4523 {
4524 puts("(ok)");
4525 }
4526 else
4527 {
4528 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4529 }
4530 }
4531
4532 puts("");
4533 }
4534
4535 #endif // TEST_STRINGS
4536
4537 // ----------------------------------------------------------------------------
4538 // entry point
4539 // ----------------------------------------------------------------------------
4540
4541 int main(int argc, char **argv)
4542 {
4543 if ( !wxInitialize() )
4544 {
4545 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
4546 }
4547
4548 #ifdef TEST_CHARSET
4549 TestCharset();
4550 #endif // TEST_CHARSET
4551
4552 #ifdef TEST_CMDLINE
4553 static const wxCmdLineEntryDesc cmdLineDesc[] =
4554 {
4555 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4556 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4557
4558 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4559 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4560 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
4561 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
4562
4563 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4564 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4565
4566 { wxCMD_LINE_NONE }
4567 };
4568
4569 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4570
4571 parser.AddOption("project_name", "", "full path to project file",
4572 wxCMD_LINE_VAL_STRING,
4573 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4574
4575 switch ( parser.Parse() )
4576 {
4577 case -1:
4578 wxLogMessage("Help was given, terminating.");
4579 break;
4580
4581 case 0:
4582 ShowCmdLine(parser);
4583 break;
4584
4585 default:
4586 wxLogMessage("Syntax error detected, aborting.");
4587 break;
4588 }
4589 #endif // TEST_CMDLINE
4590
4591 #ifdef TEST_STRINGS
4592 if ( 0 )
4593 {
4594 TestPChar();
4595 TestString();
4596 }
4597 TestStringSub();
4598 if ( 0 )
4599 {
4600 TestStringConstruction();
4601 TestStringFormat();
4602 TestStringFind();
4603 TestStringTokenizer();
4604 TestStringReplace();
4605 }
4606 #endif // TEST_STRINGS
4607
4608 #ifdef TEST_ARRAYS
4609 if ( 0 )
4610 {
4611 wxArrayString a1;
4612 a1.Add("tiger");
4613 a1.Add("cat");
4614 a1.Add("lion");
4615 a1.Add("dog");
4616 a1.Add("human");
4617 a1.Add("ape");
4618
4619 puts("*** Initially:");
4620
4621 PrintArray("a1", a1);
4622
4623 wxArrayString a2(a1);
4624 PrintArray("a2", a2);
4625
4626 wxSortedArrayString a3(a1);
4627 PrintArray("a3", a3);
4628
4629 puts("*** After deleting a string from a1");
4630 a1.Remove(2);
4631
4632 PrintArray("a1", a1);
4633 PrintArray("a2", a2);
4634 PrintArray("a3", a3);
4635
4636 puts("*** After reassigning a1 to a2 and a3");
4637 a3 = a2 = a1;
4638 PrintArray("a2", a2);
4639 PrintArray("a3", a3);
4640
4641 puts("*** After sorting a1");
4642 a1.Sort();
4643 PrintArray("a1", a1);
4644
4645 puts("*** After sorting a1 in reverse order");
4646 a1.Sort(TRUE);
4647 PrintArray("a1", a1);
4648
4649 puts("*** After sorting a1 by the string length");
4650 a1.Sort(StringLenCompare);
4651 PrintArray("a1", a1);
4652
4653 TestArrayOfObjects();
4654 }
4655 TestArrayOfInts();
4656 #endif // TEST_ARRAYS
4657
4658 #ifdef TEST_DIR
4659 if ( 0 )
4660 TestDirEnum();
4661 TestDirTraverse();
4662 #endif // TEST_DIR
4663
4664 #ifdef TEST_DLLLOADER
4665 TestDllLoad();
4666 #endif // TEST_DLLLOADER
4667
4668 #ifdef TEST_ENVIRON
4669 TestEnvironment();
4670 #endif // TEST_ENVIRON
4671
4672 #ifdef TEST_EXECUTE
4673 TestExecute();
4674 #endif // TEST_EXECUTE
4675
4676 #ifdef TEST_FILECONF
4677 TestFileConfRead();
4678 #endif // TEST_FILECONF
4679
4680 #ifdef TEST_LIST
4681 TestListCtor();
4682 #endif // TEST_LIST
4683
4684 #ifdef TEST_LOCALE
4685 TestDefaultLang();
4686 #endif // TEST_LOCALE
4687
4688 #ifdef TEST_LOG
4689 wxString s;
4690 for ( size_t n = 0; n < 8000; n++ )
4691 {
4692 s << (char)('A' + (n % 26));
4693 }
4694
4695 wxString msg;
4696 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
4697
4698 // this one shouldn't be truncated
4699 printf(msg);
4700
4701 // but this one will because log functions use fixed size buffer
4702 // (note that it doesn't need '\n' at the end neither - will be added
4703 // by wxLog anyhow)
4704 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
4705 #endif // TEST_LOG
4706
4707 #ifdef TEST_FILE
4708 if ( 0 )
4709 {
4710 TestFileRead();
4711 TestTextFileRead();
4712 }
4713 TestFileCopy();
4714 #endif // TEST_FILE
4715
4716 #ifdef TEST_FILENAME
4717 TestFileNameSplit();
4718 if ( 0 )
4719 {
4720 TestFileNameConstruction();
4721 TestFileNameCwd();
4722 TestFileNameComparison();
4723 TestFileNameOperations();
4724 }
4725 #endif // TEST_FILENAME
4726
4727 #ifdef TEST_THREADS
4728 int nCPUs = wxThread::GetCPUCount();
4729 printf("This system has %d CPUs\n", nCPUs);
4730 if ( nCPUs != -1 )
4731 wxThread::SetConcurrency(nCPUs);
4732
4733 if ( argc > 1 && argv[1][0] == 't' )
4734 wxLog::AddTraceMask("thread");
4735
4736 if ( 1 )
4737 TestDetachedThreads();
4738 if ( 1 )
4739 TestJoinableThreads();
4740 if ( 1 )
4741 TestThreadSuspend();
4742 if ( 1 )
4743 TestThreadDelete();
4744
4745 #endif // TEST_THREADS
4746
4747 #ifdef TEST_LONGLONG
4748 // seed pseudo random generator
4749 srand((unsigned)time(NULL));
4750
4751 if ( 0 )
4752 {
4753 TestSpeed();
4754 }
4755 if ( 0 )
4756 {
4757 TestMultiplication();
4758 TestDivision();
4759 TestAddition();
4760 TestLongLongConversion();
4761 TestBitOperations();
4762 }
4763 TestLongLongComparison();
4764 #endif // TEST_LONGLONG
4765
4766 #ifdef TEST_HASH
4767 TestHash();
4768 #endif // TEST_HASH
4769
4770 #ifdef TEST_MIME
4771 wxLog::AddTraceMask(_T("mime"));
4772 if ( 1 )
4773 {
4774 TestMimeEnum();
4775 TestMimeOverride();
4776 TestMimeFilename();
4777 }
4778 else
4779 TestMimeAssociate();
4780 #endif // TEST_MIME
4781
4782 #ifdef TEST_INFO_FUNCTIONS
4783 TestOsInfo();
4784 TestUserInfo();
4785 #endif // TEST_INFO_FUNCTIONS
4786
4787 #ifdef TEST_PATHLIST
4788 TestPathList();
4789 #endif // TEST_PATHLIST
4790
4791 #ifdef TEST_REGCONF
4792 TestRegConfWrite();
4793 #endif // TEST_REGCONF
4794
4795 #ifdef TEST_REGISTRY
4796 if ( 0 )
4797 TestRegistryRead();
4798 TestRegistryAssociation();
4799 #endif // TEST_REGISTRY
4800
4801 #ifdef TEST_SOCKETS
4802 if ( 0 )
4803 {
4804 TestSocketServer();
4805 }
4806 TestSocketClient();
4807 #endif // TEST_SOCKETS
4808
4809 #ifdef TEST_FTP
4810 wxLog::AddTraceMask(FTP_TRACE_MASK);
4811 if ( TestFtpConnect() )
4812 {
4813 TestFtpFileSize();
4814 if ( 0 )
4815 {
4816 TestFtpList();
4817 TestFtpDownload();
4818 TestFtpMisc();
4819 TestFtpUpload();
4820 }
4821 if ( 0 )
4822 TestFtpInteractive();
4823 }
4824 //else: connecting to the FTP server failed
4825
4826 if ( 0 )
4827 TestFtpWuFtpd();
4828 #endif // TEST_FTP
4829
4830 #ifdef TEST_STREAMS
4831 if ( 0 )
4832 TestFileStream();
4833 TestMemoryStream();
4834 #endif // TEST_STREAMS
4835
4836 #ifdef TEST_TIMER
4837 TestStopWatch();
4838 #endif // TEST_TIMER
4839
4840 #ifdef TEST_DATETIME
4841 if ( 0 )
4842 {
4843 TestTimeSet();
4844 TestTimeStatic();
4845 TestTimeRange();
4846 TestTimeZones();
4847 TestTimeTicks();
4848 TestTimeJDN();
4849 TestTimeDST();
4850 TestTimeWDays();
4851 TestTimeWNumber();
4852 TestTimeParse();
4853 TestTimeArithmetics();
4854 TestTimeHolidays();
4855 TestTimeFormat();
4856 TestTimeMS();
4857
4858 TestTimeZoneBug();
4859 }
4860 TestTimeSpanFormat();
4861 if ( 0 )
4862 TestDateTimeInteractive();
4863 #endif // TEST_DATETIME
4864
4865 #ifdef TEST_USLEEP
4866 puts("Sleeping for 3 seconds... z-z-z-z-z...");
4867 wxUsleep(3000);
4868 #endif // TEST_USLEEP
4869
4870 #ifdef TEST_VCARD
4871 if ( 0 )
4872 TestVCardRead();
4873 TestVCardWrite();
4874 #endif // TEST_VCARD
4875
4876 #ifdef TEST_WCHAR
4877 TestUtf8();
4878 #endif // TEST_WCHAR
4879
4880 #ifdef TEST_ZIP
4881 if ( 0 )
4882 TestZipStreamRead();
4883 TestZipFileSystem();
4884 #endif // TEST_ZIP
4885
4886 #ifdef TEST_ZLIB
4887 if ( 0 )
4888 TestZlibStreamWrite();
4889 TestZlibStreamRead();
4890 #endif // TEST_ZLIB
4891
4892 wxUninitialize();
4893
4894 return 0;
4895 }
4896