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