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