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