]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
4caca091afe78f027f4b4f329d3d6fcc63b8082b
[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 #if 0
3387
3388 // test compatibility with the old wxDate/wxTime classes
3389 static void TestTimeCompatibility()
3390 {
3391 puts("\n*** wxDateTime compatibility test ***");
3392
3393 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
3394 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
3395
3396 double jdnNow = wxDateTime::Now().GetJDN();
3397 long jdnMidnight = (long)(jdnNow - 0.5);
3398 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
3399
3400 jdnMidnight = wxDate().Set().GetJulianDate();
3401 printf("wxDateTime for today: %s\n",
3402 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
3403
3404 int flags = wxEUROPEAN;//wxFULL;
3405 wxDate date;
3406 date.Set();
3407 printf("Today is %s\n", date.FormatDate(flags).c_str());
3408 for ( int n = 0; n < 7; n++ )
3409 {
3410 printf("Previous %s is %s\n",
3411 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
3412 date.Previous(n + 1).FormatDate(flags).c_str());
3413 }
3414 }
3415
3416 #endif // 0
3417
3418 #endif // TEST_DATETIME
3419
3420 // ----------------------------------------------------------------------------
3421 // threads
3422 // ----------------------------------------------------------------------------
3423
3424 #ifdef TEST_THREADS
3425
3426 #include <wx/thread.h>
3427
3428 static size_t gs_counter = (size_t)-1;
3429 static wxCriticalSection gs_critsect;
3430 static wxCondition gs_cond;
3431
3432 class MyJoinableThread : public wxThread
3433 {
3434 public:
3435 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3436 { m_n = n; Create(); }
3437
3438 // thread execution starts here
3439 virtual ExitCode Entry();
3440
3441 private:
3442 size_t m_n;
3443 };
3444
3445 wxThread::ExitCode MyJoinableThread::Entry()
3446 {
3447 unsigned long res = 1;
3448 for ( size_t n = 1; n < m_n; n++ )
3449 {
3450 res *= n;
3451
3452 // it's a loooong calculation :-)
3453 Sleep(100);
3454 }
3455
3456 return (ExitCode)res;
3457 }
3458
3459 class MyDetachedThread : public wxThread
3460 {
3461 public:
3462 MyDetachedThread(size_t n, char ch)
3463 {
3464 m_n = n;
3465 m_ch = ch;
3466 m_cancelled = FALSE;
3467
3468 Create();
3469 }
3470
3471 // thread execution starts here
3472 virtual ExitCode Entry();
3473
3474 // and stops here
3475 virtual void OnExit();
3476
3477 private:
3478 size_t m_n; // number of characters to write
3479 char m_ch; // character to write
3480
3481 bool m_cancelled; // FALSE if we exit normally
3482 };
3483
3484 wxThread::ExitCode MyDetachedThread::Entry()
3485 {
3486 {
3487 wxCriticalSectionLocker lock(gs_critsect);
3488 if ( gs_counter == (size_t)-1 )
3489 gs_counter = 1;
3490 else
3491 gs_counter++;
3492 }
3493
3494 for ( size_t n = 0; n < m_n; n++ )
3495 {
3496 if ( TestDestroy() )
3497 {
3498 m_cancelled = TRUE;
3499
3500 break;
3501 }
3502
3503 putchar(m_ch);
3504 fflush(stdout);
3505
3506 wxThread::Sleep(100);
3507 }
3508
3509 return 0;
3510 }
3511
3512 void MyDetachedThread::OnExit()
3513 {
3514 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
3515
3516 wxCriticalSectionLocker lock(gs_critsect);
3517 if ( !--gs_counter && !m_cancelled )
3518 gs_cond.Signal();
3519 }
3520
3521 void TestDetachedThreads()
3522 {
3523 puts("\n*** Testing detached threads ***");
3524
3525 static const size_t nThreads = 3;
3526 MyDetachedThread *threads[nThreads];
3527 size_t n;
3528 for ( n = 0; n < nThreads; n++ )
3529 {
3530 threads[n] = new MyDetachedThread(10, 'A' + n);
3531 }
3532
3533 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3534 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3535
3536 for ( n = 0; n < nThreads; n++ )
3537 {
3538 threads[n]->Run();
3539 }
3540
3541 // wait until all threads terminate
3542 gs_cond.Wait();
3543
3544 puts("");
3545 }
3546
3547 void TestJoinableThreads()
3548 {
3549 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
3550
3551 // calc 10! in the background
3552 MyJoinableThread thread(10);
3553 thread.Run();
3554
3555 printf("\nThread terminated with exit code %lu.\n",
3556 (unsigned long)thread.Wait());
3557 }
3558
3559 void TestThreadSuspend()
3560 {
3561 puts("\n*** Testing thread suspend/resume functions ***");
3562
3563 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3564
3565 thread->Run();
3566
3567 // this is for this demo only, in a real life program we'd use another
3568 // condition variable which would be signaled from wxThread::Entry() to
3569 // tell us that the thread really started running - but here just wait a
3570 // bit and hope that it will be enough (the problem is, of course, that
3571 // the thread might still not run when we call Pause() which will result
3572 // in an error)
3573 wxThread::Sleep(300);
3574
3575 for ( size_t n = 0; n < 3; n++ )
3576 {
3577 thread->Pause();
3578
3579 puts("\nThread suspended");
3580 if ( n > 0 )
3581 {
3582 // don't sleep but resume immediately the first time
3583 wxThread::Sleep(300);
3584 }
3585 puts("Going to resume the thread");
3586
3587 thread->Resume();
3588 }
3589
3590 puts("Waiting until it terminates now");
3591
3592 // wait until the thread terminates
3593 gs_cond.Wait();
3594
3595 puts("");
3596 }
3597
3598 void TestThreadDelete()
3599 {
3600 // As above, using Sleep() is only for testing here - we must use some
3601 // synchronisation object instead to ensure that the thread is still
3602 // running when we delete it - deleting a detached thread which already
3603 // terminated will lead to a crash!
3604
3605 puts("\n*** Testing thread delete function ***");
3606
3607 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
3608
3609 thread0->Delete();
3610
3611 puts("\nDeleted a thread which didn't start to run yet.");
3612
3613 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
3614
3615 thread1->Run();
3616
3617 wxThread::Sleep(300);
3618
3619 thread1->Delete();
3620
3621 puts("\nDeleted a running thread.");
3622
3623 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
3624
3625 thread2->Run();
3626
3627 wxThread::Sleep(300);
3628
3629 thread2->Pause();
3630
3631 thread2->Delete();
3632
3633 puts("\nDeleted a sleeping thread.");
3634
3635 MyJoinableThread thread3(20);
3636 thread3.Run();
3637
3638 thread3.Delete();
3639
3640 puts("\nDeleted a joinable thread.");
3641
3642 MyJoinableThread thread4(2);
3643 thread4.Run();
3644
3645 wxThread::Sleep(300);
3646
3647 thread4.Delete();
3648
3649 puts("\nDeleted a joinable thread which already terminated.");
3650
3651 puts("");
3652 }
3653
3654 #endif // TEST_THREADS
3655
3656 // ----------------------------------------------------------------------------
3657 // arrays
3658 // ----------------------------------------------------------------------------
3659
3660 #ifdef TEST_ARRAYS
3661
3662 static void PrintArray(const char* name, const wxArrayString& array)
3663 {
3664 printf("Dump of the array '%s'\n", name);
3665
3666 size_t nCount = array.GetCount();
3667 for ( size_t n = 0; n < nCount; n++ )
3668 {
3669 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
3670 }
3671 }
3672
3673 static void PrintArray(const char* name, const wxArrayInt& array)
3674 {
3675 printf("Dump of the array '%s'\n", name);
3676
3677 size_t nCount = array.GetCount();
3678 for ( size_t n = 0; n < nCount; n++ )
3679 {
3680 printf("\t%s[%u] = %d\n", name, n, array[n]);
3681 }
3682 }
3683
3684 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
3685 const wxString& second)
3686 {
3687 return first.length() - second.length();
3688 }
3689
3690 int wxCMPFUNC_CONV IntCompare(int *first,
3691 int *second)
3692 {
3693 return *first - *second;
3694 }
3695
3696 int wxCMPFUNC_CONV IntRevCompare(int *first,
3697 int *second)
3698 {
3699 return *second - *first;
3700 }
3701
3702 static void TestArrayOfInts()
3703 {
3704 puts("*** Testing wxArrayInt ***\n");
3705
3706 wxArrayInt a;
3707 a.Add(1);
3708 a.Add(17);
3709 a.Add(5);
3710 a.Add(3);
3711
3712 puts("Initially:");
3713 PrintArray("a", a);
3714
3715 puts("After sort:");
3716 a.Sort(IntCompare);
3717 PrintArray("a", a);
3718
3719 puts("After reverse sort:");
3720 a.Sort(IntRevCompare);
3721 PrintArray("a", a);
3722 }
3723
3724 #include "wx/dynarray.h"
3725
3726 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
3727 #include "wx/arrimpl.cpp"
3728 WX_DEFINE_OBJARRAY(ArrayBars);
3729
3730 static void TestArrayOfObjects()
3731 {
3732 puts("*** Testing wxObjArray ***\n");
3733
3734 {
3735 ArrayBars bars;
3736 Bar bar("second bar");
3737
3738 printf("Initially: %u objects in the array, %u objects total.\n",
3739 bars.GetCount(), Bar::GetNumber());
3740
3741 bars.Add(new Bar("first bar"));
3742 bars.Add(bar);
3743
3744 printf("Now: %u objects in the array, %u objects total.\n",
3745 bars.GetCount(), Bar::GetNumber());
3746
3747 bars.Empty();
3748
3749 printf("After Empty(): %u objects in the array, %u objects total.\n",
3750 bars.GetCount(), Bar::GetNumber());
3751 }
3752
3753 printf("Finally: no more objects in the array, %u objects total.\n",
3754 Bar::GetNumber());
3755 }
3756
3757 #endif // TEST_ARRAYS
3758
3759 // ----------------------------------------------------------------------------
3760 // strings
3761 // ----------------------------------------------------------------------------
3762
3763 #ifdef TEST_STRINGS
3764
3765 #include "wx/timer.h"
3766 #include "wx/tokenzr.h"
3767
3768 static void TestStringConstruction()
3769 {
3770 puts("*** Testing wxString constructores ***");
3771
3772 #define TEST_CTOR(args, res) \
3773 { \
3774 wxString s args ; \
3775 printf("wxString%s = %s ", #args, s.c_str()); \
3776 if ( s == res ) \
3777 { \
3778 puts("(ok)"); \
3779 } \
3780 else \
3781 { \
3782 printf("(ERROR: should be %s)\n", res); \
3783 } \
3784 }
3785
3786 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
3787 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
3788 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
3789 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
3790
3791 static const wxChar *s = _T("?really!");
3792 const wxChar *start = wxStrchr(s, _T('r'));
3793 const wxChar *end = wxStrchr(s, _T('!'));
3794 TEST_CTOR((start, end), _T("really"));
3795
3796 puts("");
3797 }
3798
3799 static void TestString()
3800 {
3801 wxStopWatch sw;
3802
3803 wxString a, b, c;
3804
3805 a.reserve (128);
3806 b.reserve (128);
3807 c.reserve (128);
3808
3809 for (int i = 0; i < 1000000; ++i)
3810 {
3811 a = "Hello";
3812 b = " world";
3813 c = "! How'ya doin'?";
3814 a += b;
3815 a += c;
3816 c = "Hello world! What's up?";
3817 if (c != a)
3818 c = "Doh!";
3819 }
3820
3821 printf ("TestString elapsed time: %ld\n", sw.Time());
3822 }
3823
3824 static void TestPChar()
3825 {
3826 wxStopWatch sw;
3827
3828 char a [128];
3829 char b [128];
3830 char c [128];
3831
3832 for (int i = 0; i < 1000000; ++i)
3833 {
3834 strcpy (a, "Hello");
3835 strcpy (b, " world");
3836 strcpy (c, "! How'ya doin'?");
3837 strcat (a, b);
3838 strcat (a, c);
3839 strcpy (c, "Hello world! What's up?");
3840 if (strcmp (c, a) == 0)
3841 strcpy (c, "Doh!");
3842 }
3843
3844 printf ("TestPChar elapsed time: %ld\n", sw.Time());
3845 }
3846
3847 static void TestStringSub()
3848 {
3849 wxString s("Hello, world!");
3850
3851 puts("*** Testing wxString substring extraction ***");
3852
3853 printf("String = '%s'\n", s.c_str());
3854 printf("Left(5) = '%s'\n", s.Left(5).c_str());
3855 printf("Right(6) = '%s'\n", s.Right(6).c_str());
3856 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
3857 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
3858 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
3859 printf("substr(3) = '%s'\n", s.substr(3).c_str());
3860
3861 static const wxChar *prefixes[] =
3862 {
3863 _T("Hello"),
3864 _T("Hello, "),
3865 _T("Hello, world!"),
3866 _T("Hello, world!!!"),
3867 _T(""),
3868 _T("Goodbye"),
3869 _T("Hi"),
3870 };
3871
3872 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
3873 {
3874 wxString prefix = prefixes[n], rest;
3875 bool rc = s.StartsWith(prefix, &rest);
3876 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
3877 if ( rc )
3878 {
3879 printf(" (the rest is '%s')\n", rest.c_str());
3880 }
3881 else
3882 {
3883 putchar('\n');
3884 }
3885 }
3886
3887 puts("");
3888 }
3889
3890 static void TestStringFormat()
3891 {
3892 puts("*** Testing wxString formatting ***");
3893
3894 wxString s;
3895 s.Printf("%03d", 18);
3896
3897 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
3898 printf("Number 18: %s\n", s.c_str());
3899
3900 puts("");
3901 }
3902
3903 // returns "not found" for npos, value for all others
3904 static wxString PosToString(size_t res)
3905 {
3906 wxString s = res == wxString::npos ? wxString(_T("not found"))
3907 : wxString::Format(_T("%u"), res);
3908 return s;
3909 }
3910
3911 static void TestStringFind()
3912 {
3913 puts("*** Testing wxString find() functions ***");
3914
3915 static const wxChar *strToFind = _T("ell");
3916 static const struct StringFindTest
3917 {
3918 const wxChar *str;
3919 size_t start,
3920 result; // of searching "ell" in str
3921 } findTestData[] =
3922 {
3923 { _T("Well, hello world"), 0, 1 },
3924 { _T("Well, hello world"), 6, 7 },
3925 { _T("Well, hello world"), 9, wxString::npos },
3926 };
3927
3928 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
3929 {
3930 const StringFindTest& ft = findTestData[n];
3931 size_t res = wxString(ft.str).find(strToFind, ft.start);
3932
3933 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
3934 strToFind, ft.str, ft.start, PosToString(res).c_str());
3935
3936 size_t resTrue = ft.result;
3937 if ( res == resTrue )
3938 {
3939 puts(_T("(ok)"));
3940 }
3941 else
3942 {
3943 printf(_T("(ERROR: should be %s)\n"),
3944 PosToString(resTrue).c_str());
3945 }
3946 }
3947
3948 puts("");
3949 }
3950
3951 static void TestStringTokenizer()
3952 {
3953 puts("*** Testing wxStringTokenizer ***");
3954
3955 static const wxChar *modeNames[] =
3956 {
3957 _T("default"),
3958 _T("return empty"),
3959 _T("return all empty"),
3960 _T("with delims"),
3961 _T("like strtok"),
3962 };
3963
3964 static const struct StringTokenizerTest
3965 {
3966 const wxChar *str; // string to tokenize
3967 const wxChar *delims; // delimiters to use
3968 size_t count; // count of token
3969 wxStringTokenizerMode mode; // how should we tokenize it
3970 } tokenizerTestData[] =
3971 {
3972 { _T(""), _T(" "), 0 },
3973 { _T("Hello, world"), _T(" "), 2 },
3974 { _T("Hello, world "), _T(" "), 2 },
3975 { _T("Hello, world"), _T(","), 2 },
3976 { _T("Hello, world!"), _T(",!"), 2 },
3977 { _T("Hello,, world!"), _T(",!"), 3 },
3978 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
3979 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
3980 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
3981 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
3982 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
3983 { _T("01/02/99"), _T("/-"), 3 },
3984 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
3985 };
3986
3987 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
3988 {
3989 const StringTokenizerTest& tt = tokenizerTestData[n];
3990 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
3991
3992 size_t count = tkz.CountTokens();
3993 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
3994 MakePrintable(tt.str).c_str(),
3995 count,
3996 MakePrintable(tt.delims).c_str(),
3997 modeNames[tkz.GetMode()]);
3998 if ( count == tt.count )
3999 {
4000 puts(_T("(ok)"));
4001 }
4002 else
4003 {
4004 printf(_T("(ERROR: should be %u)\n"), tt.count);
4005
4006 continue;
4007 }
4008
4009 // if we emulate strtok(), check that we do it correctly
4010 wxChar *buf, *s = NULL, *last;
4011
4012 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4013 {
4014 buf = new wxChar[wxStrlen(tt.str) + 1];
4015 wxStrcpy(buf, tt.str);
4016
4017 s = wxStrtok(buf, tt.delims, &last);
4018 }
4019 else
4020 {
4021 buf = NULL;
4022 }
4023
4024 // now show the tokens themselves
4025 size_t count2 = 0;
4026 while ( tkz.HasMoreTokens() )
4027 {
4028 wxString token = tkz.GetNextToken();
4029
4030 printf(_T("\ttoken %u: '%s'"),
4031 ++count2,
4032 MakePrintable(token).c_str());
4033
4034 if ( buf )
4035 {
4036 if ( token == s )
4037 {
4038 puts(" (ok)");
4039 }
4040 else
4041 {
4042 printf(" (ERROR: should be %s)\n", s);
4043 }
4044
4045 s = wxStrtok(NULL, tt.delims, &last);
4046 }
4047 else
4048 {
4049 // nothing to compare with
4050 puts("");
4051 }
4052 }
4053
4054 if ( count2 != count )
4055 {
4056 puts(_T("\tERROR: token count mismatch"));
4057 }
4058
4059 delete [] buf;
4060 }
4061
4062 puts("");
4063 }
4064
4065 static void TestStringReplace()
4066 {
4067 puts("*** Testing wxString::replace ***");
4068
4069 static const struct StringReplaceTestData
4070 {
4071 const wxChar *original; // original test string
4072 size_t start, len; // the part to replace
4073 const wxChar *replacement; // the replacement string
4074 const wxChar *result; // and the expected result
4075 } stringReplaceTestData[] =
4076 {
4077 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4078 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4079 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4080 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4081 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4082 };
4083
4084 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4085 {
4086 const StringReplaceTestData data = stringReplaceTestData[n];
4087
4088 wxString original = data.original;
4089 original.replace(data.start, data.len, data.replacement);
4090
4091 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4092 data.original, data.start, data.len, data.replacement,
4093 original.c_str());
4094
4095 if ( original == data.result )
4096 {
4097 puts("(ok)");
4098 }
4099 else
4100 {
4101 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4102 }
4103 }
4104
4105 puts("");
4106 }
4107
4108 #endif // TEST_STRINGS
4109
4110 // ----------------------------------------------------------------------------
4111 // entry point
4112 // ----------------------------------------------------------------------------
4113
4114 int main(int argc, char **argv)
4115 {
4116 if ( !wxInitialize() )
4117 {
4118 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
4119 }
4120
4121 #ifdef TEST_USLEEP
4122 puts("Sleeping for 3 seconds... z-z-z-z-z...");
4123 wxUsleep(3000);
4124 #endif // TEST_USLEEP
4125
4126 #ifdef TEST_CMDLINE
4127 static const wxCmdLineEntryDesc cmdLineDesc[] =
4128 {
4129 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4130 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4131
4132 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4133 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4134 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
4135 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
4136
4137 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4138 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4139
4140 { wxCMD_LINE_NONE }
4141 };
4142
4143 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4144
4145 parser.AddOption("project_name", "", "full path to project file",
4146 wxCMD_LINE_VAL_STRING,
4147 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4148
4149 switch ( parser.Parse() )
4150 {
4151 case -1:
4152 wxLogMessage("Help was given, terminating.");
4153 break;
4154
4155 case 0:
4156 ShowCmdLine(parser);
4157 break;
4158
4159 default:
4160 wxLogMessage("Syntax error detected, aborting.");
4161 break;
4162 }
4163 #endif // TEST_CMDLINE
4164
4165 #ifdef TEST_STRINGS
4166 if ( 0 )
4167 {
4168 TestPChar();
4169 TestString();
4170 }
4171 TestStringSub();
4172 if ( 0 )
4173 {
4174 TestStringConstruction();
4175 TestStringFormat();
4176 TestStringFind();
4177 TestStringTokenizer();
4178 TestStringReplace();
4179 }
4180 #endif // TEST_STRINGS
4181
4182 #ifdef TEST_ARRAYS
4183 if ( 0 )
4184 {
4185 wxArrayString a1;
4186 a1.Add("tiger");
4187 a1.Add("cat");
4188 a1.Add("lion");
4189 a1.Add("dog");
4190 a1.Add("human");
4191 a1.Add("ape");
4192
4193 puts("*** Initially:");
4194
4195 PrintArray("a1", a1);
4196
4197 wxArrayString a2(a1);
4198 PrintArray("a2", a2);
4199
4200 wxSortedArrayString a3(a1);
4201 PrintArray("a3", a3);
4202
4203 puts("*** After deleting a string from a1");
4204 a1.Remove(2);
4205
4206 PrintArray("a1", a1);
4207 PrintArray("a2", a2);
4208 PrintArray("a3", a3);
4209
4210 puts("*** After reassigning a1 to a2 and a3");
4211 a3 = a2 = a1;
4212 PrintArray("a2", a2);
4213 PrintArray("a3", a3);
4214
4215 puts("*** After sorting a1");
4216 a1.Sort();
4217 PrintArray("a1", a1);
4218
4219 puts("*** After sorting a1 in reverse order");
4220 a1.Sort(TRUE);
4221 PrintArray("a1", a1);
4222
4223 puts("*** After sorting a1 by the string length");
4224 a1.Sort(StringLenCompare);
4225 PrintArray("a1", a1);
4226
4227 TestArrayOfObjects();
4228 }
4229 TestArrayOfInts();
4230 #endif // TEST_ARRAYS
4231
4232 #ifdef TEST_DIR
4233 TestDirEnum();
4234 #endif // TEST_DIR
4235
4236 #ifdef TEST_DLLLOADER
4237 TestDllLoad();
4238 #endif // TEST_DLLLOADER
4239
4240 #ifdef TEST_ENVIRON
4241 TestEnvironment();
4242 #endif // TEST_ENVIRON
4243
4244 #ifdef TEST_EXECUTE
4245 TestExecute();
4246 #endif // TEST_EXECUTE
4247
4248 #ifdef TEST_FILECONF
4249 TestFileConfRead();
4250 #endif // TEST_FILECONF
4251
4252 #ifdef TEST_LIST
4253 TestListCtor();
4254 #endif // TEST_LIST
4255
4256 #ifdef TEST_LOG
4257 wxString s;
4258 for ( size_t n = 0; n < 8000; n++ )
4259 {
4260 s << (char)('A' + (n % 26));
4261 }
4262
4263 wxString msg;
4264 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
4265
4266 // this one shouldn't be truncated
4267 printf(msg);
4268
4269 // but this one will because log functions use fixed size buffer
4270 // (note that it doesn't need '\n' at the end neither - will be added
4271 // by wxLog anyhow)
4272 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
4273 #endif // TEST_LOG
4274
4275 #ifdef TEST_FILE
4276 if ( 0 )
4277 {
4278 TestFileRead();
4279 TestTextFileRead();
4280 }
4281 TestFileCopy();
4282 #endif // TEST_FILE
4283
4284 #ifdef TEST_FILENAME
4285 TestFileNameSplit();
4286 if ( 0 )
4287 {
4288 TestFileNameConstruction();
4289 TestFileNameCwd();
4290 TestFileNameComparison();
4291 TestFileNameOperations();
4292 }
4293 #endif // TEST_FILENAME
4294
4295 #ifdef TEST_THREADS
4296 int nCPUs = wxThread::GetCPUCount();
4297 printf("This system has %d CPUs\n", nCPUs);
4298 if ( nCPUs != -1 )
4299 wxThread::SetConcurrency(nCPUs);
4300
4301 if ( argc > 1 && argv[1][0] == 't' )
4302 wxLog::AddTraceMask("thread");
4303
4304 if ( 1 )
4305 TestDetachedThreads();
4306 if ( 1 )
4307 TestJoinableThreads();
4308 if ( 1 )
4309 TestThreadSuspend();
4310 if ( 1 )
4311 TestThreadDelete();
4312
4313 #endif // TEST_THREADS
4314
4315 #ifdef TEST_LONGLONG
4316 // seed pseudo random generator
4317 srand((unsigned)time(NULL));
4318
4319 if ( 0 )
4320 {
4321 TestSpeed();
4322 }
4323 if ( 0 )
4324 {
4325 TestMultiplication();
4326 TestDivision();
4327 TestAddition();
4328 TestLongLongConversion();
4329 TestBitOperations();
4330 }
4331 TestLongLongComparison();
4332 #endif // TEST_LONGLONG
4333
4334 #ifdef TEST_HASH
4335 TestHash();
4336 #endif // TEST_HASH
4337
4338 #ifdef TEST_MIME
4339 wxLog::AddTraceMask(_T("mime"));
4340 if ( 1 )
4341 {
4342 TestMimeEnum();
4343 TestMimeOverride();
4344 TestMimeFilename();
4345 }
4346 else
4347 TestMimeAssociate();
4348 #endif // TEST_MIME
4349
4350 #ifdef TEST_INFO_FUNCTIONS
4351 TestOsInfo();
4352 TestUserInfo();
4353 #endif // TEST_INFO_FUNCTIONS
4354
4355 #ifdef TEST_PATHLIST
4356 TestPathList();
4357 #endif // TEST_PATHLIST
4358
4359 #ifdef TEST_REGISTRY
4360 if ( 0 )
4361 TestRegistryRead();
4362 TestRegistryAssociation();
4363 #endif // TEST_REGISTRY
4364
4365 #ifdef TEST_SOCKETS
4366 if ( 0 )
4367 {
4368 TestSocketServer();
4369 }
4370 TestSocketClient();
4371 #endif // TEST_SOCKETS
4372
4373 #ifdef TEST_FTP
4374 wxLog::AddTraceMask(FTP_TRACE_MASK);
4375 if ( TestFtpConnect() )
4376 {
4377 TestFtpFileSize();
4378 if ( 0 )
4379 {
4380 TestFtpList();
4381 TestFtpDownload();
4382 TestFtpMisc();
4383 TestFtpUpload();
4384 }
4385 if ( 0 )
4386 TestFtpInteractive();
4387 }
4388 //else: connecting to the FTP server failed
4389
4390 if ( 0 )
4391 TestFtpWuFtpd();
4392 #endif // TEST_FTP
4393
4394 #ifdef TEST_STREAMS
4395 if ( 0 )
4396 TestFileStream();
4397 TestMemoryStream();
4398 #endif // TEST_STREAMS
4399
4400 #ifdef TEST_TIMER
4401 TestStopWatch();
4402 #endif // TEST_TIMER
4403
4404 #ifdef TEST_DATETIME
4405 if ( 1 )
4406 {
4407 TestTimeSet();
4408 TestTimeStatic();
4409 TestTimeRange();
4410 TestTimeZones();
4411 TestTimeTicks();
4412 TestTimeJDN();
4413 TestTimeDST();
4414 TestTimeWDays();
4415 TestTimeWNumber();
4416 TestTimeParse();
4417 TestTimeArithmetics();
4418 TestTimeHolidays();
4419 TestTimeFormat();
4420 TestTimeMS();
4421
4422 TestTimeZoneBug();
4423 }
4424 if ( 0 )
4425 TestDateTimeInteractive();
4426 #endif // TEST_DATETIME
4427
4428 #ifdef TEST_VCARD
4429 if ( 0 )
4430 TestVCardRead();
4431 TestVCardWrite();
4432 #endif // TEST_VCARD
4433
4434 #ifdef TEST_WCHAR
4435 TestUtf8();
4436 #endif // TEST_WCHAR
4437
4438 #ifdef TEST_ZIP
4439 if ( 0 )
4440 TestZipStreamRead();
4441 TestZipFileSystem();
4442 #endif // TEST_ZIP
4443
4444 #ifdef TEST_ZLIB
4445 if ( 0 )
4446 TestZlibStreamWrite();
4447 TestZlibStreamRead();
4448 #endif // TEST_ZLIB
4449
4450 wxUninitialize();
4451
4452 return 0;
4453 }
4454