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