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