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