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