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