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