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