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