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