]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
updated version number
[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 TestDiskInfo()
1368 {
1369 puts("*** Testing wxGetDiskSpace() ***");
1370
1371 for ( ;; )
1372 {
1373 char pathname[128];
1374 printf("\nEnter a directory name: ");
1375 if ( !fgets(pathname, WXSIZEOF(pathname), stdin) )
1376 break;
1377
1378 // kill the last '\n'
1379 pathname[strlen(pathname) - 1] = 0;
1380
1381 wxLongLong total, free;
1382 if ( !wxGetDiskSpace(pathname, &total, &free) )
1383 {
1384 wxPuts(_T("ERROR: wxGetDiskSpace failed."));
1385 }
1386 else
1387 {
1388 wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"),
1389 (total / 1024).ToString().c_str(),
1390 (free / 1024).ToString().c_str(),
1391 pathname);
1392 }
1393 }
1394 }
1395
1396 static void TestOsInfo()
1397 {
1398 puts("*** Testing OS info functions ***\n");
1399
1400 int major, minor;
1401 wxGetOsVersion(&major, &minor);
1402 printf("Running under: %s, version %d.%d\n",
1403 wxGetOsDescription().c_str(), major, minor);
1404
1405 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
1406
1407 printf("Host name is %s (%s).\n",
1408 wxGetHostName().c_str(), wxGetFullHostName().c_str());
1409
1410 puts("");
1411 }
1412
1413 static void TestUserInfo()
1414 {
1415 puts("*** Testing user info functions ***\n");
1416
1417 printf("User id is:\t%s\n", wxGetUserId().c_str());
1418 printf("User name is:\t%s\n", wxGetUserName().c_str());
1419 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
1420 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
1421
1422 puts("");
1423 }
1424
1425 #endif // TEST_INFO_FUNCTIONS
1426
1427 // ----------------------------------------------------------------------------
1428 // long long
1429 // ----------------------------------------------------------------------------
1430
1431 #ifdef TEST_LONGLONG
1432
1433 #include <wx/longlong.h>
1434 #include <wx/timer.h>
1435
1436 // make a 64 bit number from 4 16 bit ones
1437 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1438
1439 // get a random 64 bit number
1440 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1441
1442 static const long testLongs[] =
1443 {
1444 0,
1445 1,
1446 -1,
1447 LONG_MAX,
1448 LONG_MIN,
1449 0x1234,
1450 -0x1234
1451 };
1452
1453 #if wxUSE_LONGLONG_WX
1454 inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
1455 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1456 inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
1457 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1458 #endif // wxUSE_LONGLONG_WX
1459
1460 static void TestSpeed()
1461 {
1462 static const long max = 100000000;
1463 long n;
1464
1465 {
1466 wxStopWatch sw;
1467
1468 long l = 0;
1469 for ( n = 0; n < max; n++ )
1470 {
1471 l += n;
1472 }
1473
1474 printf("Summing longs took %ld milliseconds.\n", sw.Time());
1475 }
1476
1477 #if wxUSE_LONGLONG_NATIVE
1478 {
1479 wxStopWatch sw;
1480
1481 wxLongLong_t l = 0;
1482 for ( n = 0; n < max; n++ )
1483 {
1484 l += n;
1485 }
1486
1487 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
1488 }
1489 #endif // wxUSE_LONGLONG_NATIVE
1490
1491 {
1492 wxStopWatch sw;
1493
1494 wxLongLong l;
1495 for ( n = 0; n < max; n++ )
1496 {
1497 l += n;
1498 }
1499
1500 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
1501 }
1502 }
1503
1504 static void TestLongLongConversion()
1505 {
1506 puts("*** Testing wxLongLong conversions ***\n");
1507
1508 wxLongLong a;
1509 size_t nTested = 0;
1510 for ( size_t n = 0; n < 100000; n++ )
1511 {
1512 a = RAND_LL();
1513
1514 #if wxUSE_LONGLONG_NATIVE
1515 wxLongLongNative b(a.GetHi(), a.GetLo());
1516
1517 wxASSERT_MSG( a == b, "conversions failure" );
1518 #else
1519 puts("Can't do it without native long long type, test skipped.");
1520
1521 return;
1522 #endif // wxUSE_LONGLONG_NATIVE
1523
1524 if ( !(nTested % 1000) )
1525 {
1526 putchar('.');
1527 fflush(stdout);
1528 }
1529
1530 nTested++;
1531 }
1532
1533 puts(" done!");
1534 }
1535
1536 static void TestMultiplication()
1537 {
1538 puts("*** Testing wxLongLong multiplication ***\n");
1539
1540 wxLongLong a, b;
1541 size_t nTested = 0;
1542 for ( size_t n = 0; n < 100000; n++ )
1543 {
1544 a = RAND_LL();
1545 b = RAND_LL();
1546
1547 #if wxUSE_LONGLONG_NATIVE
1548 wxLongLongNative aa(a.GetHi(), a.GetLo());
1549 wxLongLongNative bb(b.GetHi(), b.GetLo());
1550
1551 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
1552 #else // !wxUSE_LONGLONG_NATIVE
1553 puts("Can't do it without native long long type, test skipped.");
1554
1555 return;
1556 #endif // wxUSE_LONGLONG_NATIVE
1557
1558 if ( !(nTested % 1000) )
1559 {
1560 putchar('.');
1561 fflush(stdout);
1562 }
1563
1564 nTested++;
1565 }
1566
1567 puts(" done!");
1568 }
1569
1570 static void TestDivision()
1571 {
1572 puts("*** Testing wxLongLong division ***\n");
1573
1574 wxLongLong q, r;
1575 size_t nTested = 0;
1576 for ( size_t n = 0; n < 100000; n++ )
1577 {
1578 // get a random wxLongLong (shifting by 12 the MSB ensures that the
1579 // multiplication will not overflow)
1580 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
1581
1582 // get a random long (not wxLongLong for now) to divide it with
1583 long l = rand();
1584 q = ll / l;
1585 r = ll % l;
1586
1587 #if wxUSE_LONGLONG_NATIVE
1588 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1589
1590 wxLongLongNative p = m / l, s = m % l;
1591 wxASSERT_MSG( q == p && r == s, "division failure" );
1592 #else // !wxUSE_LONGLONG_NATIVE
1593 // verify the result
1594 wxASSERT_MSG( ll == q*l + r, "division failure" );
1595 #endif // wxUSE_LONGLONG_NATIVE
1596
1597 if ( !(nTested % 1000) )
1598 {
1599 putchar('.');
1600 fflush(stdout);
1601 }
1602
1603 nTested++;
1604 }
1605
1606 puts(" done!");
1607 }
1608
1609 static void TestAddition()
1610 {
1611 puts("*** Testing wxLongLong addition ***\n");
1612
1613 wxLongLong a, b, c;
1614 size_t nTested = 0;
1615 for ( size_t n = 0; n < 100000; n++ )
1616 {
1617 a = RAND_LL();
1618 b = RAND_LL();
1619 c = a + b;
1620
1621 #if wxUSE_LONGLONG_NATIVE
1622 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1623 wxLongLongNative(b.GetHi(), b.GetLo()),
1624 "addition failure" );
1625 #else // !wxUSE_LONGLONG_NATIVE
1626 wxASSERT_MSG( c - b == a, "addition failure" );
1627 #endif // wxUSE_LONGLONG_NATIVE
1628
1629 if ( !(nTested % 1000) )
1630 {
1631 putchar('.');
1632 fflush(stdout);
1633 }
1634
1635 nTested++;
1636 }
1637
1638 puts(" done!");
1639 }
1640
1641 static void TestBitOperations()
1642 {
1643 puts("*** Testing wxLongLong bit operation ***\n");
1644
1645 wxLongLong ll;
1646 size_t nTested = 0;
1647 for ( size_t n = 0; n < 100000; n++ )
1648 {
1649 ll = RAND_LL();
1650
1651 #if wxUSE_LONGLONG_NATIVE
1652 for ( size_t n = 0; n < 33; n++ )
1653 {
1654 }
1655 #else // !wxUSE_LONGLONG_NATIVE
1656 puts("Can't do it without native long long type, test skipped.");
1657
1658 return;
1659 #endif // wxUSE_LONGLONG_NATIVE
1660
1661 if ( !(nTested % 1000) )
1662 {
1663 putchar('.');
1664 fflush(stdout);
1665 }
1666
1667 nTested++;
1668 }
1669
1670 puts(" done!");
1671 }
1672
1673 static void TestLongLongComparison()
1674 {
1675 #if wxUSE_LONGLONG_WX
1676 puts("*** Testing wxLongLong comparison ***\n");
1677
1678 static const long ls[2] =
1679 {
1680 0x1234,
1681 -0x1234,
1682 };
1683
1684 wxLongLongWx lls[2];
1685 lls[0] = ls[0];
1686 lls[1] = ls[1];
1687
1688 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1689 {
1690 bool res;
1691
1692 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
1693 {
1694 res = lls[m] > testLongs[n];
1695 printf("0x%lx > 0x%lx is %s (%s)\n",
1696 ls[m], testLongs[n], res ? "true" : "false",
1697 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
1698
1699 res = lls[m] < testLongs[n];
1700 printf("0x%lx < 0x%lx is %s (%s)\n",
1701 ls[m], testLongs[n], res ? "true" : "false",
1702 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
1703
1704 res = lls[m] == testLongs[n];
1705 printf("0x%lx == 0x%lx is %s (%s)\n",
1706 ls[m], testLongs[n], res ? "true" : "false",
1707 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
1708 }
1709 }
1710 #endif // wxUSE_LONGLONG_WX
1711 }
1712
1713 static void TestLongLongPrint()
1714 {
1715 wxPuts(_T("*** Testing wxLongLong printing ***\n"));
1716
1717 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1718 {
1719 wxLongLong ll = testLongs[n];
1720 wxPrintf(_T("%ld == %s\n"), testLongs[n], ll.ToString().c_str());
1721 }
1722
1723 wxLongLong ll(0x12345678, 0x87654321);
1724 wxPrintf(_T("0x1234567887654321 = %s\n"), ll.ToString().c_str());
1725
1726 ll.Negate();
1727 wxPrintf(_T("-0x1234567887654321 = %s\n"), ll.ToString().c_str());
1728 }
1729
1730 #undef MAKE_LL
1731 #undef RAND_LL
1732
1733 #endif // TEST_LONGLONG
1734
1735 // ----------------------------------------------------------------------------
1736 // path list
1737 // ----------------------------------------------------------------------------
1738
1739 #ifdef TEST_PATHLIST
1740
1741 static void TestPathList()
1742 {
1743 puts("*** Testing wxPathList ***\n");
1744
1745 wxPathList pathlist;
1746 pathlist.AddEnvList("PATH");
1747 wxString path = pathlist.FindValidPath("ls");
1748 if ( path.empty() )
1749 {
1750 printf("ERROR: command not found in the path.\n");
1751 }
1752 else
1753 {
1754 printf("Command found in the path as '%s'.\n", path.c_str());
1755 }
1756 }
1757
1758 #endif // TEST_PATHLIST
1759
1760 // ----------------------------------------------------------------------------
1761 // regular expressions
1762 // ----------------------------------------------------------------------------
1763
1764 #ifdef TEST_REGEX
1765
1766 #include <wx/regex.h>
1767
1768 static void TestRegExCompile()
1769 {
1770 wxPuts(_T("*** Testing RE compilation ***\n"));
1771
1772 static struct RegExCompTestData
1773 {
1774 const wxChar *pattern;
1775 bool correct;
1776 } regExCompTestData[] =
1777 {
1778 { _T("foo"), TRUE },
1779 { _T("foo("), FALSE },
1780 { _T("foo(bar"), FALSE },
1781 { _T("foo(bar)"), TRUE },
1782 { _T("foo["), FALSE },
1783 { _T("foo[bar"), FALSE },
1784 { _T("foo[bar]"), TRUE },
1785 { _T("foo{"), TRUE },
1786 { _T("foo{1"), FALSE },
1787 { _T("foo{bar"), TRUE },
1788 { _T("foo{1}"), TRUE },
1789 { _T("foo{1,2}"), TRUE },
1790 { _T("foo{bar}"), TRUE },
1791 { _T("foo*"), TRUE },
1792 { _T("foo**"), FALSE },
1793 { _T("foo+"), TRUE },
1794 { _T("foo++"), FALSE },
1795 { _T("foo?"), TRUE },
1796 { _T("foo??"), FALSE },
1797 { _T("foo?+"), FALSE },
1798 };
1799
1800 wxRegEx re;
1801 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
1802 {
1803 const RegExCompTestData& data = regExCompTestData[n];
1804 bool ok = re.Compile(data.pattern);
1805
1806 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
1807 data.pattern,
1808 ok ? _T("") : _T("not "),
1809 ok == data.correct ? _T("ok") : _T("ERROR"));
1810 }
1811 }
1812
1813 static void TestRegExMatch()
1814 {
1815 wxPuts(_T("*** Testing RE matching ***\n"));
1816
1817 static struct RegExMatchTestData
1818 {
1819 const wxChar *pattern;
1820 const wxChar *text;
1821 bool correct;
1822 } regExMatchTestData[] =
1823 {
1824 { _T("foo"), _T("bar"), FALSE },
1825 { _T("foo"), _T("foobar"), TRUE },
1826 { _T("^foo"), _T("foobar"), TRUE },
1827 { _T("^foo"), _T("barfoo"), FALSE },
1828 { _T("bar$"), _T("barbar"), TRUE },
1829 { _T("bar$"), _T("barbar "), FALSE },
1830 };
1831
1832 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
1833 {
1834 const RegExMatchTestData& data = regExMatchTestData[n];
1835
1836 wxRegEx re(data.pattern);
1837 bool ok = re.Matches(data.text);
1838
1839 wxPrintf(_T("'%s' %s %s (%s)\n"),
1840 data.pattern,
1841 ok ? _T("matches") : _T("doesn't match"),
1842 data.text,
1843 ok == data.correct ? _T("ok") : _T("ERROR"));
1844 }
1845 }
1846
1847 static void TestRegExSubmatch()
1848 {
1849 wxPuts(_T("*** Testing RE subexpressions ***\n"));
1850
1851 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
1852 if ( !re.IsValid() )
1853 {
1854 wxPuts(_T("ERROR: compilation failed."));
1855 return;
1856 }
1857
1858 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
1859
1860 if ( !re.Matches(text) )
1861 {
1862 wxPuts(_T("ERROR: match expected."));
1863 }
1864 else
1865 {
1866 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
1867
1868 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
1869 re.GetMatch(text, 3).c_str(),
1870 re.GetMatch(text, 2).c_str(),
1871 re.GetMatch(text, 4).c_str(),
1872 re.GetMatch(text, 1).c_str());
1873 }
1874 }
1875
1876 static void TestRegExReplacement()
1877 {
1878 wxPuts(_T("*** Testing RE replacement ***"));
1879
1880 static struct RegExReplTestData
1881 {
1882 const wxChar *text;
1883 const wxChar *repl;
1884 const wxChar *result;
1885 size_t count;
1886 } regExReplTestData[] =
1887 {
1888 { _T("foo123"), _T("bar"), _T("bar"), 1 },
1889 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
1890 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
1891 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
1892 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
1893 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
1894 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
1895 };
1896
1897 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
1898 wxRegEx re = pattern;
1899
1900 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
1901
1902 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
1903 {
1904 const RegExReplTestData& data = regExReplTestData[n];
1905
1906 wxString text = data.text;
1907 size_t nRepl = re.Replace(&text, data.repl);
1908
1909 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
1910 data.text, data.repl,
1911 nRepl, nRepl == 1 ? _T("") : _T("es"),
1912 text.c_str());
1913 if ( text == data.result && nRepl == data.count )
1914 {
1915 wxPuts(_T("ok)"));
1916 }
1917 else
1918 {
1919 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
1920 data.count, data.result);
1921 }
1922 }
1923 }
1924
1925 static void TestRegExInteractive()
1926 {
1927 wxPuts(_T("*** Testing RE interactively ***"));
1928
1929 for ( ;; )
1930 {
1931 char pattern[128];
1932 printf("\nEnter a pattern: ");
1933 if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
1934 break;
1935
1936 // kill the last '\n'
1937 pattern[strlen(pattern) - 1] = 0;
1938
1939 wxRegEx re;
1940 if ( !re.Compile(pattern) )
1941 {
1942 continue;
1943 }
1944
1945 char text[128];
1946 for ( ;; )
1947 {
1948 printf("Enter text to match: ");
1949 if ( !fgets(text, WXSIZEOF(text), stdin) )
1950 break;
1951
1952 // kill the last '\n'
1953 text[strlen(text) - 1] = 0;
1954
1955 if ( !re.Matches(text) )
1956 {
1957 printf("No match.\n");
1958 }
1959 else
1960 {
1961 printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
1962
1963 size_t start, len;
1964 for ( size_t n = 1; ; n++ )
1965 {
1966 if ( !re.GetMatch(&start, &len, n) )
1967 {
1968 break;
1969 }
1970
1971 printf("Subexpr %u matched '%s'\n",
1972 n, wxString(text + start, len).c_str());
1973 }
1974 }
1975 }
1976 }
1977 }
1978
1979 #endif // TEST_REGEX
1980
1981 // ----------------------------------------------------------------------------
1982 // registry and related stuff
1983 // ----------------------------------------------------------------------------
1984
1985 // this is for MSW only
1986 #ifndef __WXMSW__
1987 #undef TEST_REGCONF
1988 #undef TEST_REGISTRY
1989 #endif
1990
1991 #ifdef TEST_REGCONF
1992
1993 #include <wx/confbase.h>
1994 #include <wx/msw/regconf.h>
1995
1996 static void TestRegConfWrite()
1997 {
1998 wxRegConfig regconf(_T("console"), _T("wxwindows"));
1999 regconf.Write(_T("Hello"), wxString(_T("world")));
2000 }
2001
2002 #endif // TEST_REGCONF
2003
2004 #ifdef TEST_REGISTRY
2005
2006 #include <wx/msw/registry.h>
2007
2008 // I chose this one because I liked its name, but it probably only exists under
2009 // NT
2010 static const wxChar *TESTKEY =
2011 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2012
2013 static void TestRegistryRead()
2014 {
2015 puts("*** testing registry reading ***");
2016
2017 wxRegKey key(TESTKEY);
2018 printf("The test key name is '%s'.\n", key.GetName().c_str());
2019 if ( !key.Open() )
2020 {
2021 puts("ERROR: test key can't be opened, aborting test.");
2022
2023 return;
2024 }
2025
2026 size_t nSubKeys, nValues;
2027 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2028 {
2029 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
2030 }
2031
2032 printf("Enumerating values:\n");
2033
2034 long dummy;
2035 wxString value;
2036 bool cont = key.GetFirstValue(value, dummy);
2037 while ( cont )
2038 {
2039 printf("Value '%s': type ", value.c_str());
2040 switch ( key.GetValueType(value) )
2041 {
2042 case wxRegKey::Type_None: printf("ERROR (none)"); break;
2043 case wxRegKey::Type_String: printf("SZ"); break;
2044 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
2045 case wxRegKey::Type_Binary: printf("BINARY"); break;
2046 case wxRegKey::Type_Dword: printf("DWORD"); break;
2047 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
2048 default: printf("other (unknown)"); break;
2049 }
2050
2051 printf(", value = ");
2052 if ( key.IsNumericValue(value) )
2053 {
2054 long val;
2055 key.QueryValue(value, &val);
2056 printf("%ld", val);
2057 }
2058 else // string
2059 {
2060 wxString val;
2061 key.QueryValue(value, val);
2062 printf("'%s'", val.c_str());
2063
2064 key.QueryRawValue(value, val);
2065 printf(" (raw value '%s')", val.c_str());
2066 }
2067
2068 putchar('\n');
2069
2070 cont = key.GetNextValue(value, dummy);
2071 }
2072 }
2073
2074 static void TestRegistryAssociation()
2075 {
2076 /*
2077 The second call to deleteself genertaes an error message, with a
2078 messagebox saying .flo is crucial to system operation, while the .ddf
2079 call also fails, but with no error message
2080 */
2081
2082 wxRegKey key;
2083
2084 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2085 key.Create();
2086 key = "ddxf_auto_file" ;
2087 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2088 key.Create();
2089 key = "ddxf_auto_file" ;
2090 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2091 key.Create();
2092 key = "program,0" ;
2093 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2094 key.Create();
2095 key = "program \"%1\"" ;
2096
2097 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2098 key.DeleteSelf();
2099 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2100 key.DeleteSelf();
2101 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2102 key.DeleteSelf();
2103 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2104 key.DeleteSelf();
2105 }
2106
2107 #endif // TEST_REGISTRY
2108
2109 // ----------------------------------------------------------------------------
2110 // sockets
2111 // ----------------------------------------------------------------------------
2112
2113 #ifdef TEST_SOCKETS
2114
2115 #include <wx/socket.h>
2116 #include <wx/protocol/protocol.h>
2117 #include <wx/protocol/http.h>
2118
2119 static void TestSocketServer()
2120 {
2121 puts("*** Testing wxSocketServer ***\n");
2122
2123 static const int PORT = 3000;
2124
2125 wxIPV4address addr;
2126 addr.Service(PORT);
2127
2128 wxSocketServer *server = new wxSocketServer(addr);
2129 if ( !server->Ok() )
2130 {
2131 puts("ERROR: failed to bind");
2132
2133 return;
2134 }
2135
2136 for ( ;; )
2137 {
2138 printf("Server: waiting for connection on port %d...\n", PORT);
2139
2140 wxSocketBase *socket = server->Accept();
2141 if ( !socket )
2142 {
2143 puts("ERROR: wxSocketServer::Accept() failed.");
2144 break;
2145 }
2146
2147 puts("Server: got a client.");
2148
2149 server->SetTimeout(60); // 1 min
2150
2151 while ( socket->IsConnected() )
2152 {
2153 wxString s;
2154 char ch = '\0';
2155 for ( ;; )
2156 {
2157 if ( socket->Read(&ch, sizeof(ch)).Error() )
2158 {
2159 // don't log error if the client just close the connection
2160 if ( socket->IsConnected() )
2161 {
2162 puts("ERROR: in wxSocket::Read.");
2163 }
2164
2165 break;
2166 }
2167
2168 if ( ch == '\r' )
2169 continue;
2170
2171 if ( ch == '\n' )
2172 break;
2173
2174 s += ch;
2175 }
2176
2177 if ( ch != '\n' )
2178 {
2179 break;
2180 }
2181
2182 printf("Server: got '%s'.\n", s.c_str());
2183 if ( s == _T("bye") )
2184 {
2185 delete socket;
2186
2187 break;
2188 }
2189
2190 socket->Write(s.MakeUpper().c_str(), s.length());
2191 socket->Write("\r\n", 2);
2192 printf("Server: wrote '%s'.\n", s.c_str());
2193 }
2194
2195 puts("Server: lost a client.");
2196
2197 socket->Destroy();
2198 }
2199
2200 // same as "delete server" but is consistent with GUI programs
2201 server->Destroy();
2202 }
2203
2204 static void TestSocketClient()
2205 {
2206 puts("*** Testing wxSocketClient ***\n");
2207
2208 static const char *hostname = "www.wxwindows.org";
2209
2210 wxIPV4address addr;
2211 addr.Hostname(hostname);
2212 addr.Service(80);
2213
2214 printf("--- Attempting to connect to %s:80...\n", hostname);
2215
2216 wxSocketClient client;
2217 if ( !client.Connect(addr) )
2218 {
2219 printf("ERROR: failed to connect to %s\n", hostname);
2220 }
2221 else
2222 {
2223 printf("--- Connected to %s:%u...\n",
2224 addr.Hostname().c_str(), addr.Service());
2225
2226 char buf[8192];
2227
2228 // could use simply "GET" here I suppose
2229 wxString cmdGet =
2230 wxString::Format("GET http://%s/\r\n", hostname);
2231 client.Write(cmdGet, cmdGet.length());
2232 printf("--- Sent command '%s' to the server\n",
2233 MakePrintable(cmdGet).c_str());
2234 client.Read(buf, WXSIZEOF(buf));
2235 printf("--- Server replied:\n%s", buf);
2236 }
2237 }
2238
2239 #endif // TEST_SOCKETS
2240
2241 // ----------------------------------------------------------------------------
2242 // FTP
2243 // ----------------------------------------------------------------------------
2244
2245 #ifdef TEST_FTP
2246
2247 #include <wx/protocol/ftp.h>
2248
2249 static wxFTP ftp;
2250
2251 #define FTP_ANONYMOUS
2252
2253 #ifdef FTP_ANONYMOUS
2254 static const char *directory = "/pub";
2255 static const char *filename = "welcome.msg";
2256 #else
2257 static const char *directory = "/etc";
2258 static const char *filename = "issue";
2259 #endif
2260
2261 static bool TestFtpConnect()
2262 {
2263 puts("*** Testing FTP connect ***");
2264
2265 #ifdef FTP_ANONYMOUS
2266 static const char *hostname = "ftp.wxwindows.org";
2267
2268 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
2269 #else // !FTP_ANONYMOUS
2270 static const char *hostname = "localhost";
2271
2272 char user[256];
2273 fgets(user, WXSIZEOF(user), stdin);
2274 user[strlen(user) - 1] = '\0'; // chop off '\n'
2275 ftp.SetUser(user);
2276
2277 char password[256];
2278 printf("Password for %s: ", password);
2279 fgets(password, WXSIZEOF(password), stdin);
2280 password[strlen(password) - 1] = '\0'; // chop off '\n'
2281 ftp.SetPassword(password);
2282
2283 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
2284 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2285
2286 if ( !ftp.Connect(hostname) )
2287 {
2288 printf("ERROR: failed to connect to %s\n", hostname);
2289
2290 return FALSE;
2291 }
2292 else
2293 {
2294 printf("--- Connected to %s, current directory is '%s'\n",
2295 hostname, ftp.Pwd().c_str());
2296 }
2297
2298 return TRUE;
2299 }
2300
2301 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2302 static void TestFtpWuFtpd()
2303 {
2304 wxFTP ftp;
2305 static const char *hostname = "ftp.eudora.com";
2306 if ( !ftp.Connect(hostname) )
2307 {
2308 printf("ERROR: failed to connect to %s\n", hostname);
2309 }
2310 else
2311 {
2312 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2313 wxInputStream *in = ftp.GetInputStream(filename);
2314 if ( !in )
2315 {
2316 printf("ERROR: couldn't get input stream for %s\n", filename);
2317 }
2318 else
2319 {
2320 size_t size = in->StreamSize();
2321 printf("Reading file %s (%u bytes)...", filename, size);
2322
2323 char *data = new char[size];
2324 if ( !in->Read(data, size) )
2325 {
2326 puts("ERROR: read error");
2327 }
2328 else
2329 {
2330 printf("Successfully retrieved the file.\n");
2331 }
2332
2333 delete [] data;
2334 delete in;
2335 }
2336 }
2337 }
2338
2339 static void TestFtpList()
2340 {
2341 puts("*** Testing wxFTP file listing ***\n");
2342
2343 // test CWD
2344 if ( !ftp.ChDir(directory) )
2345 {
2346 printf("ERROR: failed to cd to %s\n", directory);
2347 }
2348
2349 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2350
2351 // test NLIST and LIST
2352 wxArrayString files;
2353 if ( !ftp.GetFilesList(files) )
2354 {
2355 puts("ERROR: failed to get NLIST of files");
2356 }
2357 else
2358 {
2359 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2360 size_t count = files.GetCount();
2361 for ( size_t n = 0; n < count; n++ )
2362 {
2363 printf("\t%s\n", files[n].c_str());
2364 }
2365 puts("End of the file list");
2366 }
2367
2368 if ( !ftp.GetDirList(files) )
2369 {
2370 puts("ERROR: failed to get LIST of files");
2371 }
2372 else
2373 {
2374 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2375 size_t count = files.GetCount();
2376 for ( size_t n = 0; n < count; n++ )
2377 {
2378 printf("\t%s\n", files[n].c_str());
2379 }
2380 puts("End of the file list");
2381 }
2382
2383 if ( !ftp.ChDir(_T("..")) )
2384 {
2385 puts("ERROR: failed to cd to ..");
2386 }
2387
2388 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2389 }
2390
2391 static void TestFtpDownload()
2392 {
2393 puts("*** Testing wxFTP download ***\n");
2394
2395 // test RETR
2396 wxInputStream *in = ftp.GetInputStream(filename);
2397 if ( !in )
2398 {
2399 printf("ERROR: couldn't get input stream for %s\n", filename);
2400 }
2401 else
2402 {
2403 size_t size = in->StreamSize();
2404 printf("Reading file %s (%u bytes)...", filename, size);
2405 fflush(stdout);
2406
2407 char *data = new char[size];
2408 if ( !in->Read(data, size) )
2409 {
2410 puts("ERROR: read error");
2411 }
2412 else
2413 {
2414 printf("\nContents of %s:\n%s\n", filename, data);
2415 }
2416
2417 delete [] data;
2418 delete in;
2419 }
2420 }
2421
2422 static void TestFtpFileSize()
2423 {
2424 puts("*** Testing FTP SIZE command ***");
2425
2426 if ( !ftp.ChDir(directory) )
2427 {
2428 printf("ERROR: failed to cd to %s\n", directory);
2429 }
2430
2431 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2432
2433 if ( ftp.FileExists(filename) )
2434 {
2435 int size = ftp.GetFileSize(filename);
2436 if ( size == -1 )
2437 printf("ERROR: couldn't get size of '%s'\n", filename);
2438 else
2439 printf("Size of '%s' is %d bytes.\n", filename, size);
2440 }
2441 else
2442 {
2443 printf("ERROR: '%s' doesn't exist\n", filename);
2444 }
2445 }
2446
2447 static void TestFtpMisc()
2448 {
2449 puts("*** Testing miscellaneous wxFTP functions ***");
2450
2451 if ( ftp.SendCommand("STAT") != '2' )
2452 {
2453 puts("ERROR: STAT failed");
2454 }
2455 else
2456 {
2457 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2458 }
2459
2460 if ( ftp.SendCommand("HELP SITE") != '2' )
2461 {
2462 puts("ERROR: HELP SITE failed");
2463 }
2464 else
2465 {
2466 printf("The list of site-specific commands:\n\n%s\n",
2467 ftp.GetLastResult().c_str());
2468 }
2469 }
2470
2471 static void TestFtpInteractive()
2472 {
2473 puts("\n*** Interactive wxFTP test ***");
2474
2475 char buf[128];
2476
2477 for ( ;; )
2478 {
2479 printf("Enter FTP command: ");
2480 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2481 break;
2482
2483 // kill the last '\n'
2484 buf[strlen(buf) - 1] = 0;
2485
2486 // special handling of LIST and NLST as they require data connection
2487 wxString start(buf, 4);
2488 start.MakeUpper();
2489 if ( start == "LIST" || start == "NLST" )
2490 {
2491 wxString wildcard;
2492 if ( strlen(buf) > 4 )
2493 wildcard = buf + 5;
2494
2495 wxArrayString files;
2496 if ( !ftp.GetList(files, wildcard, start == "LIST") )
2497 {
2498 printf("ERROR: failed to get %s of files\n", start.c_str());
2499 }
2500 else
2501 {
2502 printf("--- %s of '%s' under '%s':\n",
2503 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2504 size_t count = files.GetCount();
2505 for ( size_t n = 0; n < count; n++ )
2506 {
2507 printf("\t%s\n", files[n].c_str());
2508 }
2509 puts("--- End of the file list");
2510 }
2511 }
2512 else // !list
2513 {
2514 char ch = ftp.SendCommand(buf);
2515 printf("Command %s", ch ? "succeeded" : "failed");
2516 if ( ch )
2517 {
2518 printf(" (return code %c)", ch);
2519 }
2520
2521 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2522 }
2523 }
2524
2525 puts("\n*** done ***");
2526 }
2527
2528 static void TestFtpUpload()
2529 {
2530 puts("*** Testing wxFTP uploading ***\n");
2531
2532 // upload a file
2533 static const char *file1 = "test1";
2534 static const char *file2 = "test2";
2535 wxOutputStream *out = ftp.GetOutputStream(file1);
2536 if ( out )
2537 {
2538 printf("--- Uploading to %s ---\n", file1);
2539 out->Write("First hello", 11);
2540 delete out;
2541 }
2542
2543 // send a command to check the remote file
2544 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
2545 {
2546 printf("ERROR: STAT %s failed\n", file1);
2547 }
2548 else
2549 {
2550 printf("STAT %s returned:\n\n%s\n",
2551 file1, ftp.GetLastResult().c_str());
2552 }
2553
2554 out = ftp.GetOutputStream(file2);
2555 if ( out )
2556 {
2557 printf("--- Uploading to %s ---\n", file1);
2558 out->Write("Second hello", 12);
2559 delete out;
2560 }
2561 }
2562
2563 #endif // TEST_FTP
2564
2565 // ----------------------------------------------------------------------------
2566 // streams
2567 // ----------------------------------------------------------------------------
2568
2569 #ifdef TEST_STREAMS
2570
2571 #include <wx/wfstream.h>
2572 #include <wx/mstream.h>
2573
2574 static void TestFileStream()
2575 {
2576 puts("*** Testing wxFileInputStream ***");
2577
2578 static const wxChar *filename = _T("testdata.fs");
2579 {
2580 wxFileOutputStream fsOut(filename);
2581 fsOut.Write("foo", 3);
2582 }
2583
2584 wxFileInputStream fsIn(filename);
2585 printf("File stream size: %u\n", fsIn.GetSize());
2586 while ( !fsIn.Eof() )
2587 {
2588 putchar(fsIn.GetC());
2589 }
2590
2591 if ( !wxRemoveFile(filename) )
2592 {
2593 printf("ERROR: failed to remove the file '%s'.\n", filename);
2594 }
2595
2596 puts("\n*** wxFileInputStream test done ***");
2597 }
2598
2599 static void TestMemoryStream()
2600 {
2601 puts("*** Testing wxMemoryInputStream ***");
2602
2603 wxChar buf[1024];
2604 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2605
2606 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2607 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2608 while ( !memInpStream.Eof() )
2609 {
2610 putchar(memInpStream.GetC());
2611 }
2612
2613 puts("\n*** wxMemoryInputStream test done ***");
2614 }
2615
2616 #endif // TEST_STREAMS
2617
2618 // ----------------------------------------------------------------------------
2619 // timers
2620 // ----------------------------------------------------------------------------
2621
2622 #ifdef TEST_TIMER
2623
2624 #include <wx/timer.h>
2625 #include <wx/utils.h>
2626
2627 static void TestStopWatch()
2628 {
2629 puts("*** Testing wxStopWatch ***\n");
2630
2631 wxStopWatch sw;
2632 printf("Sleeping 3 seconds...");
2633 wxSleep(3);
2634 printf("\telapsed time: %ldms\n", sw.Time());
2635
2636 sw.Pause();
2637 printf("Sleeping 2 more seconds...");
2638 wxSleep(2);
2639 printf("\telapsed time: %ldms\n", sw.Time());
2640
2641 sw.Resume();
2642 printf("And 3 more seconds...");
2643 wxSleep(3);
2644 printf("\telapsed time: %ldms\n", sw.Time());
2645
2646 wxStopWatch sw2;
2647 puts("\nChecking for 'backwards clock' bug...");
2648 for ( size_t n = 0; n < 70; n++ )
2649 {
2650 sw2.Start();
2651
2652 for ( size_t m = 0; m < 100000; m++ )
2653 {
2654 if ( sw.Time() < 0 || sw2.Time() < 0 )
2655 {
2656 puts("\ntime is negative - ERROR!");
2657 }
2658 }
2659
2660 putchar('.');
2661 }
2662
2663 puts(", ok.");
2664 }
2665
2666 #endif // TEST_TIMER
2667
2668 // ----------------------------------------------------------------------------
2669 // vCard support
2670 // ----------------------------------------------------------------------------
2671
2672 #ifdef TEST_VCARD
2673
2674 #include <wx/vcard.h>
2675
2676 static void DumpVObject(size_t level, const wxVCardObject& vcard)
2677 {
2678 void *cookie;
2679 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2680 while ( vcObj )
2681 {
2682 printf("%s%s",
2683 wxString(_T('\t'), level).c_str(),
2684 vcObj->GetName().c_str());
2685
2686 wxString value;
2687 switch ( vcObj->GetType() )
2688 {
2689 case wxVCardObject::String:
2690 case wxVCardObject::UString:
2691 {
2692 wxString val;
2693 vcObj->GetValue(&val);
2694 value << _T('"') << val << _T('"');
2695 }
2696 break;
2697
2698 case wxVCardObject::Int:
2699 {
2700 unsigned int i;
2701 vcObj->GetValue(&i);
2702 value.Printf(_T("%u"), i);
2703 }
2704 break;
2705
2706 case wxVCardObject::Long:
2707 {
2708 unsigned long l;
2709 vcObj->GetValue(&l);
2710 value.Printf(_T("%lu"), l);
2711 }
2712 break;
2713
2714 case wxVCardObject::None:
2715 break;
2716
2717 case wxVCardObject::Object:
2718 value = _T("<node>");
2719 break;
2720
2721 default:
2722 value = _T("<unknown value type>");
2723 }
2724
2725 if ( !!value )
2726 printf(" = %s", value.c_str());
2727 putchar('\n');
2728
2729 DumpVObject(level + 1, *vcObj);
2730
2731 delete vcObj;
2732 vcObj = vcard.GetNextProp(&cookie);
2733 }
2734 }
2735
2736 static void DumpVCardAddresses(const wxVCard& vcard)
2737 {
2738 puts("\nShowing all addresses from vCard:\n");
2739
2740 size_t nAdr = 0;
2741 void *cookie;
2742 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
2743 while ( addr )
2744 {
2745 wxString flagsStr;
2746 int flags = addr->GetFlags();
2747 if ( flags & wxVCardAddress::Domestic )
2748 {
2749 flagsStr << _T("domestic ");
2750 }
2751 if ( flags & wxVCardAddress::Intl )
2752 {
2753 flagsStr << _T("international ");
2754 }
2755 if ( flags & wxVCardAddress::Postal )
2756 {
2757 flagsStr << _T("postal ");
2758 }
2759 if ( flags & wxVCardAddress::Parcel )
2760 {
2761 flagsStr << _T("parcel ");
2762 }
2763 if ( flags & wxVCardAddress::Home )
2764 {
2765 flagsStr << _T("home ");
2766 }
2767 if ( flags & wxVCardAddress::Work )
2768 {
2769 flagsStr << _T("work ");
2770 }
2771
2772 printf("Address %u:\n"
2773 "\tflags = %s\n"
2774 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
2775 ++nAdr,
2776 flagsStr.c_str(),
2777 addr->GetPostOffice().c_str(),
2778 addr->GetExtAddress().c_str(),
2779 addr->GetStreet().c_str(),
2780 addr->GetLocality().c_str(),
2781 addr->GetRegion().c_str(),
2782 addr->GetPostalCode().c_str(),
2783 addr->GetCountry().c_str()
2784 );
2785
2786 delete addr;
2787 addr = vcard.GetNextAddress(&cookie);
2788 }
2789 }
2790
2791 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
2792 {
2793 puts("\nShowing all phone numbers from vCard:\n");
2794
2795 size_t nPhone = 0;
2796 void *cookie;
2797 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
2798 while ( phone )
2799 {
2800 wxString flagsStr;
2801 int flags = phone->GetFlags();
2802 if ( flags & wxVCardPhoneNumber::Voice )
2803 {
2804 flagsStr << _T("voice ");
2805 }
2806 if ( flags & wxVCardPhoneNumber::Fax )
2807 {
2808 flagsStr << _T("fax ");
2809 }
2810 if ( flags & wxVCardPhoneNumber::Cellular )
2811 {
2812 flagsStr << _T("cellular ");
2813 }
2814 if ( flags & wxVCardPhoneNumber::Modem )
2815 {
2816 flagsStr << _T("modem ");
2817 }
2818 if ( flags & wxVCardPhoneNumber::Home )
2819 {
2820 flagsStr << _T("home ");
2821 }
2822 if ( flags & wxVCardPhoneNumber::Work )
2823 {
2824 flagsStr << _T("work ");
2825 }
2826
2827 printf("Phone number %u:\n"
2828 "\tflags = %s\n"
2829 "\tvalue = %s\n",
2830 ++nPhone,
2831 flagsStr.c_str(),
2832 phone->GetNumber().c_str()
2833 );
2834
2835 delete phone;
2836 phone = vcard.GetNextPhoneNumber(&cookie);
2837 }
2838 }
2839
2840 static void TestVCardRead()
2841 {
2842 puts("*** Testing wxVCard reading ***\n");
2843
2844 wxVCard vcard(_T("vcard.vcf"));
2845 if ( !vcard.IsOk() )
2846 {
2847 puts("ERROR: couldn't load vCard.");
2848 }
2849 else
2850 {
2851 // read individual vCard properties
2852 wxVCardObject *vcObj = vcard.GetProperty("FN");
2853 wxString value;
2854 if ( vcObj )
2855 {
2856 vcObj->GetValue(&value);
2857 delete vcObj;
2858 }
2859 else
2860 {
2861 value = _T("<none>");
2862 }
2863
2864 printf("Full name retrieved directly: %s\n", value.c_str());
2865
2866
2867 if ( !vcard.GetFullName(&value) )
2868 {
2869 value = _T("<none>");
2870 }
2871
2872 printf("Full name from wxVCard API: %s\n", value.c_str());
2873
2874 // now show how to deal with multiply occuring properties
2875 DumpVCardAddresses(vcard);
2876 DumpVCardPhoneNumbers(vcard);
2877
2878 // and finally show all
2879 puts("\nNow dumping the entire vCard:\n"
2880 "-----------------------------\n");
2881
2882 DumpVObject(0, vcard);
2883 }
2884 }
2885
2886 static void TestVCardWrite()
2887 {
2888 puts("*** Testing wxVCard writing ***\n");
2889
2890 wxVCard vcard;
2891 if ( !vcard.IsOk() )
2892 {
2893 puts("ERROR: couldn't create vCard.");
2894 }
2895 else
2896 {
2897 // set some fields
2898 vcard.SetName("Zeitlin", "Vadim");
2899 vcard.SetFullName("Vadim Zeitlin");
2900 vcard.SetOrganization("wxWindows", "R&D");
2901
2902 // just dump the vCard back
2903 puts("Entire vCard follows:\n");
2904 puts(vcard.Write());
2905 }
2906 }
2907
2908 #endif // TEST_VCARD
2909
2910 // ----------------------------------------------------------------------------
2911 // wide char (Unicode) support
2912 // ----------------------------------------------------------------------------
2913
2914 #ifdef TEST_WCHAR
2915
2916 #include <wx/strconv.h>
2917 #include <wx/fontenc.h>
2918 #include <wx/encconv.h>
2919 #include <wx/buffer.h>
2920
2921 static void TestUtf8()
2922 {
2923 puts("*** Testing UTF8 support ***\n");
2924
2925 static const char textInUtf8[] =
2926 {
2927 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
2928 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
2929 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
2930 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
2931 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
2932 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
2933 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
2934 };
2935
2936 char buf[1024];
2937 wchar_t wbuf[1024];
2938 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
2939 {
2940 puts("ERROR: UTF-8 decoding failed.");
2941 }
2942 else
2943 {
2944 // using wxEncodingConverter
2945 #if 0
2946 wxEncodingConverter ec;
2947 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
2948 ec.Convert(wbuf, buf);
2949 #else // using wxCSConv
2950 wxCSConv conv(_T("koi8-r"));
2951 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
2952 {
2953 puts("ERROR: conversion to KOI8-R failed.");
2954 }
2955 else
2956 #endif
2957
2958 printf("The resulting string (in koi8-r): %s\n", buf);
2959 }
2960 }
2961
2962 #endif // TEST_WCHAR
2963
2964 // ----------------------------------------------------------------------------
2965 // ZIP stream
2966 // ----------------------------------------------------------------------------
2967
2968 #ifdef TEST_ZIP
2969
2970 #include "wx/filesys.h"
2971 #include "wx/fs_zip.h"
2972 #include "wx/zipstrm.h"
2973
2974 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
2975
2976 static void TestZipStreamRead()
2977 {
2978 puts("*** Testing ZIP reading ***\n");
2979
2980 static const wxChar *filename = _T("foo");
2981 wxZipInputStream istr(TESTFILE_ZIP, filename);
2982 printf("Archive size: %u\n", istr.GetSize());
2983
2984 printf("Dumping the file '%s':\n", filename);
2985 while ( !istr.Eof() )
2986 {
2987 putchar(istr.GetC());
2988 fflush(stdout);
2989 }
2990
2991 puts("\n----- done ------");
2992 }
2993
2994 static void DumpZipDirectory(wxFileSystem& fs,
2995 const wxString& dir,
2996 const wxString& indent)
2997 {
2998 wxString prefix = wxString::Format(_T("%s#zip:%s"),
2999 TESTFILE_ZIP, dir.c_str());
3000 wxString wildcard = prefix + _T("/*");
3001
3002 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3003 while ( !dirname.empty() )
3004 {
3005 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3006 {
3007 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3008
3009 break;
3010 }
3011
3012 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3013
3014 DumpZipDirectory(fs, dirname,
3015 indent + wxString(_T(' '), 4));
3016
3017 dirname = fs.FindNext();
3018 }
3019
3020 wxString filename = fs.FindFirst(wildcard, wxFILE);
3021 while ( !filename.empty() )
3022 {
3023 if ( !filename.StartsWith(prefix, &filename) )
3024 {
3025 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3026
3027 break;
3028 }
3029
3030 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3031
3032 filename = fs.FindNext();
3033 }
3034 }
3035
3036 static void TestZipFileSystem()
3037 {
3038 puts("*** Testing ZIP file system ***\n");
3039
3040 wxFileSystem::AddHandler(new wxZipFSHandler);
3041 wxFileSystem fs;
3042 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3043
3044 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3045 }
3046
3047 #endif // TEST_ZIP
3048
3049 // ----------------------------------------------------------------------------
3050 // ZLIB stream
3051 // ----------------------------------------------------------------------------
3052
3053 #ifdef TEST_ZLIB
3054
3055 #include <wx/zstream.h>
3056 #include <wx/wfstream.h>
3057
3058 static const wxChar *FILENAME_GZ = _T("test.gz");
3059 static const char *TEST_DATA = "hello and hello again";
3060
3061 static void TestZlibStreamWrite()
3062 {
3063 puts("*** Testing Zlib stream reading ***\n");
3064
3065 wxFileOutputStream fileOutStream(FILENAME_GZ);
3066 wxZlibOutputStream ostr(fileOutStream, 0);
3067 printf("Compressing the test string... ");
3068 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3069 if ( !ostr )
3070 {
3071 puts("(ERROR: failed)");
3072 }
3073 else
3074 {
3075 puts("(ok)");
3076 }
3077
3078 puts("\n----- done ------");
3079 }
3080
3081 static void TestZlibStreamRead()
3082 {
3083 puts("*** Testing Zlib stream reading ***\n");
3084
3085 wxFileInputStream fileInStream(FILENAME_GZ);
3086 wxZlibInputStream istr(fileInStream);
3087 printf("Archive size: %u\n", istr.GetSize());
3088
3089 puts("Dumping the file:");
3090 while ( !istr.Eof() )
3091 {
3092 putchar(istr.GetC());
3093 fflush(stdout);
3094 }
3095
3096 puts("\n----- done ------");
3097 }
3098
3099 #endif // TEST_ZLIB
3100
3101 // ----------------------------------------------------------------------------
3102 // date time
3103 // ----------------------------------------------------------------------------
3104
3105 #ifdef TEST_DATETIME
3106
3107 #include <math.h>
3108
3109 #include <wx/date.h>
3110
3111 #include <wx/datetime.h>
3112
3113 // the test data
3114 struct Date
3115 {
3116 wxDateTime::wxDateTime_t day;
3117 wxDateTime::Month month;
3118 int year;
3119 wxDateTime::wxDateTime_t hour, min, sec;
3120 double jdn;
3121 wxDateTime::WeekDay wday;
3122 time_t gmticks, ticks;
3123
3124 void Init(const wxDateTime::Tm& tm)
3125 {
3126 day = tm.mday;
3127 month = tm.mon;
3128 year = tm.year;
3129 hour = tm.hour;
3130 min = tm.min;
3131 sec = tm.sec;
3132 jdn = 0.0;
3133 gmticks = ticks = -1;
3134 }
3135
3136 wxDateTime DT() const
3137 { return wxDateTime(day, month, year, hour, min, sec); }
3138
3139 bool SameDay(const wxDateTime::Tm& tm) const
3140 {
3141 return day == tm.mday && month == tm.mon && year == tm.year;
3142 }
3143
3144 wxString Format() const
3145 {
3146 wxString s;
3147 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3148 hour, min, sec,
3149 wxDateTime::GetMonthName(month).c_str(),
3150 day,
3151 abs(wxDateTime::ConvertYearToBC(year)),
3152 year > 0 ? "AD" : "BC");
3153 return s;
3154 }
3155
3156 wxString FormatDate() const
3157 {
3158 wxString s;
3159 s.Printf("%02d-%s-%4d%s",
3160 day,
3161 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3162 abs(wxDateTime::ConvertYearToBC(year)),
3163 year > 0 ? "AD" : "BC");
3164 return s;
3165 }
3166 };
3167
3168 static const Date testDates[] =
3169 {
3170 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3171 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3172 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3173 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3174 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3175 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3176 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3177 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3178 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3179 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
3180 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3181 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3182 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3183 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
3184 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
3185 };
3186
3187 // this test miscellaneous static wxDateTime functions
3188 static void TestTimeStatic()
3189 {
3190 puts("\n*** wxDateTime static methods test ***");
3191
3192 // some info about the current date
3193 int year = wxDateTime::GetCurrentYear();
3194 printf("Current year %d is %sa leap one and has %d days.\n",
3195 year,
3196 wxDateTime::IsLeapYear(year) ? "" : "not ",
3197 wxDateTime::GetNumberOfDays(year));
3198
3199 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3200 printf("Current month is '%s' ('%s') and it has %d days\n",
3201 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3202 wxDateTime::GetMonthName(month).c_str(),
3203 wxDateTime::GetNumberOfDays(month));
3204
3205 // leap year logic
3206 static const size_t nYears = 5;
3207 static const size_t years[2][nYears] =
3208 {
3209 // first line: the years to test
3210 { 1990, 1976, 2000, 2030, 1984, },
3211
3212 // second line: TRUE if leap, FALSE otherwise
3213 { FALSE, TRUE, TRUE, FALSE, TRUE }
3214 };
3215
3216 for ( size_t n = 0; n < nYears; n++ )
3217 {
3218 int year = years[0][n];
3219 bool should = years[1][n] != 0,
3220 is = wxDateTime::IsLeapYear(year);
3221
3222 printf("Year %d is %sa leap year (%s)\n",
3223 year,
3224 is ? "" : "not ",
3225 should == is ? "ok" : "ERROR");
3226
3227 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3228 }
3229 }
3230
3231 // test constructing wxDateTime objects
3232 static void TestTimeSet()
3233 {
3234 puts("\n*** wxDateTime construction test ***");
3235
3236 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3237 {
3238 const Date& d1 = testDates[n];
3239 wxDateTime dt = d1.DT();
3240
3241 Date d2;
3242 d2.Init(dt.GetTm());
3243
3244 wxString s1 = d1.Format(),
3245 s2 = d2.Format();
3246
3247 printf("Date: %s == %s (%s)\n",
3248 s1.c_str(), s2.c_str(),
3249 s1 == s2 ? "ok" : "ERROR");
3250 }
3251 }
3252
3253 // test time zones stuff
3254 static void TestTimeZones()
3255 {
3256 puts("\n*** wxDateTime timezone test ***");
3257
3258 wxDateTime now = wxDateTime::Now();
3259
3260 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3261 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3262 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3263 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3264 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3265 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
3266
3267 wxDateTime::Tm tm = now.GetTm();
3268 if ( wxDateTime(tm) != now )
3269 {
3270 printf("ERROR: got %s instead of %s\n",
3271 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3272 }
3273 }
3274
3275 // test some minimal support for the dates outside the standard range
3276 static void TestTimeRange()
3277 {
3278 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3279
3280 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3281
3282 printf("Unix epoch:\t%s\n",
3283 wxDateTime(2440587.5).Format(fmt).c_str());
3284 printf("Feb 29, 0: \t%s\n",
3285 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3286 printf("JDN 0: \t%s\n",
3287 wxDateTime(0.0).Format(fmt).c_str());
3288 printf("Jan 1, 1AD:\t%s\n",
3289 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3290 printf("May 29, 2099:\t%s\n",
3291 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3292 }
3293
3294 static void TestTimeTicks()
3295 {
3296 puts("\n*** wxDateTime ticks test ***");
3297
3298 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3299 {
3300 const Date& d = testDates[n];
3301 if ( d.ticks == -1 )
3302 continue;
3303
3304 wxDateTime dt = d.DT();
3305 long ticks = (dt.GetValue() / 1000).ToLong();
3306 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3307 if ( ticks == d.ticks )
3308 {
3309 puts(" (ok)");
3310 }
3311 else
3312 {
3313 printf(" (ERROR: should be %ld, delta = %ld)\n",
3314 d.ticks, ticks - d.ticks);
3315 }
3316
3317 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3318 ticks = (dt.GetValue() / 1000).ToLong();
3319 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3320 if ( ticks == d.gmticks )
3321 {
3322 puts(" (ok)");
3323 }
3324 else
3325 {
3326 printf(" (ERROR: should be %ld, delta = %ld)\n",
3327 d.gmticks, ticks - d.gmticks);
3328 }
3329 }
3330
3331 puts("");
3332 }
3333
3334 // test conversions to JDN &c
3335 static void TestTimeJDN()
3336 {
3337 puts("\n*** wxDateTime to JDN test ***");
3338
3339 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3340 {
3341 const Date& d = testDates[n];
3342 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3343 double jdn = dt.GetJulianDayNumber();
3344
3345 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
3346 if ( jdn == d.jdn )
3347 {
3348 puts(" (ok)");
3349 }
3350 else
3351 {
3352 printf(" (ERROR: should be %f, delta = %f)\n",
3353 d.jdn, jdn - d.jdn);
3354 }
3355 }
3356 }
3357
3358 // test week days computation
3359 static void TestTimeWDays()
3360 {
3361 puts("\n*** wxDateTime weekday test ***");
3362
3363 // test GetWeekDay()
3364 size_t n;
3365 for ( n = 0; n < WXSIZEOF(testDates); n++ )
3366 {
3367 const Date& d = testDates[n];
3368 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3369
3370 wxDateTime::WeekDay wday = dt.GetWeekDay();
3371 printf("%s is: %s",
3372 d.Format().c_str(),
3373 wxDateTime::GetWeekDayName(wday).c_str());
3374 if ( wday == d.wday )
3375 {
3376 puts(" (ok)");
3377 }
3378 else
3379 {
3380 printf(" (ERROR: should be %s)\n",
3381 wxDateTime::GetWeekDayName(d.wday).c_str());
3382 }
3383 }
3384
3385 puts("");
3386
3387 // test SetToWeekDay()
3388 struct WeekDateTestData
3389 {
3390 Date date; // the real date (precomputed)
3391 int nWeek; // its week index in the month
3392 wxDateTime::WeekDay wday; // the weekday
3393 wxDateTime::Month month; // the month
3394 int year; // and the year
3395
3396 wxString Format() const
3397 {
3398 wxString s, which;
3399 switch ( nWeek < -1 ? -nWeek : nWeek )
3400 {
3401 case 1: which = "first"; break;
3402 case 2: which = "second"; break;
3403 case 3: which = "third"; break;
3404 case 4: which = "fourth"; break;
3405 case 5: which = "fifth"; break;
3406
3407 case -1: which = "last"; break;
3408 }
3409
3410 if ( nWeek < -1 )
3411 {
3412 which += " from end";
3413 }
3414
3415 s.Printf("The %s %s of %s in %d",
3416 which.c_str(),
3417 wxDateTime::GetWeekDayName(wday).c_str(),
3418 wxDateTime::GetMonthName(month).c_str(),
3419 year);
3420
3421 return s;
3422 }
3423 };
3424
3425 // the array data was generated by the following python program
3426 /*
3427 from DateTime import *
3428 from whrandom import *
3429 from string import *
3430
3431 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3432 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3433
3434 week = DateTimeDelta(7)
3435
3436 for n in range(20):
3437 year = randint(1900, 2100)
3438 month = randint(1, 12)
3439 day = randint(1, 28)
3440 dt = DateTime(year, month, day)
3441 wday = dt.day_of_week
3442
3443 countFromEnd = choice([-1, 1])
3444 weekNum = 0;
3445
3446 while dt.month is month:
3447 dt = dt - countFromEnd * week
3448 weekNum = weekNum + countFromEnd
3449
3450 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
3451
3452 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3453 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
3454 */
3455
3456 static const WeekDateTestData weekDatesTestData[] =
3457 {
3458 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3459 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3460 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3461 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3462 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3463 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3464 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3465 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3466 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3467 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3468 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3469 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3470 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3471 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3472 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3473 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3474 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3475 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3476 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3477 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3478 };
3479
3480 static const char *fmt = "%d-%b-%Y";
3481
3482 wxDateTime dt;
3483 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3484 {
3485 const WeekDateTestData& wd = weekDatesTestData[n];
3486
3487 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3488
3489 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3490
3491 const Date& d = wd.date;
3492 if ( d.SameDay(dt.GetTm()) )
3493 {
3494 puts(" (ok)");
3495 }
3496 else
3497 {
3498 dt.Set(d.day, d.month, d.year);
3499
3500 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
3501 }
3502 }
3503 }
3504
3505 // test the computation of (ISO) week numbers
3506 static void TestTimeWNumber()
3507 {
3508 puts("\n*** wxDateTime week number test ***");
3509
3510 struct WeekNumberTestData
3511 {
3512 Date date; // the date
3513 wxDateTime::wxDateTime_t week; // the week number in the year
3514 wxDateTime::wxDateTime_t wmon; // the week number in the month
3515 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
3516 wxDateTime::wxDateTime_t dnum; // day number in the year
3517 };
3518
3519 // data generated with the following python script:
3520 /*
3521 from DateTime import *
3522 from whrandom import *
3523 from string import *
3524
3525 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3526 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3527
3528 def GetMonthWeek(dt):
3529 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3530 if weekNumMonth < 0:
3531 weekNumMonth = weekNumMonth + 53
3532 return weekNumMonth
3533
3534 def GetLastSundayBefore(dt):
3535 if dt.iso_week[2] == 7:
3536 return dt
3537 else:
3538 return dt - DateTimeDelta(dt.iso_week[2])
3539
3540 for n in range(20):
3541 year = randint(1900, 2100)
3542 month = randint(1, 12)
3543 day = randint(1, 28)
3544 dt = DateTime(year, month, day)
3545 dayNum = dt.day_of_year
3546 weekNum = dt.iso_week[1]
3547 weekNumMonth = GetMonthWeek(dt)
3548
3549 weekNumMonth2 = 0
3550 dtSunday = GetLastSundayBefore(dt)
3551
3552 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3553 weekNumMonth2 = weekNumMonth2 + 1
3554 dtSunday = dtSunday - DateTimeDelta(7)
3555
3556 data = { 'day': rjust(`day`, 2), \
3557 'month': monthNames[month - 1], \
3558 'year': year, \
3559 'weekNum': rjust(`weekNum`, 2), \
3560 'weekNumMonth': weekNumMonth, \
3561 'weekNumMonth2': weekNumMonth2, \
3562 'dayNum': rjust(`dayNum`, 3) }
3563
3564 print " { { %(day)s, "\
3565 "wxDateTime::%(month)s, "\
3566 "%(year)d }, "\
3567 "%(weekNum)s, "\
3568 "%(weekNumMonth)s, "\
3569 "%(weekNumMonth2)s, "\
3570 "%(dayNum)s }," % data
3571
3572 */
3573 static const WeekNumberTestData weekNumberTestDates[] =
3574 {
3575 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3576 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3577 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3578 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3579 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3580 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3581 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3582 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3583 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3584 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3585 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3586 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3587 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3588 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3589 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3590 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3591 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3592 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3593 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3594 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
3595 };
3596
3597 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3598 {
3599 const WeekNumberTestData& wn = weekNumberTestDates[n];
3600 const Date& d = wn.date;
3601
3602 wxDateTime dt = d.DT();
3603
3604 wxDateTime::wxDateTime_t
3605 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3606 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3607 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3608 dnum = dt.GetDayOfYear();
3609
3610 printf("%s: the day number is %d",
3611 d.FormatDate().c_str(), dnum);
3612 if ( dnum == wn.dnum )
3613 {
3614 printf(" (ok)");
3615 }
3616 else
3617 {
3618 printf(" (ERROR: should be %d)", wn.dnum);
3619 }
3620
3621 printf(", week in month is %d", wmon);
3622 if ( wmon == wn.wmon )
3623 {
3624 printf(" (ok)");
3625 }
3626 else
3627 {
3628 printf(" (ERROR: should be %d)", wn.wmon);
3629 }
3630
3631 printf(" or %d", wmon2);
3632 if ( wmon2 == wn.wmon2 )
3633 {
3634 printf(" (ok)");
3635 }
3636 else
3637 {
3638 printf(" (ERROR: should be %d)", wn.wmon2);
3639 }
3640
3641 printf(", week in year is %d", week);
3642 if ( week == wn.week )
3643 {
3644 puts(" (ok)");
3645 }
3646 else
3647 {
3648 printf(" (ERROR: should be %d)\n", wn.week);
3649 }
3650 }
3651 }
3652
3653 // test DST calculations
3654 static void TestTimeDST()
3655 {
3656 puts("\n*** wxDateTime DST test ***");
3657
3658 printf("DST is%s in effect now.\n\n",
3659 wxDateTime::Now().IsDST() ? "" : " not");
3660
3661 // taken from http://www.energy.ca.gov/daylightsaving.html
3662 static const Date datesDST[2][2004 - 1900 + 1] =
3663 {
3664 {
3665 { 1, wxDateTime::Apr, 1990 },
3666 { 7, wxDateTime::Apr, 1991 },
3667 { 5, wxDateTime::Apr, 1992 },
3668 { 4, wxDateTime::Apr, 1993 },
3669 { 3, wxDateTime::Apr, 1994 },
3670 { 2, wxDateTime::Apr, 1995 },
3671 { 7, wxDateTime::Apr, 1996 },
3672 { 6, wxDateTime::Apr, 1997 },
3673 { 5, wxDateTime::Apr, 1998 },
3674 { 4, wxDateTime::Apr, 1999 },
3675 { 2, wxDateTime::Apr, 2000 },
3676 { 1, wxDateTime::Apr, 2001 },
3677 { 7, wxDateTime::Apr, 2002 },
3678 { 6, wxDateTime::Apr, 2003 },
3679 { 4, wxDateTime::Apr, 2004 },
3680 },
3681 {
3682 { 28, wxDateTime::Oct, 1990 },
3683 { 27, wxDateTime::Oct, 1991 },
3684 { 25, wxDateTime::Oct, 1992 },
3685 { 31, wxDateTime::Oct, 1993 },
3686 { 30, wxDateTime::Oct, 1994 },
3687 { 29, wxDateTime::Oct, 1995 },
3688 { 27, wxDateTime::Oct, 1996 },
3689 { 26, wxDateTime::Oct, 1997 },
3690 { 25, wxDateTime::Oct, 1998 },
3691 { 31, wxDateTime::Oct, 1999 },
3692 { 29, wxDateTime::Oct, 2000 },
3693 { 28, wxDateTime::Oct, 2001 },
3694 { 27, wxDateTime::Oct, 2002 },
3695 { 26, wxDateTime::Oct, 2003 },
3696 { 31, wxDateTime::Oct, 2004 },
3697 }
3698 };
3699
3700 int year;
3701 for ( year = 1990; year < 2005; year++ )
3702 {
3703 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
3704 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
3705
3706 printf("DST period in the US for year %d: from %s to %s",
3707 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
3708
3709 size_t n = year - 1990;
3710 const Date& dBegin = datesDST[0][n];
3711 const Date& dEnd = datesDST[1][n];
3712
3713 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
3714 {
3715 puts(" (ok)");
3716 }
3717 else
3718 {
3719 printf(" (ERROR: should be %s %d to %s %d)\n",
3720 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
3721 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
3722 }
3723 }
3724
3725 puts("");
3726
3727 for ( year = 1990; year < 2005; year++ )
3728 {
3729 printf("DST period in Europe for year %d: from %s to %s\n",
3730 year,
3731 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3732 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3733 }
3734 }
3735
3736 // test wxDateTime -> text conversion
3737 static void TestTimeFormat()
3738 {
3739 puts("\n*** wxDateTime formatting test ***");
3740
3741 // some information may be lost during conversion, so store what kind
3742 // of info should we recover after a round trip
3743 enum CompareKind
3744 {
3745 CompareNone, // don't try comparing
3746 CompareBoth, // dates and times should be identical
3747 CompareDate, // dates only
3748 CompareTime // time only
3749 };
3750
3751 static const struct
3752 {
3753 CompareKind compareKind;
3754 const char *format;
3755 } formatTestFormats[] =
3756 {
3757 { CompareBoth, "---> %c" },
3758 { CompareDate, "Date is %A, %d of %B, in year %Y" },
3759 { CompareBoth, "Date is %x, time is %X" },
3760 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
3761 { CompareNone, "The day of year: %j, the week of year: %W" },
3762 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
3763 };
3764
3765 static const Date formatTestDates[] =
3766 {
3767 { 29, wxDateTime::May, 1976, 18, 30, 00 },
3768 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
3769 #if 0
3770 // this test can't work for other centuries because it uses two digit
3771 // years in formats, so don't even try it
3772 { 29, wxDateTime::May, 2076, 18, 30, 00 },
3773 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
3774 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
3775 #endif
3776 };
3777
3778 // an extra test (as it doesn't depend on date, don't do it in the loop)
3779 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
3780
3781 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
3782 {
3783 puts("");
3784
3785 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
3786 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
3787 {
3788 wxString s = dt.Format(formatTestFormats[n].format);
3789 printf("%s", s.c_str());
3790
3791 // what can we recover?
3792 int kind = formatTestFormats[n].compareKind;
3793
3794 // convert back
3795 wxDateTime dt2;
3796 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
3797 if ( !result )
3798 {
3799 // converion failed - should it have?
3800 if ( kind == CompareNone )
3801 puts(" (ok)");
3802 else
3803 puts(" (ERROR: conversion back failed)");
3804 }
3805 else if ( *result )
3806 {
3807 // should have parsed the entire string
3808 puts(" (ERROR: conversion back stopped too soon)");
3809 }
3810 else
3811 {
3812 bool equal = FALSE; // suppress compilaer warning
3813 switch ( kind )
3814 {
3815 case CompareBoth:
3816 equal = dt2 == dt;
3817 break;
3818
3819 case CompareDate:
3820 equal = dt.IsSameDate(dt2);
3821 break;
3822
3823 case CompareTime:
3824 equal = dt.IsSameTime(dt2);
3825 break;
3826 }
3827
3828 if ( !equal )
3829 {
3830 printf(" (ERROR: got back '%s' instead of '%s')\n",
3831 dt2.Format().c_str(), dt.Format().c_str());
3832 }
3833 else
3834 {
3835 puts(" (ok)");
3836 }
3837 }
3838 }
3839 }
3840 }
3841
3842 // test text -> wxDateTime conversion
3843 static void TestTimeParse()
3844 {
3845 puts("\n*** wxDateTime parse test ***");
3846
3847 struct ParseTestData
3848 {
3849 const char *format;
3850 Date date;
3851 bool good;
3852 };
3853
3854 static const ParseTestData parseTestDates[] =
3855 {
3856 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
3857 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
3858 };
3859
3860 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
3861 {
3862 const char *format = parseTestDates[n].format;
3863
3864 printf("%s => ", format);
3865
3866 wxDateTime dt;
3867 if ( dt.ParseRfc822Date(format) )
3868 {
3869 printf("%s ", dt.Format().c_str());
3870
3871 if ( parseTestDates[n].good )
3872 {
3873 wxDateTime dtReal = parseTestDates[n].date.DT();
3874 if ( dt == dtReal )
3875 {
3876 puts("(ok)");
3877 }
3878 else
3879 {
3880 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
3881 }
3882 }
3883 else
3884 {
3885 puts("(ERROR: bad format)");
3886 }
3887 }
3888 else
3889 {
3890 printf("bad format (%s)\n",
3891 parseTestDates[n].good ? "ERROR" : "ok");
3892 }
3893 }
3894 }
3895
3896 static void TestDateTimeInteractive()
3897 {
3898 puts("\n*** interactive wxDateTime tests ***");
3899
3900 char buf[128];
3901
3902 for ( ;; )
3903 {
3904 printf("Enter a date: ");
3905 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
3906 break;
3907
3908 // kill the last '\n'
3909 buf[strlen(buf) - 1] = 0;
3910
3911 wxDateTime dt;
3912 const char *p = dt.ParseDate(buf);
3913 if ( !p )
3914 {
3915 printf("ERROR: failed to parse the date '%s'.\n", buf);
3916
3917 continue;
3918 }
3919 else if ( *p )
3920 {
3921 printf("WARNING: parsed only first %u characters.\n", p - buf);
3922 }
3923
3924 printf("%s: day %u, week of month %u/%u, week of year %u\n",
3925 dt.Format("%b %d, %Y").c_str(),
3926 dt.GetDayOfYear(),
3927 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3928 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3929 dt.GetWeekOfYear(wxDateTime::Monday_First));
3930 }
3931
3932 puts("\n*** done ***");
3933 }
3934
3935 static void TestTimeMS()
3936 {
3937 puts("*** testing millisecond-resolution support in wxDateTime ***");
3938
3939 wxDateTime dt1 = wxDateTime::Now(),
3940 dt2 = wxDateTime::UNow();
3941
3942 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
3943 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3944 printf("Dummy loop: ");
3945 for ( int i = 0; i < 6000; i++ )
3946 {
3947 //for ( int j = 0; j < 10; j++ )
3948 {
3949 wxString s;
3950 s.Printf("%g", sqrt(i));
3951 }
3952
3953 if ( !(i % 100) )
3954 putchar('.');
3955 }
3956 puts(", done");
3957
3958 dt1 = dt2;
3959 dt2 = wxDateTime::UNow();
3960 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3961
3962 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
3963
3964 puts("\n*** done ***");
3965 }
3966
3967 static void TestTimeArithmetics()
3968 {
3969 puts("\n*** testing arithmetic operations on wxDateTime ***");
3970
3971 static const struct ArithmData
3972 {
3973 ArithmData(const wxDateSpan& sp, const char *nam)
3974 : span(sp), name(nam) { }
3975
3976 wxDateSpan span;
3977 const char *name;
3978 } testArithmData[] =
3979 {
3980 ArithmData(wxDateSpan::Day(), "day"),
3981 ArithmData(wxDateSpan::Week(), "week"),
3982 ArithmData(wxDateSpan::Month(), "month"),
3983 ArithmData(wxDateSpan::Year(), "year"),
3984 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
3985 };
3986
3987 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
3988
3989 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
3990 {
3991 wxDateSpan span = testArithmData[n].span;
3992 dt1 = dt + span;
3993 dt2 = dt - span;
3994
3995 const char *name = testArithmData[n].name;
3996 printf("%s + %s = %s, %s - %s = %s\n",
3997 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
3998 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
3999
4000 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
4001 if ( dt1 - span == dt )
4002 {
4003 puts(" (ok)");
4004 }
4005 else
4006 {
4007 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4008 }
4009
4010 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
4011 if ( dt2 + span == dt )
4012 {
4013 puts(" (ok)");
4014 }
4015 else
4016 {
4017 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4018 }
4019
4020 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
4021 if ( dt2 + 2*span == dt1 )
4022 {
4023 puts(" (ok)");
4024 }
4025 else
4026 {
4027 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
4028 }
4029
4030 puts("");
4031 }
4032 }
4033
4034 static void TestTimeHolidays()
4035 {
4036 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
4037
4038 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
4039 wxDateTime dtStart(1, tm.mon, tm.year),
4040 dtEnd = dtStart.GetLastMonthDay();
4041
4042 wxDateTimeArray hol;
4043 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
4044
4045 const wxChar *format = "%d-%b-%Y (%a)";
4046
4047 printf("All holidays between %s and %s:\n",
4048 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4049
4050 size_t count = hol.GetCount();
4051 for ( size_t n = 0; n < count; n++ )
4052 {
4053 printf("\t%s\n", hol[n].Format(format).c_str());
4054 }
4055
4056 puts("");
4057 }
4058
4059 static void TestTimeZoneBug()
4060 {
4061 puts("\n*** testing for DST/timezone bug ***\n");
4062
4063 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4064 for ( int i = 0; i < 31; i++ )
4065 {
4066 printf("Date %s: week day %s.\n",
4067 date.Format(_T("%d-%m-%Y")).c_str(),
4068 date.GetWeekDayName(date.GetWeekDay()).c_str());
4069
4070 date += wxDateSpan::Day();
4071 }
4072
4073 puts("");
4074 }
4075
4076 static void TestTimeSpanFormat()
4077 {
4078 puts("\n*** wxTimeSpan tests ***");
4079
4080 static const char *formats[] =
4081 {
4082 _T("(default) %H:%M:%S"),
4083 _T("%E weeks and %D days"),
4084 _T("%l milliseconds"),
4085 _T("(with ms) %H:%M:%S:%l"),
4086 _T("100%% of minutes is %M"), // test "%%"
4087 _T("%D days and %H hours"),
4088 _T("or also %S seconds"),
4089 };
4090
4091 wxTimeSpan ts1(1, 2, 3, 4),
4092 ts2(111, 222, 333);
4093 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4094 {
4095 printf("ts1 = %s\tts2 = %s\n",
4096 ts1.Format(formats[n]).c_str(),
4097 ts2.Format(formats[n]).c_str());
4098 }
4099
4100 puts("");
4101 }
4102
4103 #if 0
4104
4105 // test compatibility with the old wxDate/wxTime classes
4106 static void TestTimeCompatibility()
4107 {
4108 puts("\n*** wxDateTime compatibility test ***");
4109
4110 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4111 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4112
4113 double jdnNow = wxDateTime::Now().GetJDN();
4114 long jdnMidnight = (long)(jdnNow - 0.5);
4115 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4116
4117 jdnMidnight = wxDate().Set().GetJulianDate();
4118 printf("wxDateTime for today: %s\n",
4119 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4120
4121 int flags = wxEUROPEAN;//wxFULL;
4122 wxDate date;
4123 date.Set();
4124 printf("Today is %s\n", date.FormatDate(flags).c_str());
4125 for ( int n = 0; n < 7; n++ )
4126 {
4127 printf("Previous %s is %s\n",
4128 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4129 date.Previous(n + 1).FormatDate(flags).c_str());
4130 }
4131 }
4132
4133 #endif // 0
4134
4135 #endif // TEST_DATETIME
4136
4137 // ----------------------------------------------------------------------------
4138 // threads
4139 // ----------------------------------------------------------------------------
4140
4141 #ifdef TEST_THREADS
4142
4143 #include <wx/thread.h>
4144
4145 static size_t gs_counter = (size_t)-1;
4146 static wxCriticalSection gs_critsect;
4147 static wxCondition gs_cond;
4148
4149 class MyJoinableThread : public wxThread
4150 {
4151 public:
4152 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4153 { m_n = n; Create(); }
4154
4155 // thread execution starts here
4156 virtual ExitCode Entry();
4157
4158 private:
4159 size_t m_n;
4160 };
4161
4162 wxThread::ExitCode MyJoinableThread::Entry()
4163 {
4164 unsigned long res = 1;
4165 for ( size_t n = 1; n < m_n; n++ )
4166 {
4167 res *= n;
4168
4169 // it's a loooong calculation :-)
4170 Sleep(100);
4171 }
4172
4173 return (ExitCode)res;
4174 }
4175
4176 class MyDetachedThread : public wxThread
4177 {
4178 public:
4179 MyDetachedThread(size_t n, char ch)
4180 {
4181 m_n = n;
4182 m_ch = ch;
4183 m_cancelled = FALSE;
4184
4185 Create();
4186 }
4187
4188 // thread execution starts here
4189 virtual ExitCode Entry();
4190
4191 // and stops here
4192 virtual void OnExit();
4193
4194 private:
4195 size_t m_n; // number of characters to write
4196 char m_ch; // character to write
4197
4198 bool m_cancelled; // FALSE if we exit normally
4199 };
4200
4201 wxThread::ExitCode MyDetachedThread::Entry()
4202 {
4203 {
4204 wxCriticalSectionLocker lock(gs_critsect);
4205 if ( gs_counter == (size_t)-1 )
4206 gs_counter = 1;
4207 else
4208 gs_counter++;
4209 }
4210
4211 for ( size_t n = 0; n < m_n; n++ )
4212 {
4213 if ( TestDestroy() )
4214 {
4215 m_cancelled = TRUE;
4216
4217 break;
4218 }
4219
4220 putchar(m_ch);
4221 fflush(stdout);
4222
4223 wxThread::Sleep(100);
4224 }
4225
4226 return 0;
4227 }
4228
4229 void MyDetachedThread::OnExit()
4230 {
4231 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4232
4233 wxCriticalSectionLocker lock(gs_critsect);
4234 if ( !--gs_counter && !m_cancelled )
4235 gs_cond.Signal();
4236 }
4237
4238 void TestDetachedThreads()
4239 {
4240 puts("\n*** Testing detached threads ***");
4241
4242 static const size_t nThreads = 3;
4243 MyDetachedThread *threads[nThreads];
4244 size_t n;
4245 for ( n = 0; n < nThreads; n++ )
4246 {
4247 threads[n] = new MyDetachedThread(10, 'A' + n);
4248 }
4249
4250 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4251 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4252
4253 for ( n = 0; n < nThreads; n++ )
4254 {
4255 threads[n]->Run();
4256 }
4257
4258 // wait until all threads terminate
4259 gs_cond.Wait();
4260
4261 puts("");
4262 }
4263
4264 void TestJoinableThreads()
4265 {
4266 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
4267
4268 // calc 10! in the background
4269 MyJoinableThread thread(10);
4270 thread.Run();
4271
4272 printf("\nThread terminated with exit code %lu.\n",
4273 (unsigned long)thread.Wait());
4274 }
4275
4276 void TestThreadSuspend()
4277 {
4278 puts("\n*** Testing thread suspend/resume functions ***");
4279
4280 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
4281
4282 thread->Run();
4283
4284 // this is for this demo only, in a real life program we'd use another
4285 // condition variable which would be signaled from wxThread::Entry() to
4286 // tell us that the thread really started running - but here just wait a
4287 // bit and hope that it will be enough (the problem is, of course, that
4288 // the thread might still not run when we call Pause() which will result
4289 // in an error)
4290 wxThread::Sleep(300);
4291
4292 for ( size_t n = 0; n < 3; n++ )
4293 {
4294 thread->Pause();
4295
4296 puts("\nThread suspended");
4297 if ( n > 0 )
4298 {
4299 // don't sleep but resume immediately the first time
4300 wxThread::Sleep(300);
4301 }
4302 puts("Going to resume the thread");
4303
4304 thread->Resume();
4305 }
4306
4307 puts("Waiting until it terminates now");
4308
4309 // wait until the thread terminates
4310 gs_cond.Wait();
4311
4312 puts("");
4313 }
4314
4315 void TestThreadDelete()
4316 {
4317 // As above, using Sleep() is only for testing here - we must use some
4318 // synchronisation object instead to ensure that the thread is still
4319 // running when we delete it - deleting a detached thread which already
4320 // terminated will lead to a crash!
4321
4322 puts("\n*** Testing thread delete function ***");
4323
4324 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4325
4326 thread0->Delete();
4327
4328 puts("\nDeleted a thread which didn't start to run yet.");
4329
4330 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4331
4332 thread1->Run();
4333
4334 wxThread::Sleep(300);
4335
4336 thread1->Delete();
4337
4338 puts("\nDeleted a running thread.");
4339
4340 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4341
4342 thread2->Run();
4343
4344 wxThread::Sleep(300);
4345
4346 thread2->Pause();
4347
4348 thread2->Delete();
4349
4350 puts("\nDeleted a sleeping thread.");
4351
4352 MyJoinableThread thread3(20);
4353 thread3.Run();
4354
4355 thread3.Delete();
4356
4357 puts("\nDeleted a joinable thread.");
4358
4359 MyJoinableThread thread4(2);
4360 thread4.Run();
4361
4362 wxThread::Sleep(300);
4363
4364 thread4.Delete();
4365
4366 puts("\nDeleted a joinable thread which already terminated.");
4367
4368 puts("");
4369 }
4370
4371 #endif // TEST_THREADS
4372
4373 // ----------------------------------------------------------------------------
4374 // arrays
4375 // ----------------------------------------------------------------------------
4376
4377 #ifdef TEST_ARRAYS
4378
4379 static void PrintArray(const char* name, const wxArrayString& array)
4380 {
4381 printf("Dump of the array '%s'\n", name);
4382
4383 size_t nCount = array.GetCount();
4384 for ( size_t n = 0; n < nCount; n++ )
4385 {
4386 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4387 }
4388 }
4389
4390 static void PrintArray(const char* name, const wxArrayInt& array)
4391 {
4392 printf("Dump of the array '%s'\n", name);
4393
4394 size_t nCount = array.GetCount();
4395 for ( size_t n = 0; n < nCount; n++ )
4396 {
4397 printf("\t%s[%u] = %d\n", name, n, array[n]);
4398 }
4399 }
4400
4401 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4402 const wxString& second)
4403 {
4404 return first.length() - second.length();
4405 }
4406
4407 int wxCMPFUNC_CONV IntCompare(int *first,
4408 int *second)
4409 {
4410 return *first - *second;
4411 }
4412
4413 int wxCMPFUNC_CONV IntRevCompare(int *first,
4414 int *second)
4415 {
4416 return *second - *first;
4417 }
4418
4419 static void TestArrayOfInts()
4420 {
4421 puts("*** Testing wxArrayInt ***\n");
4422
4423 wxArrayInt a;
4424 a.Add(1);
4425 a.Add(17);
4426 a.Add(5);
4427 a.Add(3);
4428
4429 puts("Initially:");
4430 PrintArray("a", a);
4431
4432 puts("After sort:");
4433 a.Sort(IntCompare);
4434 PrintArray("a", a);
4435
4436 puts("After reverse sort:");
4437 a.Sort(IntRevCompare);
4438 PrintArray("a", a);
4439 }
4440
4441 #include "wx/dynarray.h"
4442
4443 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4444 #include "wx/arrimpl.cpp"
4445 WX_DEFINE_OBJARRAY(ArrayBars);
4446
4447 static void TestArrayOfObjects()
4448 {
4449 puts("*** Testing wxObjArray ***\n");
4450
4451 {
4452 ArrayBars bars;
4453 Bar bar("second bar");
4454
4455 printf("Initially: %u objects in the array, %u objects total.\n",
4456 bars.GetCount(), Bar::GetNumber());
4457
4458 bars.Add(new Bar("first bar"));
4459 bars.Add(bar);
4460
4461 printf("Now: %u objects in the array, %u objects total.\n",
4462 bars.GetCount(), Bar::GetNumber());
4463
4464 bars.Empty();
4465
4466 printf("After Empty(): %u objects in the array, %u objects total.\n",
4467 bars.GetCount(), Bar::GetNumber());
4468 }
4469
4470 printf("Finally: no more objects in the array, %u objects total.\n",
4471 Bar::GetNumber());
4472 }
4473
4474 #endif // TEST_ARRAYS
4475
4476 // ----------------------------------------------------------------------------
4477 // strings
4478 // ----------------------------------------------------------------------------
4479
4480 #ifdef TEST_STRINGS
4481
4482 #include "wx/timer.h"
4483 #include "wx/tokenzr.h"
4484
4485 static void TestStringConstruction()
4486 {
4487 puts("*** Testing wxString constructores ***");
4488
4489 #define TEST_CTOR(args, res) \
4490 { \
4491 wxString s args ; \
4492 printf("wxString%s = %s ", #args, s.c_str()); \
4493 if ( s == res ) \
4494 { \
4495 puts("(ok)"); \
4496 } \
4497 else \
4498 { \
4499 printf("(ERROR: should be %s)\n", res); \
4500 } \
4501 }
4502
4503 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
4504 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
4505 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
4506 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
4507
4508 static const wxChar *s = _T("?really!");
4509 const wxChar *start = wxStrchr(s, _T('r'));
4510 const wxChar *end = wxStrchr(s, _T('!'));
4511 TEST_CTOR((start, end), _T("really"));
4512
4513 puts("");
4514 }
4515
4516 static void TestString()
4517 {
4518 wxStopWatch sw;
4519
4520 wxString a, b, c;
4521
4522 a.reserve (128);
4523 b.reserve (128);
4524 c.reserve (128);
4525
4526 for (int i = 0; i < 1000000; ++i)
4527 {
4528 a = "Hello";
4529 b = " world";
4530 c = "! How'ya doin'?";
4531 a += b;
4532 a += c;
4533 c = "Hello world! What's up?";
4534 if (c != a)
4535 c = "Doh!";
4536 }
4537
4538 printf ("TestString elapsed time: %ld\n", sw.Time());
4539 }
4540
4541 static void TestPChar()
4542 {
4543 wxStopWatch sw;
4544
4545 char a [128];
4546 char b [128];
4547 char c [128];
4548
4549 for (int i = 0; i < 1000000; ++i)
4550 {
4551 strcpy (a, "Hello");
4552 strcpy (b, " world");
4553 strcpy (c, "! How'ya doin'?");
4554 strcat (a, b);
4555 strcat (a, c);
4556 strcpy (c, "Hello world! What's up?");
4557 if (strcmp (c, a) == 0)
4558 strcpy (c, "Doh!");
4559 }
4560
4561 printf ("TestPChar elapsed time: %ld\n", sw.Time());
4562 }
4563
4564 static void TestStringSub()
4565 {
4566 wxString s("Hello, world!");
4567
4568 puts("*** Testing wxString substring extraction ***");
4569
4570 printf("String = '%s'\n", s.c_str());
4571 printf("Left(5) = '%s'\n", s.Left(5).c_str());
4572 printf("Right(6) = '%s'\n", s.Right(6).c_str());
4573 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
4574 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
4575 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
4576 printf("substr(3) = '%s'\n", s.substr(3).c_str());
4577
4578 static const wxChar *prefixes[] =
4579 {
4580 _T("Hello"),
4581 _T("Hello, "),
4582 _T("Hello, world!"),
4583 _T("Hello, world!!!"),
4584 _T(""),
4585 _T("Goodbye"),
4586 _T("Hi"),
4587 };
4588
4589 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
4590 {
4591 wxString prefix = prefixes[n], rest;
4592 bool rc = s.StartsWith(prefix, &rest);
4593 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
4594 if ( rc )
4595 {
4596 printf(" (the rest is '%s')\n", rest.c_str());
4597 }
4598 else
4599 {
4600 putchar('\n');
4601 }
4602 }
4603
4604 puts("");
4605 }
4606
4607 static void TestStringFormat()
4608 {
4609 puts("*** Testing wxString formatting ***");
4610
4611 wxString s;
4612 s.Printf("%03d", 18);
4613
4614 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
4615 printf("Number 18: %s\n", s.c_str());
4616
4617 puts("");
4618 }
4619
4620 // returns "not found" for npos, value for all others
4621 static wxString PosToString(size_t res)
4622 {
4623 wxString s = res == wxString::npos ? wxString(_T("not found"))
4624 : wxString::Format(_T("%u"), res);
4625 return s;
4626 }
4627
4628 static void TestStringFind()
4629 {
4630 puts("*** Testing wxString find() functions ***");
4631
4632 static const wxChar *strToFind = _T("ell");
4633 static const struct StringFindTest
4634 {
4635 const wxChar *str;
4636 size_t start,
4637 result; // of searching "ell" in str
4638 } findTestData[] =
4639 {
4640 { _T("Well, hello world"), 0, 1 },
4641 { _T("Well, hello world"), 6, 7 },
4642 { _T("Well, hello world"), 9, wxString::npos },
4643 };
4644
4645 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
4646 {
4647 const StringFindTest& ft = findTestData[n];
4648 size_t res = wxString(ft.str).find(strToFind, ft.start);
4649
4650 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
4651 strToFind, ft.str, ft.start, PosToString(res).c_str());
4652
4653 size_t resTrue = ft.result;
4654 if ( res == resTrue )
4655 {
4656 puts(_T("(ok)"));
4657 }
4658 else
4659 {
4660 printf(_T("(ERROR: should be %s)\n"),
4661 PosToString(resTrue).c_str());
4662 }
4663 }
4664
4665 puts("");
4666 }
4667
4668 static void TestStringTokenizer()
4669 {
4670 puts("*** Testing wxStringTokenizer ***");
4671
4672 static const wxChar *modeNames[] =
4673 {
4674 _T("default"),
4675 _T("return empty"),
4676 _T("return all empty"),
4677 _T("with delims"),
4678 _T("like strtok"),
4679 };
4680
4681 static const struct StringTokenizerTest
4682 {
4683 const wxChar *str; // string to tokenize
4684 const wxChar *delims; // delimiters to use
4685 size_t count; // count of token
4686 wxStringTokenizerMode mode; // how should we tokenize it
4687 } tokenizerTestData[] =
4688 {
4689 { _T(""), _T(" "), 0 },
4690 { _T("Hello, world"), _T(" "), 2 },
4691 { _T("Hello, world "), _T(" "), 2 },
4692 { _T("Hello, world"), _T(","), 2 },
4693 { _T("Hello, world!"), _T(",!"), 2 },
4694 { _T("Hello,, world!"), _T(",!"), 3 },
4695 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
4696 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
4697 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
4698 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
4699 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
4700 { _T("01/02/99"), _T("/-"), 3 },
4701 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
4702 };
4703
4704 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
4705 {
4706 const StringTokenizerTest& tt = tokenizerTestData[n];
4707 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
4708
4709 size_t count = tkz.CountTokens();
4710 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
4711 MakePrintable(tt.str).c_str(),
4712 count,
4713 MakePrintable(tt.delims).c_str(),
4714 modeNames[tkz.GetMode()]);
4715 if ( count == tt.count )
4716 {
4717 puts(_T("(ok)"));
4718 }
4719 else
4720 {
4721 printf(_T("(ERROR: should be %u)\n"), tt.count);
4722
4723 continue;
4724 }
4725
4726 // if we emulate strtok(), check that we do it correctly
4727 wxChar *buf, *s = NULL, *last;
4728
4729 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4730 {
4731 buf = new wxChar[wxStrlen(tt.str) + 1];
4732 wxStrcpy(buf, tt.str);
4733
4734 s = wxStrtok(buf, tt.delims, &last);
4735 }
4736 else
4737 {
4738 buf = NULL;
4739 }
4740
4741 // now show the tokens themselves
4742 size_t count2 = 0;
4743 while ( tkz.HasMoreTokens() )
4744 {
4745 wxString token = tkz.GetNextToken();
4746
4747 printf(_T("\ttoken %u: '%s'"),
4748 ++count2,
4749 MakePrintable(token).c_str());
4750
4751 if ( buf )
4752 {
4753 if ( token == s )
4754 {
4755 puts(" (ok)");
4756 }
4757 else
4758 {
4759 printf(" (ERROR: should be %s)\n", s);
4760 }
4761
4762 s = wxStrtok(NULL, tt.delims, &last);
4763 }
4764 else
4765 {
4766 // nothing to compare with
4767 puts("");
4768 }
4769 }
4770
4771 if ( count2 != count )
4772 {
4773 puts(_T("\tERROR: token count mismatch"));
4774 }
4775
4776 delete [] buf;
4777 }
4778
4779 puts("");
4780 }
4781
4782 static void TestStringReplace()
4783 {
4784 puts("*** Testing wxString::replace ***");
4785
4786 static const struct StringReplaceTestData
4787 {
4788 const wxChar *original; // original test string
4789 size_t start, len; // the part to replace
4790 const wxChar *replacement; // the replacement string
4791 const wxChar *result; // and the expected result
4792 } stringReplaceTestData[] =
4793 {
4794 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4795 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4796 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4797 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4798 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4799 };
4800
4801 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4802 {
4803 const StringReplaceTestData data = stringReplaceTestData[n];
4804
4805 wxString original = data.original;
4806 original.replace(data.start, data.len, data.replacement);
4807
4808 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4809 data.original, data.start, data.len, data.replacement,
4810 original.c_str());
4811
4812 if ( original == data.result )
4813 {
4814 puts("(ok)");
4815 }
4816 else
4817 {
4818 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4819 }
4820 }
4821
4822 puts("");
4823 }
4824
4825 static void TestStringMatch()
4826 {
4827 wxPuts(_T("*** Testing wxString::Matches() ***"));
4828
4829 static const struct StringMatchTestData
4830 {
4831 const wxChar *text;
4832 const wxChar *wildcard;
4833 bool matches;
4834 } stringMatchTestData[] =
4835 {
4836 { _T("foobar"), _T("foo*"), 1 },
4837 { _T("foobar"), _T("*oo*"), 1 },
4838 { _T("foobar"), _T("*bar"), 1 },
4839 { _T("foobar"), _T("??????"), 1 },
4840 { _T("foobar"), _T("f??b*"), 1 },
4841 { _T("foobar"), _T("f?b*"), 0 },
4842 { _T("foobar"), _T("*goo*"), 0 },
4843 { _T("foobar"), _T("*foo"), 0 },
4844 { _T("foobarfoo"), _T("*foo"), 1 },
4845 { _T(""), _T("*"), 1 },
4846 { _T(""), _T("?"), 0 },
4847 };
4848
4849 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
4850 {
4851 const StringMatchTestData& data = stringMatchTestData[n];
4852 bool matches = wxString(data.text).Matches(data.wildcard);
4853 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
4854 data.wildcard,
4855 matches ? _T("matches") : _T("doesn't match"),
4856 data.text,
4857 matches == data.matches ? _T("ok") : _T("ERROR"));
4858 }
4859
4860 wxPuts(_T(""));
4861 }
4862
4863 #endif // TEST_STRINGS
4864
4865 // ----------------------------------------------------------------------------
4866 // entry point
4867 // ----------------------------------------------------------------------------
4868
4869 int main(int argc, char **argv)
4870 {
4871 wxInitializer initializer;
4872 if ( !initializer )
4873 {
4874 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
4875
4876 return -1;
4877 }
4878
4879 #ifdef TEST_SNGLINST
4880 wxSingleInstanceChecker checker;
4881 if ( checker.Create(_T(".wxconsole.lock")) )
4882 {
4883 if ( checker.IsAnotherRunning() )
4884 {
4885 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
4886
4887 return 1;
4888 }
4889
4890 // wait some time to give time to launch another instance
4891 wxPrintf(_T("Press \"Enter\" to continue..."));
4892 wxFgetc(stdin);
4893 }
4894 else // failed to create
4895 {
4896 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4897 }
4898 #endif // TEST_SNGLINST
4899
4900 #ifdef TEST_CHARSET
4901 TestCharset();
4902 #endif // TEST_CHARSET
4903
4904 #ifdef TEST_CMDLINE
4905 static const wxCmdLineEntryDesc cmdLineDesc[] =
4906 {
4907 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
4908 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
4909 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4910 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4911
4912 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4913 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4914 { wxCMD_LINE_OPTION, "s", "size", "output block size",
4915 wxCMD_LINE_VAL_NUMBER },
4916 { wxCMD_LINE_OPTION, "d", "date", "output file date",
4917 wxCMD_LINE_VAL_DATE },
4918
4919 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4920 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4921
4922 { wxCMD_LINE_NONE }
4923 };
4924
4925 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4926
4927 parser.AddOption("project_name", "", "full path to project file",
4928 wxCMD_LINE_VAL_STRING,
4929 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4930
4931 switch ( parser.Parse() )
4932 {
4933 case -1:
4934 wxLogMessage("Help was given, terminating.");
4935 break;
4936
4937 case 0:
4938 ShowCmdLine(parser);
4939 break;
4940
4941 default:
4942 wxLogMessage("Syntax error detected, aborting.");
4943 break;
4944 }
4945 #endif // TEST_CMDLINE
4946
4947 #ifdef TEST_STRINGS
4948 if ( 0 )
4949 {
4950 TestPChar();
4951 TestString();
4952 TestStringSub();
4953 TestStringConstruction();
4954 TestStringFormat();
4955 TestStringFind();
4956 TestStringTokenizer();
4957 TestStringReplace();
4958 }
4959 TestStringMatch();
4960 #endif // TEST_STRINGS
4961
4962 #ifdef TEST_ARRAYS
4963 if ( 0 )
4964 {
4965 wxArrayString a1;
4966 a1.Add("tiger");
4967 a1.Add("cat");
4968 a1.Add("lion");
4969 a1.Add("dog");
4970 a1.Add("human");
4971 a1.Add("ape");
4972
4973 puts("*** Initially:");
4974
4975 PrintArray("a1", a1);
4976
4977 wxArrayString a2(a1);
4978 PrintArray("a2", a2);
4979
4980 wxSortedArrayString a3(a1);
4981 PrintArray("a3", a3);
4982
4983 puts("*** After deleting a string from a1");
4984 a1.Remove(2);
4985
4986 PrintArray("a1", a1);
4987 PrintArray("a2", a2);
4988 PrintArray("a3", a3);
4989
4990 puts("*** After reassigning a1 to a2 and a3");
4991 a3 = a2 = a1;
4992 PrintArray("a2", a2);
4993 PrintArray("a3", a3);
4994
4995 puts("*** After sorting a1");
4996 a1.Sort();
4997 PrintArray("a1", a1);
4998
4999 puts("*** After sorting a1 in reverse order");
5000 a1.Sort(TRUE);
5001 PrintArray("a1", a1);
5002
5003 puts("*** After sorting a1 by the string length");
5004 a1.Sort(StringLenCompare);
5005 PrintArray("a1", a1);
5006
5007 TestArrayOfObjects();
5008 }
5009 TestArrayOfInts();
5010 #endif // TEST_ARRAYS
5011
5012 #ifdef TEST_DIR
5013 if ( 0 )
5014 TestDirEnum();
5015 TestDirTraverse();
5016 #endif // TEST_DIR
5017
5018 #ifdef TEST_DLLLOADER
5019 TestDllLoad();
5020 #endif // TEST_DLLLOADER
5021
5022 #ifdef TEST_ENVIRON
5023 TestEnvironment();
5024 #endif // TEST_ENVIRON
5025
5026 #ifdef TEST_EXECUTE
5027 TestExecute();
5028 #endif // TEST_EXECUTE
5029
5030 #ifdef TEST_FILECONF
5031 TestFileConfRead();
5032 #endif // TEST_FILECONF
5033
5034 #ifdef TEST_LIST
5035 TestListCtor();
5036 #endif // TEST_LIST
5037
5038 #ifdef TEST_LOCALE
5039 TestDefaultLang();
5040 #endif // TEST_LOCALE
5041
5042 #ifdef TEST_LOG
5043 wxString s;
5044 for ( size_t n = 0; n < 8000; n++ )
5045 {
5046 s << (char)('A' + (n % 26));
5047 }
5048
5049 wxString msg;
5050 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5051
5052 // this one shouldn't be truncated
5053 printf(msg);
5054
5055 // but this one will because log functions use fixed size buffer
5056 // (note that it doesn't need '\n' at the end neither - will be added
5057 // by wxLog anyhow)
5058 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
5059 #endif // TEST_LOG
5060
5061 #ifdef TEST_FILE
5062 if ( 0 )
5063 {
5064 TestFileRead();
5065 TestTextFileRead();
5066 }
5067 TestFileCopy();
5068 #endif // TEST_FILE
5069
5070 #ifdef TEST_FILENAME
5071 TestFileNameSplit();
5072 if ( 0 )
5073 {
5074 TestFileNameConstruction();
5075 TestFileNameCwd();
5076 TestFileNameComparison();
5077 TestFileNameOperations();
5078 }
5079 #endif // TEST_FILENAME
5080
5081 #ifdef TEST_FTP
5082 wxLog::AddTraceMask(FTP_TRACE_MASK);
5083 if ( TestFtpConnect() )
5084 {
5085 TestFtpFileSize();
5086 if ( 0 )
5087 {
5088 TestFtpList();
5089 TestFtpDownload();
5090 TestFtpMisc();
5091 TestFtpUpload();
5092 }
5093 if ( 0 )
5094 TestFtpInteractive();
5095 }
5096 //else: connecting to the FTP server failed
5097
5098 if ( 0 )
5099 TestFtpWuFtpd();
5100 #endif // TEST_FTP
5101
5102 #ifdef TEST_THREADS
5103 int nCPUs = wxThread::GetCPUCount();
5104 printf("This system has %d CPUs\n", nCPUs);
5105 if ( nCPUs != -1 )
5106 wxThread::SetConcurrency(nCPUs);
5107
5108 if ( argc > 1 && argv[1][0] == 't' )
5109 wxLog::AddTraceMask("thread");
5110
5111 if ( 1 )
5112 TestDetachedThreads();
5113 if ( 1 )
5114 TestJoinableThreads();
5115 if ( 1 )
5116 TestThreadSuspend();
5117 if ( 1 )
5118 TestThreadDelete();
5119
5120 #endif // TEST_THREADS
5121
5122 #ifdef TEST_LONGLONG
5123 // seed pseudo random generator
5124 srand((unsigned)time(NULL));
5125
5126 if ( 0 )
5127 {
5128 TestSpeed();
5129 }
5130 if ( 0 )
5131 {
5132 TestMultiplication();
5133 TestDivision();
5134 TestAddition();
5135 TestLongLongConversion();
5136 TestBitOperations();
5137 TestLongLongComparison();
5138 }
5139 TestLongLongPrint();
5140 #endif // TEST_LONGLONG
5141
5142 #ifdef TEST_HASH
5143 TestHash();
5144 #endif // TEST_HASH
5145
5146 #ifdef TEST_MIME
5147 wxLog::AddTraceMask(_T("mime"));
5148 if ( 1 )
5149 {
5150 TestMimeEnum();
5151 TestMimeOverride();
5152 TestMimeFilename();
5153 }
5154 else
5155 TestMimeAssociate();
5156 #endif // TEST_MIME
5157
5158 #ifdef TEST_INFO_FUNCTIONS
5159 TestDiskInfo();
5160 if ( 0 )
5161 {
5162 TestOsInfo();
5163 TestUserInfo();
5164 }
5165 #endif // TEST_INFO_FUNCTIONS
5166
5167 #ifdef TEST_PATHLIST
5168 TestPathList();
5169 #endif // TEST_PATHLIST
5170
5171 #ifdef TEST_REGCONF
5172 TestRegConfWrite();
5173 #endif // TEST_REGCONF
5174
5175 #ifdef TEST_REGEX
5176 // TODO: write a real test using src/regex/tests file
5177 if ( 0 )
5178 {
5179 TestRegExCompile();
5180 TestRegExMatch();
5181 TestRegExSubmatch();
5182 TestRegExInteractive();
5183 }
5184 TestRegExReplacement();
5185 #endif // TEST_REGEX
5186
5187 #ifdef TEST_REGISTRY
5188 if ( 0 )
5189 TestRegistryRead();
5190 TestRegistryAssociation();
5191 #endif // TEST_REGISTRY
5192
5193 #ifdef TEST_SOCKETS
5194 if ( 0 )
5195 {
5196 TestSocketServer();
5197 }
5198 TestSocketClient();
5199 #endif // TEST_SOCKETS
5200
5201 #ifdef TEST_STREAMS
5202 if ( 0 )
5203 TestFileStream();
5204 TestMemoryStream();
5205 #endif // TEST_STREAMS
5206
5207 #ifdef TEST_TIMER
5208 TestStopWatch();
5209 #endif // TEST_TIMER
5210
5211 #ifdef TEST_DATETIME
5212 if ( 0 )
5213 {
5214 TestTimeSet();
5215 TestTimeStatic();
5216 TestTimeRange();
5217 TestTimeZones();
5218 TestTimeTicks();
5219 TestTimeJDN();
5220 TestTimeDST();
5221 TestTimeWDays();
5222 TestTimeWNumber();
5223 TestTimeParse();
5224 TestTimeArithmetics();
5225 TestTimeHolidays();
5226 TestTimeFormat();
5227 TestTimeMS();
5228
5229 TestTimeZoneBug();
5230 }
5231 TestTimeSpanFormat();
5232 if ( 0 )
5233 TestDateTimeInteractive();
5234 #endif // TEST_DATETIME
5235
5236 #ifdef TEST_USLEEP
5237 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5238 wxUsleep(3000);
5239 #endif // TEST_USLEEP
5240
5241 #ifdef TEST_VCARD
5242 if ( 0 )
5243 TestVCardRead();
5244 TestVCardWrite();
5245 #endif // TEST_VCARD
5246
5247 #ifdef TEST_WCHAR
5248 TestUtf8();
5249 #endif // TEST_WCHAR
5250
5251 #ifdef TEST_ZIP
5252 if ( 0 )
5253 TestZipStreamRead();
5254 TestZipFileSystem();
5255 #endif // TEST_ZIP
5256
5257 #ifdef TEST_ZLIB
5258 if ( 0 )
5259 TestZlibStreamWrite();
5260 TestZlibStreamRead();
5261 #endif // TEST_ZLIB
5262
5263 return 0;
5264 }
5265