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