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