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