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