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