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