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