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