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