]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
added missing wxSTDs
[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
32 // without this pragma, the stupid compiler precompiles #defines below so that
33 // changing them doesn't "take place" later!
34 #ifdef __VISUALC__
35 #pragma hdrstop
36 #endif
37
38 // ----------------------------------------------------------------------------
39 // conditional compilation
40 // ----------------------------------------------------------------------------
41
42 // what to test (in alphabetic order)?
43
44 //#define TEST_ARRAYS
45 //#define TEST_CHARSET
46 //#define TEST_CMDLINE
47 #define TEST_DATETIME
48 //#define TEST_DIR
49 //#define TEST_DLLLOADER
50 //#define TEST_ENVIRON
51 //#define TEST_EXECUTE
52 //#define TEST_FILE
53 //#define TEST_FILECONF
54 //#define TEST_FILENAME
55 //#define TEST_FTP
56 //#define TEST_HASH
57 //#define TEST_INFO_FUNCTIONS
58 //#define TEST_LIST
59 //#define TEST_LOCALE
60 //#define TEST_LOG
61 //#define TEST_LONGLONG
62 //#define TEST_MIME
63 //#define TEST_PATHLIST
64 //#define TEST_REGCONF
65 //#define TEST_REGEX
66 //#define TEST_REGISTRY
67 //#define TEST_SNGLINST
68 //#define TEST_SOCKETS
69 //#define TEST_STREAMS
70 //#define TEST_STRINGS
71 //#define TEST_THREADS
72 //#define TEST_TIMER
73 //#define TEST_VCARD -- don't enable this (VZ)
74 //#define TEST_WCHAR
75 //#define TEST_ZIP
76 //#define TEST_ZLIB
77
78 #ifdef TEST_SNGLINST
79 #include <wx/snglinst.h>
80 #endif // TEST_SNGLINST
81
82 // ----------------------------------------------------------------------------
83 // test class for container objects
84 // ----------------------------------------------------------------------------
85
86 #if defined(TEST_ARRAYS) || defined(TEST_LIST)
87
88 class Bar // Foo is already taken in the hash test
89 {
90 public:
91 Bar(const wxString& name) : m_name(name) { ms_bars++; }
92 ~Bar() { ms_bars--; }
93
94 static size_t GetNumber() { return ms_bars; }
95
96 const char *GetName() const { return m_name; }
97
98 private:
99 wxString m_name;
100
101 static size_t ms_bars;
102 };
103
104 size_t Bar::ms_bars = 0;
105
106 #endif // defined(TEST_ARRAYS) || defined(TEST_LIST)
107
108 // ============================================================================
109 // implementation
110 // ============================================================================
111
112 // ----------------------------------------------------------------------------
113 // helper functions
114 // ----------------------------------------------------------------------------
115
116 #if defined(TEST_STRINGS) || defined(TEST_SOCKETS)
117
118 // replace TABs with \t and CRs with \n
119 static wxString MakePrintable(const wxChar *s)
120 {
121 wxString str(s);
122 (void)str.Replace(_T("\t"), _T("\\t"));
123 (void)str.Replace(_T("\n"), _T("\\n"));
124 (void)str.Replace(_T("\r"), _T("\\r"));
125
126 return str;
127 }
128
129 #endif // MakePrintable() is used
130
131 // ----------------------------------------------------------------------------
132 // wxFontMapper::CharsetToEncoding
133 // ----------------------------------------------------------------------------
134
135 #ifdef TEST_CHARSET
136
137 #include <wx/fontmap.h>
138
139 static void TestCharset()
140 {
141 static const wxChar *charsets[] =
142 {
143 // some vali charsets
144 _T("us-ascii "),
145 _T("iso8859-1 "),
146 _T("iso-8859-12 "),
147 _T("koi8-r "),
148 _T("utf-7 "),
149 _T("cp1250 "),
150 _T("windows-1252"),
151
152 // and now some bogus ones
153 _T(" "),
154 _T("cp1249 "),
155 _T("iso--8859-1 "),
156 _T("iso-8859-19 "),
157 };
158
159 for ( size_t n = 0; n < WXSIZEOF(charsets); n++ )
160 {
161 wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(charsets[n]);
162 wxPrintf(_T("Charset: %s\tEncoding: %s (%s)\n"),
163 charsets[n],
164 wxTheFontMapper->GetEncodingName(enc).c_str(),
165 wxTheFontMapper->GetEncodingDescription(enc).c_str());
166 }
167 }
168
169 #endif // TEST_CHARSET
170
171 // ----------------------------------------------------------------------------
172 // wxCmdLineParser
173 // ----------------------------------------------------------------------------
174
175 #ifdef TEST_CMDLINE
176
177 #include <wx/cmdline.h>
178 #include <wx/datetime.h>
179
180 static void ShowCmdLine(const wxCmdLineParser& parser)
181 {
182 wxString s = "Input files: ";
183
184 size_t count = parser.GetParamCount();
185 for ( size_t param = 0; param < count; param++ )
186 {
187 s << parser.GetParam(param) << ' ';
188 }
189
190 s << '\n'
191 << "Verbose:\t" << (parser.Found("v") ? "yes" : "no") << '\n'
192 << "Quiet:\t" << (parser.Found("q") ? "yes" : "no") << '\n';
193
194 wxString strVal;
195 long lVal;
196 wxDateTime dt;
197 if ( parser.Found("o", &strVal) )
198 s << "Output file:\t" << strVal << '\n';
199 if ( parser.Found("i", &strVal) )
200 s << "Input dir:\t" << strVal << '\n';
201 if ( parser.Found("s", &lVal) )
202 s << "Size:\t" << lVal << '\n';
203 if ( parser.Found("d", &dt) )
204 s << "Date:\t" << dt.FormatISODate() << '\n';
205 if ( parser.Found("project_name", &strVal) )
206 s << "Project:\t" << strVal << '\n';
207
208 wxLogMessage(s);
209 }
210
211 #endif // TEST_CMDLINE
212
213 // ----------------------------------------------------------------------------
214 // wxDir
215 // ----------------------------------------------------------------------------
216
217 #ifdef TEST_DIR
218
219 #include <wx/dir.h>
220
221 #ifdef __UNIX__
222 static const wxChar *ROOTDIR = _T("/");
223 static const wxChar *TESTDIR = _T("/usr");
224 #elif defined(__WXMSW__)
225 static const wxChar *ROOTDIR = _T("c:\\");
226 static const wxChar *TESTDIR = _T("d:\\");
227 #else
228 #error "don't know where the root directory is"
229 #endif
230
231 static void TestDirEnumHelper(wxDir& dir,
232 int flags = wxDIR_DEFAULT,
233 const wxString& filespec = wxEmptyString)
234 {
235 wxString filename;
236
237 if ( !dir.IsOpened() )
238 return;
239
240 bool cont = dir.GetFirst(&filename, filespec, flags);
241 while ( cont )
242 {
243 printf("\t%s\n", filename.c_str());
244
245 cont = dir.GetNext(&filename);
246 }
247
248 puts("");
249 }
250
251 static void TestDirEnum()
252 {
253 puts("*** Testing wxDir::GetFirst/GetNext ***");
254
255 wxDir dir(wxGetCwd());
256
257 puts("Enumerating everything in current directory:");
258 TestDirEnumHelper(dir);
259
260 puts("Enumerating really everything in current directory:");
261 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
262
263 puts("Enumerating object files in current directory:");
264 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
265
266 puts("Enumerating directories in current directory:");
267 TestDirEnumHelper(dir, wxDIR_DIRS);
268
269 puts("Enumerating files in current directory:");
270 TestDirEnumHelper(dir, wxDIR_FILES);
271
272 puts("Enumerating files including hidden in current directory:");
273 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
274
275 dir.Open(ROOTDIR);
276
277 puts("Enumerating everything in root directory:");
278 TestDirEnumHelper(dir, wxDIR_DEFAULT);
279
280 puts("Enumerating directories in root directory:");
281 TestDirEnumHelper(dir, wxDIR_DIRS);
282
283 puts("Enumerating files in root directory:");
284 TestDirEnumHelper(dir, wxDIR_FILES);
285
286 puts("Enumerating files including hidden in root directory:");
287 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
288
289 puts("Enumerating files in non existing directory:");
290 wxDir dirNo("nosuchdir");
291 TestDirEnumHelper(dirNo);
292 }
293
294 class DirPrintTraverser : public wxDirTraverser
295 {
296 public:
297 virtual wxDirTraverseResult OnFile(const wxString& filename)
298 {
299 return wxDIR_CONTINUE;
300 }
301
302 virtual wxDirTraverseResult OnDir(const wxString& dirname)
303 {
304 wxString path, name, ext;
305 wxSplitPath(dirname, &path, &name, &ext);
306
307 if ( !ext.empty() )
308 name << _T('.') << ext;
309
310 wxString indent;
311 for ( const wxChar *p = path.c_str(); *p; p++ )
312 {
313 if ( wxIsPathSeparator(*p) )
314 indent += _T(" ");
315 }
316
317 printf("%s%s\n", indent.c_str(), name.c_str());
318
319 return wxDIR_CONTINUE;
320 }
321 };
322
323 static void TestDirTraverse()
324 {
325 puts("*** Testing wxDir::Traverse() ***");
326
327 // enum all files
328 wxArrayString files;
329 size_t n = wxDir::GetAllFiles(TESTDIR, &files);
330 printf("There are %u files under '%s'\n", n, TESTDIR);
331 if ( n > 1 )
332 {
333 printf("First one is '%s'\n", files[0u].c_str());
334 printf(" last one is '%s'\n", files[n - 1].c_str());
335 }
336
337 // enum again with custom traverser
338 wxDir dir(TESTDIR);
339 DirPrintTraverser traverser;
340 dir.Traverse(traverser, _T(""), wxDIR_DIRS | wxDIR_HIDDEN);
341 }
342
343 #endif // TEST_DIR
344
345 // ----------------------------------------------------------------------------
346 // wxDllLoader
347 // ----------------------------------------------------------------------------
348
349 #ifdef TEST_DLLLOADER
350
351 #include <wx/dynlib.h>
352
353 static void TestDllLoad()
354 {
355 #if defined(__WXMSW__)
356 static const wxChar *LIB_NAME = _T("kernel32.dll");
357 static const wxChar *FUNC_NAME = _T("lstrlenA");
358 #elif defined(__UNIX__)
359 // weird: using just libc.so does *not* work!
360 static const wxChar *LIB_NAME = _T("/lib/libc-2.0.7.so");
361 static const wxChar *FUNC_NAME = _T("strlen");
362 #else
363 #error "don't know how to test wxDllLoader on this platform"
364 #endif
365
366 puts("*** testing wxDllLoader ***\n");
367
368 wxDllType dllHandle = wxDllLoader::LoadLibrary(LIB_NAME);
369 if ( !dllHandle )
370 {
371 wxPrintf(_T("ERROR: failed to load '%s'.\n"), LIB_NAME);
372 }
373 else
374 {
375 typedef int (*strlenType)(char *);
376 strlenType pfnStrlen = (strlenType)wxDllLoader::GetSymbol(dllHandle, FUNC_NAME);
377 if ( !pfnStrlen )
378 {
379 wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
380 FUNC_NAME, LIB_NAME);
381 }
382 else
383 {
384 if ( pfnStrlen("foo") != 3 )
385 {
386 wxPrintf(_T("ERROR: loaded function is not strlen()!\n"));
387 }
388 else
389 {
390 puts("... ok");
391 }
392 }
393
394 wxDllLoader::UnloadLibrary(dllHandle);
395 }
396 }
397
398 #endif // TEST_DLLLOADER
399
400 // ----------------------------------------------------------------------------
401 // wxGet/SetEnv
402 // ----------------------------------------------------------------------------
403
404 #ifdef TEST_ENVIRON
405
406 #include <wx/utils.h>
407
408 static wxString MyGetEnv(const wxString& var)
409 {
410 wxString val;
411 if ( !wxGetEnv(var, &val) )
412 val = _T("<empty>");
413 else
414 val = wxString(_T('\'')) + val + _T('\'');
415
416 return val;
417 }
418
419 static void TestEnvironment()
420 {
421 const wxChar *var = _T("wxTestVar");
422
423 puts("*** testing environment access functions ***");
424
425 printf("Initially getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
426 wxSetEnv(var, _T("value for wxTestVar"));
427 printf("After wxSetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
428 wxSetEnv(var, _T("another value"));
429 printf("After 2nd wxSetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
430 wxUnsetEnv(var);
431 printf("After wxUnsetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
432 printf("PATH = %s\n", MyGetEnv(_T("PATH")).c_str());
433 }
434
435 #endif // TEST_ENVIRON
436
437 // ----------------------------------------------------------------------------
438 // wxExecute
439 // ----------------------------------------------------------------------------
440
441 #ifdef TEST_EXECUTE
442
443 #include <wx/utils.h>
444
445 static void TestExecute()
446 {
447 puts("*** testing wxExecute ***");
448
449 #ifdef __UNIX__
450 #define COMMAND "cat -n ../../Makefile" // "echo hi"
451 #define SHELL_COMMAND "echo hi from shell"
452 #define REDIRECT_COMMAND COMMAND // "date"
453 #elif defined(__WXMSW__)
454 #define COMMAND "command.com -c 'echo hi'"
455 #define SHELL_COMMAND "echo hi"
456 #define REDIRECT_COMMAND COMMAND
457 #else
458 #error "no command to exec"
459 #endif // OS
460
461 printf("Testing wxShell: ");
462 fflush(stdout);
463 if ( wxShell(SHELL_COMMAND) )
464 puts("Ok.");
465 else
466 puts("ERROR.");
467
468 printf("Testing wxExecute: ");
469 fflush(stdout);
470 if ( wxExecute(COMMAND, TRUE /* sync */) == 0 )
471 puts("Ok.");
472 else
473 puts("ERROR.");
474
475 #if 0 // no, it doesn't work (yet?)
476 printf("Testing async wxExecute: ");
477 fflush(stdout);
478 if ( wxExecute(COMMAND) != 0 )
479 puts("Ok (command launched).");
480 else
481 puts("ERROR.");
482 #endif // 0
483
484 printf("Testing wxExecute with redirection:\n");
485 wxArrayString output;
486 if ( wxExecute(REDIRECT_COMMAND, output) != 0 )
487 {
488 puts("ERROR.");
489 }
490 else
491 {
492 size_t count = output.GetCount();
493 for ( size_t n = 0; n < count; n++ )
494 {
495 printf("\t%s\n", output[n].c_str());
496 }
497
498 puts("Ok.");
499 }
500 }
501
502 #endif // TEST_EXECUTE
503
504 // ----------------------------------------------------------------------------
505 // file
506 // ----------------------------------------------------------------------------
507
508 #ifdef TEST_FILE
509
510 #include <wx/file.h>
511 #include <wx/ffile.h>
512 #include <wx/textfile.h>
513
514 static void TestFileRead()
515 {
516 puts("*** wxFile read test ***");
517
518 wxFile file(_T("testdata.fc"));
519 if ( file.IsOpened() )
520 {
521 printf("File length: %lu\n", file.Length());
522
523 puts("File dump:\n----------");
524
525 static const off_t len = 1024;
526 char buf[len];
527 for ( ;; )
528 {
529 off_t nRead = file.Read(buf, len);
530 if ( nRead == wxInvalidOffset )
531 {
532 printf("Failed to read the file.");
533 break;
534 }
535
536 fwrite(buf, nRead, 1, stdout);
537
538 if ( nRead < len )
539 break;
540 }
541
542 puts("----------");
543 }
544 else
545 {
546 printf("ERROR: can't open test file.\n");
547 }
548
549 puts("");
550 }
551
552 static void TestTextFileRead()
553 {
554 puts("*** wxTextFile read test ***");
555
556 wxTextFile file(_T("testdata.fc"));
557 if ( file.Open() )
558 {
559 printf("Number of lines: %u\n", file.GetLineCount());
560 printf("Last line: '%s'\n", file.GetLastLine().c_str());
561
562 wxString s;
563
564 puts("\nDumping the entire file:");
565 for ( s = file.GetFirstLine(); !file.Eof(); s = file.GetNextLine() )
566 {
567 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
568 }
569 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
570
571 puts("\nAnd now backwards:");
572 for ( s = file.GetLastLine();
573 file.GetCurrentLine() != 0;
574 s = file.GetPrevLine() )
575 {
576 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
577 }
578 printf("%6u: %s\n", file.GetCurrentLine() + 1, s.c_str());
579 }
580 else
581 {
582 printf("ERROR: can't open '%s'\n", file.GetName());
583 }
584
585 puts("");
586 }
587
588 static void TestFileCopy()
589 {
590 puts("*** Testing wxCopyFile ***");
591
592 static const wxChar *filename1 = _T("testdata.fc");
593 static const wxChar *filename2 = _T("test2");
594 if ( !wxCopyFile(filename1, filename2) )
595 {
596 puts("ERROR: failed to copy file");
597 }
598 else
599 {
600 wxFFile f1(filename1, "rb"),
601 f2(filename2, "rb");
602
603 if ( !f1.IsOpened() || !f2.IsOpened() )
604 {
605 puts("ERROR: failed to open file(s)");
606 }
607 else
608 {
609 wxString s1, s2;
610 if ( !f1.ReadAll(&s1) || !f2.ReadAll(&s2) )
611 {
612 puts("ERROR: failed to read file(s)");
613 }
614 else
615 {
616 if ( (s1.length() != s2.length()) ||
617 (memcmp(s1.c_str(), s2.c_str(), s1.length()) != 0) )
618 {
619 puts("ERROR: copy error!");
620 }
621 else
622 {
623 puts("File was copied ok.");
624 }
625 }
626 }
627 }
628
629 if ( !wxRemoveFile(filename2) )
630 {
631 puts("ERROR: failed to remove the file");
632 }
633
634 puts("");
635 }
636
637 #endif // TEST_FILE
638
639 // ----------------------------------------------------------------------------
640 // wxFileConfig
641 // ----------------------------------------------------------------------------
642
643 #ifdef TEST_FILECONF
644
645 #include <wx/confbase.h>
646 #include <wx/fileconf.h>
647
648 static const struct FileConfTestData
649 {
650 const wxChar *name; // value name
651 const wxChar *value; // the value from the file
652 } fcTestData[] =
653 {
654 { _T("value1"), _T("one") },
655 { _T("value2"), _T("two") },
656 { _T("novalue"), _T("default") },
657 };
658
659 static void TestFileConfRead()
660 {
661 puts("*** testing wxFileConfig loading/reading ***");
662
663 wxFileConfig fileconf(_T("test"), wxEmptyString,
664 _T("testdata.fc"), wxEmptyString,
665 wxCONFIG_USE_RELATIVE_PATH);
666
667 // test simple reading
668 puts("\nReading config file:");
669 wxString defValue(_T("default")), value;
670 for ( size_t n = 0; n < WXSIZEOF(fcTestData); n++ )
671 {
672 const FileConfTestData& data = fcTestData[n];
673 value = fileconf.Read(data.name, defValue);
674 printf("\t%s = %s ", data.name, value.c_str());
675 if ( value == data.value )
676 {
677 puts("(ok)");
678 }
679 else
680 {
681 printf("(ERROR: should be %s)\n", data.value);
682 }
683 }
684
685 // test enumerating the entries
686 puts("\nEnumerating all root entries:");
687 long dummy;
688 wxString name;
689 bool cont = fileconf.GetFirstEntry(name, dummy);
690 while ( cont )
691 {
692 printf("\t%s = %s\n",
693 name.c_str(),
694 fileconf.Read(name.c_str(), _T("ERROR")).c_str());
695
696 cont = fileconf.GetNextEntry(name, dummy);
697 }
698 }
699
700 #endif // TEST_FILECONF
701
702 // ----------------------------------------------------------------------------
703 // wxFileName
704 // ----------------------------------------------------------------------------
705
706 #ifdef TEST_FILENAME
707
708 #include <wx/filename.h>
709
710 static struct FileNameInfo
711 {
712 const wxChar *fullname;
713 const wxChar *path;
714 const wxChar *name;
715 const wxChar *ext;
716 } filenames[] =
717 {
718 { _T("/usr/bin/ls"), _T("/usr/bin"), _T("ls"), _T("") },
719 { _T("/usr/bin/"), _T("/usr/bin"), _T(""), _T("") },
720 { _T("~/.zshrc"), _T("~"), _T(".zshrc"), _T("") },
721 { _T("../../foo"), _T("../.."), _T("foo"), _T("") },
722 { _T("foo.bar"), _T(""), _T("foo"), _T("bar") },
723 { _T("~/foo.bar"), _T("~"), _T("foo"), _T("bar") },
724 { _T("Mahogany-0.60/foo.bar"), _T("Mahogany-0.60"), _T("foo"), _T("bar") },
725 { _T("/tmp/wxwin.tar.bz"), _T("/tmp"), _T("wxwin.tar"), _T("bz") },
726 };
727
728 static void TestFileNameConstruction()
729 {
730 puts("*** testing wxFileName construction ***");
731
732 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
733 {
734 wxFileName fn(filenames[n].fullname, wxPATH_UNIX);
735
736 printf("Filename: '%s'\t", fn.GetFullPath().c_str());
737 if ( !fn.Normalize(wxPATH_NORM_ALL, _T(""), wxPATH_UNIX) )
738 {
739 puts("ERROR (couldn't be normalized)");
740 }
741 else
742 {
743 printf("normalized: '%s'\n", fn.GetFullPath().c_str());
744 }
745 }
746
747 puts("");
748 }
749
750 static void TestFileNameSplit()
751 {
752 puts("*** testing wxFileName splitting ***");
753
754 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
755 {
756 const FileNameInfo &fni = filenames[n];
757 wxString path, name, ext;
758 wxFileName::SplitPath(fni.fullname, &path, &name, &ext);
759
760 printf("%s -> path = '%s', name = '%s', ext = '%s'",
761 fni.fullname, path.c_str(), name.c_str(), ext.c_str());
762 if ( path != fni.path )
763 printf(" (ERROR: path = '%s')", fni.path);
764 if ( name != fni.name )
765 printf(" (ERROR: name = '%s')", fni.name);
766 if ( ext != fni.ext )
767 printf(" (ERROR: ext = '%s')", fni.ext);
768 puts("");
769 }
770
771 puts("");
772 }
773
774 static void TestFileNameComparison()
775 {
776 // TODO!
777 }
778
779 static void TestFileNameOperations()
780 {
781 // TODO!
782 }
783
784 static void TestFileNameCwd()
785 {
786 // TODO!
787 }
788
789 #endif // TEST_FILENAME
790
791 // ----------------------------------------------------------------------------
792 // wxHashTable
793 // ----------------------------------------------------------------------------
794
795 #ifdef TEST_HASH
796
797 #include <wx/hash.h>
798
799 struct Foo
800 {
801 Foo(int n_) { n = n_; count++; }
802 ~Foo() { count--; }
803
804 int n;
805
806 static size_t count;
807 };
808
809 size_t Foo::count = 0;
810
811 WX_DECLARE_LIST(Foo, wxListFoos);
812 WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
813
814 #include <wx/listimpl.cpp>
815
816 WX_DEFINE_LIST(wxListFoos);
817
818 static void TestHash()
819 {
820 puts("*** Testing wxHashTable ***\n");
821
822 {
823 wxHashFoos hash;
824 hash.DeleteContents(TRUE);
825
826 printf("Hash created: %u foos in hash, %u foos totally\n",
827 hash.GetCount(), Foo::count);
828
829 static const int hashTestData[] =
830 {
831 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
832 };
833
834 size_t n;
835 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
836 {
837 hash.Put(hashTestData[n], n, new Foo(n));
838 }
839
840 printf("Hash filled: %u foos in hash, %u foos totally\n",
841 hash.GetCount(), Foo::count);
842
843 puts("Hash access test:");
844 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
845 {
846 printf("\tGetting element with key %d, value %d: ",
847 hashTestData[n], n);
848 Foo *foo = hash.Get(hashTestData[n], n);
849 if ( !foo )
850 {
851 printf("ERROR, not found.\n");
852 }
853 else
854 {
855 printf("%d (%s)\n", foo->n,
856 (size_t)foo->n == n ? "ok" : "ERROR");
857 }
858 }
859
860 printf("\nTrying to get an element not in hash: ");
861
862 if ( hash.Get(1234) || hash.Get(1, 0) )
863 {
864 puts("ERROR: found!");
865 }
866 else
867 {
868 puts("ok (not found)");
869 }
870 }
871
872 printf("Hash destroyed: %u foos left\n", Foo::count);
873 }
874
875 #endif // TEST_HASH
876
877 // ----------------------------------------------------------------------------
878 // wxList
879 // ----------------------------------------------------------------------------
880
881 #ifdef TEST_LIST
882
883 #include <wx/list.h>
884
885 WX_DECLARE_LIST(Bar, wxListBars);
886 #include <wx/listimpl.cpp>
887 WX_DEFINE_LIST(wxListBars);
888
889 static void TestListCtor()
890 {
891 puts("*** Testing wxList construction ***\n");
892
893 {
894 wxListBars list1;
895 list1.Append(new Bar(_T("first")));
896 list1.Append(new Bar(_T("second")));
897
898 printf("After 1st list creation: %u objects in the list, %u objects total.\n",
899 list1.GetCount(), Bar::GetNumber());
900
901 wxListBars list2;
902 list2 = list1;
903
904 printf("After 2nd list creation: %u and %u objects in the lists, %u objects total.\n",
905 list1.GetCount(), list2.GetCount(), Bar::GetNumber());
906
907 list1.DeleteContents(TRUE);
908 }
909
910 printf("After list destruction: %u objects left.\n", Bar::GetNumber());
911 }
912
913 #endif // TEST_LIST
914
915 // ----------------------------------------------------------------------------
916 // wxLocale
917 // ----------------------------------------------------------------------------
918
919 #ifdef TEST_LOCALE
920
921 #include "wx/intl.h"
922 #include "wx/utils.h" // for wxSetEnv
923
924 static wxLocale gs_localeDefault(wxLANGUAGE_ENGLISH);
925
926 // find the name of the language from its value
927 static const char *GetLangName(int lang)
928 {
929 static const char *languageNames[] =
930 {
931 "DEFAULT",
932 "UNKNOWN",
933 "ABKHAZIAN",
934 "AFAR",
935 "AFRIKAANS",
936 "ALBANIAN",
937 "AMHARIC",
938 "ARABIC",
939 "ARABIC_ALGERIA",
940 "ARABIC_BAHRAIN",
941 "ARABIC_EGYPT",
942 "ARABIC_IRAQ",
943 "ARABIC_JORDAN",
944 "ARABIC_KUWAIT",
945 "ARABIC_LEBANON",
946 "ARABIC_LIBYA",
947 "ARABIC_MOROCCO",
948 "ARABIC_OMAN",
949 "ARABIC_QATAR",
950 "ARABIC_SAUDI_ARABIA",
951 "ARABIC_SUDAN",
952 "ARABIC_SYRIA",
953 "ARABIC_TUNISIA",
954 "ARABIC_UAE",
955 "ARABIC_YEMEN",
956 "ARMENIAN",
957 "ASSAMESE",
958 "AYMARA",
959 "AZERI",
960 "AZERI_CYRILLIC",
961 "AZERI_LATIN",
962 "BASHKIR",
963 "BASQUE",
964 "BELARUSIAN",
965 "BENGALI",
966 "BHUTANI",
967 "BIHARI",
968 "BISLAMA",
969 "BRETON",
970 "BULGARIAN",
971 "BURMESE",
972 "CAMBODIAN",
973 "CATALAN",
974 "CHINESE",
975 "CHINESE_SIMPLIFIED",
976 "CHINESE_TRADITIONAL",
977 "CHINESE_HONGKONG",
978 "CHINESE_MACAU",
979 "CHINESE_SINGAPORE",
980 "CHINESE_TAIWAN",
981 "CORSICAN",
982 "CROATIAN",
983 "CZECH",
984 "DANISH",
985 "DUTCH",
986 "DUTCH_BELGIAN",
987 "ENGLISH",
988 "ENGLISH_UK",
989 "ENGLISH_US",
990 "ENGLISH_AUSTRALIA",
991 "ENGLISH_BELIZE",
992 "ENGLISH_BOTSWANA",
993 "ENGLISH_CANADA",
994 "ENGLISH_CARIBBEAN",
995 "ENGLISH_DENMARK",
996 "ENGLISH_EIRE",
997 "ENGLISH_JAMAICA",
998 "ENGLISH_NEW_ZEALAND",
999 "ENGLISH_PHILIPPINES",
1000 "ENGLISH_SOUTH_AFRICA",
1001 "ENGLISH_TRINIDAD",
1002 "ENGLISH_ZIMBABWE",
1003 "ESPERANTO",
1004 "ESTONIAN",
1005 "FAEROESE",
1006 "FARSI",
1007 "FIJI",
1008 "FINNISH",
1009 "FRENCH",
1010 "FRENCH_BELGIAN",
1011 "FRENCH_CANADIAN",
1012 "FRENCH_LUXEMBOURG",
1013 "FRENCH_MONACO",
1014 "FRENCH_SWISS",
1015 "FRISIAN",
1016 "GALICIAN",
1017 "GEORGIAN",
1018 "GERMAN",
1019 "GERMAN_AUSTRIAN",
1020 "GERMAN_BELGIUM",
1021 "GERMAN_LIECHTENSTEIN",
1022 "GERMAN_LUXEMBOURG",
1023 "GERMAN_SWISS",
1024 "GREEK",
1025 "GREENLANDIC",
1026 "GUARANI",
1027 "GUJARATI",
1028 "HAUSA",
1029 "HEBREW",
1030 "HINDI",
1031 "HUNGARIAN",
1032 "ICELANDIC",
1033 "INDONESIAN",
1034 "INTERLINGUA",
1035 "INTERLINGUE",
1036 "INUKTITUT",
1037 "INUPIAK",
1038 "IRISH",
1039 "ITALIAN",
1040 "ITALIAN_SWISS",
1041 "JAPANESE",
1042 "JAVANESE",
1043 "KANNADA",
1044 "KASHMIRI",
1045 "KASHMIRI_INDIA",
1046 "KAZAKH",
1047 "KERNEWEK",
1048 "KINYARWANDA",
1049 "KIRGHIZ",
1050 "KIRUNDI",
1051 "KONKANI",
1052 "KOREAN",
1053 "KURDISH",
1054 "LAOTHIAN",
1055 "LATIN",
1056 "LATVIAN",
1057 "LINGALA",
1058 "LITHUANIAN",
1059 "MACEDONIAN",
1060 "MALAGASY",
1061 "MALAY",
1062 "MALAYALAM",
1063 "MALAY_BRUNEI_DARUSSALAM",
1064 "MALAY_MALAYSIA",
1065 "MALTESE",
1066 "MANIPURI",
1067 "MAORI",
1068 "MARATHI",
1069 "MOLDAVIAN",
1070 "MONGOLIAN",
1071 "NAURU",
1072 "NEPALI",
1073 "NEPALI_INDIA",
1074 "NORWEGIAN_BOKMAL",
1075 "NORWEGIAN_NYNORSK",
1076 "OCCITAN",
1077 "ORIYA",
1078 "OROMO",
1079 "PASHTO",
1080 "POLISH",
1081 "PORTUGUESE",
1082 "PORTUGUESE_BRAZILIAN",
1083 "PUNJABI",
1084 "QUECHUA",
1085 "RHAETO_ROMANCE",
1086 "ROMANIAN",
1087 "RUSSIAN",
1088 "RUSSIAN_UKRAINE",
1089 "SAMOAN",
1090 "SANGHO",
1091 "SANSKRIT",
1092 "SCOTS_GAELIC",
1093 "SERBIAN",
1094 "SERBIAN_CYRILLIC",
1095 "SERBIAN_LATIN",
1096 "SERBO_CROATIAN",
1097 "SESOTHO",
1098 "SETSWANA",
1099 "SHONA",
1100 "SINDHI",
1101 "SINHALESE",
1102 "SISWATI",
1103 "SLOVAK",
1104 "SLOVENIAN",
1105 "SOMALI",
1106 "SPANISH",
1107 "SPANISH_ARGENTINA",
1108 "SPANISH_BOLIVIA",
1109 "SPANISH_CHILE",
1110 "SPANISH_COLOMBIA",
1111 "SPANISH_COSTA_RICA",
1112 "SPANISH_DOMINICAN_REPUBLIC",
1113 "SPANISH_ECUADOR",
1114 "SPANISH_EL_SALVADOR",
1115 "SPANISH_GUATEMALA",
1116 "SPANISH_HONDURAS",
1117 "SPANISH_MEXICAN",
1118 "SPANISH_MODERN",
1119 "SPANISH_NICARAGUA",
1120 "SPANISH_PANAMA",
1121 "SPANISH_PARAGUAY",
1122 "SPANISH_PERU",
1123 "SPANISH_PUERTO_RICO",
1124 "SPANISH_URUGUAY",
1125 "SPANISH_US",
1126 "SPANISH_VENEZUELA",
1127 "SUNDANESE",
1128 "SWAHILI",
1129 "SWEDISH",
1130 "SWEDISH_FINLAND",
1131 "TAGALOG",
1132 "TAJIK",
1133 "TAMIL",
1134 "TATAR",
1135 "TELUGU",
1136 "THAI",
1137 "TIBETAN",
1138 "TIGRINYA",
1139 "TONGA",
1140 "TSONGA",
1141 "TURKISH",
1142 "TURKMEN",
1143 "TWI",
1144 "UIGHUR",
1145 "UKRAINIAN",
1146 "URDU",
1147 "URDU_INDIA",
1148 "URDU_PAKISTAN",
1149 "UZBEK",
1150 "UZBEK_CYRILLIC",
1151 "UZBEK_LATIN",
1152 "VIETNAMESE",
1153 "VOLAPUK",
1154 "WELSH",
1155 "WOLOF",
1156 "XHOSA",
1157 "YIDDISH",
1158 "YORUBA",
1159 "ZHUANG",
1160 "ZULU",
1161 };
1162
1163 if ( (size_t)lang < WXSIZEOF(languageNames) )
1164 return languageNames[lang];
1165 else
1166 return "INVALID";
1167 }
1168
1169 static void TestDefaultLang()
1170 {
1171 puts("*** Testing wxLocale::GetSystemLanguage ***");
1172
1173 static const wxChar *langStrings[] =
1174 {
1175 NULL, // system default
1176 _T("C"),
1177 _T("fr"),
1178 _T("fr_FR"),
1179 _T("en"),
1180 _T("en_GB"),
1181 _T("en_US"),
1182 _T("de_DE.iso88591"),
1183 _T("german"),
1184 _T("?"), // invalid lang spec
1185 _T("klingonese"), // I bet on some systems it does exist...
1186 };
1187
1188 wxPrintf(_T("The default system encoding is %s (%d)\n"),
1189 wxLocale::GetSystemEncodingName().c_str(),
1190 wxLocale::GetSystemEncoding());
1191
1192 for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ )
1193 {
1194 const char *langStr = langStrings[n];
1195 if ( langStr )
1196 {
1197 // FIXME: this doesn't do anything at all under Windows, we need
1198 // to create a new wxLocale!
1199 wxSetEnv(_T("LC_ALL"), langStr);
1200 }
1201
1202 int lang = gs_localeDefault.GetSystemLanguage();
1203 printf("Locale for '%s' is %s.\n",
1204 langStr ? langStr : "system default", GetLangName(lang));
1205 }
1206 }
1207
1208 #endif // TEST_LOCALE
1209
1210 // ----------------------------------------------------------------------------
1211 // MIME types
1212 // ----------------------------------------------------------------------------
1213
1214 #ifdef TEST_MIME
1215
1216 #include <wx/mimetype.h>
1217
1218 static void TestMimeEnum()
1219 {
1220 wxPuts(_T("*** Testing wxMimeTypesManager::EnumAllFileTypes() ***\n"));
1221
1222 wxArrayString mimetypes;
1223
1224 size_t count = wxTheMimeTypesManager->EnumAllFileTypes(mimetypes);
1225
1226 printf("*** All %u known filetypes: ***\n", count);
1227
1228 wxArrayString exts;
1229 wxString desc;
1230
1231 for ( size_t n = 0; n < count; n++ )
1232 {
1233 wxFileType *filetype =
1234 wxTheMimeTypesManager->GetFileTypeFromMimeType(mimetypes[n]);
1235 if ( !filetype )
1236 {
1237 printf("nothing known about the filetype '%s'!\n",
1238 mimetypes[n].c_str());
1239 continue;
1240 }
1241
1242 filetype->GetDescription(&desc);
1243 filetype->GetExtensions(exts);
1244
1245 filetype->GetIcon(NULL);
1246
1247 wxString extsAll;
1248 for ( size_t e = 0; e < exts.GetCount(); e++ )
1249 {
1250 if ( e > 0 )
1251 extsAll << _T(", ");
1252 extsAll += exts[e];
1253 }
1254
1255 printf("\t%s: %s (%s)\n",
1256 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
1257 }
1258
1259 puts("");
1260 }
1261
1262 static void TestMimeOverride()
1263 {
1264 wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
1265
1266 static const wxChar *mailcap = _T("/tmp/mailcap");
1267 static const wxChar *mimetypes = _T("/tmp/mime.types");
1268
1269 if ( wxFile::Exists(mailcap) )
1270 wxPrintf(_T("Loading mailcap from '%s': %s\n"),
1271 mailcap,
1272 wxTheMimeTypesManager->ReadMailcap(mailcap) ? _T("ok") : _T("ERROR"));
1273 else
1274 wxPrintf(_T("WARN: mailcap file '%s' doesn't exist, not loaded.\n"),
1275 mailcap);
1276
1277 if ( wxFile::Exists(mimetypes) )
1278 wxPrintf(_T("Loading mime.types from '%s': %s\n"),
1279 mimetypes,
1280 wxTheMimeTypesManager->ReadMimeTypes(mimetypes) ? _T("ok") : _T("ERROR"));
1281 else
1282 wxPrintf(_T("WARN: mime.types file '%s' doesn't exist, not loaded.\n"),
1283 mimetypes);
1284
1285 puts("");
1286 }
1287
1288 static void TestMimeFilename()
1289 {
1290 wxPuts(_T("*** Testing MIME type from filename query ***\n"));
1291
1292 static const wxChar *filenames[] =
1293 {
1294 _T("readme.txt"),
1295 _T("document.pdf"),
1296 _T("image.gif"),
1297 };
1298
1299 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
1300 {
1301 const wxString fname = filenames[n];
1302 wxString ext = fname.AfterLast(_T('.'));
1303 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
1304 if ( !ft )
1305 {
1306 wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext.c_str());
1307 }
1308 else
1309 {
1310 wxString desc;
1311 if ( !ft->GetDescription(&desc) )
1312 desc = _T("<no description>");
1313
1314 wxString cmd;
1315 if ( !ft->GetOpenCommand(&cmd,
1316 wxFileType::MessageParameters(fname, _T(""))) )
1317 cmd = _T("<no command available>");
1318
1319 wxPrintf(_T("To open %s (%s) do '%s'.\n"),
1320 fname.c_str(), desc.c_str(), cmd.c_str());
1321
1322 delete ft;
1323 }
1324 }
1325
1326 puts("");
1327 }
1328
1329 static void TestMimeAssociate()
1330 {
1331 wxPuts(_T("*** Testing creation of filetype association ***\n"));
1332
1333 wxFileTypeInfo ftInfo(
1334 _T("application/x-xyz"),
1335 _T("xyzview '%s'"), // open cmd
1336 _T(""), // print cmd
1337 _T("XYZ File") // description
1338 _T(".xyz"), // extensions
1339 NULL // end of extensions
1340 );
1341 ftInfo.SetShortDesc(_T("XYZFile")); // used under Win32 only
1342
1343 wxFileType *ft = wxTheMimeTypesManager->Associate(ftInfo);
1344 if ( !ft )
1345 {
1346 wxPuts(_T("ERROR: failed to create association!"));
1347 }
1348 else
1349 {
1350 // TODO: read it back
1351 delete ft;
1352 }
1353
1354 puts("");
1355 }
1356
1357 #endif // TEST_MIME
1358
1359 // ----------------------------------------------------------------------------
1360 // misc information functions
1361 // ----------------------------------------------------------------------------
1362
1363 #ifdef TEST_INFO_FUNCTIONS
1364
1365 #include <wx/utils.h>
1366
1367 static void TestOsInfo()
1368 {
1369 puts("*** Testing OS info functions ***\n");
1370
1371 int major, minor;
1372 wxGetOsVersion(&major, &minor);
1373 printf("Running under: %s, version %d.%d\n",
1374 wxGetOsDescription().c_str(), major, minor);
1375
1376 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
1377
1378 printf("Host name is %s (%s).\n",
1379 wxGetHostName().c_str(), wxGetFullHostName().c_str());
1380
1381 puts("");
1382 }
1383
1384 static void TestUserInfo()
1385 {
1386 puts("*** Testing user info functions ***\n");
1387
1388 printf("User id is:\t%s\n", wxGetUserId().c_str());
1389 printf("User name is:\t%s\n", wxGetUserName().c_str());
1390 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
1391 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
1392
1393 puts("");
1394 }
1395
1396 #endif // TEST_INFO_FUNCTIONS
1397
1398 // ----------------------------------------------------------------------------
1399 // long long
1400 // ----------------------------------------------------------------------------
1401
1402 #ifdef TEST_LONGLONG
1403
1404 #include <wx/longlong.h>
1405 #include <wx/timer.h>
1406
1407 // make a 64 bit number from 4 16 bit ones
1408 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1409
1410 // get a random 64 bit number
1411 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1412
1413 #if wxUSE_LONGLONG_WX
1414 inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
1415 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1416 inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
1417 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1418 #endif // wxUSE_LONGLONG_WX
1419
1420 static void TestSpeed()
1421 {
1422 static const long max = 100000000;
1423 long n;
1424
1425 {
1426 wxStopWatch sw;
1427
1428 long l = 0;
1429 for ( n = 0; n < max; n++ )
1430 {
1431 l += n;
1432 }
1433
1434 printf("Summing longs took %ld milliseconds.\n", sw.Time());
1435 }
1436
1437 #if wxUSE_LONGLONG_NATIVE
1438 {
1439 wxStopWatch sw;
1440
1441 wxLongLong_t l = 0;
1442 for ( n = 0; n < max; n++ )
1443 {
1444 l += n;
1445 }
1446
1447 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
1448 }
1449 #endif // wxUSE_LONGLONG_NATIVE
1450
1451 {
1452 wxStopWatch sw;
1453
1454 wxLongLong l;
1455 for ( n = 0; n < max; n++ )
1456 {
1457 l += n;
1458 }
1459
1460 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
1461 }
1462 }
1463
1464 static void TestLongLongConversion()
1465 {
1466 puts("*** Testing wxLongLong conversions ***\n");
1467
1468 wxLongLong a;
1469 size_t nTested = 0;
1470 for ( size_t n = 0; n < 100000; n++ )
1471 {
1472 a = RAND_LL();
1473
1474 #if wxUSE_LONGLONG_NATIVE
1475 wxLongLongNative b(a.GetHi(), a.GetLo());
1476
1477 wxASSERT_MSG( a == b, "conversions failure" );
1478 #else
1479 puts("Can't do it without native long long type, test skipped.");
1480
1481 return;
1482 #endif // wxUSE_LONGLONG_NATIVE
1483
1484 if ( !(nTested % 1000) )
1485 {
1486 putchar('.');
1487 fflush(stdout);
1488 }
1489
1490 nTested++;
1491 }
1492
1493 puts(" done!");
1494 }
1495
1496 static void TestMultiplication()
1497 {
1498 puts("*** Testing wxLongLong multiplication ***\n");
1499
1500 wxLongLong a, b;
1501 size_t nTested = 0;
1502 for ( size_t n = 0; n < 100000; n++ )
1503 {
1504 a = RAND_LL();
1505 b = RAND_LL();
1506
1507 #if wxUSE_LONGLONG_NATIVE
1508 wxLongLongNative aa(a.GetHi(), a.GetLo());
1509 wxLongLongNative bb(b.GetHi(), b.GetLo());
1510
1511 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
1512 #else // !wxUSE_LONGLONG_NATIVE
1513 puts("Can't do it without native long long type, test skipped.");
1514
1515 return;
1516 #endif // wxUSE_LONGLONG_NATIVE
1517
1518 if ( !(nTested % 1000) )
1519 {
1520 putchar('.');
1521 fflush(stdout);
1522 }
1523
1524 nTested++;
1525 }
1526
1527 puts(" done!");
1528 }
1529
1530 static void TestDivision()
1531 {
1532 puts("*** Testing wxLongLong division ***\n");
1533
1534 wxLongLong q, r;
1535 size_t nTested = 0;
1536 for ( size_t n = 0; n < 100000; n++ )
1537 {
1538 // get a random wxLongLong (shifting by 12 the MSB ensures that the
1539 // multiplication will not overflow)
1540 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
1541
1542 // get a random long (not wxLongLong for now) to divide it with
1543 long l = rand();
1544 q = ll / l;
1545 r = ll % l;
1546
1547 #if wxUSE_LONGLONG_NATIVE
1548 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1549
1550 wxLongLongNative p = m / l, s = m % l;
1551 wxASSERT_MSG( q == p && r == s, "division failure" );
1552 #else // !wxUSE_LONGLONG_NATIVE
1553 // verify the result
1554 wxASSERT_MSG( ll == q*l + r, "division failure" );
1555 #endif // wxUSE_LONGLONG_NATIVE
1556
1557 if ( !(nTested % 1000) )
1558 {
1559 putchar('.');
1560 fflush(stdout);
1561 }
1562
1563 nTested++;
1564 }
1565
1566 puts(" done!");
1567 }
1568
1569 static void TestAddition()
1570 {
1571 puts("*** Testing wxLongLong addition ***\n");
1572
1573 wxLongLong a, b, c;
1574 size_t nTested = 0;
1575 for ( size_t n = 0; n < 100000; n++ )
1576 {
1577 a = RAND_LL();
1578 b = RAND_LL();
1579 c = a + b;
1580
1581 #if wxUSE_LONGLONG_NATIVE
1582 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1583 wxLongLongNative(b.GetHi(), b.GetLo()),
1584 "addition failure" );
1585 #else // !wxUSE_LONGLONG_NATIVE
1586 wxASSERT_MSG( c - b == a, "addition failure" );
1587 #endif // wxUSE_LONGLONG_NATIVE
1588
1589 if ( !(nTested % 1000) )
1590 {
1591 putchar('.');
1592 fflush(stdout);
1593 }
1594
1595 nTested++;
1596 }
1597
1598 puts(" done!");
1599 }
1600
1601 static void TestBitOperations()
1602 {
1603 puts("*** Testing wxLongLong bit operation ***\n");
1604
1605 wxLongLong ll;
1606 size_t nTested = 0;
1607 for ( size_t n = 0; n < 100000; n++ )
1608 {
1609 ll = RAND_LL();
1610
1611 #if wxUSE_LONGLONG_NATIVE
1612 for ( size_t n = 0; n < 33; n++ )
1613 {
1614 }
1615 #else // !wxUSE_LONGLONG_NATIVE
1616 puts("Can't do it without native long long type, test skipped.");
1617
1618 return;
1619 #endif // wxUSE_LONGLONG_NATIVE
1620
1621 if ( !(nTested % 1000) )
1622 {
1623 putchar('.');
1624 fflush(stdout);
1625 }
1626
1627 nTested++;
1628 }
1629
1630 puts(" done!");
1631 }
1632
1633 static void TestLongLongComparison()
1634 {
1635 #if wxUSE_LONGLONG_WX
1636 puts("*** Testing wxLongLong comparison ***\n");
1637
1638 static const long testLongs[] =
1639 {
1640 0,
1641 1,
1642 -1,
1643 LONG_MAX,
1644 LONG_MIN,
1645 0x1234,
1646 -0x1234
1647 };
1648
1649 static const long ls[2] =
1650 {
1651 0x1234,
1652 -0x1234,
1653 };
1654
1655 wxLongLongWx lls[2];
1656 lls[0] = ls[0];
1657 lls[1] = ls[1];
1658
1659 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1660 {
1661 bool res;
1662
1663 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
1664 {
1665 res = lls[m] > testLongs[n];
1666 printf("0x%lx > 0x%lx is %s (%s)\n",
1667 ls[m], testLongs[n], res ? "true" : "false",
1668 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
1669
1670 res = lls[m] < testLongs[n];
1671 printf("0x%lx < 0x%lx is %s (%s)\n",
1672 ls[m], testLongs[n], res ? "true" : "false",
1673 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
1674
1675 res = lls[m] == testLongs[n];
1676 printf("0x%lx == 0x%lx is %s (%s)\n",
1677 ls[m], testLongs[n], res ? "true" : "false",
1678 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
1679 }
1680 }
1681 #endif // wxUSE_LONGLONG_WX
1682 }
1683
1684 #undef MAKE_LL
1685 #undef RAND_LL
1686
1687 #endif // TEST_LONGLONG
1688
1689 // ----------------------------------------------------------------------------
1690 // path list
1691 // ----------------------------------------------------------------------------
1692
1693 #ifdef TEST_PATHLIST
1694
1695 static void TestPathList()
1696 {
1697 puts("*** Testing wxPathList ***\n");
1698
1699 wxPathList pathlist;
1700 pathlist.AddEnvList("PATH");
1701 wxString path = pathlist.FindValidPath("ls");
1702 if ( path.empty() )
1703 {
1704 printf("ERROR: command not found in the path.\n");
1705 }
1706 else
1707 {
1708 printf("Command found in the path as '%s'.\n", path.c_str());
1709 }
1710 }
1711
1712 #endif // TEST_PATHLIST
1713
1714 // ----------------------------------------------------------------------------
1715 // regular expressions
1716 // ----------------------------------------------------------------------------
1717
1718 #ifdef TEST_REGEX
1719
1720 #include <wx/regex.h>
1721
1722 static void TestRegExCompile()
1723 {
1724 wxPuts(_T("*** Testing RE compilation ***\n"));
1725
1726 static struct RegExCompTestData
1727 {
1728 const wxChar *pattern;
1729 bool correct;
1730 } regExCompTestData[] =
1731 {
1732 { _T("foo"), TRUE },
1733 { _T("foo("), FALSE },
1734 { _T("foo(bar"), FALSE },
1735 { _T("foo(bar)"), TRUE },
1736 { _T("foo["), FALSE },
1737 { _T("foo[bar"), FALSE },
1738 { _T("foo[bar]"), TRUE },
1739 { _T("foo{"), TRUE },
1740 { _T("foo{1"), FALSE },
1741 { _T("foo{bar"), TRUE },
1742 { _T("foo{1}"), TRUE },
1743 { _T("foo{1,2}"), TRUE },
1744 { _T("foo{bar}"), TRUE },
1745 { _T("foo*"), TRUE },
1746 { _T("foo**"), FALSE },
1747 { _T("foo+"), TRUE },
1748 { _T("foo++"), FALSE },
1749 { _T("foo?"), TRUE },
1750 { _T("foo??"), FALSE },
1751 { _T("foo?+"), FALSE },
1752 };
1753
1754 wxRegEx re;
1755 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
1756 {
1757 const RegExCompTestData& data = regExCompTestData[n];
1758 bool ok = re.Compile(data.pattern);
1759
1760 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
1761 data.pattern,
1762 ok ? _T("") : _T("not "),
1763 ok == data.correct ? _T("ok") : _T("ERROR"));
1764 }
1765 }
1766
1767 static void TestRegExMatch()
1768 {
1769 wxPuts(_T("*** Testing RE matching ***\n"));
1770
1771 static struct RegExMatchTestData
1772 {
1773 const wxChar *pattern;
1774 const wxChar *text;
1775 bool correct;
1776 } regExMatchTestData[] =
1777 {
1778 { _T("foo"), _T("bar"), FALSE },
1779 { _T("foo"), _T("foobar"), TRUE },
1780 { _T("^foo"), _T("foobar"), TRUE },
1781 { _T("^foo"), _T("barfoo"), FALSE },
1782 { _T("bar$"), _T("barbar"), TRUE },
1783 { _T("bar$"), _T("barbar "), FALSE },
1784 };
1785
1786 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
1787 {
1788 const RegExMatchTestData& data = regExMatchTestData[n];
1789
1790 wxRegEx re(data.pattern);
1791 bool ok = re.Matches(data.text);
1792
1793 wxPrintf(_T("'%s' %s %s (%s)\n"),
1794 data.pattern,
1795 ok ? _T("matches") : _T("doesn't match"),
1796 data.text,
1797 ok == data.correct ? _T("ok") : _T("ERROR"));
1798 }
1799 }
1800
1801 static void TestRegExSubmatch()
1802 {
1803 wxPuts(_T("*** Testing RE subexpressions ***\n"));
1804
1805 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
1806 if ( !re.IsValid() )
1807 {
1808 wxPuts(_T("ERROR: compilation failed."));
1809 return;
1810 }
1811
1812 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
1813
1814 if ( !re.Matches(text) )
1815 {
1816 wxPuts(_T("ERROR: match expected."));
1817 }
1818 else
1819 {
1820 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
1821
1822 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
1823 re.GetMatch(text, 3).c_str(),
1824 re.GetMatch(text, 2).c_str(),
1825 re.GetMatch(text, 4).c_str(),
1826 re.GetMatch(text, 1).c_str());
1827 }
1828 }
1829
1830 static void TestRegExReplacement()
1831 {
1832 wxPuts(_T("*** Testing RE replacement ***"));
1833
1834 static struct RegExReplTestData
1835 {
1836 const wxChar *text;
1837 const wxChar *repl;
1838 const wxChar *result;
1839 size_t count;
1840 } regExReplTestData[] =
1841 {
1842 { _T("foo123"), _T("bar"), _T("bar"), 1 },
1843 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
1844 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
1845 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
1846 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
1847 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
1848 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
1849 };
1850
1851 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
1852 wxRegEx re = pattern;
1853
1854 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
1855
1856 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
1857 {
1858 const RegExReplTestData& data = regExReplTestData[n];
1859
1860 wxString text = data.text;
1861 size_t nRepl = re.Replace(&text, data.repl);
1862
1863 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
1864 data.text, data.repl,
1865 nRepl, nRepl == 1 ? _T("") : _T("es"),
1866 text.c_str());
1867 if ( text == data.result && nRepl == data.count )
1868 {
1869 wxPuts(_T("ok)"));
1870 }
1871 else
1872 {
1873 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
1874 data.count, data.result);
1875 }
1876 }
1877 }
1878
1879 static void TestRegExInteractive()
1880 {
1881 wxPuts(_T("*** Testing RE interactively ***"));
1882
1883 for ( ;; )
1884 {
1885 char pattern[128];
1886 printf("\nEnter a pattern: ");
1887 if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
1888 break;
1889
1890 // kill the last '\n'
1891 pattern[strlen(pattern) - 1] = 0;
1892
1893 wxRegEx re;
1894 if ( !re.Compile(pattern) )
1895 {
1896 continue;
1897 }
1898
1899 char text[128];
1900 for ( ;; )
1901 {
1902 printf("Enter text to match: ");
1903 if ( !fgets(text, WXSIZEOF(text), stdin) )
1904 break;
1905
1906 // kill the last '\n'
1907 text[strlen(text) - 1] = 0;
1908
1909 if ( !re.Matches(text) )
1910 {
1911 printf("No match.\n");
1912 }
1913 else
1914 {
1915 printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
1916
1917 size_t start, len;
1918 for ( size_t n = 1; ; n++ )
1919 {
1920 if ( !re.GetMatch(&start, &len, n) )
1921 {
1922 break;
1923 }
1924
1925 printf("Subexpr %u matched '%s'\n",
1926 n, wxString(text + start, len).c_str());
1927 }
1928 }
1929 }
1930 }
1931 }
1932
1933 #endif // TEST_REGEX
1934
1935 // ----------------------------------------------------------------------------
1936 // registry and related stuff
1937 // ----------------------------------------------------------------------------
1938
1939 // this is for MSW only
1940 #ifndef __WXMSW__
1941 #undef TEST_REGCONF
1942 #undef TEST_REGISTRY
1943 #endif
1944
1945 #ifdef TEST_REGCONF
1946
1947 #include <wx/confbase.h>
1948 #include <wx/msw/regconf.h>
1949
1950 static void TestRegConfWrite()
1951 {
1952 wxRegConfig regconf(_T("console"), _T("wxwindows"));
1953 regconf.Write(_T("Hello"), wxString(_T("world")));
1954 }
1955
1956 #endif // TEST_REGCONF
1957
1958 #ifdef TEST_REGISTRY
1959
1960 #include <wx/msw/registry.h>
1961
1962 // I chose this one because I liked its name, but it probably only exists under
1963 // NT
1964 static const wxChar *TESTKEY =
1965 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
1966
1967 static void TestRegistryRead()
1968 {
1969 puts("*** testing registry reading ***");
1970
1971 wxRegKey key(TESTKEY);
1972 printf("The test key name is '%s'.\n", key.GetName().c_str());
1973 if ( !key.Open() )
1974 {
1975 puts("ERROR: test key can't be opened, aborting test.");
1976
1977 return;
1978 }
1979
1980 size_t nSubKeys, nValues;
1981 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
1982 {
1983 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
1984 }
1985
1986 printf("Enumerating values:\n");
1987
1988 long dummy;
1989 wxString value;
1990 bool cont = key.GetFirstValue(value, dummy);
1991 while ( cont )
1992 {
1993 printf("Value '%s': type ", value.c_str());
1994 switch ( key.GetValueType(value) )
1995 {
1996 case wxRegKey::Type_None: printf("ERROR (none)"); break;
1997 case wxRegKey::Type_String: printf("SZ"); break;
1998 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
1999 case wxRegKey::Type_Binary: printf("BINARY"); break;
2000 case wxRegKey::Type_Dword: printf("DWORD"); break;
2001 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
2002 default: printf("other (unknown)"); break;
2003 }
2004
2005 printf(", value = ");
2006 if ( key.IsNumericValue(value) )
2007 {
2008 long val;
2009 key.QueryValue(value, &val);
2010 printf("%ld", val);
2011 }
2012 else // string
2013 {
2014 wxString val;
2015 key.QueryValue(value, val);
2016 printf("'%s'", val.c_str());
2017
2018 key.QueryRawValue(value, val);
2019 printf(" (raw value '%s')", val.c_str());
2020 }
2021
2022 putchar('\n');
2023
2024 cont = key.GetNextValue(value, dummy);
2025 }
2026 }
2027
2028 static void TestRegistryAssociation()
2029 {
2030 /*
2031 The second call to deleteself genertaes an error message, with a
2032 messagebox saying .flo is crucial to system operation, while the .ddf
2033 call also fails, but with no error message
2034 */
2035
2036 wxRegKey key;
2037
2038 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2039 key.Create();
2040 key = "ddxf_auto_file" ;
2041 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2042 key.Create();
2043 key = "ddxf_auto_file" ;
2044 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2045 key.Create();
2046 key = "program,0" ;
2047 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2048 key.Create();
2049 key = "program \"%1\"" ;
2050
2051 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2052 key.DeleteSelf();
2053 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2054 key.DeleteSelf();
2055 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2056 key.DeleteSelf();
2057 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2058 key.DeleteSelf();
2059 }
2060
2061 #endif // TEST_REGISTRY
2062
2063 // ----------------------------------------------------------------------------
2064 // sockets
2065 // ----------------------------------------------------------------------------
2066
2067 #ifdef TEST_SOCKETS
2068
2069 #include <wx/socket.h>
2070 #include <wx/protocol/protocol.h>
2071 #include <wx/protocol/http.h>
2072
2073 static void TestSocketServer()
2074 {
2075 puts("*** Testing wxSocketServer ***\n");
2076
2077 static const int PORT = 3000;
2078
2079 wxIPV4address addr;
2080 addr.Service(PORT);
2081
2082 wxSocketServer *server = new wxSocketServer(addr);
2083 if ( !server->Ok() )
2084 {
2085 puts("ERROR: failed to bind");
2086
2087 return;
2088 }
2089
2090 for ( ;; )
2091 {
2092 printf("Server: waiting for connection on port %d...\n", PORT);
2093
2094 wxSocketBase *socket = server->Accept();
2095 if ( !socket )
2096 {
2097 puts("ERROR: wxSocketServer::Accept() failed.");
2098 break;
2099 }
2100
2101 puts("Server: got a client.");
2102
2103 server->SetTimeout(60); // 1 min
2104
2105 while ( socket->IsConnected() )
2106 {
2107 wxString s;
2108 char ch = '\0';
2109 for ( ;; )
2110 {
2111 if ( socket->Read(&ch, sizeof(ch)).Error() )
2112 {
2113 // don't log error if the client just close the connection
2114 if ( socket->IsConnected() )
2115 {
2116 puts("ERROR: in wxSocket::Read.");
2117 }
2118
2119 break;
2120 }
2121
2122 if ( ch == '\r' )
2123 continue;
2124
2125 if ( ch == '\n' )
2126 break;
2127
2128 s += ch;
2129 }
2130
2131 if ( ch != '\n' )
2132 {
2133 break;
2134 }
2135
2136 printf("Server: got '%s'.\n", s.c_str());
2137 if ( s == _T("bye") )
2138 {
2139 delete socket;
2140
2141 break;
2142 }
2143
2144 socket->Write(s.MakeUpper().c_str(), s.length());
2145 socket->Write("\r\n", 2);
2146 printf("Server: wrote '%s'.\n", s.c_str());
2147 }
2148
2149 puts("Server: lost a client.");
2150
2151 socket->Destroy();
2152 }
2153
2154 // same as "delete server" but is consistent with GUI programs
2155 server->Destroy();
2156 }
2157
2158 static void TestSocketClient()
2159 {
2160 puts("*** Testing wxSocketClient ***\n");
2161
2162 static const char *hostname = "www.wxwindows.org";
2163
2164 wxIPV4address addr;
2165 addr.Hostname(hostname);
2166 addr.Service(80);
2167
2168 printf("--- Attempting to connect to %s:80...\n", hostname);
2169
2170 wxSocketClient client;
2171 if ( !client.Connect(addr) )
2172 {
2173 printf("ERROR: failed to connect to %s\n", hostname);
2174 }
2175 else
2176 {
2177 printf("--- Connected to %s:%u...\n",
2178 addr.Hostname().c_str(), addr.Service());
2179
2180 char buf[8192];
2181
2182 // could use simply "GET" here I suppose
2183 wxString cmdGet =
2184 wxString::Format("GET http://%s/\r\n", hostname);
2185 client.Write(cmdGet, cmdGet.length());
2186 printf("--- Sent command '%s' to the server\n",
2187 MakePrintable(cmdGet).c_str());
2188 client.Read(buf, WXSIZEOF(buf));
2189 printf("--- Server replied:\n%s", buf);
2190 }
2191 }
2192
2193 #endif // TEST_SOCKETS
2194
2195 // ----------------------------------------------------------------------------
2196 // FTP
2197 // ----------------------------------------------------------------------------
2198
2199 #ifdef TEST_FTP
2200
2201 #include <wx/protocol/ftp.h>
2202
2203 static wxFTP ftp;
2204
2205 #define FTP_ANONYMOUS
2206
2207 #ifdef FTP_ANONYMOUS
2208 static const char *directory = "/pub";
2209 static const char *filename = "welcome.msg";
2210 #else
2211 static const char *directory = "/etc";
2212 static const char *filename = "issue";
2213 #endif
2214
2215 static bool TestFtpConnect()
2216 {
2217 puts("*** Testing FTP connect ***");
2218
2219 #ifdef FTP_ANONYMOUS
2220 static const char *hostname = "ftp.wxwindows.org";
2221
2222 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
2223 #else // !FTP_ANONYMOUS
2224 static const char *hostname = "localhost";
2225
2226 char user[256];
2227 fgets(user, WXSIZEOF(user), stdin);
2228 user[strlen(user) - 1] = '\0'; // chop off '\n'
2229 ftp.SetUser(user);
2230
2231 char password[256];
2232 printf("Password for %s: ", password);
2233 fgets(password, WXSIZEOF(password), stdin);
2234 password[strlen(password) - 1] = '\0'; // chop off '\n'
2235 ftp.SetPassword(password);
2236
2237 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
2238 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2239
2240 if ( !ftp.Connect(hostname) )
2241 {
2242 printf("ERROR: failed to connect to %s\n", hostname);
2243
2244 return FALSE;
2245 }
2246 else
2247 {
2248 printf("--- Connected to %s, current directory is '%s'\n",
2249 hostname, ftp.Pwd().c_str());
2250 }
2251
2252 return TRUE;
2253 }
2254
2255 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2256 static void TestFtpWuFtpd()
2257 {
2258 wxFTP ftp;
2259 static const char *hostname = "ftp.eudora.com";
2260 if ( !ftp.Connect(hostname) )
2261 {
2262 printf("ERROR: failed to connect to %s\n", hostname);
2263 }
2264 else
2265 {
2266 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2267 wxInputStream *in = ftp.GetInputStream(filename);
2268 if ( !in )
2269 {
2270 printf("ERROR: couldn't get input stream for %s\n", filename);
2271 }
2272 else
2273 {
2274 size_t size = in->StreamSize();
2275 printf("Reading file %s (%u bytes)...", filename, size);
2276
2277 char *data = new char[size];
2278 if ( !in->Read(data, size) )
2279 {
2280 puts("ERROR: read error");
2281 }
2282 else
2283 {
2284 printf("Successfully retrieved the file.\n");
2285 }
2286
2287 delete [] data;
2288 delete in;
2289 }
2290 }
2291 }
2292
2293 static void TestFtpList()
2294 {
2295 puts("*** Testing wxFTP file listing ***\n");
2296
2297 // test CWD
2298 if ( !ftp.ChDir(directory) )
2299 {
2300 printf("ERROR: failed to cd to %s\n", directory);
2301 }
2302
2303 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2304
2305 // test NLIST and LIST
2306 wxArrayString files;
2307 if ( !ftp.GetFilesList(files) )
2308 {
2309 puts("ERROR: failed to get NLIST of files");
2310 }
2311 else
2312 {
2313 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2314 size_t count = files.GetCount();
2315 for ( size_t n = 0; n < count; n++ )
2316 {
2317 printf("\t%s\n", files[n].c_str());
2318 }
2319 puts("End of the file list");
2320 }
2321
2322 if ( !ftp.GetDirList(files) )
2323 {
2324 puts("ERROR: failed to get LIST of files");
2325 }
2326 else
2327 {
2328 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2329 size_t count = files.GetCount();
2330 for ( size_t n = 0; n < count; n++ )
2331 {
2332 printf("\t%s\n", files[n].c_str());
2333 }
2334 puts("End of the file list");
2335 }
2336
2337 if ( !ftp.ChDir(_T("..")) )
2338 {
2339 puts("ERROR: failed to cd to ..");
2340 }
2341
2342 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2343 }
2344
2345 static void TestFtpDownload()
2346 {
2347 puts("*** Testing wxFTP download ***\n");
2348
2349 // test RETR
2350 wxInputStream *in = ftp.GetInputStream(filename);
2351 if ( !in )
2352 {
2353 printf("ERROR: couldn't get input stream for %s\n", filename);
2354 }
2355 else
2356 {
2357 size_t size = in->StreamSize();
2358 printf("Reading file %s (%u bytes)...", filename, size);
2359 fflush(stdout);
2360
2361 char *data = new char[size];
2362 if ( !in->Read(data, size) )
2363 {
2364 puts("ERROR: read error");
2365 }
2366 else
2367 {
2368 printf("\nContents of %s:\n%s\n", filename, data);
2369 }
2370
2371 delete [] data;
2372 delete in;
2373 }
2374 }
2375
2376 static void TestFtpFileSize()
2377 {
2378 puts("*** Testing FTP SIZE command ***");
2379
2380 if ( !ftp.ChDir(directory) )
2381 {
2382 printf("ERROR: failed to cd to %s\n", directory);
2383 }
2384
2385 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2386
2387 if ( ftp.FileExists(filename) )
2388 {
2389 int size = ftp.GetFileSize(filename);
2390 if ( size == -1 )
2391 printf("ERROR: couldn't get size of '%s'\n", filename);
2392 else
2393 printf("Size of '%s' is %d bytes.\n", filename, size);
2394 }
2395 else
2396 {
2397 printf("ERROR: '%s' doesn't exist\n", filename);
2398 }
2399 }
2400
2401 static void TestFtpMisc()
2402 {
2403 puts("*** Testing miscellaneous wxFTP functions ***");
2404
2405 if ( ftp.SendCommand("STAT") != '2' )
2406 {
2407 puts("ERROR: STAT failed");
2408 }
2409 else
2410 {
2411 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2412 }
2413
2414 if ( ftp.SendCommand("HELP SITE") != '2' )
2415 {
2416 puts("ERROR: HELP SITE failed");
2417 }
2418 else
2419 {
2420 printf("The list of site-specific commands:\n\n%s\n",
2421 ftp.GetLastResult().c_str());
2422 }
2423 }
2424
2425 static void TestFtpInteractive()
2426 {
2427 puts("\n*** Interactive wxFTP test ***");
2428
2429 char buf[128];
2430
2431 for ( ;; )
2432 {
2433 printf("Enter FTP command: ");
2434 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2435 break;
2436
2437 // kill the last '\n'
2438 buf[strlen(buf) - 1] = 0;
2439
2440 // special handling of LIST and NLST as they require data connection
2441 wxString start(buf, 4);
2442 start.MakeUpper();
2443 if ( start == "LIST" || start == "NLST" )
2444 {
2445 wxString wildcard;
2446 if ( strlen(buf) > 4 )
2447 wildcard = buf + 5;
2448
2449 wxArrayString files;
2450 if ( !ftp.GetList(files, wildcard, start == "LIST") )
2451 {
2452 printf("ERROR: failed to get %s of files\n", start.c_str());
2453 }
2454 else
2455 {
2456 printf("--- %s of '%s' under '%s':\n",
2457 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2458 size_t count = files.GetCount();
2459 for ( size_t n = 0; n < count; n++ )
2460 {
2461 printf("\t%s\n", files[n].c_str());
2462 }
2463 puts("--- End of the file list");
2464 }
2465 }
2466 else // !list
2467 {
2468 char ch = ftp.SendCommand(buf);
2469 printf("Command %s", ch ? "succeeded" : "failed");
2470 if ( ch )
2471 {
2472 printf(" (return code %c)", ch);
2473 }
2474
2475 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2476 }
2477 }
2478
2479 puts("\n*** done ***");
2480 }
2481
2482 static void TestFtpUpload()
2483 {
2484 puts("*** Testing wxFTP uploading ***\n");
2485
2486 // upload a file
2487 static const char *file1 = "test1";
2488 static const char *file2 = "test2";
2489 wxOutputStream *out = ftp.GetOutputStream(file1);
2490 if ( out )
2491 {
2492 printf("--- Uploading to %s ---\n", file1);
2493 out->Write("First hello", 11);
2494 delete out;
2495 }
2496
2497 // send a command to check the remote file
2498 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
2499 {
2500 printf("ERROR: STAT %s failed\n", file1);
2501 }
2502 else
2503 {
2504 printf("STAT %s returned:\n\n%s\n",
2505 file1, ftp.GetLastResult().c_str());
2506 }
2507
2508 out = ftp.GetOutputStream(file2);
2509 if ( out )
2510 {
2511 printf("--- Uploading to %s ---\n", file1);
2512 out->Write("Second hello", 12);
2513 delete out;
2514 }
2515 }
2516
2517 #endif // TEST_FTP
2518
2519 // ----------------------------------------------------------------------------
2520 // streams
2521 // ----------------------------------------------------------------------------
2522
2523 #ifdef TEST_STREAMS
2524
2525 #include <wx/wfstream.h>
2526 #include <wx/mstream.h>
2527
2528 static void TestFileStream()
2529 {
2530 puts("*** Testing wxFileInputStream ***");
2531
2532 static const wxChar *filename = _T("testdata.fs");
2533 {
2534 wxFileOutputStream fsOut(filename);
2535 fsOut.Write("foo", 3);
2536 }
2537
2538 wxFileInputStream fsIn(filename);
2539 printf("File stream size: %u\n", fsIn.GetSize());
2540 while ( !fsIn.Eof() )
2541 {
2542 putchar(fsIn.GetC());
2543 }
2544
2545 if ( !wxRemoveFile(filename) )
2546 {
2547 printf("ERROR: failed to remove the file '%s'.\n", filename);
2548 }
2549
2550 puts("\n*** wxFileInputStream test done ***");
2551 }
2552
2553 static void TestMemoryStream()
2554 {
2555 puts("*** Testing wxMemoryInputStream ***");
2556
2557 wxChar buf[1024];
2558 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2559
2560 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2561 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2562 while ( !memInpStream.Eof() )
2563 {
2564 putchar(memInpStream.GetC());
2565 }
2566
2567 puts("\n*** wxMemoryInputStream test done ***");
2568 }
2569
2570 #endif // TEST_STREAMS
2571
2572 // ----------------------------------------------------------------------------
2573 // timers
2574 // ----------------------------------------------------------------------------
2575
2576 #ifdef TEST_TIMER
2577
2578 #include <wx/timer.h>
2579 #include <wx/utils.h>
2580
2581 static void TestStopWatch()
2582 {
2583 puts("*** Testing wxStopWatch ***\n");
2584
2585 wxStopWatch sw;
2586 printf("Sleeping 3 seconds...");
2587 wxSleep(3);
2588 printf("\telapsed time: %ldms\n", sw.Time());
2589
2590 sw.Pause();
2591 printf("Sleeping 2 more seconds...");
2592 wxSleep(2);
2593 printf("\telapsed time: %ldms\n", sw.Time());
2594
2595 sw.Resume();
2596 printf("And 3 more seconds...");
2597 wxSleep(3);
2598 printf("\telapsed time: %ldms\n", sw.Time());
2599
2600 wxStopWatch sw2;
2601 puts("\nChecking for 'backwards clock' bug...");
2602 for ( size_t n = 0; n < 70; n++ )
2603 {
2604 sw2.Start();
2605
2606 for ( size_t m = 0; m < 100000; m++ )
2607 {
2608 if ( sw.Time() < 0 || sw2.Time() < 0 )
2609 {
2610 puts("\ntime is negative - ERROR!");
2611 }
2612 }
2613
2614 putchar('.');
2615 }
2616
2617 puts(", ok.");
2618 }
2619
2620 #endif // TEST_TIMER
2621
2622 // ----------------------------------------------------------------------------
2623 // vCard support
2624 // ----------------------------------------------------------------------------
2625
2626 #ifdef TEST_VCARD
2627
2628 #include <wx/vcard.h>
2629
2630 static void DumpVObject(size_t level, const wxVCardObject& vcard)
2631 {
2632 void *cookie;
2633 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2634 while ( vcObj )
2635 {
2636 printf("%s%s",
2637 wxString(_T('\t'), level).c_str(),
2638 vcObj->GetName().c_str());
2639
2640 wxString value;
2641 switch ( vcObj->GetType() )
2642 {
2643 case wxVCardObject::String:
2644 case wxVCardObject::UString:
2645 {
2646 wxString val;
2647 vcObj->GetValue(&val);
2648 value << _T('"') << val << _T('"');
2649 }
2650 break;
2651
2652 case wxVCardObject::Int:
2653 {
2654 unsigned int i;
2655 vcObj->GetValue(&i);
2656 value.Printf(_T("%u"), i);
2657 }
2658 break;
2659
2660 case wxVCardObject::Long:
2661 {
2662 unsigned long l;
2663 vcObj->GetValue(&l);
2664 value.Printf(_T("%lu"), l);
2665 }
2666 break;
2667
2668 case wxVCardObject::None:
2669 break;
2670
2671 case wxVCardObject::Object:
2672 value = _T("<node>");
2673 break;
2674
2675 default:
2676 value = _T("<unknown value type>");
2677 }
2678
2679 if ( !!value )
2680 printf(" = %s", value.c_str());
2681 putchar('\n');
2682
2683 DumpVObject(level + 1, *vcObj);
2684
2685 delete vcObj;
2686 vcObj = vcard.GetNextProp(&cookie);
2687 }
2688 }
2689
2690 static void DumpVCardAddresses(const wxVCard& vcard)
2691 {
2692 puts("\nShowing all addresses from vCard:\n");
2693
2694 size_t nAdr = 0;
2695 void *cookie;
2696 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
2697 while ( addr )
2698 {
2699 wxString flagsStr;
2700 int flags = addr->GetFlags();
2701 if ( flags & wxVCardAddress::Domestic )
2702 {
2703 flagsStr << _T("domestic ");
2704 }
2705 if ( flags & wxVCardAddress::Intl )
2706 {
2707 flagsStr << _T("international ");
2708 }
2709 if ( flags & wxVCardAddress::Postal )
2710 {
2711 flagsStr << _T("postal ");
2712 }
2713 if ( flags & wxVCardAddress::Parcel )
2714 {
2715 flagsStr << _T("parcel ");
2716 }
2717 if ( flags & wxVCardAddress::Home )
2718 {
2719 flagsStr << _T("home ");
2720 }
2721 if ( flags & wxVCardAddress::Work )
2722 {
2723 flagsStr << _T("work ");
2724 }
2725
2726 printf("Address %u:\n"
2727 "\tflags = %s\n"
2728 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
2729 ++nAdr,
2730 flagsStr.c_str(),
2731 addr->GetPostOffice().c_str(),
2732 addr->GetExtAddress().c_str(),
2733 addr->GetStreet().c_str(),
2734 addr->GetLocality().c_str(),
2735 addr->GetRegion().c_str(),
2736 addr->GetPostalCode().c_str(),
2737 addr->GetCountry().c_str()
2738 );
2739
2740 delete addr;
2741 addr = vcard.GetNextAddress(&cookie);
2742 }
2743 }
2744
2745 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
2746 {
2747 puts("\nShowing all phone numbers from vCard:\n");
2748
2749 size_t nPhone = 0;
2750 void *cookie;
2751 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
2752 while ( phone )
2753 {
2754 wxString flagsStr;
2755 int flags = phone->GetFlags();
2756 if ( flags & wxVCardPhoneNumber::Voice )
2757 {
2758 flagsStr << _T("voice ");
2759 }
2760 if ( flags & wxVCardPhoneNumber::Fax )
2761 {
2762 flagsStr << _T("fax ");
2763 }
2764 if ( flags & wxVCardPhoneNumber::Cellular )
2765 {
2766 flagsStr << _T("cellular ");
2767 }
2768 if ( flags & wxVCardPhoneNumber::Modem )
2769 {
2770 flagsStr << _T("modem ");
2771 }
2772 if ( flags & wxVCardPhoneNumber::Home )
2773 {
2774 flagsStr << _T("home ");
2775 }
2776 if ( flags & wxVCardPhoneNumber::Work )
2777 {
2778 flagsStr << _T("work ");
2779 }
2780
2781 printf("Phone number %u:\n"
2782 "\tflags = %s\n"
2783 "\tvalue = %s\n",
2784 ++nPhone,
2785 flagsStr.c_str(),
2786 phone->GetNumber().c_str()
2787 );
2788
2789 delete phone;
2790 phone = vcard.GetNextPhoneNumber(&cookie);
2791 }
2792 }
2793
2794 static void TestVCardRead()
2795 {
2796 puts("*** Testing wxVCard reading ***\n");
2797
2798 wxVCard vcard(_T("vcard.vcf"));
2799 if ( !vcard.IsOk() )
2800 {
2801 puts("ERROR: couldn't load vCard.");
2802 }
2803 else
2804 {
2805 // read individual vCard properties
2806 wxVCardObject *vcObj = vcard.GetProperty("FN");
2807 wxString value;
2808 if ( vcObj )
2809 {
2810 vcObj->GetValue(&value);
2811 delete vcObj;
2812 }
2813 else
2814 {
2815 value = _T("<none>");
2816 }
2817
2818 printf("Full name retrieved directly: %s\n", value.c_str());
2819
2820
2821 if ( !vcard.GetFullName(&value) )
2822 {
2823 value = _T("<none>");
2824 }
2825
2826 printf("Full name from wxVCard API: %s\n", value.c_str());
2827
2828 // now show how to deal with multiply occuring properties
2829 DumpVCardAddresses(vcard);
2830 DumpVCardPhoneNumbers(vcard);
2831
2832 // and finally show all
2833 puts("\nNow dumping the entire vCard:\n"
2834 "-----------------------------\n");
2835
2836 DumpVObject(0, vcard);
2837 }
2838 }
2839
2840 static void TestVCardWrite()
2841 {
2842 puts("*** Testing wxVCard writing ***\n");
2843
2844 wxVCard vcard;
2845 if ( !vcard.IsOk() )
2846 {
2847 puts("ERROR: couldn't create vCard.");
2848 }
2849 else
2850 {
2851 // set some fields
2852 vcard.SetName("Zeitlin", "Vadim");
2853 vcard.SetFullName("Vadim Zeitlin");
2854 vcard.SetOrganization("wxWindows", "R&D");
2855
2856 // just dump the vCard back
2857 puts("Entire vCard follows:\n");
2858 puts(vcard.Write());
2859 }
2860 }
2861
2862 #endif // TEST_VCARD
2863
2864 // ----------------------------------------------------------------------------
2865 // wide char (Unicode) support
2866 // ----------------------------------------------------------------------------
2867
2868 #ifdef TEST_WCHAR
2869
2870 #include <wx/strconv.h>
2871 #include <wx/fontenc.h>
2872 #include <wx/encconv.h>
2873 #include <wx/buffer.h>
2874
2875 static void TestUtf8()
2876 {
2877 puts("*** Testing UTF8 support ***\n");
2878
2879 static const char textInUtf8[] =
2880 {
2881 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
2882 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
2883 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
2884 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
2885 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
2886 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
2887 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
2888 };
2889
2890 char buf[1024];
2891 wchar_t wbuf[1024];
2892 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
2893 {
2894 puts("ERROR: UTF-8 decoding failed.");
2895 }
2896 else
2897 {
2898 // using wxEncodingConverter
2899 #if 0
2900 wxEncodingConverter ec;
2901 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
2902 ec.Convert(wbuf, buf);
2903 #else // using wxCSConv
2904 wxCSConv conv(_T("koi8-r"));
2905 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
2906 {
2907 puts("ERROR: conversion to KOI8-R failed.");
2908 }
2909 else
2910 #endif
2911
2912 printf("The resulting string (in koi8-r): %s\n", buf);
2913 }
2914 }
2915
2916 #endif // TEST_WCHAR
2917
2918 // ----------------------------------------------------------------------------
2919 // ZIP stream
2920 // ----------------------------------------------------------------------------
2921
2922 #ifdef TEST_ZIP
2923
2924 #include "wx/filesys.h"
2925 #include "wx/fs_zip.h"
2926 #include "wx/zipstrm.h"
2927
2928 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
2929
2930 static void TestZipStreamRead()
2931 {
2932 puts("*** Testing ZIP reading ***\n");
2933
2934 static const wxChar *filename = _T("foo");
2935 wxZipInputStream istr(TESTFILE_ZIP, filename);
2936 printf("Archive size: %u\n", istr.GetSize());
2937
2938 printf("Dumping the file '%s':\n", filename);
2939 while ( !istr.Eof() )
2940 {
2941 putchar(istr.GetC());
2942 fflush(stdout);
2943 }
2944
2945 puts("\n----- done ------");
2946 }
2947
2948 static void DumpZipDirectory(wxFileSystem& fs,
2949 const wxString& dir,
2950 const wxString& indent)
2951 {
2952 wxString prefix = wxString::Format(_T("%s#zip:%s"),
2953 TESTFILE_ZIP, dir.c_str());
2954 wxString wildcard = prefix + _T("/*");
2955
2956 wxString dirname = fs.FindFirst(wildcard, wxDIR);
2957 while ( !dirname.empty() )
2958 {
2959 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
2960 {
2961 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2962
2963 break;
2964 }
2965
2966 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
2967
2968 DumpZipDirectory(fs, dirname,
2969 indent + wxString(_T(' '), 4));
2970
2971 dirname = fs.FindNext();
2972 }
2973
2974 wxString filename = fs.FindFirst(wildcard, wxFILE);
2975 while ( !filename.empty() )
2976 {
2977 if ( !filename.StartsWith(prefix, &filename) )
2978 {
2979 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2980
2981 break;
2982 }
2983
2984 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
2985
2986 filename = fs.FindNext();
2987 }
2988 }
2989
2990 static void TestZipFileSystem()
2991 {
2992 puts("*** Testing ZIP file system ***\n");
2993
2994 wxFileSystem::AddHandler(new wxZipFSHandler);
2995 wxFileSystem fs;
2996 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
2997
2998 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
2999 }
3000
3001 #endif // TEST_ZIP
3002
3003 // ----------------------------------------------------------------------------
3004 // ZLIB stream
3005 // ----------------------------------------------------------------------------
3006
3007 #ifdef TEST_ZLIB
3008
3009 #include <wx/zstream.h>
3010 #include <wx/wfstream.h>
3011
3012 static const wxChar *FILENAME_GZ = _T("test.gz");
3013 static const char *TEST_DATA = "hello and hello again";
3014
3015 static void TestZlibStreamWrite()
3016 {
3017 puts("*** Testing Zlib stream reading ***\n");
3018
3019 wxFileOutputStream fileOutStream(FILENAME_GZ);
3020 wxZlibOutputStream ostr(fileOutStream, 0);
3021 printf("Compressing the test string... ");
3022 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3023 if ( !ostr )
3024 {
3025 puts("(ERROR: failed)");
3026 }
3027 else
3028 {
3029 puts("(ok)");
3030 }
3031
3032 puts("\n----- done ------");
3033 }
3034
3035 static void TestZlibStreamRead()
3036 {
3037 puts("*** Testing Zlib stream reading ***\n");
3038
3039 wxFileInputStream fileInStream(FILENAME_GZ);
3040 wxZlibInputStream istr(fileInStream);
3041 printf("Archive size: %u\n", istr.GetSize());
3042
3043 puts("Dumping the file:");
3044 while ( !istr.Eof() )
3045 {
3046 putchar(istr.GetC());
3047 fflush(stdout);
3048 }
3049
3050 puts("\n----- done ------");
3051 }
3052
3053 #endif // TEST_ZLIB
3054
3055 // ----------------------------------------------------------------------------
3056 // date time
3057 // ----------------------------------------------------------------------------
3058
3059 #ifdef TEST_DATETIME
3060
3061 #include <math.h>
3062
3063 #include <wx/date.h>
3064
3065 #include <wx/datetime.h>
3066
3067 // the test data
3068 struct Date
3069 {
3070 wxDateTime::wxDateTime_t day;
3071 wxDateTime::Month month;
3072 int year;
3073 wxDateTime::wxDateTime_t hour, min, sec;
3074 double jdn;
3075 wxDateTime::WeekDay wday;
3076 time_t gmticks, ticks;
3077
3078 void Init(const wxDateTime::Tm& tm)
3079 {
3080 day = tm.mday;
3081 month = tm.mon;
3082 year = tm.year;
3083 hour = tm.hour;
3084 min = tm.min;
3085 sec = tm.sec;
3086 jdn = 0.0;
3087 gmticks = ticks = -1;
3088 }
3089
3090 wxDateTime DT() const
3091 { return wxDateTime(day, month, year, hour, min, sec); }
3092
3093 bool SameDay(const wxDateTime::Tm& tm) const
3094 {
3095 return day == tm.mday && month == tm.mon && year == tm.year;
3096 }
3097
3098 wxString Format() const
3099 {
3100 wxString s;
3101 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3102 hour, min, sec,
3103 wxDateTime::GetMonthName(month).c_str(),
3104 day,
3105 abs(wxDateTime::ConvertYearToBC(year)),
3106 year > 0 ? "AD" : "BC");
3107 return s;
3108 }
3109
3110 wxString FormatDate() const
3111 {
3112 wxString s;
3113 s.Printf("%02d-%s-%4d%s",
3114 day,
3115 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3116 abs(wxDateTime::ConvertYearToBC(year)),
3117 year > 0 ? "AD" : "BC");
3118 return s;
3119 }
3120 };
3121
3122 static const Date testDates[] =
3123 {
3124 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3125 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3126 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3127 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3128 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3129 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3130 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3131 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3132 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3133 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
3134 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3135 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3136 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3137 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
3138 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
3139 };
3140
3141 // this test miscellaneous static wxDateTime functions
3142 static void TestTimeStatic()
3143 {
3144 puts("\n*** wxDateTime static methods test ***");
3145
3146 // some info about the current date
3147 int year = wxDateTime::GetCurrentYear();
3148 printf("Current year %d is %sa leap one and has %d days.\n",
3149 year,
3150 wxDateTime::IsLeapYear(year) ? "" : "not ",
3151 wxDateTime::GetNumberOfDays(year));
3152
3153 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3154 printf("Current month is '%s' ('%s') and it has %d days\n",
3155 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3156 wxDateTime::GetMonthName(month).c_str(),
3157 wxDateTime::GetNumberOfDays(month));
3158
3159 // leap year logic
3160 static const size_t nYears = 5;
3161 static const size_t years[2][nYears] =
3162 {
3163 // first line: the years to test
3164 { 1990, 1976, 2000, 2030, 1984, },
3165
3166 // second line: TRUE if leap, FALSE otherwise
3167 { FALSE, TRUE, TRUE, FALSE, TRUE }
3168 };
3169
3170 for ( size_t n = 0; n < nYears; n++ )
3171 {
3172 int year = years[0][n];
3173 bool should = years[1][n] != 0,
3174 is = wxDateTime::IsLeapYear(year);
3175
3176 printf("Year %d is %sa leap year (%s)\n",
3177 year,
3178 is ? "" : "not ",
3179 should == is ? "ok" : "ERROR");
3180
3181 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3182 }
3183 }
3184
3185 // test constructing wxDateTime objects
3186 static void TestTimeSet()
3187 {
3188 puts("\n*** wxDateTime construction test ***");
3189
3190 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3191 {
3192 const Date& d1 = testDates[n];
3193 wxDateTime dt = d1.DT();
3194
3195 Date d2;
3196 d2.Init(dt.GetTm());
3197
3198 wxString s1 = d1.Format(),
3199 s2 = d2.Format();
3200
3201 printf("Date: %s == %s (%s)\n",
3202 s1.c_str(), s2.c_str(),
3203 s1 == s2 ? "ok" : "ERROR");
3204 }
3205 }
3206
3207 // test time zones stuff
3208 static void TestTimeZones()
3209 {
3210 puts("\n*** wxDateTime timezone test ***");
3211
3212 wxDateTime now = wxDateTime::Now();
3213
3214 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3215 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3216 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3217 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3218 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3219 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
3220
3221 wxDateTime::Tm tm = now.GetTm();
3222 if ( wxDateTime(tm) != now )
3223 {
3224 printf("ERROR: got %s instead of %s\n",
3225 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3226 }
3227 }
3228
3229 // test some minimal support for the dates outside the standard range
3230 static void TestTimeRange()
3231 {
3232 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3233
3234 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3235
3236 printf("Unix epoch:\t%s\n",
3237 wxDateTime(2440587.5).Format(fmt).c_str());
3238 printf("Feb 29, 0: \t%s\n",
3239 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3240 printf("JDN 0: \t%s\n",
3241 wxDateTime(0.0).Format(fmt).c_str());
3242 printf("Jan 1, 1AD:\t%s\n",
3243 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3244 printf("May 29, 2099:\t%s\n",
3245 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3246 }
3247
3248 static void TestTimeTicks()
3249 {
3250 puts("\n*** wxDateTime ticks test ***");
3251
3252 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3253 {
3254 const Date& d = testDates[n];
3255 if ( d.ticks == -1 )
3256 continue;
3257
3258 wxDateTime dt = d.DT();
3259 long ticks = (dt.GetValue() / 1000).ToLong();
3260 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3261 if ( ticks == d.ticks )
3262 {
3263 puts(" (ok)");
3264 }
3265 else
3266 {
3267 printf(" (ERROR: should be %ld, delta = %ld)\n",
3268 d.ticks, ticks - d.ticks);
3269 }
3270
3271 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3272 ticks = (dt.GetValue() / 1000).ToLong();
3273 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3274 if ( ticks == d.gmticks )
3275 {
3276 puts(" (ok)");
3277 }
3278 else
3279 {
3280 printf(" (ERROR: should be %ld, delta = %ld)\n",
3281 d.gmticks, ticks - d.gmticks);
3282 }
3283 }
3284
3285 puts("");
3286 }
3287
3288 // test conversions to JDN &c
3289 static void TestTimeJDN()
3290 {
3291 puts("\n*** wxDateTime to JDN test ***");
3292
3293 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3294 {
3295 const Date& d = testDates[n];
3296 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3297 double jdn = dt.GetJulianDayNumber();
3298
3299 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
3300 if ( jdn == d.jdn )
3301 {
3302 puts(" (ok)");
3303 }
3304 else
3305 {
3306 printf(" (ERROR: should be %f, delta = %f)\n",
3307 d.jdn, jdn - d.jdn);
3308 }
3309 }
3310 }
3311
3312 // test week days computation
3313 static void TestTimeWDays()
3314 {
3315 puts("\n*** wxDateTime weekday test ***");
3316
3317 // test GetWeekDay()
3318 size_t n;
3319 for ( n = 0; n < WXSIZEOF(testDates); n++ )
3320 {
3321 const Date& d = testDates[n];
3322 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3323
3324 wxDateTime::WeekDay wday = dt.GetWeekDay();
3325 printf("%s is: %s",
3326 d.Format().c_str(),
3327 wxDateTime::GetWeekDayName(wday).c_str());
3328 if ( wday == d.wday )
3329 {
3330 puts(" (ok)");
3331 }
3332 else
3333 {
3334 printf(" (ERROR: should be %s)\n",
3335 wxDateTime::GetWeekDayName(d.wday).c_str());
3336 }
3337 }
3338
3339 puts("");
3340
3341 // test SetToWeekDay()
3342 struct WeekDateTestData
3343 {
3344 Date date; // the real date (precomputed)
3345 int nWeek; // its week index in the month
3346 wxDateTime::WeekDay wday; // the weekday
3347 wxDateTime::Month month; // the month
3348 int year; // and the year
3349
3350 wxString Format() const
3351 {
3352 wxString s, which;
3353 switch ( nWeek < -1 ? -nWeek : nWeek )
3354 {
3355 case 1: which = "first"; break;
3356 case 2: which = "second"; break;
3357 case 3: which = "third"; break;
3358 case 4: which = "fourth"; break;
3359 case 5: which = "fifth"; break;
3360
3361 case -1: which = "last"; break;
3362 }
3363
3364 if ( nWeek < -1 )
3365 {
3366 which += " from end";
3367 }
3368
3369 s.Printf("The %s %s of %s in %d",
3370 which.c_str(),
3371 wxDateTime::GetWeekDayName(wday).c_str(),
3372 wxDateTime::GetMonthName(month).c_str(),
3373 year);
3374
3375 return s;
3376 }
3377 };
3378
3379 // the array data was generated by the following python program
3380 /*
3381 from DateTime import *
3382 from whrandom import *
3383 from string import *
3384
3385 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3386 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3387
3388 week = DateTimeDelta(7)
3389
3390 for n in range(20):
3391 year = randint(1900, 2100)
3392 month = randint(1, 12)
3393 day = randint(1, 28)
3394 dt = DateTime(year, month, day)
3395 wday = dt.day_of_week
3396
3397 countFromEnd = choice([-1, 1])
3398 weekNum = 0;
3399
3400 while dt.month is month:
3401 dt = dt - countFromEnd * week
3402 weekNum = weekNum + countFromEnd
3403
3404 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
3405
3406 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3407 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
3408 */
3409
3410 static const WeekDateTestData weekDatesTestData[] =
3411 {
3412 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3413 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3414 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3415 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3416 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3417 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3418 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3419 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3420 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3421 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3422 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3423 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3424 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3425 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3426 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3427 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3428 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3429 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3430 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3431 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3432 };
3433
3434 static const char *fmt = "%d-%b-%Y";
3435
3436 wxDateTime dt;
3437 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3438 {
3439 const WeekDateTestData& wd = weekDatesTestData[n];
3440
3441 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3442
3443 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3444
3445 const Date& d = wd.date;
3446 if ( d.SameDay(dt.GetTm()) )
3447 {
3448 puts(" (ok)");
3449 }
3450 else
3451 {
3452 dt.Set(d.day, d.month, d.year);
3453
3454 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
3455 }
3456 }
3457 }
3458
3459 // test the computation of (ISO) week numbers
3460 static void TestTimeWNumber()
3461 {
3462 puts("\n*** wxDateTime week number test ***");
3463
3464 struct WeekNumberTestData
3465 {
3466 Date date; // the date
3467 wxDateTime::wxDateTime_t week; // the week number in the year
3468 wxDateTime::wxDateTime_t wmon; // the week number in the month
3469 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
3470 wxDateTime::wxDateTime_t dnum; // day number in the year
3471 };
3472
3473 // data generated with the following python script:
3474 /*
3475 from DateTime import *
3476 from whrandom import *
3477 from string import *
3478
3479 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3480 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3481
3482 def GetMonthWeek(dt):
3483 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3484 if weekNumMonth < 0:
3485 weekNumMonth = weekNumMonth + 53
3486 return weekNumMonth
3487
3488 def GetLastSundayBefore(dt):
3489 if dt.iso_week[2] == 7:
3490 return dt
3491 else:
3492 return dt - DateTimeDelta(dt.iso_week[2])
3493
3494 for n in range(20):
3495 year = randint(1900, 2100)
3496 month = randint(1, 12)
3497 day = randint(1, 28)
3498 dt = DateTime(year, month, day)
3499 dayNum = dt.day_of_year
3500 weekNum = dt.iso_week[1]
3501 weekNumMonth = GetMonthWeek(dt)
3502
3503 weekNumMonth2 = 0
3504 dtSunday = GetLastSundayBefore(dt)
3505
3506 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3507 weekNumMonth2 = weekNumMonth2 + 1
3508 dtSunday = dtSunday - DateTimeDelta(7)
3509
3510 data = { 'day': rjust(`day`, 2), \
3511 'month': monthNames[month - 1], \
3512 'year': year, \
3513 'weekNum': rjust(`weekNum`, 2), \
3514 'weekNumMonth': weekNumMonth, \
3515 'weekNumMonth2': weekNumMonth2, \
3516 'dayNum': rjust(`dayNum`, 3) }
3517
3518 print " { { %(day)s, "\
3519 "wxDateTime::%(month)s, "\
3520 "%(year)d }, "\
3521 "%(weekNum)s, "\
3522 "%(weekNumMonth)s, "\
3523 "%(weekNumMonth2)s, "\
3524 "%(dayNum)s }," % data
3525
3526 */
3527 static const WeekNumberTestData weekNumberTestDates[] =
3528 {
3529 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3530 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3531 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3532 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3533 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3534 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3535 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3536 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3537 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3538 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3539 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3540 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3541 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3542 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3543 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3544 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3545 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3546 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3547 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3548 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
3549 };
3550
3551 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3552 {
3553 const WeekNumberTestData& wn = weekNumberTestDates[n];
3554 const Date& d = wn.date;
3555
3556 wxDateTime dt = d.DT();
3557
3558 wxDateTime::wxDateTime_t
3559 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3560 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3561 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3562 dnum = dt.GetDayOfYear();
3563
3564 printf("%s: the day number is %d",
3565 d.FormatDate().c_str(), dnum);
3566 if ( dnum == wn.dnum )
3567 {
3568 printf(" (ok)");
3569 }
3570 else
3571 {
3572 printf(" (ERROR: should be %d)", wn.dnum);
3573 }
3574
3575 printf(", week in month is %d", wmon);
3576 if ( wmon == wn.wmon )
3577 {
3578 printf(" (ok)");
3579 }
3580 else
3581 {
3582 printf(" (ERROR: should be %d)", wn.wmon);
3583 }
3584
3585 printf(" or %d", wmon2);
3586 if ( wmon2 == wn.wmon2 )
3587 {
3588 printf(" (ok)");
3589 }
3590 else
3591 {
3592 printf(" (ERROR: should be %d)", wn.wmon2);
3593 }
3594
3595 printf(", week in year is %d", week);
3596 if ( week == wn.week )
3597 {
3598 puts(" (ok)");
3599 }
3600 else
3601 {
3602 printf(" (ERROR: should be %d)\n", wn.week);
3603 }
3604 }
3605 }
3606
3607 // test DST calculations
3608 static void TestTimeDST()
3609 {
3610 puts("\n*** wxDateTime DST test ***");
3611
3612 printf("DST is%s in effect now.\n\n",
3613 wxDateTime::Now().IsDST() ? "" : " not");
3614
3615 // taken from http://www.energy.ca.gov/daylightsaving.html
3616 static const Date datesDST[2][2004 - 1900 + 1] =
3617 {
3618 {
3619 { 1, wxDateTime::Apr, 1990 },
3620 { 7, wxDateTime::Apr, 1991 },
3621 { 5, wxDateTime::Apr, 1992 },
3622 { 4, wxDateTime::Apr, 1993 },
3623 { 3, wxDateTime::Apr, 1994 },
3624 { 2, wxDateTime::Apr, 1995 },
3625 { 7, wxDateTime::Apr, 1996 },
3626 { 6, wxDateTime::Apr, 1997 },
3627 { 5, wxDateTime::Apr, 1998 },
3628 { 4, wxDateTime::Apr, 1999 },
3629 { 2, wxDateTime::Apr, 2000 },
3630 { 1, wxDateTime::Apr, 2001 },
3631 { 7, wxDateTime::Apr, 2002 },
3632 { 6, wxDateTime::Apr, 2003 },
3633 { 4, wxDateTime::Apr, 2004 },
3634 },
3635 {
3636 { 28, wxDateTime::Oct, 1990 },
3637 { 27, wxDateTime::Oct, 1991 },
3638 { 25, wxDateTime::Oct, 1992 },
3639 { 31, wxDateTime::Oct, 1993 },
3640 { 30, wxDateTime::Oct, 1994 },
3641 { 29, wxDateTime::Oct, 1995 },
3642 { 27, wxDateTime::Oct, 1996 },
3643 { 26, wxDateTime::Oct, 1997 },
3644 { 25, wxDateTime::Oct, 1998 },
3645 { 31, wxDateTime::Oct, 1999 },
3646 { 29, wxDateTime::Oct, 2000 },
3647 { 28, wxDateTime::Oct, 2001 },
3648 { 27, wxDateTime::Oct, 2002 },
3649 { 26, wxDateTime::Oct, 2003 },
3650 { 31, wxDateTime::Oct, 2004 },
3651 }
3652 };
3653
3654 int year;
3655 for ( year = 1990; year < 2005; year++ )
3656 {
3657 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
3658 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
3659
3660 printf("DST period in the US for year %d: from %s to %s",
3661 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
3662
3663 size_t n = year - 1990;
3664 const Date& dBegin = datesDST[0][n];
3665 const Date& dEnd = datesDST[1][n];
3666
3667 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
3668 {
3669 puts(" (ok)");
3670 }
3671 else
3672 {
3673 printf(" (ERROR: should be %s %d to %s %d)\n",
3674 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
3675 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
3676 }
3677 }
3678
3679 puts("");
3680
3681 for ( year = 1990; year < 2005; year++ )
3682 {
3683 printf("DST period in Europe for year %d: from %s to %s\n",
3684 year,
3685 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3686 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3687 }
3688 }
3689
3690 // test wxDateTime -> text conversion
3691 static void TestTimeFormat()
3692 {
3693 puts("\n*** wxDateTime formatting test ***");
3694
3695 // some information may be lost during conversion, so store what kind
3696 // of info should we recover after a round trip
3697 enum CompareKind
3698 {
3699 CompareNone, // don't try comparing
3700 CompareBoth, // dates and times should be identical
3701 CompareDate, // dates only
3702 CompareTime // time only
3703 };
3704
3705 static const struct
3706 {
3707 CompareKind compareKind;
3708 const char *format;
3709 } formatTestFormats[] =
3710 {
3711 { CompareBoth, "---> %c" },
3712 { CompareDate, "Date is %A, %d of %B, in year %Y" },
3713 { CompareBoth, "Date is %x, time is %X" },
3714 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
3715 { CompareNone, "The day of year: %j, the week of year: %W" },
3716 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
3717 };
3718
3719 static const Date formatTestDates[] =
3720 {
3721 { 29, wxDateTime::May, 1976, 18, 30, 00 },
3722 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
3723 #if 0
3724 // this test can't work for other centuries because it uses two digit
3725 // years in formats, so don't even try it
3726 { 29, wxDateTime::May, 2076, 18, 30, 00 },
3727 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
3728 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
3729 #endif
3730 };
3731
3732 // an extra test (as it doesn't depend on date, don't do it in the loop)
3733 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
3734
3735 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
3736 {
3737 puts("");
3738
3739 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
3740 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
3741 {
3742 wxString s = dt.Format(formatTestFormats[n].format);
3743 printf("%s", s.c_str());
3744
3745 // what can we recover?
3746 int kind = formatTestFormats[n].compareKind;
3747
3748 // convert back
3749 wxDateTime dt2;
3750 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
3751 if ( !result )
3752 {
3753 // converion failed - should it have?
3754 if ( kind == CompareNone )
3755 puts(" (ok)");
3756 else
3757 puts(" (ERROR: conversion back failed)");
3758 }
3759 else if ( *result )
3760 {
3761 // should have parsed the entire string
3762 puts(" (ERROR: conversion back stopped too soon)");
3763 }
3764 else
3765 {
3766 bool equal = FALSE; // suppress compilaer warning
3767 switch ( kind )
3768 {
3769 case CompareBoth:
3770 equal = dt2 == dt;
3771 break;
3772
3773 case CompareDate:
3774 equal = dt.IsSameDate(dt2);
3775 break;
3776
3777 case CompareTime:
3778 equal = dt.IsSameTime(dt2);
3779 break;
3780 }
3781
3782 if ( !equal )
3783 {
3784 printf(" (ERROR: got back '%s' instead of '%s')\n",
3785 dt2.Format().c_str(), dt.Format().c_str());
3786 }
3787 else
3788 {
3789 puts(" (ok)");
3790 }
3791 }
3792 }
3793 }
3794 }
3795
3796 // test text -> wxDateTime conversion
3797 static void TestTimeParse()
3798 {
3799 puts("\n*** wxDateTime parse test ***");
3800
3801 struct ParseTestData
3802 {
3803 const char *format;
3804 Date date;
3805 bool good;
3806 };
3807
3808 static const ParseTestData parseTestDates[] =
3809 {
3810 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
3811 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
3812 };
3813
3814 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
3815 {
3816 const char *format = parseTestDates[n].format;
3817
3818 printf("%s => ", format);
3819
3820 wxDateTime dt;
3821 if ( dt.ParseRfc822Date(format) )
3822 {
3823 printf("%s ", dt.Format().c_str());
3824
3825 if ( parseTestDates[n].good )
3826 {
3827 wxDateTime dtReal = parseTestDates[n].date.DT();
3828 if ( dt == dtReal )
3829 {
3830 puts("(ok)");
3831 }
3832 else
3833 {
3834 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
3835 }
3836 }
3837 else
3838 {
3839 puts("(ERROR: bad format)");
3840 }
3841 }
3842 else
3843 {
3844 printf("bad format (%s)\n",
3845 parseTestDates[n].good ? "ERROR" : "ok");
3846 }
3847 }
3848 }
3849
3850 static void TestDateTimeInteractive()
3851 {
3852 puts("\n*** interactive wxDateTime tests ***");
3853
3854 char buf[128];
3855
3856 for ( ;; )
3857 {
3858 printf("Enter a date: ");
3859 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
3860 break;
3861
3862 // kill the last '\n'
3863 buf[strlen(buf) - 1] = 0;
3864
3865 wxDateTime dt;
3866 const char *p = dt.ParseDate(buf);
3867 if ( !p )
3868 {
3869 printf("ERROR: failed to parse the date '%s'.\n", buf);
3870
3871 continue;
3872 }
3873 else if ( *p )
3874 {
3875 printf("WARNING: parsed only first %u characters.\n", p - buf);
3876 }
3877
3878 printf("%s: day %u, week of month %u/%u, week of year %u\n",
3879 dt.Format("%b %d, %Y").c_str(),
3880 dt.GetDayOfYear(),
3881 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3882 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3883 dt.GetWeekOfYear(wxDateTime::Monday_First));
3884 }
3885
3886 puts("\n*** done ***");
3887 }
3888
3889 static void TestTimeMS()
3890 {
3891 puts("*** testing millisecond-resolution support in wxDateTime ***");
3892
3893 wxDateTime dt1 = wxDateTime::Now(),
3894 dt2 = wxDateTime::UNow();
3895
3896 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
3897 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3898 printf("Dummy loop: ");
3899 for ( int i = 0; i < 6000; i++ )
3900 {
3901 //for ( int j = 0; j < 10; j++ )
3902 {
3903 wxString s;
3904 s.Printf("%g", sqrt(i));
3905 }
3906
3907 if ( !(i % 100) )
3908 putchar('.');
3909 }
3910 puts(", done");
3911
3912 dt1 = dt2;
3913 dt2 = wxDateTime::UNow();
3914 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3915
3916 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
3917
3918 puts("\n*** done ***");
3919 }
3920
3921 static void TestTimeArithmetics()
3922 {
3923 puts("\n*** testing arithmetic operations on wxDateTime ***");
3924
3925 static const struct ArithmData
3926 {
3927 ArithmData(const wxDateSpan& sp, const char *nam)
3928 : span(sp), name(nam) { }
3929
3930 wxDateSpan span;
3931 const char *name;
3932 } testArithmData[] =
3933 {
3934 ArithmData(wxDateSpan::Day(), "day"),
3935 ArithmData(wxDateSpan::Week(), "week"),
3936 ArithmData(wxDateSpan::Month(), "month"),
3937 ArithmData(wxDateSpan::Year(), "year"),
3938 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
3939 };
3940
3941 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
3942
3943 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
3944 {
3945 wxDateSpan span = testArithmData[n].span;
3946 dt1 = dt + span;
3947 dt2 = dt - span;
3948
3949 const char *name = testArithmData[n].name;
3950 printf("%s + %s = %s, %s - %s = %s\n",
3951 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
3952 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
3953
3954 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
3955 if ( dt1 - span == dt )
3956 {
3957 puts(" (ok)");
3958 }
3959 else
3960 {
3961 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3962 }
3963
3964 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
3965 if ( dt2 + span == dt )
3966 {
3967 puts(" (ok)");
3968 }
3969 else
3970 {
3971 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3972 }
3973
3974 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
3975 if ( dt2 + 2*span == dt1 )
3976 {
3977 puts(" (ok)");
3978 }
3979 else
3980 {
3981 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
3982 }
3983
3984 puts("");
3985 }
3986 }
3987
3988 static void TestTimeHolidays()
3989 {
3990 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
3991
3992 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3993 wxDateTime dtStart(1, tm.mon, tm.year),
3994 dtEnd = dtStart.GetLastMonthDay();
3995
3996 wxDateTimeArray hol;
3997 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3998
3999 const wxChar *format = "%d-%b-%Y (%a)";
4000
4001 printf("All holidays between %s and %s:\n",
4002 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4003
4004 size_t count = hol.GetCount();
4005 for ( size_t n = 0; n < count; n++ )
4006 {
4007 printf("\t%s\n", hol[n].Format(format).c_str());
4008 }
4009
4010 puts("");
4011 }
4012
4013 static void TestTimeZoneBug()
4014 {
4015 puts("\n*** testing for DST/timezone bug ***\n");
4016
4017 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4018 for ( int i = 0; i < 31; i++ )
4019 {
4020 printf("Date %s: week day %s.\n",
4021 date.Format(_T("%d-%m-%Y")).c_str(),
4022 date.GetWeekDayName(date.GetWeekDay()).c_str());
4023
4024 date += wxDateSpan::Day();
4025 }
4026
4027 puts("");
4028 }
4029
4030 static void TestTimeSpanFormat()
4031 {
4032 puts("\n*** wxTimeSpan tests ***");
4033
4034 static const char *formats[] =
4035 {
4036 _T("(default) %H:%M:%S"),
4037 _T("%E weeks and %D days"),
4038 _T("%l milliseconds"),
4039 _T("(with ms) %H:%M:%S:%l"),
4040 _T("100%% of minutes is %M"), // test "%%"
4041 _T("%D days and %H hours"),
4042 _T("or also %S seconds"),
4043 };
4044
4045 wxTimeSpan ts1(1, 2, 3, 4),
4046 ts2(111, 222, 333);
4047 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4048 {
4049 printf("ts1 = %s\tts2 = %s\n",
4050 ts1.Format(formats[n]).c_str(),
4051 ts2.Format(formats[n]).c_str());
4052 }
4053
4054 puts("");
4055 }
4056
4057 #if 0
4058
4059 // test compatibility with the old wxDate/wxTime classes
4060 static void TestTimeCompatibility()
4061 {
4062 puts("\n*** wxDateTime compatibility test ***");
4063
4064 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4065 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4066
4067 double jdnNow = wxDateTime::Now().GetJDN();
4068 long jdnMidnight = (long)(jdnNow - 0.5);
4069 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4070
4071 jdnMidnight = wxDate().Set().GetJulianDate();
4072 printf("wxDateTime for today: %s\n",
4073 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4074
4075 int flags = wxEUROPEAN;//wxFULL;
4076 wxDate date;
4077 date.Set();
4078 printf("Today is %s\n", date.FormatDate(flags).c_str());
4079 for ( int n = 0; n < 7; n++ )
4080 {
4081 printf("Previous %s is %s\n",
4082 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4083 date.Previous(n + 1).FormatDate(flags).c_str());
4084 }
4085 }
4086
4087 #endif // 0
4088
4089 #endif // TEST_DATETIME
4090
4091 // ----------------------------------------------------------------------------
4092 // threads
4093 // ----------------------------------------------------------------------------
4094
4095 #ifdef TEST_THREADS
4096
4097 #include <wx/thread.h>
4098
4099 static size_t gs_counter = (size_t)-1;
4100 static wxCriticalSection gs_critsect;
4101 static wxCondition gs_cond;
4102
4103 class MyJoinableThread : public wxThread
4104 {
4105 public:
4106 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4107 { m_n = n; Create(); }
4108
4109 // thread execution starts here
4110 virtual ExitCode Entry();
4111
4112 private:
4113 size_t m_n;
4114 };
4115
4116 wxThread::ExitCode MyJoinableThread::Entry()
4117 {
4118 unsigned long res = 1;
4119 for ( size_t n = 1; n < m_n; n++ )
4120 {
4121 res *= n;
4122
4123 // it's a loooong calculation :-)
4124 Sleep(100);
4125 }
4126
4127 return (ExitCode)res;
4128 }
4129
4130 class MyDetachedThread : public wxThread
4131 {
4132 public:
4133 MyDetachedThread(size_t n, char ch)
4134 {
4135 m_n = n;
4136 m_ch = ch;
4137 m_cancelled = FALSE;
4138
4139 Create();
4140 }
4141
4142 // thread execution starts here
4143 virtual ExitCode Entry();
4144
4145 // and stops here
4146 virtual void OnExit();
4147
4148 private:
4149 size_t m_n; // number of characters to write
4150 char m_ch; // character to write
4151
4152 bool m_cancelled; // FALSE if we exit normally
4153 };
4154
4155 wxThread::ExitCode MyDetachedThread::Entry()
4156 {
4157 {
4158 wxCriticalSectionLocker lock(gs_critsect);
4159 if ( gs_counter == (size_t)-1 )
4160 gs_counter = 1;
4161 else
4162 gs_counter++;
4163 }
4164
4165 for ( size_t n = 0; n < m_n; n++ )
4166 {
4167 if ( TestDestroy() )
4168 {
4169 m_cancelled = TRUE;
4170
4171 break;
4172 }
4173
4174 putchar(m_ch);
4175 fflush(stdout);
4176
4177 wxThread::Sleep(100);
4178 }
4179
4180 return 0;
4181 }
4182
4183 void MyDetachedThread::OnExit()
4184 {
4185 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4186
4187 wxCriticalSectionLocker lock(gs_critsect);
4188 if ( !--gs_counter && !m_cancelled )
4189 gs_cond.Signal();
4190 }
4191
4192 void TestDetachedThreads()
4193 {
4194 puts("\n*** Testing detached threads ***");
4195
4196 static const size_t nThreads = 3;
4197 MyDetachedThread *threads[nThreads];
4198 size_t n;
4199 for ( n = 0; n < nThreads; n++ )
4200 {
4201 threads[n] = new MyDetachedThread(10, 'A' + n);
4202 }
4203
4204 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4205 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4206
4207 for ( n = 0; n < nThreads; n++ )
4208 {
4209 threads[n]->Run();
4210 }
4211
4212 // wait until all threads terminate
4213 gs_cond.Wait();
4214
4215 puts("");
4216 }
4217
4218 void TestJoinableThreads()
4219 {
4220 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
4221
4222 // calc 10! in the background
4223 MyJoinableThread thread(10);
4224 thread.Run();
4225
4226 printf("\nThread terminated with exit code %lu.\n",
4227 (unsigned long)thread.Wait());
4228 }
4229
4230 void TestThreadSuspend()
4231 {
4232 puts("\n*** Testing thread suspend/resume functions ***");
4233
4234 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
4235
4236 thread->Run();
4237
4238 // this is for this demo only, in a real life program we'd use another
4239 // condition variable which would be signaled from wxThread::Entry() to
4240 // tell us that the thread really started running - but here just wait a
4241 // bit and hope that it will be enough (the problem is, of course, that
4242 // the thread might still not run when we call Pause() which will result
4243 // in an error)
4244 wxThread::Sleep(300);
4245
4246 for ( size_t n = 0; n < 3; n++ )
4247 {
4248 thread->Pause();
4249
4250 puts("\nThread suspended");
4251 if ( n > 0 )
4252 {
4253 // don't sleep but resume immediately the first time
4254 wxThread::Sleep(300);
4255 }
4256 puts("Going to resume the thread");
4257
4258 thread->Resume();
4259 }
4260
4261 puts("Waiting until it terminates now");
4262
4263 // wait until the thread terminates
4264 gs_cond.Wait();
4265
4266 puts("");
4267 }
4268
4269 void TestThreadDelete()
4270 {
4271 // As above, using Sleep() is only for testing here - we must use some
4272 // synchronisation object instead to ensure that the thread is still
4273 // running when we delete it - deleting a detached thread which already
4274 // terminated will lead to a crash!
4275
4276 puts("\n*** Testing thread delete function ***");
4277
4278 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4279
4280 thread0->Delete();
4281
4282 puts("\nDeleted a thread which didn't start to run yet.");
4283
4284 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4285
4286 thread1->Run();
4287
4288 wxThread::Sleep(300);
4289
4290 thread1->Delete();
4291
4292 puts("\nDeleted a running thread.");
4293
4294 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4295
4296 thread2->Run();
4297
4298 wxThread::Sleep(300);
4299
4300 thread2->Pause();
4301
4302 thread2->Delete();
4303
4304 puts("\nDeleted a sleeping thread.");
4305
4306 MyJoinableThread thread3(20);
4307 thread3.Run();
4308
4309 thread3.Delete();
4310
4311 puts("\nDeleted a joinable thread.");
4312
4313 MyJoinableThread thread4(2);
4314 thread4.Run();
4315
4316 wxThread::Sleep(300);
4317
4318 thread4.Delete();
4319
4320 puts("\nDeleted a joinable thread which already terminated.");
4321
4322 puts("");
4323 }
4324
4325 #endif // TEST_THREADS
4326
4327 // ----------------------------------------------------------------------------
4328 // arrays
4329 // ----------------------------------------------------------------------------
4330
4331 #ifdef TEST_ARRAYS
4332
4333 static void PrintArray(const char* name, const wxArrayString& array)
4334 {
4335 printf("Dump of the array '%s'\n", name);
4336
4337 size_t nCount = array.GetCount();
4338 for ( size_t n = 0; n < nCount; n++ )
4339 {
4340 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4341 }
4342 }
4343
4344 static void PrintArray(const char* name, const wxArrayInt& array)
4345 {
4346 printf("Dump of the array '%s'\n", name);
4347
4348 size_t nCount = array.GetCount();
4349 for ( size_t n = 0; n < nCount; n++ )
4350 {
4351 printf("\t%s[%u] = %d\n", name, n, array[n]);
4352 }
4353 }
4354
4355 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4356 const wxString& second)
4357 {
4358 return first.length() - second.length();
4359 }
4360
4361 int wxCMPFUNC_CONV IntCompare(int *first,
4362 int *second)
4363 {
4364 return *first - *second;
4365 }
4366
4367 int wxCMPFUNC_CONV IntRevCompare(int *first,
4368 int *second)
4369 {
4370 return *second - *first;
4371 }
4372
4373 static void TestArrayOfInts()
4374 {
4375 puts("*** Testing wxArrayInt ***\n");
4376
4377 wxArrayInt a;
4378 a.Add(1);
4379 a.Add(17);
4380 a.Add(5);
4381 a.Add(3);
4382
4383 puts("Initially:");
4384 PrintArray("a", a);
4385
4386 puts("After sort:");
4387 a.Sort(IntCompare);
4388 PrintArray("a", a);
4389
4390 puts("After reverse sort:");
4391 a.Sort(IntRevCompare);
4392 PrintArray("a", a);
4393 }
4394
4395 #include "wx/dynarray.h"
4396
4397 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4398 #include "wx/arrimpl.cpp"
4399 WX_DEFINE_OBJARRAY(ArrayBars);
4400
4401 static void TestArrayOfObjects()
4402 {
4403 puts("*** Testing wxObjArray ***\n");
4404
4405 {
4406 ArrayBars bars;
4407 Bar bar("second bar");
4408
4409 printf("Initially: %u objects in the array, %u objects total.\n",
4410 bars.GetCount(), Bar::GetNumber());
4411
4412 bars.Add(new Bar("first bar"));
4413 bars.Add(bar);
4414
4415 printf("Now: %u objects in the array, %u objects total.\n",
4416 bars.GetCount(), Bar::GetNumber());
4417
4418 bars.Empty();
4419
4420 printf("After Empty(): %u objects in the array, %u objects total.\n",
4421 bars.GetCount(), Bar::GetNumber());
4422 }
4423
4424 printf("Finally: no more objects in the array, %u objects total.\n",
4425 Bar::GetNumber());
4426 }
4427
4428 #endif // TEST_ARRAYS
4429
4430 // ----------------------------------------------------------------------------
4431 // strings
4432 // ----------------------------------------------------------------------------
4433
4434 #ifdef TEST_STRINGS
4435
4436 #include "wx/timer.h"
4437 #include "wx/tokenzr.h"
4438
4439 static void TestStringConstruction()
4440 {
4441 puts("*** Testing wxString constructores ***");
4442
4443 #define TEST_CTOR(args, res) \
4444 { \
4445 wxString s args ; \
4446 printf("wxString%s = %s ", #args, s.c_str()); \
4447 if ( s == res ) \
4448 { \
4449 puts("(ok)"); \
4450 } \
4451 else \
4452 { \
4453 printf("(ERROR: should be %s)\n", res); \
4454 } \
4455 }
4456
4457 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
4458 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
4459 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
4460 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
4461
4462 static const wxChar *s = _T("?really!");
4463 const wxChar *start = wxStrchr(s, _T('r'));
4464 const wxChar *end = wxStrchr(s, _T('!'));
4465 TEST_CTOR((start, end), _T("really"));
4466
4467 puts("");
4468 }
4469
4470 static void TestString()
4471 {
4472 wxStopWatch sw;
4473
4474 wxString a, b, c;
4475
4476 a.reserve (128);
4477 b.reserve (128);
4478 c.reserve (128);
4479
4480 for (int i = 0; i < 1000000; ++i)
4481 {
4482 a = "Hello";
4483 b = " world";
4484 c = "! How'ya doin'?";
4485 a += b;
4486 a += c;
4487 c = "Hello world! What's up?";
4488 if (c != a)
4489 c = "Doh!";
4490 }
4491
4492 printf ("TestString elapsed time: %ld\n", sw.Time());
4493 }
4494
4495 static void TestPChar()
4496 {
4497 wxStopWatch sw;
4498
4499 char a [128];
4500 char b [128];
4501 char c [128];
4502
4503 for (int i = 0; i < 1000000; ++i)
4504 {
4505 strcpy (a, "Hello");
4506 strcpy (b, " world");
4507 strcpy (c, "! How'ya doin'?");
4508 strcat (a, b);
4509 strcat (a, c);
4510 strcpy (c, "Hello world! What's up?");
4511 if (strcmp (c, a) == 0)
4512 strcpy (c, "Doh!");
4513 }
4514
4515 printf ("TestPChar elapsed time: %ld\n", sw.Time());
4516 }
4517
4518 static void TestStringSub()
4519 {
4520 wxString s("Hello, world!");
4521
4522 puts("*** Testing wxString substring extraction ***");
4523
4524 printf("String = '%s'\n", s.c_str());
4525 printf("Left(5) = '%s'\n", s.Left(5).c_str());
4526 printf("Right(6) = '%s'\n", s.Right(6).c_str());
4527 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
4528 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
4529 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
4530 printf("substr(3) = '%s'\n", s.substr(3).c_str());
4531
4532 static const wxChar *prefixes[] =
4533 {
4534 _T("Hello"),
4535 _T("Hello, "),
4536 _T("Hello, world!"),
4537 _T("Hello, world!!!"),
4538 _T(""),
4539 _T("Goodbye"),
4540 _T("Hi"),
4541 };
4542
4543 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
4544 {
4545 wxString prefix = prefixes[n], rest;
4546 bool rc = s.StartsWith(prefix, &rest);
4547 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
4548 if ( rc )
4549 {
4550 printf(" (the rest is '%s')\n", rest.c_str());
4551 }
4552 else
4553 {
4554 putchar('\n');
4555 }
4556 }
4557
4558 puts("");
4559 }
4560
4561 static void TestStringFormat()
4562 {
4563 puts("*** Testing wxString formatting ***");
4564
4565 wxString s;
4566 s.Printf("%03d", 18);
4567
4568 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
4569 printf("Number 18: %s\n", s.c_str());
4570
4571 puts("");
4572 }
4573
4574 // returns "not found" for npos, value for all others
4575 static wxString PosToString(size_t res)
4576 {
4577 wxString s = res == wxString::npos ? wxString(_T("not found"))
4578 : wxString::Format(_T("%u"), res);
4579 return s;
4580 }
4581
4582 static void TestStringFind()
4583 {
4584 puts("*** Testing wxString find() functions ***");
4585
4586 static const wxChar *strToFind = _T("ell");
4587 static const struct StringFindTest
4588 {
4589 const wxChar *str;
4590 size_t start,
4591 result; // of searching "ell" in str
4592 } findTestData[] =
4593 {
4594 { _T("Well, hello world"), 0, 1 },
4595 { _T("Well, hello world"), 6, 7 },
4596 { _T("Well, hello world"), 9, wxString::npos },
4597 };
4598
4599 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
4600 {
4601 const StringFindTest& ft = findTestData[n];
4602 size_t res = wxString(ft.str).find(strToFind, ft.start);
4603
4604 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
4605 strToFind, ft.str, ft.start, PosToString(res).c_str());
4606
4607 size_t resTrue = ft.result;
4608 if ( res == resTrue )
4609 {
4610 puts(_T("(ok)"));
4611 }
4612 else
4613 {
4614 printf(_T("(ERROR: should be %s)\n"),
4615 PosToString(resTrue).c_str());
4616 }
4617 }
4618
4619 puts("");
4620 }
4621
4622 static void TestStringTokenizer()
4623 {
4624 puts("*** Testing wxStringTokenizer ***");
4625
4626 static const wxChar *modeNames[] =
4627 {
4628 _T("default"),
4629 _T("return empty"),
4630 _T("return all empty"),
4631 _T("with delims"),
4632 _T("like strtok"),
4633 };
4634
4635 static const struct StringTokenizerTest
4636 {
4637 const wxChar *str; // string to tokenize
4638 const wxChar *delims; // delimiters to use
4639 size_t count; // count of token
4640 wxStringTokenizerMode mode; // how should we tokenize it
4641 } tokenizerTestData[] =
4642 {
4643 { _T(""), _T(" "), 0 },
4644 { _T("Hello, world"), _T(" "), 2 },
4645 { _T("Hello, world "), _T(" "), 2 },
4646 { _T("Hello, world"), _T(","), 2 },
4647 { _T("Hello, world!"), _T(",!"), 2 },
4648 { _T("Hello,, world!"), _T(",!"), 3 },
4649 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
4650 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
4651 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
4652 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
4653 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
4654 { _T("01/02/99"), _T("/-"), 3 },
4655 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
4656 };
4657
4658 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
4659 {
4660 const StringTokenizerTest& tt = tokenizerTestData[n];
4661 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
4662
4663 size_t count = tkz.CountTokens();
4664 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
4665 MakePrintable(tt.str).c_str(),
4666 count,
4667 MakePrintable(tt.delims).c_str(),
4668 modeNames[tkz.GetMode()]);
4669 if ( count == tt.count )
4670 {
4671 puts(_T("(ok)"));
4672 }
4673 else
4674 {
4675 printf(_T("(ERROR: should be %u)\n"), tt.count);
4676
4677 continue;
4678 }
4679
4680 // if we emulate strtok(), check that we do it correctly
4681 wxChar *buf, *s = NULL, *last;
4682
4683 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4684 {
4685 buf = new wxChar[wxStrlen(tt.str) + 1];
4686 wxStrcpy(buf, tt.str);
4687
4688 s = wxStrtok(buf, tt.delims, &last);
4689 }
4690 else
4691 {
4692 buf = NULL;
4693 }
4694
4695 // now show the tokens themselves
4696 size_t count2 = 0;
4697 while ( tkz.HasMoreTokens() )
4698 {
4699 wxString token = tkz.GetNextToken();
4700
4701 printf(_T("\ttoken %u: '%s'"),
4702 ++count2,
4703 MakePrintable(token).c_str());
4704
4705 if ( buf )
4706 {
4707 if ( token == s )
4708 {
4709 puts(" (ok)");
4710 }
4711 else
4712 {
4713 printf(" (ERROR: should be %s)\n", s);
4714 }
4715
4716 s = wxStrtok(NULL, tt.delims, &last);
4717 }
4718 else
4719 {
4720 // nothing to compare with
4721 puts("");
4722 }
4723 }
4724
4725 if ( count2 != count )
4726 {
4727 puts(_T("\tERROR: token count mismatch"));
4728 }
4729
4730 delete [] buf;
4731 }
4732
4733 puts("");
4734 }
4735
4736 static void TestStringReplace()
4737 {
4738 puts("*** Testing wxString::replace ***");
4739
4740 static const struct StringReplaceTestData
4741 {
4742 const wxChar *original; // original test string
4743 size_t start, len; // the part to replace
4744 const wxChar *replacement; // the replacement string
4745 const wxChar *result; // and the expected result
4746 } stringReplaceTestData[] =
4747 {
4748 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4749 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4750 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4751 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4752 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4753 };
4754
4755 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4756 {
4757 const StringReplaceTestData data = stringReplaceTestData[n];
4758
4759 wxString original = data.original;
4760 original.replace(data.start, data.len, data.replacement);
4761
4762 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4763 data.original, data.start, data.len, data.replacement,
4764 original.c_str());
4765
4766 if ( original == data.result )
4767 {
4768 puts("(ok)");
4769 }
4770 else
4771 {
4772 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4773 }
4774 }
4775
4776 puts("");
4777 }
4778
4779 static void TestStringMatch()
4780 {
4781 wxPuts(_T("*** Testing wxString::Matches() ***"));
4782
4783 static const struct StringMatchTestData
4784 {
4785 const wxChar *text;
4786 const wxChar *wildcard;
4787 bool matches;
4788 } stringMatchTestData[] =
4789 {
4790 { _T("foobar"), _T("foo*"), 1 },
4791 { _T("foobar"), _T("*oo*"), 1 },
4792 { _T("foobar"), _T("*bar"), 1 },
4793 { _T("foobar"), _T("??????"), 1 },
4794 { _T("foobar"), _T("f??b*"), 1 },
4795 { _T("foobar"), _T("f?b*"), 0 },
4796 { _T("foobar"), _T("*goo*"), 0 },
4797 { _T("foobar"), _T("*foo"), 0 },
4798 { _T("foobarfoo"), _T("*foo"), 1 },
4799 { _T(""), _T("*"), 1 },
4800 { _T(""), _T("?"), 0 },
4801 };
4802
4803 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
4804 {
4805 const StringMatchTestData& data = stringMatchTestData[n];
4806 bool matches = wxString(data.text).Matches(data.wildcard);
4807 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
4808 data.wildcard,
4809 matches ? _T("matches") : _T("doesn't match"),
4810 data.text,
4811 matches == data.matches ? _T("ok") : _T("ERROR"));
4812 }
4813
4814 wxPuts(_T(""));
4815 }
4816
4817 #endif // TEST_STRINGS
4818
4819 // ----------------------------------------------------------------------------
4820 // entry point
4821 // ----------------------------------------------------------------------------
4822
4823 int main(int argc, char **argv)
4824 {
4825 wxInitializer initializer;
4826 if ( !initializer )
4827 {
4828 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
4829
4830 return -1;
4831 }
4832
4833 #ifdef TEST_SNGLINST
4834 wxSingleInstanceChecker checker;
4835 if ( checker.Create(_T(".wxconsole.lock")) )
4836 {
4837 if ( checker.IsAnotherRunning() )
4838 {
4839 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
4840
4841 return 1;
4842 }
4843
4844 // wait some time to give time to launch another instance
4845 wxPrintf(_T("Press \"Enter\" to continue..."));
4846 wxFgetc(stdin);
4847 }
4848 else // failed to create
4849 {
4850 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4851 }
4852 #endif // TEST_SNGLINST
4853
4854 #ifdef TEST_CHARSET
4855 TestCharset();
4856 #endif // TEST_CHARSET
4857
4858 #ifdef TEST_CMDLINE
4859 static const wxCmdLineEntryDesc cmdLineDesc[] =
4860 {
4861 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4862 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4863
4864 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4865 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4866 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
4867 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
4868
4869 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4870 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4871
4872 { wxCMD_LINE_NONE }
4873 };
4874
4875 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4876
4877 parser.AddOption("project_name", "", "full path to project file",
4878 wxCMD_LINE_VAL_STRING,
4879 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4880
4881 switch ( parser.Parse() )
4882 {
4883 case -1:
4884 wxLogMessage("Help was given, terminating.");
4885 break;
4886
4887 case 0:
4888 ShowCmdLine(parser);
4889 break;
4890
4891 default:
4892 wxLogMessage("Syntax error detected, aborting.");
4893 break;
4894 }
4895 #endif // TEST_CMDLINE
4896
4897 #ifdef TEST_STRINGS
4898 if ( 0 )
4899 {
4900 TestPChar();
4901 TestString();
4902 TestStringSub();
4903 TestStringConstruction();
4904 TestStringFormat();
4905 TestStringFind();
4906 TestStringTokenizer();
4907 TestStringReplace();
4908 }
4909 TestStringMatch();
4910 #endif // TEST_STRINGS
4911
4912 #ifdef TEST_ARRAYS
4913 if ( 0 )
4914 {
4915 wxArrayString a1;
4916 a1.Add("tiger");
4917 a1.Add("cat");
4918 a1.Add("lion");
4919 a1.Add("dog");
4920 a1.Add("human");
4921 a1.Add("ape");
4922
4923 puts("*** Initially:");
4924
4925 PrintArray("a1", a1);
4926
4927 wxArrayString a2(a1);
4928 PrintArray("a2", a2);
4929
4930 wxSortedArrayString a3(a1);
4931 PrintArray("a3", a3);
4932
4933 puts("*** After deleting a string from a1");
4934 a1.Remove(2);
4935
4936 PrintArray("a1", a1);
4937 PrintArray("a2", a2);
4938 PrintArray("a3", a3);
4939
4940 puts("*** After reassigning a1 to a2 and a3");
4941 a3 = a2 = a1;
4942 PrintArray("a2", a2);
4943 PrintArray("a3", a3);
4944
4945 puts("*** After sorting a1");
4946 a1.Sort();
4947 PrintArray("a1", a1);
4948
4949 puts("*** After sorting a1 in reverse order");
4950 a1.Sort(TRUE);
4951 PrintArray("a1", a1);
4952
4953 puts("*** After sorting a1 by the string length");
4954 a1.Sort(StringLenCompare);
4955 PrintArray("a1", a1);
4956
4957 TestArrayOfObjects();
4958 }
4959 TestArrayOfInts();
4960 #endif // TEST_ARRAYS
4961
4962 #ifdef TEST_DIR
4963 if ( 0 )
4964 TestDirEnum();
4965 TestDirTraverse();
4966 #endif // TEST_DIR
4967
4968 #ifdef TEST_DLLLOADER
4969 TestDllLoad();
4970 #endif // TEST_DLLLOADER
4971
4972 #ifdef TEST_ENVIRON
4973 TestEnvironment();
4974 #endif // TEST_ENVIRON
4975
4976 #ifdef TEST_EXECUTE
4977 TestExecute();
4978 #endif // TEST_EXECUTE
4979
4980 #ifdef TEST_FILECONF
4981 TestFileConfRead();
4982 #endif // TEST_FILECONF
4983
4984 #ifdef TEST_LIST
4985 TestListCtor();
4986 #endif // TEST_LIST
4987
4988 #ifdef TEST_LOCALE
4989 TestDefaultLang();
4990 #endif // TEST_LOCALE
4991
4992 #ifdef TEST_LOG
4993 wxString s;
4994 for ( size_t n = 0; n < 8000; n++ )
4995 {
4996 s << (char)('A' + (n % 26));
4997 }
4998
4999 wxString msg;
5000 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5001
5002 // this one shouldn't be truncated
5003 printf(msg);
5004
5005 // but this one will because log functions use fixed size buffer
5006 // (note that it doesn't need '\n' at the end neither - will be added
5007 // by wxLog anyhow)
5008 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
5009 #endif // TEST_LOG
5010
5011 #ifdef TEST_FILE
5012 if ( 0 )
5013 {
5014 TestFileRead();
5015 TestTextFileRead();
5016 }
5017 TestFileCopy();
5018 #endif // TEST_FILE
5019
5020 #ifdef TEST_FILENAME
5021 TestFileNameSplit();
5022 if ( 0 )
5023 {
5024 TestFileNameConstruction();
5025 TestFileNameCwd();
5026 TestFileNameComparison();
5027 TestFileNameOperations();
5028 }
5029 #endif // TEST_FILENAME
5030
5031 #ifdef TEST_FTP
5032 wxLog::AddTraceMask(FTP_TRACE_MASK);
5033 if ( TestFtpConnect() )
5034 {
5035 TestFtpFileSize();
5036 if ( 0 )
5037 {
5038 TestFtpList();
5039 TestFtpDownload();
5040 TestFtpMisc();
5041 TestFtpUpload();
5042 }
5043 if ( 0 )
5044 TestFtpInteractive();
5045 }
5046 //else: connecting to the FTP server failed
5047
5048 if ( 0 )
5049 TestFtpWuFtpd();
5050 #endif // TEST_FTP
5051
5052 #ifdef TEST_THREADS
5053 int nCPUs = wxThread::GetCPUCount();
5054 printf("This system has %d CPUs\n", nCPUs);
5055 if ( nCPUs != -1 )
5056 wxThread::SetConcurrency(nCPUs);
5057
5058 if ( argc > 1 && argv[1][0] == 't' )
5059 wxLog::AddTraceMask("thread");
5060
5061 if ( 1 )
5062 TestDetachedThreads();
5063 if ( 1 )
5064 TestJoinableThreads();
5065 if ( 1 )
5066 TestThreadSuspend();
5067 if ( 1 )
5068 TestThreadDelete();
5069
5070 #endif // TEST_THREADS
5071
5072 #ifdef TEST_LONGLONG
5073 // seed pseudo random generator
5074 srand((unsigned)time(NULL));
5075
5076 if ( 0 )
5077 {
5078 TestSpeed();
5079 }
5080 if ( 0 )
5081 {
5082 TestMultiplication();
5083 TestDivision();
5084 TestAddition();
5085 TestLongLongConversion();
5086 TestBitOperations();
5087 }
5088 TestLongLongComparison();
5089 #endif // TEST_LONGLONG
5090
5091 #ifdef TEST_HASH
5092 TestHash();
5093 #endif // TEST_HASH
5094
5095 #ifdef TEST_MIME
5096 wxLog::AddTraceMask(_T("mime"));
5097 if ( 1 )
5098 {
5099 TestMimeEnum();
5100 TestMimeOverride();
5101 TestMimeFilename();
5102 }
5103 else
5104 TestMimeAssociate();
5105 #endif // TEST_MIME
5106
5107 #ifdef TEST_INFO_FUNCTIONS
5108 TestOsInfo();
5109 TestUserInfo();
5110 #endif // TEST_INFO_FUNCTIONS
5111
5112 #ifdef TEST_PATHLIST
5113 TestPathList();
5114 #endif // TEST_PATHLIST
5115
5116 #ifdef TEST_REGCONF
5117 TestRegConfWrite();
5118 #endif // TEST_REGCONF
5119
5120 #ifdef TEST_REGEX
5121 // TODO: write a real test using src/regex/tests file
5122 if ( 0 )
5123 {
5124 TestRegExCompile();
5125 TestRegExMatch();
5126 TestRegExSubmatch();
5127 TestRegExInteractive();
5128 }
5129 TestRegExReplacement();
5130 #endif // TEST_REGEX
5131
5132 #ifdef TEST_REGISTRY
5133 if ( 0 )
5134 TestRegistryRead();
5135 TestRegistryAssociation();
5136 #endif // TEST_REGISTRY
5137
5138 #ifdef TEST_SOCKETS
5139 if ( 0 )
5140 {
5141 TestSocketServer();
5142 }
5143 TestSocketClient();
5144 #endif // TEST_SOCKETS
5145
5146 #ifdef TEST_STREAMS
5147 if ( 0 )
5148 TestFileStream();
5149 TestMemoryStream();
5150 #endif // TEST_STREAMS
5151
5152 #ifdef TEST_TIMER
5153 TestStopWatch();
5154 #endif // TEST_TIMER
5155
5156 #ifdef TEST_DATETIME
5157 if ( 0 )
5158 {
5159 TestTimeSet();
5160 TestTimeStatic();
5161 TestTimeRange();
5162 TestTimeZones();
5163 TestTimeTicks();
5164 TestTimeJDN();
5165 TestTimeDST();
5166 TestTimeWDays();
5167 TestTimeWNumber();
5168 TestTimeParse();
5169 TestTimeArithmetics();
5170 TestTimeHolidays();
5171 TestTimeFormat();
5172 TestTimeMS();
5173
5174 TestTimeZoneBug();
5175 }
5176 TestTimeSpanFormat();
5177 if ( 0 )
5178 TestDateTimeInteractive();
5179 #endif // TEST_DATETIME
5180
5181 #ifdef TEST_USLEEP
5182 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5183 wxUsleep(3000);
5184 #endif // TEST_USLEEP
5185
5186 #ifdef TEST_VCARD
5187 if ( 0 )
5188 TestVCardRead();
5189 TestVCardWrite();
5190 #endif // TEST_VCARD
5191
5192 #ifdef TEST_WCHAR
5193 TestUtf8();
5194 #endif // TEST_WCHAR
5195
5196 #ifdef TEST_ZIP
5197 if ( 0 )
5198 TestZipStreamRead();
5199 TestZipFileSystem();
5200 #endif // TEST_ZIP
5201
5202 #ifdef TEST_ZLIB
5203 if ( 0 )
5204 TestZlibStreamWrite();
5205 TestZlibStreamRead();
5206 #endif // TEST_ZLIB
5207
5208 return 0;
5209 }
5210