]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
Allow building with wxUSE_CALENDARCTRL=0
[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_TIMER
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 sw.Pause();
3036 printf("Initially paused, after 2 seconds time is...");
3037 fflush(stdout);
3038 wxSleep(2);
3039 printf("\t%ldms\n", sw.Time());
3040
3041 printf("Resuming stopwatch and sleeping 3 seconds...");
3042 fflush(stdout);
3043 sw.Resume();
3044 wxSleep(3);
3045 printf("\telapsed time: %ldms\n", sw.Time());
3046
3047 sw.Pause();
3048 printf("Pausing agan and sleeping 2 more seconds...");
3049 fflush(stdout);
3050 wxSleep(2);
3051 printf("\telapsed time: %ldms\n", sw.Time());
3052
3053 sw.Resume();
3054 printf("Finally resuming and sleeping 2 more seconds...");
3055 fflush(stdout);
3056 wxSleep(2);
3057 printf("\telapsed time: %ldms\n", sw.Time());
3058
3059 wxStopWatch sw2;
3060 puts("\nChecking for 'backwards clock' bug...");
3061 for ( size_t n = 0; n < 70; n++ )
3062 {
3063 sw2.Start();
3064
3065 for ( size_t m = 0; m < 100000; m++ )
3066 {
3067 if ( sw.Time() < 0 || sw2.Time() < 0 )
3068 {
3069 puts("\ntime is negative - ERROR!");
3070 }
3071 }
3072
3073 putchar('.');
3074 fflush(stdout);
3075 }
3076
3077 puts(", ok.");
3078 }
3079
3080 #endif // TEST_TIMER
3081
3082 // ----------------------------------------------------------------------------
3083 // vCard support
3084 // ----------------------------------------------------------------------------
3085
3086 #ifdef TEST_VCARD
3087
3088 #include "wx/vcard.h"
3089
3090 static void DumpVObject(size_t level, const wxVCardObject& vcard)
3091 {
3092 void *cookie;
3093 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3094 while ( vcObj )
3095 {
3096 printf("%s%s",
3097 wxString(_T('\t'), level).c_str(),
3098 vcObj->GetName().c_str());
3099
3100 wxString value;
3101 switch ( vcObj->GetType() )
3102 {
3103 case wxVCardObject::String:
3104 case wxVCardObject::UString:
3105 {
3106 wxString val;
3107 vcObj->GetValue(&val);
3108 value << _T('"') << val << _T('"');
3109 }
3110 break;
3111
3112 case wxVCardObject::Int:
3113 {
3114 unsigned int i;
3115 vcObj->GetValue(&i);
3116 value.Printf(_T("%u"), i);
3117 }
3118 break;
3119
3120 case wxVCardObject::Long:
3121 {
3122 unsigned long l;
3123 vcObj->GetValue(&l);
3124 value.Printf(_T("%lu"), l);
3125 }
3126 break;
3127
3128 case wxVCardObject::None:
3129 break;
3130
3131 case wxVCardObject::Object:
3132 value = _T("<node>");
3133 break;
3134
3135 default:
3136 value = _T("<unknown value type>");
3137 }
3138
3139 if ( !!value )
3140 printf(" = %s", value.c_str());
3141 putchar('\n');
3142
3143 DumpVObject(level + 1, *vcObj);
3144
3145 delete vcObj;
3146 vcObj = vcard.GetNextProp(&cookie);
3147 }
3148 }
3149
3150 static void DumpVCardAddresses(const wxVCard& vcard)
3151 {
3152 puts("\nShowing all addresses from vCard:\n");
3153
3154 size_t nAdr = 0;
3155 void *cookie;
3156 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3157 while ( addr )
3158 {
3159 wxString flagsStr;
3160 int flags = addr->GetFlags();
3161 if ( flags & wxVCardAddress::Domestic )
3162 {
3163 flagsStr << _T("domestic ");
3164 }
3165 if ( flags & wxVCardAddress::Intl )
3166 {
3167 flagsStr << _T("international ");
3168 }
3169 if ( flags & wxVCardAddress::Postal )
3170 {
3171 flagsStr << _T("postal ");
3172 }
3173 if ( flags & wxVCardAddress::Parcel )
3174 {
3175 flagsStr << _T("parcel ");
3176 }
3177 if ( flags & wxVCardAddress::Home )
3178 {
3179 flagsStr << _T("home ");
3180 }
3181 if ( flags & wxVCardAddress::Work )
3182 {
3183 flagsStr << _T("work ");
3184 }
3185
3186 printf("Address %u:\n"
3187 "\tflags = %s\n"
3188 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3189 ++nAdr,
3190 flagsStr.c_str(),
3191 addr->GetPostOffice().c_str(),
3192 addr->GetExtAddress().c_str(),
3193 addr->GetStreet().c_str(),
3194 addr->GetLocality().c_str(),
3195 addr->GetRegion().c_str(),
3196 addr->GetPostalCode().c_str(),
3197 addr->GetCountry().c_str()
3198 );
3199
3200 delete addr;
3201 addr = vcard.GetNextAddress(&cookie);
3202 }
3203 }
3204
3205 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3206 {
3207 puts("\nShowing all phone numbers from vCard:\n");
3208
3209 size_t nPhone = 0;
3210 void *cookie;
3211 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3212 while ( phone )
3213 {
3214 wxString flagsStr;
3215 int flags = phone->GetFlags();
3216 if ( flags & wxVCardPhoneNumber::Voice )
3217 {
3218 flagsStr << _T("voice ");
3219 }
3220 if ( flags & wxVCardPhoneNumber::Fax )
3221 {
3222 flagsStr << _T("fax ");
3223 }
3224 if ( flags & wxVCardPhoneNumber::Cellular )
3225 {
3226 flagsStr << _T("cellular ");
3227 }
3228 if ( flags & wxVCardPhoneNumber::Modem )
3229 {
3230 flagsStr << _T("modem ");
3231 }
3232 if ( flags & wxVCardPhoneNumber::Home )
3233 {
3234 flagsStr << _T("home ");
3235 }
3236 if ( flags & wxVCardPhoneNumber::Work )
3237 {
3238 flagsStr << _T("work ");
3239 }
3240
3241 printf("Phone number %u:\n"
3242 "\tflags = %s\n"
3243 "\tvalue = %s\n",
3244 ++nPhone,
3245 flagsStr.c_str(),
3246 phone->GetNumber().c_str()
3247 );
3248
3249 delete phone;
3250 phone = vcard.GetNextPhoneNumber(&cookie);
3251 }
3252 }
3253
3254 static void TestVCardRead()
3255 {
3256 puts("*** Testing wxVCard reading ***\n");
3257
3258 wxVCard vcard(_T("vcard.vcf"));
3259 if ( !vcard.IsOk() )
3260 {
3261 puts("ERROR: couldn't load vCard.");
3262 }
3263 else
3264 {
3265 // read individual vCard properties
3266 wxVCardObject *vcObj = vcard.GetProperty("FN");
3267 wxString value;
3268 if ( vcObj )
3269 {
3270 vcObj->GetValue(&value);
3271 delete vcObj;
3272 }
3273 else
3274 {
3275 value = _T("<none>");
3276 }
3277
3278 printf("Full name retrieved directly: %s\n", value.c_str());
3279
3280
3281 if ( !vcard.GetFullName(&value) )
3282 {
3283 value = _T("<none>");
3284 }
3285
3286 printf("Full name from wxVCard API: %s\n", value.c_str());
3287
3288 // now show how to deal with multiply occuring properties
3289 DumpVCardAddresses(vcard);
3290 DumpVCardPhoneNumbers(vcard);
3291
3292 // and finally show all
3293 puts("\nNow dumping the entire vCard:\n"
3294 "-----------------------------\n");
3295
3296 DumpVObject(0, vcard);
3297 }
3298 }
3299
3300 static void TestVCardWrite()
3301 {
3302 puts("*** Testing wxVCard writing ***\n");
3303
3304 wxVCard vcard;
3305 if ( !vcard.IsOk() )
3306 {
3307 puts("ERROR: couldn't create vCard.");
3308 }
3309 else
3310 {
3311 // set some fields
3312 vcard.SetName("Zeitlin", "Vadim");
3313 vcard.SetFullName("Vadim Zeitlin");
3314 vcard.SetOrganization("wxWindows", "R&D");
3315
3316 // just dump the vCard back
3317 puts("Entire vCard follows:\n");
3318 puts(vcard.Write());
3319 }
3320 }
3321
3322 #endif // TEST_VCARD
3323
3324 // ----------------------------------------------------------------------------
3325 // wxVolume tests
3326 // ----------------------------------------------------------------------------
3327
3328 #if !wxUSE_FSVOLUME
3329 #undef TEST_VOLUME
3330 #endif
3331
3332 #ifdef TEST_VOLUME
3333
3334 #include "wx/volume.h"
3335
3336 static const wxChar *volumeKinds[] =
3337 {
3338 _T("floppy"),
3339 _T("hard disk"),
3340 _T("CD-ROM"),
3341 _T("DVD-ROM"),
3342 _T("network volume"),
3343 _T("other volume"),
3344 };
3345
3346 static void TestFSVolume()
3347 {
3348 wxPuts(_T("*** Testing wxFSVolume class ***"));
3349
3350 wxArrayString volumes = wxFSVolume::GetVolumes();
3351 size_t count = volumes.GetCount();
3352
3353 if ( !count )
3354 {
3355 wxPuts(_T("ERROR: no mounted volumes?"));
3356 return;
3357 }
3358
3359 wxPrintf(_T("%u mounted volumes found:\n"), count);
3360
3361 for ( size_t n = 0; n < count; n++ )
3362 {
3363 wxFSVolume vol(volumes[n]);
3364 if ( !vol.IsOk() )
3365 {
3366 wxPuts(_T("ERROR: couldn't create volume"));
3367 continue;
3368 }
3369
3370 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3371 n + 1,
3372 vol.GetDisplayName().c_str(),
3373 vol.GetName().c_str(),
3374 volumeKinds[vol.GetKind()],
3375 vol.IsWritable() ? _T("rw") : _T("ro"),
3376 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3377 : _T("fixed"));
3378 }
3379 }
3380
3381 #endif // TEST_VOLUME
3382
3383 // ----------------------------------------------------------------------------
3384 // wide char (Unicode) support
3385 // ----------------------------------------------------------------------------
3386
3387 #ifdef TEST_WCHAR
3388
3389 #include "wx/strconv.h"
3390 #include "wx/fontenc.h"
3391 #include "wx/encconv.h"
3392 #include "wx/buffer.h"
3393
3394 static const char textInUtf8[] =
3395 {
3396 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3397 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3398 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3399 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3400 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3401 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3402 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3403 };
3404
3405 static void TestUtf8()
3406 {
3407 puts("*** Testing UTF8 support ***\n");
3408
3409 char buf[1024];
3410 wchar_t wbuf[1024];
3411 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
3412 {
3413 puts("ERROR: UTF-8 decoding failed.");
3414 }
3415 else
3416 {
3417 wxCSConv conv(_T("koi8-r"));
3418 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
3419 {
3420 puts("ERROR: conversion to KOI8-R failed.");
3421 }
3422 else
3423 {
3424 printf("The resulting string (in KOI8-R): %s\n", buf);
3425 }
3426 }
3427
3428 if ( wxConvUTF8.WC2MB(buf, L"à la", WXSIZEOF(buf)) <= 0 )
3429 {
3430 puts("ERROR: conversion to UTF-8 failed.");
3431 }
3432 else
3433 {
3434 printf("The string in UTF-8: %s\n", buf);
3435 }
3436
3437 puts("");
3438 }
3439
3440 static void TestEncodingConverter()
3441 {
3442 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3443
3444 // using wxEncodingConverter should give the same result as above
3445 char buf[1024];
3446 wchar_t wbuf[1024];
3447 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
3448 {
3449 puts("ERROR: UTF-8 decoding failed.");
3450 }
3451 else
3452 {
3453 wxEncodingConverter ec;
3454 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3455 ec.Convert(wbuf, buf);
3456 printf("The same string obtained using wxEC: %s\n", buf);
3457 }
3458
3459 puts("");
3460 }
3461
3462 #endif // TEST_WCHAR
3463
3464 // ----------------------------------------------------------------------------
3465 // ZIP stream
3466 // ----------------------------------------------------------------------------
3467
3468 #ifdef TEST_ZIP
3469
3470 #include "wx/filesys.h"
3471 #include "wx/fs_zip.h"
3472 #include "wx/zipstrm.h"
3473
3474 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3475
3476 static void TestZipStreamRead()
3477 {
3478 puts("*** Testing ZIP reading ***\n");
3479
3480 static const wxChar *filename = _T("foo");
3481 wxZipInputStream istr(TESTFILE_ZIP, filename);
3482 printf("Archive size: %u\n", istr.GetSize());
3483
3484 printf("Dumping the file '%s':\n", filename);
3485 while ( !istr.Eof() )
3486 {
3487 putchar(istr.GetC());
3488 fflush(stdout);
3489 }
3490
3491 puts("\n----- done ------");
3492 }
3493
3494 static void DumpZipDirectory(wxFileSystem& fs,
3495 const wxString& dir,
3496 const wxString& indent)
3497 {
3498 wxString prefix = wxString::Format(_T("%s#zip:%s"),
3499 TESTFILE_ZIP, dir.c_str());
3500 wxString wildcard = prefix + _T("/*");
3501
3502 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3503 while ( !dirname.empty() )
3504 {
3505 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3506 {
3507 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3508
3509 break;
3510 }
3511
3512 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3513
3514 DumpZipDirectory(fs, dirname,
3515 indent + wxString(_T(' '), 4));
3516
3517 dirname = fs.FindNext();
3518 }
3519
3520 wxString filename = fs.FindFirst(wildcard, wxFILE);
3521 while ( !filename.empty() )
3522 {
3523 if ( !filename.StartsWith(prefix, &filename) )
3524 {
3525 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3526
3527 break;
3528 }
3529
3530 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3531
3532 filename = fs.FindNext();
3533 }
3534 }
3535
3536 static void TestZipFileSystem()
3537 {
3538 puts("*** Testing ZIP file system ***\n");
3539
3540 wxFileSystem::AddHandler(new wxZipFSHandler);
3541 wxFileSystem fs;
3542 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3543
3544 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3545 }
3546
3547 #endif // TEST_ZIP
3548
3549 // ----------------------------------------------------------------------------
3550 // ZLIB stream
3551 // ----------------------------------------------------------------------------
3552
3553 #ifdef TEST_ZLIB
3554
3555 #include "wx/zstream.h"
3556 #include "wx/wfstream.h"
3557
3558 static const wxChar *FILENAME_GZ = _T("test.gz");
3559 static const char *TEST_DATA = "hello and hello again";
3560
3561 static void TestZlibStreamWrite()
3562 {
3563 puts("*** Testing Zlib stream reading ***\n");
3564
3565 wxFileOutputStream fileOutStream(FILENAME_GZ);
3566 wxZlibOutputStream ostr(fileOutStream, 0);
3567 printf("Compressing the test string... ");
3568 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3569 if ( !ostr )
3570 {
3571 puts("(ERROR: failed)");
3572 }
3573 else
3574 {
3575 puts("(ok)");
3576 }
3577
3578 puts("\n----- done ------");
3579 }
3580
3581 static void TestZlibStreamRead()
3582 {
3583 puts("*** Testing Zlib stream reading ***\n");
3584
3585 wxFileInputStream fileInStream(FILENAME_GZ);
3586 wxZlibInputStream istr(fileInStream);
3587 printf("Archive size: %u\n", istr.GetSize());
3588
3589 puts("Dumping the file:");
3590 while ( !istr.Eof() )
3591 {
3592 putchar(istr.GetC());
3593 fflush(stdout);
3594 }
3595
3596 puts("\n----- done ------");
3597 }
3598
3599 #endif // TEST_ZLIB
3600
3601 // ----------------------------------------------------------------------------
3602 // date time
3603 // ----------------------------------------------------------------------------
3604
3605 #ifdef TEST_DATETIME
3606
3607 #include <math.h>
3608
3609 #include "wx/date.h"
3610 #include "wx/datetime.h"
3611
3612 // the test data
3613 struct Date
3614 {
3615 wxDateTime::wxDateTime_t day;
3616 wxDateTime::Month month;
3617 int year;
3618 wxDateTime::wxDateTime_t hour, min, sec;
3619 double jdn;
3620 wxDateTime::WeekDay wday;
3621 time_t gmticks, ticks;
3622
3623 void Init(const wxDateTime::Tm& tm)
3624 {
3625 day = tm.mday;
3626 month = tm.mon;
3627 year = tm.year;
3628 hour = tm.hour;
3629 min = tm.min;
3630 sec = tm.sec;
3631 jdn = 0.0;
3632 gmticks = ticks = -1;
3633 }
3634
3635 wxDateTime DT() const
3636 { return wxDateTime(day, month, year, hour, min, sec); }
3637
3638 bool SameDay(const wxDateTime::Tm& tm) const
3639 {
3640 return day == tm.mday && month == tm.mon && year == tm.year;
3641 }
3642
3643 wxString Format() const
3644 {
3645 wxString s;
3646 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3647 hour, min, sec,
3648 wxDateTime::GetMonthName(month).c_str(),
3649 day,
3650 abs(wxDateTime::ConvertYearToBC(year)),
3651 year > 0 ? "AD" : "BC");
3652 return s;
3653 }
3654
3655 wxString FormatDate() const
3656 {
3657 wxString s;
3658 s.Printf("%02d-%s-%4d%s",
3659 day,
3660 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3661 abs(wxDateTime::ConvertYearToBC(year)),
3662 year > 0 ? "AD" : "BC");
3663 return s;
3664 }
3665 };
3666
3667 static const Date testDates[] =
3668 {
3669 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3670 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3671 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3672 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3673 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3674 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3675 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3676 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3677 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3678 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
3679 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3680 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3681 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3682 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
3683 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
3684 };
3685
3686 // this test miscellaneous static wxDateTime functions
3687 static void TestTimeStatic()
3688 {
3689 puts("\n*** wxDateTime static methods test ***");
3690
3691 // some info about the current date
3692 int year = wxDateTime::GetCurrentYear();
3693 printf("Current year %d is %sa leap one and has %d days.\n",
3694 year,
3695 wxDateTime::IsLeapYear(year) ? "" : "not ",
3696 wxDateTime::GetNumberOfDays(year));
3697
3698 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3699 printf("Current month is '%s' ('%s') and it has %d days\n",
3700 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3701 wxDateTime::GetMonthName(month).c_str(),
3702 wxDateTime::GetNumberOfDays(month));
3703
3704 // leap year logic
3705 static const size_t nYears = 5;
3706 static const size_t years[2][nYears] =
3707 {
3708 // first line: the years to test
3709 { 1990, 1976, 2000, 2030, 1984, },
3710
3711 // second line: TRUE if leap, FALSE otherwise
3712 { FALSE, TRUE, TRUE, FALSE, TRUE }
3713 };
3714
3715 for ( size_t n = 0; n < nYears; n++ )
3716 {
3717 int year = years[0][n];
3718 bool should = years[1][n] != 0,
3719 is = wxDateTime::IsLeapYear(year);
3720
3721 printf("Year %d is %sa leap year (%s)\n",
3722 year,
3723 is ? "" : "not ",
3724 should == is ? "ok" : "ERROR");
3725
3726 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3727 }
3728 }
3729
3730 // test constructing wxDateTime objects
3731 static void TestTimeSet()
3732 {
3733 puts("\n*** wxDateTime construction test ***");
3734
3735 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3736 {
3737 const Date& d1 = testDates[n];
3738 wxDateTime dt = d1.DT();
3739
3740 Date d2;
3741 d2.Init(dt.GetTm());
3742
3743 wxString s1 = d1.Format(),
3744 s2 = d2.Format();
3745
3746 printf("Date: %s == %s (%s)\n",
3747 s1.c_str(), s2.c_str(),
3748 s1 == s2 ? "ok" : "ERROR");
3749 }
3750 }
3751
3752 // test time zones stuff
3753 static void TestTimeZones()
3754 {
3755 puts("\n*** wxDateTime timezone test ***");
3756
3757 wxDateTime now = wxDateTime::Now();
3758
3759 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3760 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3761 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3762 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3763 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3764 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
3765
3766 wxDateTime::Tm tm = now.GetTm();
3767 if ( wxDateTime(tm) != now )
3768 {
3769 printf("ERROR: got %s instead of %s\n",
3770 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3771 }
3772 }
3773
3774 // test some minimal support for the dates outside the standard range
3775 static void TestTimeRange()
3776 {
3777 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3778
3779 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3780
3781 printf("Unix epoch:\t%s\n",
3782 wxDateTime(2440587.5).Format(fmt).c_str());
3783 printf("Feb 29, 0: \t%s\n",
3784 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3785 printf("JDN 0: \t%s\n",
3786 wxDateTime(0.0).Format(fmt).c_str());
3787 printf("Jan 1, 1AD:\t%s\n",
3788 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3789 printf("May 29, 2099:\t%s\n",
3790 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3791 }
3792
3793 static void TestTimeTicks()
3794 {
3795 puts("\n*** wxDateTime ticks test ***");
3796
3797 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3798 {
3799 const Date& d = testDates[n];
3800 if ( d.ticks == -1 )
3801 continue;
3802
3803 wxDateTime dt = d.DT();
3804 long ticks = (dt.GetValue() / 1000).ToLong();
3805 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3806 if ( ticks == d.ticks )
3807 {
3808 puts(" (ok)");
3809 }
3810 else
3811 {
3812 printf(" (ERROR: should be %ld, delta = %ld)\n",
3813 d.ticks, ticks - d.ticks);
3814 }
3815
3816 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3817 ticks = (dt.GetValue() / 1000).ToLong();
3818 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3819 if ( ticks == d.gmticks )
3820 {
3821 puts(" (ok)");
3822 }
3823 else
3824 {
3825 printf(" (ERROR: should be %ld, delta = %ld)\n",
3826 d.gmticks, ticks - d.gmticks);
3827 }
3828 }
3829
3830 puts("");
3831 }
3832
3833 // test conversions to JDN &c
3834 static void TestTimeJDN()
3835 {
3836 puts("\n*** wxDateTime to JDN test ***");
3837
3838 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3839 {
3840 const Date& d = testDates[n];
3841 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3842 double jdn = dt.GetJulianDayNumber();
3843
3844 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
3845 if ( jdn == d.jdn )
3846 {
3847 puts(" (ok)");
3848 }
3849 else
3850 {
3851 printf(" (ERROR: should be %f, delta = %f)\n",
3852 d.jdn, jdn - d.jdn);
3853 }
3854 }
3855 }
3856
3857 // test week days computation
3858 static void TestTimeWDays()
3859 {
3860 puts("\n*** wxDateTime weekday test ***");
3861
3862 // test GetWeekDay()
3863 size_t n;
3864 for ( n = 0; n < WXSIZEOF(testDates); n++ )
3865 {
3866 const Date& d = testDates[n];
3867 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3868
3869 wxDateTime::WeekDay wday = dt.GetWeekDay();
3870 printf("%s is: %s",
3871 d.Format().c_str(),
3872 wxDateTime::GetWeekDayName(wday).c_str());
3873 if ( wday == d.wday )
3874 {
3875 puts(" (ok)");
3876 }
3877 else
3878 {
3879 printf(" (ERROR: should be %s)\n",
3880 wxDateTime::GetWeekDayName(d.wday).c_str());
3881 }
3882 }
3883
3884 puts("");
3885
3886 // test SetToWeekDay()
3887 struct WeekDateTestData
3888 {
3889 Date date; // the real date (precomputed)
3890 int nWeek; // its week index in the month
3891 wxDateTime::WeekDay wday; // the weekday
3892 wxDateTime::Month month; // the month
3893 int year; // and the year
3894
3895 wxString Format() const
3896 {
3897 wxString s, which;
3898 switch ( nWeek < -1 ? -nWeek : nWeek )
3899 {
3900 case 1: which = "first"; break;
3901 case 2: which = "second"; break;
3902 case 3: which = "third"; break;
3903 case 4: which = "fourth"; break;
3904 case 5: which = "fifth"; break;
3905
3906 case -1: which = "last"; break;
3907 }
3908
3909 if ( nWeek < -1 )
3910 {
3911 which += " from end";
3912 }
3913
3914 s.Printf("The %s %s of %s in %d",
3915 which.c_str(),
3916 wxDateTime::GetWeekDayName(wday).c_str(),
3917 wxDateTime::GetMonthName(month).c_str(),
3918 year);
3919
3920 return s;
3921 }
3922 };
3923
3924 // the array data was generated by the following python program
3925 /*
3926 from DateTime import *
3927 from whrandom import *
3928 from string import *
3929
3930 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3931 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3932
3933 week = DateTimeDelta(7)
3934
3935 for n in range(20):
3936 year = randint(1900, 2100)
3937 month = randint(1, 12)
3938 day = randint(1, 28)
3939 dt = DateTime(year, month, day)
3940 wday = dt.day_of_week
3941
3942 countFromEnd = choice([-1, 1])
3943 weekNum = 0;
3944
3945 while dt.month is month:
3946 dt = dt - countFromEnd * week
3947 weekNum = weekNum + countFromEnd
3948
3949 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
3950
3951 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3952 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
3953 */
3954
3955 static const WeekDateTestData weekDatesTestData[] =
3956 {
3957 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3958 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3959 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3960 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3961 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3962 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3963 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3964 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3965 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3966 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3967 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3968 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3969 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3970 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3971 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3972 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3973 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3974 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3975 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3976 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3977 };
3978
3979 static const char *fmt = "%d-%b-%Y";
3980
3981 wxDateTime dt;
3982 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3983 {
3984 const WeekDateTestData& wd = weekDatesTestData[n];
3985
3986 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3987
3988 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3989
3990 const Date& d = wd.date;
3991 if ( d.SameDay(dt.GetTm()) )
3992 {
3993 puts(" (ok)");
3994 }
3995 else
3996 {
3997 dt.Set(d.day, d.month, d.year);
3998
3999 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
4000 }
4001 }
4002 }
4003
4004 // test the computation of (ISO) week numbers
4005 static void TestTimeWNumber()
4006 {
4007 puts("\n*** wxDateTime week number test ***");
4008
4009 struct WeekNumberTestData
4010 {
4011 Date date; // the date
4012 wxDateTime::wxDateTime_t week; // the week number in the year
4013 wxDateTime::wxDateTime_t wmon; // the week number in the month
4014 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
4015 wxDateTime::wxDateTime_t dnum; // day number in the year
4016 };
4017
4018 // data generated with the following python script:
4019 /*
4020 from DateTime import *
4021 from whrandom import *
4022 from string import *
4023
4024 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4025 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4026
4027 def GetMonthWeek(dt):
4028 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4029 if weekNumMonth < 0:
4030 weekNumMonth = weekNumMonth + 53
4031 return weekNumMonth
4032
4033 def GetLastSundayBefore(dt):
4034 if dt.iso_week[2] == 7:
4035 return dt
4036 else:
4037 return dt - DateTimeDelta(dt.iso_week[2])
4038
4039 for n in range(20):
4040 year = randint(1900, 2100)
4041 month = randint(1, 12)
4042 day = randint(1, 28)
4043 dt = DateTime(year, month, day)
4044 dayNum = dt.day_of_year
4045 weekNum = dt.iso_week[1]
4046 weekNumMonth = GetMonthWeek(dt)
4047
4048 weekNumMonth2 = 0
4049 dtSunday = GetLastSundayBefore(dt)
4050
4051 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4052 weekNumMonth2 = weekNumMonth2 + 1
4053 dtSunday = dtSunday - DateTimeDelta(7)
4054
4055 data = { 'day': rjust(`day`, 2), \
4056 'month': monthNames[month - 1], \
4057 'year': year, \
4058 'weekNum': rjust(`weekNum`, 2), \
4059 'weekNumMonth': weekNumMonth, \
4060 'weekNumMonth2': weekNumMonth2, \
4061 'dayNum': rjust(`dayNum`, 3) }
4062
4063 print " { { %(day)s, "\
4064 "wxDateTime::%(month)s, "\
4065 "%(year)d }, "\
4066 "%(weekNum)s, "\
4067 "%(weekNumMonth)s, "\
4068 "%(weekNumMonth2)s, "\
4069 "%(dayNum)s }," % data
4070
4071 */
4072 static const WeekNumberTestData weekNumberTestDates[] =
4073 {
4074 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
4075 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
4076 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
4077 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
4078 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
4079 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
4080 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
4081 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
4082 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
4083 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
4084 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
4085 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
4086 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
4087 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
4088 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
4089 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
4090 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
4091 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
4092 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
4093 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
4094 };
4095
4096 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
4097 {
4098 const WeekNumberTestData& wn = weekNumberTestDates[n];
4099 const Date& d = wn.date;
4100
4101 wxDateTime dt = d.DT();
4102
4103 wxDateTime::wxDateTime_t
4104 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
4105 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
4106 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4107 dnum = dt.GetDayOfYear();
4108
4109 printf("%s: the day number is %d",
4110 d.FormatDate().c_str(), dnum);
4111 if ( dnum == wn.dnum )
4112 {
4113 printf(" (ok)");
4114 }
4115 else
4116 {
4117 printf(" (ERROR: should be %d)", wn.dnum);
4118 }
4119
4120 printf(", week in month is %d", wmon);
4121 if ( wmon == wn.wmon )
4122 {
4123 printf(" (ok)");
4124 }
4125 else
4126 {
4127 printf(" (ERROR: should be %d)", wn.wmon);
4128 }
4129
4130 printf(" or %d", wmon2);
4131 if ( wmon2 == wn.wmon2 )
4132 {
4133 printf(" (ok)");
4134 }
4135 else
4136 {
4137 printf(" (ERROR: should be %d)", wn.wmon2);
4138 }
4139
4140 printf(", week in year is %d", week);
4141 if ( week == wn.week )
4142 {
4143 puts(" (ok)");
4144 }
4145 else
4146 {
4147 printf(" (ERROR: should be %d)\n", wn.week);
4148 }
4149 }
4150 }
4151
4152 // test DST calculations
4153 static void TestTimeDST()
4154 {
4155 puts("\n*** wxDateTime DST test ***");
4156
4157 printf("DST is%s in effect now.\n\n",
4158 wxDateTime::Now().IsDST() ? "" : " not");
4159
4160 // taken from http://www.energy.ca.gov/daylightsaving.html
4161 static const Date datesDST[2][2004 - 1900 + 1] =
4162 {
4163 {
4164 { 1, wxDateTime::Apr, 1990 },
4165 { 7, wxDateTime::Apr, 1991 },
4166 { 5, wxDateTime::Apr, 1992 },
4167 { 4, wxDateTime::Apr, 1993 },
4168 { 3, wxDateTime::Apr, 1994 },
4169 { 2, wxDateTime::Apr, 1995 },
4170 { 7, wxDateTime::Apr, 1996 },
4171 { 6, wxDateTime::Apr, 1997 },
4172 { 5, wxDateTime::Apr, 1998 },
4173 { 4, wxDateTime::Apr, 1999 },
4174 { 2, wxDateTime::Apr, 2000 },
4175 { 1, wxDateTime::Apr, 2001 },
4176 { 7, wxDateTime::Apr, 2002 },
4177 { 6, wxDateTime::Apr, 2003 },
4178 { 4, wxDateTime::Apr, 2004 },
4179 },
4180 {
4181 { 28, wxDateTime::Oct, 1990 },
4182 { 27, wxDateTime::Oct, 1991 },
4183 { 25, wxDateTime::Oct, 1992 },
4184 { 31, wxDateTime::Oct, 1993 },
4185 { 30, wxDateTime::Oct, 1994 },
4186 { 29, wxDateTime::Oct, 1995 },
4187 { 27, wxDateTime::Oct, 1996 },
4188 { 26, wxDateTime::Oct, 1997 },
4189 { 25, wxDateTime::Oct, 1998 },
4190 { 31, wxDateTime::Oct, 1999 },
4191 { 29, wxDateTime::Oct, 2000 },
4192 { 28, wxDateTime::Oct, 2001 },
4193 { 27, wxDateTime::Oct, 2002 },
4194 { 26, wxDateTime::Oct, 2003 },
4195 { 31, wxDateTime::Oct, 2004 },
4196 }
4197 };
4198
4199 int year;
4200 for ( year = 1990; year < 2005; year++ )
4201 {
4202 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4203 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4204
4205 printf("DST period in the US for year %d: from %s to %s",
4206 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
4207
4208 size_t n = year - 1990;
4209 const Date& dBegin = datesDST[0][n];
4210 const Date& dEnd = datesDST[1][n];
4211
4212 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4213 {
4214 puts(" (ok)");
4215 }
4216 else
4217 {
4218 printf(" (ERROR: should be %s %d to %s %d)\n",
4219 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4220 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
4221 }
4222 }
4223
4224 puts("");
4225
4226 for ( year = 1990; year < 2005; year++ )
4227 {
4228 printf("DST period in Europe for year %d: from %s to %s\n",
4229 year,
4230 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4231 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
4232 }
4233 }
4234
4235 // test wxDateTime -> text conversion
4236 static void TestTimeFormat()
4237 {
4238 puts("\n*** wxDateTime formatting test ***");
4239
4240 // some information may be lost during conversion, so store what kind
4241 // of info should we recover after a round trip
4242 enum CompareKind
4243 {
4244 CompareNone, // don't try comparing
4245 CompareBoth, // dates and times should be identical
4246 CompareDate, // dates only
4247 CompareTime // time only
4248 };
4249
4250 static const struct
4251 {
4252 CompareKind compareKind;
4253 const char *format;
4254 } formatTestFormats[] =
4255 {
4256 { CompareBoth, "---> %c" },
4257 { CompareDate, "Date is %A, %d of %B, in year %Y" },
4258 { CompareBoth, "Date is %x, time is %X" },
4259 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
4260 { CompareNone, "The day of year: %j, the week of year: %W" },
4261 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
4262 };
4263
4264 static const Date formatTestDates[] =
4265 {
4266 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4267 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
4268 #if 0
4269 // this test can't work for other centuries because it uses two digit
4270 // years in formats, so don't even try it
4271 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4272 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4273 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
4274 #endif
4275 };
4276
4277 // an extra test (as it doesn't depend on date, don't do it in the loop)
4278 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
4279
4280 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
4281 {
4282 puts("");
4283
4284 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
4285 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4286 {
4287 wxString s = dt.Format(formatTestFormats[n].format);
4288 printf("%s", s.c_str());
4289
4290 // what can we recover?
4291 int kind = formatTestFormats[n].compareKind;
4292
4293 // convert back
4294 wxDateTime dt2;
4295 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
4296 if ( !result )
4297 {
4298 // converion failed - should it have?
4299 if ( kind == CompareNone )
4300 puts(" (ok)");
4301 else
4302 puts(" (ERROR: conversion back failed)");
4303 }
4304 else if ( *result )
4305 {
4306 // should have parsed the entire string
4307 puts(" (ERROR: conversion back stopped too soon)");
4308 }
4309 else
4310 {
4311 bool equal = FALSE; // suppress compilaer warning
4312 switch ( kind )
4313 {
4314 case CompareBoth:
4315 equal = dt2 == dt;
4316 break;
4317
4318 case CompareDate:
4319 equal = dt.IsSameDate(dt2);
4320 break;
4321
4322 case CompareTime:
4323 equal = dt.IsSameTime(dt2);
4324 break;
4325 }
4326
4327 if ( !equal )
4328 {
4329 printf(" (ERROR: got back '%s' instead of '%s')\n",
4330 dt2.Format().c_str(), dt.Format().c_str());
4331 }
4332 else
4333 {
4334 puts(" (ok)");
4335 }
4336 }
4337 }
4338 }
4339 }
4340
4341 // test text -> wxDateTime conversion
4342 static void TestTimeParse()
4343 {
4344 puts("\n*** wxDateTime parse test ***");
4345
4346 struct ParseTestData
4347 {
4348 const char *format;
4349 Date date;
4350 bool good;
4351 };
4352
4353 static const ParseTestData parseTestDates[] =
4354 {
4355 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
4356 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
4357 };
4358
4359 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4360 {
4361 const char *format = parseTestDates[n].format;
4362
4363 printf("%s => ", format);
4364
4365 wxDateTime dt;
4366 if ( dt.ParseRfc822Date(format) )
4367 {
4368 printf("%s ", dt.Format().c_str());
4369
4370 if ( parseTestDates[n].good )
4371 {
4372 wxDateTime dtReal = parseTestDates[n].date.DT();
4373 if ( dt == dtReal )
4374 {
4375 puts("(ok)");
4376 }
4377 else
4378 {
4379 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
4380 }
4381 }
4382 else
4383 {
4384 puts("(ERROR: bad format)");
4385 }
4386 }
4387 else
4388 {
4389 printf("bad format (%s)\n",
4390 parseTestDates[n].good ? "ERROR" : "ok");
4391 }
4392 }
4393 }
4394
4395 static void TestDateTimeInteractive()
4396 {
4397 puts("\n*** interactive wxDateTime tests ***");
4398
4399 char buf[128];
4400
4401 for ( ;; )
4402 {
4403 printf("Enter a date: ");
4404 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
4405 break;
4406
4407 // kill the last '\n'
4408 buf[strlen(buf) - 1] = 0;
4409
4410 wxDateTime dt;
4411 const char *p = dt.ParseDate(buf);
4412 if ( !p )
4413 {
4414 printf("ERROR: failed to parse the date '%s'.\n", buf);
4415
4416 continue;
4417 }
4418 else if ( *p )
4419 {
4420 printf("WARNING: parsed only first %u characters.\n", p - buf);
4421 }
4422
4423 printf("%s: day %u, week of month %u/%u, week of year %u\n",
4424 dt.Format("%b %d, %Y").c_str(),
4425 dt.GetDayOfYear(),
4426 dt.GetWeekOfMonth(wxDateTime::Monday_First),
4427 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4428 dt.GetWeekOfYear(wxDateTime::Monday_First));
4429 }
4430
4431 puts("\n*** done ***");
4432 }
4433
4434 static void TestTimeMS()
4435 {
4436 puts("*** testing millisecond-resolution support in wxDateTime ***");
4437
4438 wxDateTime dt1 = wxDateTime::Now(),
4439 dt2 = wxDateTime::UNow();
4440
4441 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
4442 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
4443 printf("Dummy loop: ");
4444 for ( int i = 0; i < 6000; i++ )
4445 {
4446 //for ( int j = 0; j < 10; j++ )
4447 {
4448 wxString s;
4449 s.Printf("%g", sqrt(i));
4450 }
4451
4452 if ( !(i % 100) )
4453 putchar('.');
4454 }
4455 puts(", done");
4456
4457 dt1 = dt2;
4458 dt2 = wxDateTime::UNow();
4459 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
4460
4461 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
4462
4463 puts("\n*** done ***");
4464 }
4465
4466 static void TestTimeArithmetics()
4467 {
4468 puts("\n*** testing arithmetic operations on wxDateTime ***");
4469
4470 static const struct ArithmData
4471 {
4472 ArithmData(const wxDateSpan& sp, const char *nam)
4473 : span(sp), name(nam) { }
4474
4475 wxDateSpan span;
4476 const char *name;
4477 } testArithmData[] =
4478 {
4479 ArithmData(wxDateSpan::Day(), "day"),
4480 ArithmData(wxDateSpan::Week(), "week"),
4481 ArithmData(wxDateSpan::Month(), "month"),
4482 ArithmData(wxDateSpan::Year(), "year"),
4483 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
4484 };
4485
4486 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
4487
4488 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
4489 {
4490 wxDateSpan span = testArithmData[n].span;
4491 dt1 = dt + span;
4492 dt2 = dt - span;
4493
4494 const char *name = testArithmData[n].name;
4495 printf("%s + %s = %s, %s - %s = %s\n",
4496 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
4497 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
4498
4499 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
4500 if ( dt1 - span == dt )
4501 {
4502 puts(" (ok)");
4503 }
4504 else
4505 {
4506 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4507 }
4508
4509 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
4510 if ( dt2 + span == dt )
4511 {
4512 puts(" (ok)");
4513 }
4514 else
4515 {
4516 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4517 }
4518
4519 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
4520 if ( dt2 + 2*span == dt1 )
4521 {
4522 puts(" (ok)");
4523 }
4524 else
4525 {
4526 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
4527 }
4528
4529 puts("");
4530 }
4531 }
4532
4533 static void TestTimeHolidays()
4534 {
4535 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
4536
4537 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
4538 wxDateTime dtStart(1, tm.mon, tm.year),
4539 dtEnd = dtStart.GetLastMonthDay();
4540
4541 wxDateTimeArray hol;
4542 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
4543
4544 const wxChar *format = "%d-%b-%Y (%a)";
4545
4546 printf("All holidays between %s and %s:\n",
4547 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4548
4549 size_t count = hol.GetCount();
4550 for ( size_t n = 0; n < count; n++ )
4551 {
4552 printf("\t%s\n", hol[n].Format(format).c_str());
4553 }
4554
4555 puts("");
4556 }
4557
4558 static void TestTimeZoneBug()
4559 {
4560 puts("\n*** testing for DST/timezone bug ***\n");
4561
4562 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4563 for ( int i = 0; i < 31; i++ )
4564 {
4565 printf("Date %s: week day %s.\n",
4566 date.Format(_T("%d-%m-%Y")).c_str(),
4567 date.GetWeekDayName(date.GetWeekDay()).c_str());
4568
4569 date += wxDateSpan::Day();
4570 }
4571
4572 puts("");
4573 }
4574
4575 static void TestTimeSpanFormat()
4576 {
4577 puts("\n*** wxTimeSpan tests ***");
4578
4579 static const char *formats[] =
4580 {
4581 _T("(default) %H:%M:%S"),
4582 _T("%E weeks and %D days"),
4583 _T("%l milliseconds"),
4584 _T("(with ms) %H:%M:%S:%l"),
4585 _T("100%% of minutes is %M"), // test "%%"
4586 _T("%D days and %H hours"),
4587 _T("or also %S seconds"),
4588 };
4589
4590 wxTimeSpan ts1(1, 2, 3, 4),
4591 ts2(111, 222, 333);
4592 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4593 {
4594 printf("ts1 = %s\tts2 = %s\n",
4595 ts1.Format(formats[n]).c_str(),
4596 ts2.Format(formats[n]).c_str());
4597 }
4598
4599 puts("");
4600 }
4601
4602 #if 0
4603
4604 // test compatibility with the old wxDate/wxTime classes
4605 static void TestTimeCompatibility()
4606 {
4607 puts("\n*** wxDateTime compatibility test ***");
4608
4609 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4610 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4611
4612 double jdnNow = wxDateTime::Now().GetJDN();
4613 long jdnMidnight = (long)(jdnNow - 0.5);
4614 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4615
4616 jdnMidnight = wxDate().Set().GetJulianDate();
4617 printf("wxDateTime for today: %s\n",
4618 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4619
4620 int flags = wxEUROPEAN;//wxFULL;
4621 wxDate date;
4622 date.Set();
4623 printf("Today is %s\n", date.FormatDate(flags).c_str());
4624 for ( int n = 0; n < 7; n++ )
4625 {
4626 printf("Previous %s is %s\n",
4627 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4628 date.Previous(n + 1).FormatDate(flags).c_str());
4629 }
4630 }
4631
4632 #endif // 0
4633
4634 #endif // TEST_DATETIME
4635
4636 // ----------------------------------------------------------------------------
4637 // threads
4638 // ----------------------------------------------------------------------------
4639
4640 #ifdef TEST_THREADS
4641
4642 #include "wx/thread.h"
4643
4644 static size_t gs_counter = (size_t)-1;
4645 static wxCriticalSection gs_critsect;
4646 static wxSemaphore gs_cond;
4647
4648 class MyJoinableThread : public wxThread
4649 {
4650 public:
4651 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4652 { m_n = n; Create(); }
4653
4654 // thread execution starts here
4655 virtual ExitCode Entry();
4656
4657 private:
4658 size_t m_n;
4659 };
4660
4661 wxThread::ExitCode MyJoinableThread::Entry()
4662 {
4663 unsigned long res = 1;
4664 for ( size_t n = 1; n < m_n; n++ )
4665 {
4666 res *= n;
4667
4668 // it's a loooong calculation :-)
4669 Sleep(100);
4670 }
4671
4672 return (ExitCode)res;
4673 }
4674
4675 class MyDetachedThread : public wxThread
4676 {
4677 public:
4678 MyDetachedThread(size_t n, char ch)
4679 {
4680 m_n = n;
4681 m_ch = ch;
4682 m_cancelled = FALSE;
4683
4684 Create();
4685 }
4686
4687 // thread execution starts here
4688 virtual ExitCode Entry();
4689
4690 // and stops here
4691 virtual void OnExit();
4692
4693 private:
4694 size_t m_n; // number of characters to write
4695 char m_ch; // character to write
4696
4697 bool m_cancelled; // FALSE if we exit normally
4698 };
4699
4700 wxThread::ExitCode MyDetachedThread::Entry()
4701 {
4702 {
4703 wxCriticalSectionLocker lock(gs_critsect);
4704 if ( gs_counter == (size_t)-1 )
4705 gs_counter = 1;
4706 else
4707 gs_counter++;
4708 }
4709
4710 for ( size_t n = 0; n < m_n; n++ )
4711 {
4712 if ( TestDestroy() )
4713 {
4714 m_cancelled = TRUE;
4715
4716 break;
4717 }
4718
4719 putchar(m_ch);
4720 fflush(stdout);
4721
4722 wxThread::Sleep(100);
4723 }
4724
4725 return 0;
4726 }
4727
4728 void MyDetachedThread::OnExit()
4729 {
4730 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4731
4732 wxCriticalSectionLocker lock(gs_critsect);
4733 if ( !--gs_counter && !m_cancelled )
4734 gs_cond.Post();
4735 }
4736
4737 static void TestDetachedThreads()
4738 {
4739 puts("\n*** Testing detached threads ***");
4740
4741 static const size_t nThreads = 3;
4742 MyDetachedThread *threads[nThreads];
4743 size_t n;
4744 for ( n = 0; n < nThreads; n++ )
4745 {
4746 threads[n] = new MyDetachedThread(10, 'A' + n);
4747 }
4748
4749 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4750 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4751
4752 for ( n = 0; n < nThreads; n++ )
4753 {
4754 threads[n]->Run();
4755 }
4756
4757 // wait until all threads terminate
4758 gs_cond.Wait();
4759
4760 puts("");
4761 }
4762
4763 static void TestJoinableThreads()
4764 {
4765 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
4766
4767 // calc 10! in the background
4768 MyJoinableThread thread(10);
4769 thread.Run();
4770
4771 printf("\nThread terminated with exit code %lu.\n",
4772 (unsigned long)thread.Wait());
4773 }
4774
4775 static void TestThreadSuspend()
4776 {
4777 puts("\n*** Testing thread suspend/resume functions ***");
4778
4779 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
4780
4781 thread->Run();
4782
4783 // this is for this demo only, in a real life program we'd use another
4784 // condition variable which would be signaled from wxThread::Entry() to
4785 // tell us that the thread really started running - but here just wait a
4786 // bit and hope that it will be enough (the problem is, of course, that
4787 // the thread might still not run when we call Pause() which will result
4788 // in an error)
4789 wxThread::Sleep(300);
4790
4791 for ( size_t n = 0; n < 3; n++ )
4792 {
4793 thread->Pause();
4794
4795 puts("\nThread suspended");
4796 if ( n > 0 )
4797 {
4798 // don't sleep but resume immediately the first time
4799 wxThread::Sleep(300);
4800 }
4801 puts("Going to resume the thread");
4802
4803 thread->Resume();
4804 }
4805
4806 puts("Waiting until it terminates now");
4807
4808 // wait until the thread terminates
4809 gs_cond.Wait();
4810
4811 puts("");
4812 }
4813
4814 static void TestThreadDelete()
4815 {
4816 // As above, using Sleep() is only for testing here - we must use some
4817 // synchronisation object instead to ensure that the thread is still
4818 // running when we delete it - deleting a detached thread which already
4819 // terminated will lead to a crash!
4820
4821 puts("\n*** Testing thread delete function ***");
4822
4823 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4824
4825 thread0->Delete();
4826
4827 puts("\nDeleted a thread which didn't start to run yet.");
4828
4829 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4830
4831 thread1->Run();
4832
4833 wxThread::Sleep(300);
4834
4835 thread1->Delete();
4836
4837 puts("\nDeleted a running thread.");
4838
4839 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4840
4841 thread2->Run();
4842
4843 wxThread::Sleep(300);
4844
4845 thread2->Pause();
4846
4847 thread2->Delete();
4848
4849 puts("\nDeleted a sleeping thread.");
4850
4851 MyJoinableThread thread3(20);
4852 thread3.Run();
4853
4854 thread3.Delete();
4855
4856 puts("\nDeleted a joinable thread.");
4857
4858 MyJoinableThread thread4(2);
4859 thread4.Run();
4860
4861 wxThread::Sleep(300);
4862
4863 thread4.Delete();
4864
4865 puts("\nDeleted a joinable thread which already terminated.");
4866
4867 puts("");
4868 }
4869
4870 class MyWaitingThread : public wxThread
4871 {
4872 public:
4873 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
4874 {
4875 m_mutex = mutex;
4876 m_condition = condition;
4877
4878 Create();
4879 }
4880
4881 virtual ExitCode Entry()
4882 {
4883 printf("Thread %lu has started running.\n", GetId());
4884 fflush(stdout);
4885
4886 gs_cond.Post();
4887
4888 printf("Thread %lu starts to wait...\n", GetId());
4889 fflush(stdout);
4890
4891 m_mutex->Lock();
4892 m_condition->Wait();
4893 m_mutex->Unlock();
4894
4895 printf("Thread %lu finished to wait, exiting.\n", GetId());
4896 fflush(stdout);
4897
4898 return 0;
4899 }
4900
4901 private:
4902 wxMutex *m_mutex;
4903 wxCondition *m_condition;
4904 };
4905
4906 static void TestThreadConditions()
4907 {
4908 wxMutex mutex;
4909 wxCondition condition(mutex);
4910
4911 // otherwise its difficult to understand which log messages pertain to
4912 // which condition
4913 //wxLogTrace("thread", "Local condition var is %08x, gs_cond = %08x",
4914 // condition.GetId(), gs_cond.GetId());
4915
4916 // create and launch threads
4917 MyWaitingThread *threads[10];
4918
4919 size_t n;
4920 for ( n = 0; n < WXSIZEOF(threads); n++ )
4921 {
4922 threads[n] = new MyWaitingThread( &mutex, &condition );
4923 }
4924
4925 for ( n = 0; n < WXSIZEOF(threads); n++ )
4926 {
4927 threads[n]->Run();
4928 }
4929
4930 // wait until all threads run
4931 puts("Main thread is waiting for the other threads to start");
4932 fflush(stdout);
4933
4934 size_t nRunning = 0;
4935 while ( nRunning < WXSIZEOF(threads) )
4936 {
4937 gs_cond.Wait();
4938
4939 nRunning++;
4940
4941 printf("Main thread: %u already running\n", nRunning);
4942 fflush(stdout);
4943 }
4944
4945 puts("Main thread: all threads started up.");
4946 fflush(stdout);
4947
4948 wxThread::Sleep(500);
4949
4950 #if 1
4951 // now wake one of them up
4952 printf("Main thread: about to signal the condition.\n");
4953 fflush(stdout);
4954 condition.Signal();
4955 #endif
4956
4957 wxThread::Sleep(200);
4958
4959 // wake all the (remaining) threads up, so that they can exit
4960 printf("Main thread: about to broadcast the condition.\n");
4961 fflush(stdout);
4962 condition.Broadcast();
4963
4964 // give them time to terminate (dirty!)
4965 wxThread::Sleep(500);
4966 }
4967
4968 #include "wx/utils.h"
4969
4970 class MyExecThread : public wxThread
4971 {
4972 public:
4973 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
4974 m_command(command)
4975 {
4976 Create();
4977 }
4978
4979 virtual ExitCode Entry()
4980 {
4981 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
4982 }
4983
4984 private:
4985 wxString m_command;
4986 };
4987
4988 static void TestThreadExec()
4989 {
4990 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
4991
4992 MyExecThread thread(_T("true"));
4993 thread.Run();
4994
4995 wxPrintf(_T("Main program exit code: %ld.\n"),
4996 wxExecute(_T("false"), wxEXEC_SYNC));
4997
4998 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
4999 }
5000
5001 // semaphore tests
5002 #include "wx/datetime.h"
5003
5004 class MySemaphoreThread : public wxThread
5005 {
5006 public:
5007 MySemaphoreThread(int i, wxSemaphore *sem)
5008 : wxThread(wxTHREAD_JOINABLE),
5009 m_sem(sem),
5010 m_i(i)
5011 {
5012 Create();
5013 }
5014
5015 virtual ExitCode Entry()
5016 {
5017 wxPrintf(_T("%s: Thread %d starting to wait for semaphore...\n"),
5018 wxDateTime::Now().FormatTime().c_str(), m_i);
5019
5020 m_sem->Wait();
5021
5022 wxPrintf(_T("%s: Thread %d acquired the semaphore.\n"),
5023 wxDateTime::Now().FormatTime().c_str(), m_i);
5024
5025 Sleep(1000);
5026
5027 wxPrintf(_T("%s: Thread %d releasing the semaphore.\n"),
5028 wxDateTime::Now().FormatTime().c_str(), m_i);
5029
5030 m_sem->Post();
5031
5032 return 0;
5033 }
5034
5035 private:
5036 wxSemaphore *m_sem;
5037 int m_i;
5038 };
5039
5040 WX_DEFINE_ARRAY(wxThread *, ArrayThreads);
5041
5042 static void TestSemaphore()
5043 {
5044 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5045
5046 static const int SEM_LIMIT = 3;
5047
5048 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
5049 ArrayThreads threads;
5050
5051 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
5052 {
5053 threads.Add(new MySemaphoreThread(i, &sem));
5054 threads.Last()->Run();
5055 }
5056
5057 for ( size_t n = 0; n < threads.GetCount(); n++ )
5058 {
5059 threads[n]->Wait();
5060 delete threads[n];
5061 }
5062 }
5063
5064 #endif // TEST_THREADS
5065
5066 // ----------------------------------------------------------------------------
5067 // arrays
5068 // ----------------------------------------------------------------------------
5069
5070 #ifdef TEST_ARRAYS
5071
5072 #include "wx/dynarray.h"
5073
5074 #define DefineCompare(name, T) \
5075 \
5076 int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
5077 { \
5078 return first - second; \
5079 } \
5080 \
5081 int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
5082 { \
5083 return *first - *second; \
5084 } \
5085 \
5086 int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
5087 { \
5088 return *second - *first; \
5089 } \
5090
5091 DefineCompare(Short, short);
5092 DefineCompare(Int, int);
5093
5094 // test compilation of all macros
5095 WX_DEFINE_ARRAY(short, wxArrayShort);
5096 WX_DEFINE_SORTED_ARRAY(short, wxSortedArrayShortNoCmp);
5097 WX_DEFINE_SORTED_ARRAY_CMP(short, ShortCompareValues, wxSortedArrayShort);
5098 WX_DEFINE_SORTED_ARRAY_CMP(int, IntCompareValues, wxSortedArrayInt);
5099
5100 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
5101 #include "wx/arrimpl.cpp"
5102 WX_DEFINE_OBJARRAY(ArrayBars);
5103
5104 static void PrintArray(const char* name, const wxArrayString& array)
5105 {
5106 printf("Dump of the array '%s'\n", name);
5107
5108 size_t nCount = array.GetCount();
5109 for ( size_t n = 0; n < nCount; n++ )
5110 {
5111 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
5112 }
5113 }
5114
5115 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
5116 const wxString& second)
5117 {
5118 return first.length() - second.length();
5119 }
5120
5121 #define TestArrayOf(name) \
5122 \
5123 static void PrintArray(const char* name, const wxSortedArray##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 PrintArray(const char* name, const wxArray##name & array) \
5135 { \
5136 printf("Dump of the array '%s'\n", name); \
5137 \
5138 size_t nCount = array.GetCount(); \
5139 for ( size_t n = 0; n < nCount; n++ ) \
5140 { \
5141 printf("\t%s[%u] = %d\n", name, n, array[n]); \
5142 } \
5143 } \
5144 \
5145 static void TestArrayOf ## name ## s() \
5146 { \
5147 printf("*** Testing wxArray%s ***\n", #name); \
5148 \
5149 wxArray##name a; \
5150 a.Add(1); \
5151 a.Add(17); \
5152 a.Add(5); \
5153 a.Add(3); \
5154 \
5155 puts("Initially:"); \
5156 PrintArray("a", a); \
5157 \
5158 puts("After sort:"); \
5159 a.Sort(name ## Compare); \
5160 PrintArray("a", a); \
5161 \
5162 puts("After reverse sort:"); \
5163 a.Sort(name ## RevCompare); \
5164 PrintArray("a", a); \
5165 \
5166 wxSortedArray##name b; \
5167 b.Add(1); \
5168 b.Add(17); \
5169 b.Add(5); \
5170 b.Add(3); \
5171 \
5172 puts("Sorted array initially:"); \
5173 PrintArray("b", b); \
5174 }
5175
5176 TestArrayOf(Short);
5177 TestArrayOf(Int);
5178
5179 static void TestArrayOfObjects()
5180 {
5181 puts("*** Testing wxObjArray ***\n");
5182
5183 {
5184 ArrayBars bars;
5185 Bar bar("second bar");
5186
5187 printf("Initially: %u objects in the array, %u objects total.\n",
5188 bars.GetCount(), Bar::GetNumber());
5189
5190 bars.Add(new Bar("first bar"));
5191 bars.Add(bar);
5192
5193 printf("Now: %u objects in the array, %u objects total.\n",
5194 bars.GetCount(), Bar::GetNumber());
5195
5196 bars.Empty();
5197
5198 printf("After Empty(): %u objects in the array, %u objects total.\n",
5199 bars.GetCount(), Bar::GetNumber());
5200 }
5201
5202 printf("Finally: no more objects in the array, %u objects total.\n",
5203 Bar::GetNumber());
5204 }
5205
5206 #endif // TEST_ARRAYS
5207
5208 // ----------------------------------------------------------------------------
5209 // strings
5210 // ----------------------------------------------------------------------------
5211
5212 #ifdef TEST_STRINGS
5213
5214 #include "wx/timer.h"
5215 #include "wx/tokenzr.h"
5216
5217 static void TestStringConstruction()
5218 {
5219 puts("*** Testing wxString constructores ***");
5220
5221 #define TEST_CTOR(args, res) \
5222 { \
5223 wxString s args ; \
5224 printf("wxString%s = %s ", #args, s.c_str()); \
5225 if ( s == res ) \
5226 { \
5227 puts("(ok)"); \
5228 } \
5229 else \
5230 { \
5231 printf("(ERROR: should be %s)\n", res); \
5232 } \
5233 }
5234
5235 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5236 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5237 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5238 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5239
5240 static const wxChar *s = _T("?really!");
5241 const wxChar *start = wxStrchr(s, _T('r'));
5242 const wxChar *end = wxStrchr(s, _T('!'));
5243 TEST_CTOR((start, end), _T("really"));
5244
5245 puts("");
5246 }
5247
5248 static void TestString()
5249 {
5250 wxStopWatch sw;
5251
5252 wxString a, b, c;
5253
5254 a.reserve (128);
5255 b.reserve (128);
5256 c.reserve (128);
5257
5258 for (int i = 0; i < 1000000; ++i)
5259 {
5260 a = "Hello";
5261 b = " world";
5262 c = "! How'ya doin'?";
5263 a += b;
5264 a += c;
5265 c = "Hello world! What's up?";
5266 if (c != a)
5267 c = "Doh!";
5268 }
5269
5270 printf ("TestString elapsed time: %ld\n", sw.Time());
5271 }
5272
5273 static void TestPChar()
5274 {
5275 wxStopWatch sw;
5276
5277 char a [128];
5278 char b [128];
5279 char c [128];
5280
5281 for (int i = 0; i < 1000000; ++i)
5282 {
5283 strcpy (a, "Hello");
5284 strcpy (b, " world");
5285 strcpy (c, "! How'ya doin'?");
5286 strcat (a, b);
5287 strcat (a, c);
5288 strcpy (c, "Hello world! What's up?");
5289 if (strcmp (c, a) == 0)
5290 strcpy (c, "Doh!");
5291 }
5292
5293 printf ("TestPChar elapsed time: %ld\n", sw.Time());
5294 }
5295
5296 static void TestStringSub()
5297 {
5298 wxString s("Hello, world!");
5299
5300 puts("*** Testing wxString substring extraction ***");
5301
5302 printf("String = '%s'\n", s.c_str());
5303 printf("Left(5) = '%s'\n", s.Left(5).c_str());
5304 printf("Right(6) = '%s'\n", s.Right(6).c_str());
5305 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
5306 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
5307 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
5308 printf("substr(3) = '%s'\n", s.substr(3).c_str());
5309
5310 static const wxChar *prefixes[] =
5311 {
5312 _T("Hello"),
5313 _T("Hello, "),
5314 _T("Hello, world!"),
5315 _T("Hello, world!!!"),
5316 _T(""),
5317 _T("Goodbye"),
5318 _T("Hi"),
5319 };
5320
5321 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5322 {
5323 wxString prefix = prefixes[n], rest;
5324 bool rc = s.StartsWith(prefix, &rest);
5325 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
5326 if ( rc )
5327 {
5328 printf(" (the rest is '%s')\n", rest.c_str());
5329 }
5330 else
5331 {
5332 putchar('\n');
5333 }
5334 }
5335
5336 puts("");
5337 }
5338
5339 static void TestStringFormat()
5340 {
5341 puts("*** Testing wxString formatting ***");
5342
5343 wxString s;
5344 s.Printf("%03d", 18);
5345
5346 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
5347 printf("Number 18: %s\n", s.c_str());
5348
5349 puts("");
5350 }
5351
5352 // returns "not found" for npos, value for all others
5353 static wxString PosToString(size_t res)
5354 {
5355 wxString s = res == wxString::npos ? wxString(_T("not found"))
5356 : wxString::Format(_T("%u"), res);
5357 return s;
5358 }
5359
5360 static void TestStringFind()
5361 {
5362 puts("*** Testing wxString find() functions ***");
5363
5364 static const wxChar *strToFind = _T("ell");
5365 static const struct StringFindTest
5366 {
5367 const wxChar *str;
5368 size_t start,
5369 result; // of searching "ell" in str
5370 } findTestData[] =
5371 {
5372 { _T("Well, hello world"), 0, 1 },
5373 { _T("Well, hello world"), 6, 7 },
5374 { _T("Well, hello world"), 9, wxString::npos },
5375 };
5376
5377 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5378 {
5379 const StringFindTest& ft = findTestData[n];
5380 size_t res = wxString(ft.str).find(strToFind, ft.start);
5381
5382 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
5383 strToFind, ft.str, ft.start, PosToString(res).c_str());
5384
5385 size_t resTrue = ft.result;
5386 if ( res == resTrue )
5387 {
5388 puts(_T("(ok)"));
5389 }
5390 else
5391 {
5392 printf(_T("(ERROR: should be %s)\n"),
5393 PosToString(resTrue).c_str());
5394 }
5395 }
5396
5397 puts("");
5398 }
5399
5400 static void TestStringTokenizer()
5401 {
5402 puts("*** Testing wxStringTokenizer ***");
5403
5404 static const wxChar *modeNames[] =
5405 {
5406 _T("default"),
5407 _T("return empty"),
5408 _T("return all empty"),
5409 _T("with delims"),
5410 _T("like strtok"),
5411 };
5412
5413 static const struct StringTokenizerTest
5414 {
5415 const wxChar *str; // string to tokenize
5416 const wxChar *delims; // delimiters to use
5417 size_t count; // count of token
5418 wxStringTokenizerMode mode; // how should we tokenize it
5419 } tokenizerTestData[] =
5420 {
5421 { _T(""), _T(" "), 0 },
5422 { _T("Hello, world"), _T(" "), 2 },
5423 { _T("Hello, world "), _T(" "), 2 },
5424 { _T("Hello, world"), _T(","), 2 },
5425 { _T("Hello, world!"), _T(",!"), 2 },
5426 { _T("Hello,, world!"), _T(",!"), 3 },
5427 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
5428 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
5429 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
5430 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
5431 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
5432 { _T("01/02/99"), _T("/-"), 3 },
5433 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
5434 };
5435
5436 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
5437 {
5438 const StringTokenizerTest& tt = tokenizerTestData[n];
5439 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
5440
5441 size_t count = tkz.CountTokens();
5442 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
5443 MakePrintable(tt.str).c_str(),
5444 count,
5445 MakePrintable(tt.delims).c_str(),
5446 modeNames[tkz.GetMode()]);
5447 if ( count == tt.count )
5448 {
5449 puts(_T("(ok)"));
5450 }
5451 else
5452 {
5453 printf(_T("(ERROR: should be %u)\n"), tt.count);
5454
5455 continue;
5456 }
5457
5458 // if we emulate strtok(), check that we do it correctly
5459 wxChar *buf, *s = NULL, *last;
5460
5461 if ( tkz.GetMode() == wxTOKEN_STRTOK )
5462 {
5463 buf = new wxChar[wxStrlen(tt.str) + 1];
5464 wxStrcpy(buf, tt.str);
5465
5466 s = wxStrtok(buf, tt.delims, &last);
5467 }
5468 else
5469 {
5470 buf = NULL;
5471 }
5472
5473 // now show the tokens themselves
5474 size_t count2 = 0;
5475 while ( tkz.HasMoreTokens() )
5476 {
5477 wxString token = tkz.GetNextToken();
5478
5479 printf(_T("\ttoken %u: '%s'"),
5480 ++count2,
5481 MakePrintable(token).c_str());
5482
5483 if ( buf )
5484 {
5485 if ( token == s )
5486 {
5487 puts(" (ok)");
5488 }
5489 else
5490 {
5491 printf(" (ERROR: should be %s)\n", s);
5492 }
5493
5494 s = wxStrtok(NULL, tt.delims, &last);
5495 }
5496 else
5497 {
5498 // nothing to compare with
5499 puts("");
5500 }
5501 }
5502
5503 if ( count2 != count )
5504 {
5505 puts(_T("\tERROR: token count mismatch"));
5506 }
5507
5508 delete [] buf;
5509 }
5510
5511 puts("");
5512 }
5513
5514 static void TestStringReplace()
5515 {
5516 puts("*** Testing wxString::replace ***");
5517
5518 static const struct StringReplaceTestData
5519 {
5520 const wxChar *original; // original test string
5521 size_t start, len; // the part to replace
5522 const wxChar *replacement; // the replacement string
5523 const wxChar *result; // and the expected result
5524 } stringReplaceTestData[] =
5525 {
5526 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
5527 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
5528 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
5529 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
5530 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
5531 };
5532
5533 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
5534 {
5535 const StringReplaceTestData data = stringReplaceTestData[n];
5536
5537 wxString original = data.original;
5538 original.replace(data.start, data.len, data.replacement);
5539
5540 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
5541 data.original, data.start, data.len, data.replacement,
5542 original.c_str());
5543
5544 if ( original == data.result )
5545 {
5546 puts("(ok)");
5547 }
5548 else
5549 {
5550 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
5551 }
5552 }
5553
5554 puts("");
5555 }
5556
5557 static void TestStringMatch()
5558 {
5559 wxPuts(_T("*** Testing wxString::Matches() ***"));
5560
5561 static const struct StringMatchTestData
5562 {
5563 const wxChar *text;
5564 const wxChar *wildcard;
5565 bool matches;
5566 } stringMatchTestData[] =
5567 {
5568 { _T("foobar"), _T("foo*"), 1 },
5569 { _T("foobar"), _T("*oo*"), 1 },
5570 { _T("foobar"), _T("*bar"), 1 },
5571 { _T("foobar"), _T("??????"), 1 },
5572 { _T("foobar"), _T("f??b*"), 1 },
5573 { _T("foobar"), _T("f?b*"), 0 },
5574 { _T("foobar"), _T("*goo*"), 0 },
5575 { _T("foobar"), _T("*foo"), 0 },
5576 { _T("foobarfoo"), _T("*foo"), 1 },
5577 { _T(""), _T("*"), 1 },
5578 { _T(""), _T("?"), 0 },
5579 };
5580
5581 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
5582 {
5583 const StringMatchTestData& data = stringMatchTestData[n];
5584 bool matches = wxString(data.text).Matches(data.wildcard);
5585 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
5586 data.wildcard,
5587 matches ? _T("matches") : _T("doesn't match"),
5588 data.text,
5589 matches == data.matches ? _T("ok") : _T("ERROR"));
5590 }
5591
5592 wxPuts(_T(""));
5593 }
5594
5595 #endif // TEST_STRINGS
5596
5597 // ----------------------------------------------------------------------------
5598 // entry point
5599 // ----------------------------------------------------------------------------
5600
5601 #ifdef TEST_SNGLINST
5602 #include "wx/snglinst.h"
5603 #endif // TEST_SNGLINST
5604
5605 int main(int argc, char **argv)
5606 {
5607 wxInitializer initializer;
5608 if ( !initializer )
5609 {
5610 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
5611
5612 return -1;
5613 }
5614
5615 #ifdef TEST_SNGLINST
5616 wxSingleInstanceChecker checker;
5617 if ( checker.Create(_T(".wxconsole.lock")) )
5618 {
5619 if ( checker.IsAnotherRunning() )
5620 {
5621 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
5622
5623 return 1;
5624 }
5625
5626 // wait some time to give time to launch another instance
5627 wxPrintf(_T("Press \"Enter\" to continue..."));
5628 wxFgetc(stdin);
5629 }
5630 else // failed to create
5631 {
5632 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
5633 }
5634 #endif // TEST_SNGLINST
5635
5636 #ifdef TEST_CHARSET
5637 TestCharset();
5638 #endif // TEST_CHARSET
5639
5640 #ifdef TEST_CMDLINE
5641 TestCmdLineConvert();
5642
5643 #if wxUSE_CMDLINE_PARSER
5644 static const wxCmdLineEntryDesc cmdLineDesc[] =
5645 {
5646 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
5647 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
5648 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
5649 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
5650
5651 { wxCMD_LINE_OPTION, "o", "output", "output file" },
5652 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
5653 { wxCMD_LINE_OPTION, "s", "size", "output block size",
5654 wxCMD_LINE_VAL_NUMBER },
5655 { wxCMD_LINE_OPTION, "d", "date", "output file date",
5656 wxCMD_LINE_VAL_DATE },
5657
5658 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
5659 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
5660
5661 { wxCMD_LINE_NONE }
5662 };
5663
5664 wxCmdLineParser parser(cmdLineDesc, argc, argv);
5665
5666 parser.AddOption("project_name", "", "full path to project file",
5667 wxCMD_LINE_VAL_STRING,
5668 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
5669
5670 switch ( parser.Parse() )
5671 {
5672 case -1:
5673 wxLogMessage("Help was given, terminating.");
5674 break;
5675
5676 case 0:
5677 ShowCmdLine(parser);
5678 break;
5679
5680 default:
5681 wxLogMessage("Syntax error detected, aborting.");
5682 break;
5683 }
5684 #endif // wxUSE_CMDLINE_PARSER
5685
5686 #endif // TEST_CMDLINE
5687
5688 #ifdef TEST_STRINGS
5689 if ( TEST_ALL )
5690 {
5691 TestPChar();
5692 TestString();
5693 TestStringSub();
5694 TestStringConstruction();
5695 TestStringFormat();
5696 TestStringFind();
5697 TestStringTokenizer();
5698 TestStringReplace();
5699 }
5700 else
5701 {
5702 TestStringMatch();
5703 }
5704 #endif // TEST_STRINGS
5705
5706 #ifdef TEST_ARRAYS
5707 if ( TEST_ALL )
5708 {
5709 wxArrayString a1;
5710 a1.Add("tiger");
5711 a1.Add("cat");
5712 a1.Add("lion");
5713 a1.Add("dog");
5714 a1.Add("human");
5715 a1.Add("ape");
5716
5717 puts("*** Initially:");
5718
5719 PrintArray("a1", a1);
5720
5721 wxArrayString a2(a1);
5722 PrintArray("a2", a2);
5723
5724 wxSortedArrayString a3(a1);
5725 PrintArray("a3", a3);
5726
5727 puts("*** After deleting a string from a1");
5728 a1.Remove(2);
5729
5730 PrintArray("a1", a1);
5731 PrintArray("a2", a2);
5732 PrintArray("a3", a3);
5733
5734 puts("*** After reassigning a1 to a2 and a3");
5735 a3 = a2 = a1;
5736 PrintArray("a2", a2);
5737 PrintArray("a3", a3);
5738
5739 puts("*** After sorting a1");
5740 a1.Sort();
5741 PrintArray("a1", a1);
5742
5743 puts("*** After sorting a1 in reverse order");
5744 a1.Sort(TRUE);
5745 PrintArray("a1", a1);
5746
5747 puts("*** After sorting a1 by the string length");
5748 a1.Sort(StringLenCompare);
5749 PrintArray("a1", a1);
5750
5751 TestArrayOfObjects();
5752 TestArrayOfShorts();
5753 }
5754
5755 TestArrayOfInts();
5756 #endif // TEST_ARRAYS
5757
5758 #ifdef TEST_DIR
5759 if ( TEST_ALL )
5760 {
5761 TestDirEnum();
5762 TestDirTraverse();
5763 }
5764 #endif // TEST_DIR
5765
5766 #ifdef TEST_DLLLOADER
5767 TestDllLoad();
5768 #endif // TEST_DLLLOADER
5769
5770 #ifdef TEST_ENVIRON
5771 TestEnvironment();
5772 #endif // TEST_ENVIRON
5773
5774 #ifdef TEST_EXECUTE
5775 TestExecute();
5776 #endif // TEST_EXECUTE
5777
5778 #ifdef TEST_FILECONF
5779 TestFileConfRead();
5780 #endif // TEST_FILECONF
5781
5782 #ifdef TEST_LIST
5783 TestListCtor();
5784 #endif // TEST_LIST
5785
5786 #ifdef TEST_LOCALE
5787 TestDefaultLang();
5788 #endif // TEST_LOCALE
5789
5790 #ifdef TEST_LOG
5791 wxString s;
5792 for ( size_t n = 0; n < 8000; n++ )
5793 {
5794 s << (char)('A' + (n % 26));
5795 }
5796
5797 wxString msg;
5798 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5799
5800 // this one shouldn't be truncated
5801 printf(msg);
5802
5803 // but this one will because log functions use fixed size buffer
5804 // (note that it doesn't need '\n' at the end neither - will be added
5805 // by wxLog anyhow)
5806 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
5807 #endif // TEST_LOG
5808
5809 #ifdef TEST_FILE
5810 if ( TEST_ALL )
5811 {
5812 TestFileRead();
5813 TestTextFileRead();
5814 TestFileCopy();
5815 }
5816 #endif // TEST_FILE
5817
5818 #ifdef TEST_FILENAME
5819 if ( 0 )
5820 {
5821 wxFileName fn;
5822 fn.Assign("c:\\foo", "bar.baz");
5823
5824 DumpFileName(fn);
5825 }
5826
5827 if ( 1 )
5828 {
5829 TestFileNameConstruction();
5830 TestFileNameMakeRelative();
5831 TestFileNameSplit();
5832 TestFileNameTemp();
5833 TestFileNameCwd();
5834 TestFileNameComparison();
5835 TestFileNameOperations();
5836 }
5837 #endif // TEST_FILENAME
5838
5839 #ifdef TEST_FILETIME
5840 TestFileGetTimes();
5841 TestFileSetTimes();
5842 #endif // TEST_FILETIME
5843
5844 #ifdef TEST_FTP
5845 wxLog::AddTraceMask(FTP_TRACE_MASK);
5846 if ( TestFtpConnect() )
5847 {
5848 if ( TEST_ALL )
5849 {
5850 TestFtpList();
5851 TestFtpDownload();
5852 TestFtpMisc();
5853 TestFtpFileSize();
5854 TestFtpUpload();
5855 }
5856
5857 if ( TEST_INTERACTIVE )
5858 TestFtpInteractive();
5859 }
5860 //else: connecting to the FTP server failed
5861
5862 if ( 0 )
5863 TestFtpWuFtpd();
5864 #endif // TEST_FTP
5865
5866 #ifdef TEST_LONGLONG
5867 // seed pseudo random generator
5868 srand((unsigned)time(NULL));
5869
5870 if ( 0 )
5871 {
5872 TestSpeed();
5873 }
5874
5875 if ( TEST_ALL )
5876 {
5877 TestMultiplication();
5878 TestDivision();
5879 TestAddition();
5880 TestLongLongConversion();
5881 TestBitOperations();
5882 TestLongLongComparison();
5883 TestLongLongPrint();
5884 }
5885 #endif // TEST_LONGLONG
5886
5887 #ifdef TEST_HASH
5888 TestHash();
5889 #endif // TEST_HASH
5890
5891 #ifdef TEST_HASHMAP
5892 TestHashMap();
5893 #endif // TEST_HASHMAP
5894
5895 #ifdef TEST_MIME
5896 wxLog::AddTraceMask(_T("mime"));
5897 if ( TEST_ALL )
5898 {
5899 TestMimeEnum();
5900 TestMimeOverride();
5901 TestMimeFilename();
5902 }
5903
5904 TestMimeAssociate();
5905 #endif // TEST_MIME
5906
5907 #ifdef TEST_INFO_FUNCTIONS
5908 if ( TEST_ALL )
5909 {
5910 TestOsInfo();
5911 TestUserInfo();
5912
5913 if ( TEST_INTERACTIVE )
5914 TestDiskInfo();
5915 }
5916 #endif // TEST_INFO_FUNCTIONS
5917
5918 #ifdef TEST_PATHLIST
5919 TestPathList();
5920 #endif // TEST_PATHLIST
5921
5922 #ifdef TEST_ODBC
5923 TestDbOpen();
5924 #endif // TEST_ODBC
5925
5926 #ifdef TEST_REGCONF
5927 TestRegConfWrite();
5928 #endif // TEST_REGCONF
5929
5930 #ifdef TEST_REGEX
5931 // TODO: write a real test using src/regex/tests file
5932 if ( TEST_ALL )
5933 {
5934 TestRegExCompile();
5935 TestRegExMatch();
5936 TestRegExSubmatch();
5937 TestRegExReplacement();
5938
5939 if ( TEST_INTERACTIVE )
5940 TestRegExInteractive();
5941 }
5942 #endif // TEST_REGEX
5943
5944 #ifdef TEST_REGISTRY
5945 TestRegistryRead();
5946 TestRegistryAssociation();
5947 #endif // TEST_REGISTRY
5948
5949 #ifdef TEST_SOCKETS
5950 TestSocketServer();
5951 TestSocketClient();
5952 #endif // TEST_SOCKETS
5953
5954 #ifdef TEST_STREAMS
5955 TestFileStream();
5956 TestMemoryStream();
5957 #endif // TEST_STREAMS
5958
5959 #ifdef TEST_THREADS
5960 int nCPUs = wxThread::GetCPUCount();
5961 printf("This system has %d CPUs\n", nCPUs);
5962 if ( nCPUs != -1 )
5963 wxThread::SetConcurrency(nCPUs);
5964
5965 if ( TEST_ALL )
5966 {
5967 TestDetachedThreads();
5968 TestJoinableThreads();
5969 TestThreadSuspend();
5970 TestThreadDelete();
5971 TestThreadConditions();
5972 TestThreadExec();
5973 }
5974
5975 TestSemaphore();
5976 #endif // TEST_THREADS
5977
5978 #ifdef TEST_TIMER
5979 TestStopWatch();
5980 #endif // TEST_TIMER
5981
5982 #ifdef TEST_DATETIME
5983 if ( TEST_ALL )
5984 {
5985 TestTimeSet();
5986 TestTimeStatic();
5987 TestTimeRange();
5988 TestTimeZones();
5989 TestTimeTicks();
5990 TestTimeJDN();
5991 TestTimeDST();
5992 TestTimeWDays();
5993 TestTimeWNumber();
5994 TestTimeParse();
5995 TestTimeArithmetics();
5996 TestTimeHolidays();
5997 TestTimeFormat();
5998 TestTimeSpanFormat();
5999 TestTimeMS();
6000
6001 TestTimeZoneBug();
6002 }
6003
6004 if ( TEST_INTERACTIVE )
6005 TestDateTimeInteractive();
6006 #endif // TEST_DATETIME
6007
6008 #ifdef TEST_USLEEP
6009 puts("Sleeping for 3 seconds... z-z-z-z-z...");
6010 wxUsleep(3000);
6011 #endif // TEST_USLEEP
6012
6013 #ifdef TEST_VCARD
6014 TestVCardRead();
6015 TestVCardWrite();
6016 #endif // TEST_VCARD
6017
6018 #ifdef TEST_VOLUME
6019 TestFSVolume();
6020 #endif // TEST_VOLUME
6021
6022 #ifdef TEST_WCHAR
6023 TestUtf8();
6024 TestEncodingConverter();
6025 #endif // TEST_WCHAR
6026
6027 #ifdef TEST_ZIP
6028 TestZipStreamRead();
6029 TestZipFileSystem();
6030 #endif // TEST_ZIP
6031
6032 #ifdef TEST_ZLIB
6033 TestZlibStreamWrite();
6034 TestZlibStreamRead();
6035 #endif // TEST_ZLIB
6036
6037 return 0;
6038 }
6039