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