]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
2a507f9a88f2a4f9f7064f523e977904f9dc5246
[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/zipstrm.h"
2283
2284 static void TestZipStreamRead()
2285 {
2286 puts("*** Testing ZIP reading ***\n");
2287
2288 wxZipInputStream istr(_T("idx.zip"), _T("IDX.txt"));
2289 printf("Archive size: %u\n", istr.GetSize());
2290
2291 puts("Dumping the file:");
2292 while ( !istr.Eof() )
2293 {
2294 putchar(istr.GetC());
2295 fflush(stdout);
2296 }
2297
2298 puts("\n----- done ------");
2299 }
2300
2301 #endif // TEST_ZIP
2302
2303 // ----------------------------------------------------------------------------
2304 // ZLIB stream
2305 // ----------------------------------------------------------------------------
2306
2307 #ifdef TEST_ZLIB
2308
2309 #include <wx/zstream.h>
2310 #include <wx/wfstream.h>
2311
2312 static const wxChar *FILENAME_GZ = _T("test.gz");
2313 static const char *TEST_DATA = "hello and hello again";
2314
2315 static void TestZlibStreamWrite()
2316 {
2317 puts("*** Testing Zlib stream reading ***\n");
2318
2319 wxFileOutputStream fileOutStream(FILENAME_GZ);
2320 wxZlibOutputStream ostr(fileOutStream, 0);
2321 printf("Compressing the test string... ");
2322 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
2323 if ( !ostr )
2324 {
2325 puts("(ERROR: failed)");
2326 }
2327 else
2328 {
2329 puts("(ok)");
2330 }
2331
2332 puts("\n----- done ------");
2333 }
2334
2335 static void TestZlibStreamRead()
2336 {
2337 puts("*** Testing Zlib stream reading ***\n");
2338
2339 wxFileInputStream fileInStream(FILENAME_GZ);
2340 wxZlibInputStream istr(fileInStream);
2341 printf("Archive size: %u\n", istr.GetSize());
2342
2343 puts("Dumping the file:");
2344 while ( !istr.Eof() )
2345 {
2346 putchar(istr.GetC());
2347 fflush(stdout);
2348 }
2349
2350 puts("\n----- done ------");
2351 }
2352
2353 #endif // TEST_ZLIB
2354
2355 // ----------------------------------------------------------------------------
2356 // date time
2357 // ----------------------------------------------------------------------------
2358
2359 #ifdef TEST_DATETIME
2360
2361 #include <wx/date.h>
2362
2363 #include <wx/datetime.h>
2364
2365 // the test data
2366 struct Date
2367 {
2368 wxDateTime::wxDateTime_t day;
2369 wxDateTime::Month month;
2370 int year;
2371 wxDateTime::wxDateTime_t hour, min, sec;
2372 double jdn;
2373 wxDateTime::WeekDay wday;
2374 time_t gmticks, ticks;
2375
2376 void Init(const wxDateTime::Tm& tm)
2377 {
2378 day = tm.mday;
2379 month = tm.mon;
2380 year = tm.year;
2381 hour = tm.hour;
2382 min = tm.min;
2383 sec = tm.sec;
2384 jdn = 0.0;
2385 gmticks = ticks = -1;
2386 }
2387
2388 wxDateTime DT() const
2389 { return wxDateTime(day, month, year, hour, min, sec); }
2390
2391 bool SameDay(const wxDateTime::Tm& tm) const
2392 {
2393 return day == tm.mday && month == tm.mon && year == tm.year;
2394 }
2395
2396 wxString Format() const
2397 {
2398 wxString s;
2399 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
2400 hour, min, sec,
2401 wxDateTime::GetMonthName(month).c_str(),
2402 day,
2403 abs(wxDateTime::ConvertYearToBC(year)),
2404 year > 0 ? "AD" : "BC");
2405 return s;
2406 }
2407
2408 wxString FormatDate() const
2409 {
2410 wxString s;
2411 s.Printf("%02d-%s-%4d%s",
2412 day,
2413 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2414 abs(wxDateTime::ConvertYearToBC(year)),
2415 year > 0 ? "AD" : "BC");
2416 return s;
2417 }
2418 };
2419
2420 static const Date testDates[] =
2421 {
2422 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
2423 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
2424 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
2425 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
2426 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
2427 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
2428 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
2429 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
2430 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
2431 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
2432 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
2433 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
2434 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
2435 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
2436 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
2437 };
2438
2439 // this test miscellaneous static wxDateTime functions
2440 static void TestTimeStatic()
2441 {
2442 puts("\n*** wxDateTime static methods test ***");
2443
2444 // some info about the current date
2445 int year = wxDateTime::GetCurrentYear();
2446 printf("Current year %d is %sa leap one and has %d days.\n",
2447 year,
2448 wxDateTime::IsLeapYear(year) ? "" : "not ",
2449 wxDateTime::GetNumberOfDays(year));
2450
2451 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
2452 printf("Current month is '%s' ('%s') and it has %d days\n",
2453 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2454 wxDateTime::GetMonthName(month).c_str(),
2455 wxDateTime::GetNumberOfDays(month));
2456
2457 // leap year logic
2458 static const size_t nYears = 5;
2459 static const size_t years[2][nYears] =
2460 {
2461 // first line: the years to test
2462 { 1990, 1976, 2000, 2030, 1984, },
2463
2464 // second line: TRUE if leap, FALSE otherwise
2465 { FALSE, TRUE, TRUE, FALSE, TRUE }
2466 };
2467
2468 for ( size_t n = 0; n < nYears; n++ )
2469 {
2470 int year = years[0][n];
2471 bool should = years[1][n] != 0,
2472 is = wxDateTime::IsLeapYear(year);
2473
2474 printf("Year %d is %sa leap year (%s)\n",
2475 year,
2476 is ? "" : "not ",
2477 should == is ? "ok" : "ERROR");
2478
2479 wxASSERT( should == wxDateTime::IsLeapYear(year) );
2480 }
2481 }
2482
2483 // test constructing wxDateTime objects
2484 static void TestTimeSet()
2485 {
2486 puts("\n*** wxDateTime construction test ***");
2487
2488 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2489 {
2490 const Date& d1 = testDates[n];
2491 wxDateTime dt = d1.DT();
2492
2493 Date d2;
2494 d2.Init(dt.GetTm());
2495
2496 wxString s1 = d1.Format(),
2497 s2 = d2.Format();
2498
2499 printf("Date: %s == %s (%s)\n",
2500 s1.c_str(), s2.c_str(),
2501 s1 == s2 ? "ok" : "ERROR");
2502 }
2503 }
2504
2505 // test time zones stuff
2506 static void TestTimeZones()
2507 {
2508 puts("\n*** wxDateTime timezone test ***");
2509
2510 wxDateTime now = wxDateTime::Now();
2511
2512 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
2513 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
2514 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
2515 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
2516 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
2517 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
2518
2519 wxDateTime::Tm tm = now.GetTm();
2520 if ( wxDateTime(tm) != now )
2521 {
2522 printf("ERROR: got %s instead of %s\n",
2523 wxDateTime(tm).Format().c_str(), now.Format().c_str());
2524 }
2525 }
2526
2527 // test some minimal support for the dates outside the standard range
2528 static void TestTimeRange()
2529 {
2530 puts("\n*** wxDateTime out-of-standard-range dates test ***");
2531
2532 static const char *fmt = "%d-%b-%Y %H:%M:%S";
2533
2534 printf("Unix epoch:\t%s\n",
2535 wxDateTime(2440587.5).Format(fmt).c_str());
2536 printf("Feb 29, 0: \t%s\n",
2537 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
2538 printf("JDN 0: \t%s\n",
2539 wxDateTime(0.0).Format(fmt).c_str());
2540 printf("Jan 1, 1AD:\t%s\n",
2541 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
2542 printf("May 29, 2099:\t%s\n",
2543 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
2544 }
2545
2546 static void TestTimeTicks()
2547 {
2548 puts("\n*** wxDateTime ticks test ***");
2549
2550 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2551 {
2552 const Date& d = testDates[n];
2553 if ( d.ticks == -1 )
2554 continue;
2555
2556 wxDateTime dt = d.DT();
2557 long ticks = (dt.GetValue() / 1000).ToLong();
2558 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
2559 if ( ticks == d.ticks )
2560 {
2561 puts(" (ok)");
2562 }
2563 else
2564 {
2565 printf(" (ERROR: should be %ld, delta = %ld)\n",
2566 d.ticks, ticks - d.ticks);
2567 }
2568
2569 dt = d.DT().ToTimezone(wxDateTime::GMT0);
2570 ticks = (dt.GetValue() / 1000).ToLong();
2571 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
2572 if ( ticks == d.gmticks )
2573 {
2574 puts(" (ok)");
2575 }
2576 else
2577 {
2578 printf(" (ERROR: should be %ld, delta = %ld)\n",
2579 d.gmticks, ticks - d.gmticks);
2580 }
2581 }
2582
2583 puts("");
2584 }
2585
2586 // test conversions to JDN &c
2587 static void TestTimeJDN()
2588 {
2589 puts("\n*** wxDateTime to JDN test ***");
2590
2591 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
2592 {
2593 const Date& d = testDates[n];
2594 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
2595 double jdn = dt.GetJulianDayNumber();
2596
2597 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
2598 if ( jdn == d.jdn )
2599 {
2600 puts(" (ok)");
2601 }
2602 else
2603 {
2604 printf(" (ERROR: should be %f, delta = %f)\n",
2605 d.jdn, jdn - d.jdn);
2606 }
2607 }
2608 }
2609
2610 // test week days computation
2611 static void TestTimeWDays()
2612 {
2613 puts("\n*** wxDateTime weekday test ***");
2614
2615 // test GetWeekDay()
2616 size_t n;
2617 for ( n = 0; n < WXSIZEOF(testDates); n++ )
2618 {
2619 const Date& d = testDates[n];
2620 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
2621
2622 wxDateTime::WeekDay wday = dt.GetWeekDay();
2623 printf("%s is: %s",
2624 d.Format().c_str(),
2625 wxDateTime::GetWeekDayName(wday).c_str());
2626 if ( wday == d.wday )
2627 {
2628 puts(" (ok)");
2629 }
2630 else
2631 {
2632 printf(" (ERROR: should be %s)\n",
2633 wxDateTime::GetWeekDayName(d.wday).c_str());
2634 }
2635 }
2636
2637 puts("");
2638
2639 // test SetToWeekDay()
2640 struct WeekDateTestData
2641 {
2642 Date date; // the real date (precomputed)
2643 int nWeek; // its week index in the month
2644 wxDateTime::WeekDay wday; // the weekday
2645 wxDateTime::Month month; // the month
2646 int year; // and the year
2647
2648 wxString Format() const
2649 {
2650 wxString s, which;
2651 switch ( nWeek < -1 ? -nWeek : nWeek )
2652 {
2653 case 1: which = "first"; break;
2654 case 2: which = "second"; break;
2655 case 3: which = "third"; break;
2656 case 4: which = "fourth"; break;
2657 case 5: which = "fifth"; break;
2658
2659 case -1: which = "last"; break;
2660 }
2661
2662 if ( nWeek < -1 )
2663 {
2664 which += " from end";
2665 }
2666
2667 s.Printf("The %s %s of %s in %d",
2668 which.c_str(),
2669 wxDateTime::GetWeekDayName(wday).c_str(),
2670 wxDateTime::GetMonthName(month).c_str(),
2671 year);
2672
2673 return s;
2674 }
2675 };
2676
2677 // the array data was generated by the following python program
2678 /*
2679 from DateTime import *
2680 from whrandom import *
2681 from string import *
2682
2683 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
2684 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
2685
2686 week = DateTimeDelta(7)
2687
2688 for n in range(20):
2689 year = randint(1900, 2100)
2690 month = randint(1, 12)
2691 day = randint(1, 28)
2692 dt = DateTime(year, month, day)
2693 wday = dt.day_of_week
2694
2695 countFromEnd = choice([-1, 1])
2696 weekNum = 0;
2697
2698 while dt.month is month:
2699 dt = dt - countFromEnd * week
2700 weekNum = weekNum + countFromEnd
2701
2702 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
2703
2704 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
2705 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
2706 */
2707
2708 static const WeekDateTestData weekDatesTestData[] =
2709 {
2710 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
2711 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
2712 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
2713 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
2714 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
2715 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
2716 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
2717 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
2718 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
2719 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
2720 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
2721 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
2722 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
2723 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
2724 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
2725 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
2726 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
2727 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
2728 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
2729 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
2730 };
2731
2732 static const char *fmt = "%d-%b-%Y";
2733
2734 wxDateTime dt;
2735 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
2736 {
2737 const WeekDateTestData& wd = weekDatesTestData[n];
2738
2739 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
2740
2741 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
2742
2743 const Date& d = wd.date;
2744 if ( d.SameDay(dt.GetTm()) )
2745 {
2746 puts(" (ok)");
2747 }
2748 else
2749 {
2750 dt.Set(d.day, d.month, d.year);
2751
2752 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
2753 }
2754 }
2755 }
2756
2757 // test the computation of (ISO) week numbers
2758 static void TestTimeWNumber()
2759 {
2760 puts("\n*** wxDateTime week number test ***");
2761
2762 struct WeekNumberTestData
2763 {
2764 Date date; // the date
2765 wxDateTime::wxDateTime_t week; // the week number in the year
2766 wxDateTime::wxDateTime_t wmon; // the week number in the month
2767 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
2768 wxDateTime::wxDateTime_t dnum; // day number in the year
2769 };
2770
2771 // data generated with the following python script:
2772 /*
2773 from DateTime import *
2774 from whrandom import *
2775 from string import *
2776
2777 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
2778 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
2779
2780 def GetMonthWeek(dt):
2781 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
2782 if weekNumMonth < 0:
2783 weekNumMonth = weekNumMonth + 53
2784 return weekNumMonth
2785
2786 def GetLastSundayBefore(dt):
2787 if dt.iso_week[2] == 7:
2788 return dt
2789 else:
2790 return dt - DateTimeDelta(dt.iso_week[2])
2791
2792 for n in range(20):
2793 year = randint(1900, 2100)
2794 month = randint(1, 12)
2795 day = randint(1, 28)
2796 dt = DateTime(year, month, day)
2797 dayNum = dt.day_of_year
2798 weekNum = dt.iso_week[1]
2799 weekNumMonth = GetMonthWeek(dt)
2800
2801 weekNumMonth2 = 0
2802 dtSunday = GetLastSundayBefore(dt)
2803
2804 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
2805 weekNumMonth2 = weekNumMonth2 + 1
2806 dtSunday = dtSunday - DateTimeDelta(7)
2807
2808 data = { 'day': rjust(`day`, 2), \
2809 'month': monthNames[month - 1], \
2810 'year': year, \
2811 'weekNum': rjust(`weekNum`, 2), \
2812 'weekNumMonth': weekNumMonth, \
2813 'weekNumMonth2': weekNumMonth2, \
2814 'dayNum': rjust(`dayNum`, 3) }
2815
2816 print " { { %(day)s, "\
2817 "wxDateTime::%(month)s, "\
2818 "%(year)d }, "\
2819 "%(weekNum)s, "\
2820 "%(weekNumMonth)s, "\
2821 "%(weekNumMonth2)s, "\
2822 "%(dayNum)s }," % data
2823
2824 */
2825 static const WeekNumberTestData weekNumberTestDates[] =
2826 {
2827 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
2828 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
2829 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
2830 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
2831 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
2832 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
2833 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
2834 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
2835 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
2836 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
2837 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
2838 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
2839 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
2840 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
2841 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
2842 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
2843 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
2844 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
2845 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
2846 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
2847 };
2848
2849 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
2850 {
2851 const WeekNumberTestData& wn = weekNumberTestDates[n];
2852 const Date& d = wn.date;
2853
2854 wxDateTime dt = d.DT();
2855
2856 wxDateTime::wxDateTime_t
2857 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
2858 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
2859 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
2860 dnum = dt.GetDayOfYear();
2861
2862 printf("%s: the day number is %d",
2863 d.FormatDate().c_str(), dnum);
2864 if ( dnum == wn.dnum )
2865 {
2866 printf(" (ok)");
2867 }
2868 else
2869 {
2870 printf(" (ERROR: should be %d)", wn.dnum);
2871 }
2872
2873 printf(", week in month is %d", wmon);
2874 if ( wmon == wn.wmon )
2875 {
2876 printf(" (ok)");
2877 }
2878 else
2879 {
2880 printf(" (ERROR: should be %d)", wn.wmon);
2881 }
2882
2883 printf(" or %d", wmon2);
2884 if ( wmon2 == wn.wmon2 )
2885 {
2886 printf(" (ok)");
2887 }
2888 else
2889 {
2890 printf(" (ERROR: should be %d)", wn.wmon2);
2891 }
2892
2893 printf(", week in year is %d", week);
2894 if ( week == wn.week )
2895 {
2896 puts(" (ok)");
2897 }
2898 else
2899 {
2900 printf(" (ERROR: should be %d)\n", wn.week);
2901 }
2902 }
2903 }
2904
2905 // test DST calculations
2906 static void TestTimeDST()
2907 {
2908 puts("\n*** wxDateTime DST test ***");
2909
2910 printf("DST is%s in effect now.\n\n",
2911 wxDateTime::Now().IsDST() ? "" : " not");
2912
2913 // taken from http://www.energy.ca.gov/daylightsaving.html
2914 static const Date datesDST[2][2004 - 1900 + 1] =
2915 {
2916 {
2917 { 1, wxDateTime::Apr, 1990 },
2918 { 7, wxDateTime::Apr, 1991 },
2919 { 5, wxDateTime::Apr, 1992 },
2920 { 4, wxDateTime::Apr, 1993 },
2921 { 3, wxDateTime::Apr, 1994 },
2922 { 2, wxDateTime::Apr, 1995 },
2923 { 7, wxDateTime::Apr, 1996 },
2924 { 6, wxDateTime::Apr, 1997 },
2925 { 5, wxDateTime::Apr, 1998 },
2926 { 4, wxDateTime::Apr, 1999 },
2927 { 2, wxDateTime::Apr, 2000 },
2928 { 1, wxDateTime::Apr, 2001 },
2929 { 7, wxDateTime::Apr, 2002 },
2930 { 6, wxDateTime::Apr, 2003 },
2931 { 4, wxDateTime::Apr, 2004 },
2932 },
2933 {
2934 { 28, wxDateTime::Oct, 1990 },
2935 { 27, wxDateTime::Oct, 1991 },
2936 { 25, wxDateTime::Oct, 1992 },
2937 { 31, wxDateTime::Oct, 1993 },
2938 { 30, wxDateTime::Oct, 1994 },
2939 { 29, wxDateTime::Oct, 1995 },
2940 { 27, wxDateTime::Oct, 1996 },
2941 { 26, wxDateTime::Oct, 1997 },
2942 { 25, wxDateTime::Oct, 1998 },
2943 { 31, wxDateTime::Oct, 1999 },
2944 { 29, wxDateTime::Oct, 2000 },
2945 { 28, wxDateTime::Oct, 2001 },
2946 { 27, wxDateTime::Oct, 2002 },
2947 { 26, wxDateTime::Oct, 2003 },
2948 { 31, wxDateTime::Oct, 2004 },
2949 }
2950 };
2951
2952 int year;
2953 for ( year = 1990; year < 2005; year++ )
2954 {
2955 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
2956 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
2957
2958 printf("DST period in the US for year %d: from %s to %s",
2959 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
2960
2961 size_t n = year - 1990;
2962 const Date& dBegin = datesDST[0][n];
2963 const Date& dEnd = datesDST[1][n];
2964
2965 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
2966 {
2967 puts(" (ok)");
2968 }
2969 else
2970 {
2971 printf(" (ERROR: should be %s %d to %s %d)\n",
2972 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
2973 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
2974 }
2975 }
2976
2977 puts("");
2978
2979 for ( year = 1990; year < 2005; year++ )
2980 {
2981 printf("DST period in Europe for year %d: from %s to %s\n",
2982 year,
2983 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
2984 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
2985 }
2986 }
2987
2988 // test wxDateTime -> text conversion
2989 static void TestTimeFormat()
2990 {
2991 puts("\n*** wxDateTime formatting test ***");
2992
2993 // some information may be lost during conversion, so store what kind
2994 // of info should we recover after a round trip
2995 enum CompareKind
2996 {
2997 CompareNone, // don't try comparing
2998 CompareBoth, // dates and times should be identical
2999 CompareDate, // dates only
3000 CompareTime // time only
3001 };
3002
3003 static const struct
3004 {
3005 CompareKind compareKind;
3006 const char *format;
3007 } formatTestFormats[] =
3008 {
3009 { CompareBoth, "---> %c" },
3010 { CompareDate, "Date is %A, %d of %B, in year %Y" },
3011 { CompareBoth, "Date is %x, time is %X" },
3012 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
3013 { CompareNone, "The day of year: %j, the week of year: %W" },
3014 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
3015 };
3016
3017 static const Date formatTestDates[] =
3018 {
3019 { 29, wxDateTime::May, 1976, 18, 30, 00 },
3020 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
3021 #if 0
3022 // this test can't work for other centuries because it uses two digit
3023 // years in formats, so don't even try it
3024 { 29, wxDateTime::May, 2076, 18, 30, 00 },
3025 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
3026 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
3027 #endif
3028 };
3029
3030 // an extra test (as it doesn't depend on date, don't do it in the loop)
3031 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
3032
3033 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
3034 {
3035 puts("");
3036
3037 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
3038 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
3039 {
3040 wxString s = dt.Format(formatTestFormats[n].format);
3041 printf("%s", s.c_str());
3042
3043 // what can we recover?
3044 int kind = formatTestFormats[n].compareKind;
3045
3046 // convert back
3047 wxDateTime dt2;
3048 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
3049 if ( !result )
3050 {
3051 // converion failed - should it have?
3052 if ( kind == CompareNone )
3053 puts(" (ok)");
3054 else
3055 puts(" (ERROR: conversion back failed)");
3056 }
3057 else if ( *result )
3058 {
3059 // should have parsed the entire string
3060 puts(" (ERROR: conversion back stopped too soon)");
3061 }
3062 else
3063 {
3064 bool equal = FALSE; // suppress compilaer warning
3065 switch ( kind )
3066 {
3067 case CompareBoth:
3068 equal = dt2 == dt;
3069 break;
3070
3071 case CompareDate:
3072 equal = dt.IsSameDate(dt2);
3073 break;
3074
3075 case CompareTime:
3076 equal = dt.IsSameTime(dt2);
3077 break;
3078 }
3079
3080 if ( !equal )
3081 {
3082 printf(" (ERROR: got back '%s' instead of '%s')\n",
3083 dt2.Format().c_str(), dt.Format().c_str());
3084 }
3085 else
3086 {
3087 puts(" (ok)");
3088 }
3089 }
3090 }
3091 }
3092 }
3093
3094 // test text -> wxDateTime conversion
3095 static void TestTimeParse()
3096 {
3097 puts("\n*** wxDateTime parse test ***");
3098
3099 struct ParseTestData
3100 {
3101 const char *format;
3102 Date date;
3103 bool good;
3104 };
3105
3106 static const ParseTestData parseTestDates[] =
3107 {
3108 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
3109 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
3110 };
3111
3112 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
3113 {
3114 const char *format = parseTestDates[n].format;
3115
3116 printf("%s => ", format);
3117
3118 wxDateTime dt;
3119 if ( dt.ParseRfc822Date(format) )
3120 {
3121 printf("%s ", dt.Format().c_str());
3122
3123 if ( parseTestDates[n].good )
3124 {
3125 wxDateTime dtReal = parseTestDates[n].date.DT();
3126 if ( dt == dtReal )
3127 {
3128 puts("(ok)");
3129 }
3130 else
3131 {
3132 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
3133 }
3134 }
3135 else
3136 {
3137 puts("(ERROR: bad format)");
3138 }
3139 }
3140 else
3141 {
3142 printf("bad format (%s)\n",
3143 parseTestDates[n].good ? "ERROR" : "ok");
3144 }
3145 }
3146 }
3147
3148 static void TestDateTimeInteractive()
3149 {
3150 puts("\n*** interactive wxDateTime tests ***");
3151
3152 char buf[128];
3153
3154 for ( ;; )
3155 {
3156 printf("Enter a date: ");
3157 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
3158 break;
3159
3160 // kill the last '\n'
3161 buf[strlen(buf) - 1] = 0;
3162
3163 wxDateTime dt;
3164 const char *p = dt.ParseDate(buf);
3165 if ( !p )
3166 {
3167 printf("ERROR: failed to parse the date '%s'.\n", buf);
3168
3169 continue;
3170 }
3171 else if ( *p )
3172 {
3173 printf("WARNING: parsed only first %u characters.\n", p - buf);
3174 }
3175
3176 printf("%s: day %u, week of month %u/%u, week of year %u\n",
3177 dt.Format("%b %d, %Y").c_str(),
3178 dt.GetDayOfYear(),
3179 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3180 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3181 dt.GetWeekOfYear(wxDateTime::Monday_First));
3182 }
3183
3184 puts("\n*** done ***");
3185 }
3186
3187 static void TestTimeMS()
3188 {
3189 puts("*** testing millisecond-resolution support in wxDateTime ***");
3190
3191 wxDateTime dt1 = wxDateTime::Now(),
3192 dt2 = wxDateTime::UNow();
3193
3194 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
3195 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3196 printf("Dummy loop: ");
3197 for ( int i = 0; i < 6000; i++ )
3198 {
3199 //for ( int j = 0; j < 10; j++ )
3200 {
3201 wxString s;
3202 s.Printf("%g", sqrt(i));
3203 }
3204
3205 if ( !(i % 100) )
3206 putchar('.');
3207 }
3208 puts(", done");
3209
3210 dt1 = dt2;
3211 dt2 = wxDateTime::UNow();
3212 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3213
3214 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
3215
3216 puts("\n*** done ***");
3217 }
3218
3219 static void TestTimeArithmetics()
3220 {
3221 puts("\n*** testing arithmetic operations on wxDateTime ***");
3222
3223 static const struct ArithmData
3224 {
3225 ArithmData(const wxDateSpan& sp, const char *nam)
3226 : span(sp), name(nam) { }
3227
3228 wxDateSpan span;
3229 const char *name;
3230 } testArithmData[] =
3231 {
3232 ArithmData(wxDateSpan::Day(), "day"),
3233 ArithmData(wxDateSpan::Week(), "week"),
3234 ArithmData(wxDateSpan::Month(), "month"),
3235 ArithmData(wxDateSpan::Year(), "year"),
3236 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
3237 };
3238
3239 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
3240
3241 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
3242 {
3243 wxDateSpan span = testArithmData[n].span;
3244 dt1 = dt + span;
3245 dt2 = dt - span;
3246
3247 const char *name = testArithmData[n].name;
3248 printf("%s + %s = %s, %s - %s = %s\n",
3249 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
3250 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
3251
3252 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
3253 if ( dt1 - span == dt )
3254 {
3255 puts(" (ok)");
3256 }
3257 else
3258 {
3259 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3260 }
3261
3262 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
3263 if ( dt2 + span == dt )
3264 {
3265 puts(" (ok)");
3266 }
3267 else
3268 {
3269 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3270 }
3271
3272 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
3273 if ( dt2 + 2*span == dt1 )
3274 {
3275 puts(" (ok)");
3276 }
3277 else
3278 {
3279 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
3280 }
3281
3282 puts("");
3283 }
3284 }
3285
3286 static void TestTimeHolidays()
3287 {
3288 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
3289
3290 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3291 wxDateTime dtStart(1, tm.mon, tm.year),
3292 dtEnd = dtStart.GetLastMonthDay();
3293
3294 wxDateTimeArray hol;
3295 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3296
3297 const wxChar *format = "%d-%b-%Y (%a)";
3298
3299 printf("All holidays between %s and %s:\n",
3300 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
3301
3302 size_t count = hol.GetCount();
3303 for ( size_t n = 0; n < count; n++ )
3304 {
3305 printf("\t%s\n", hol[n].Format(format).c_str());
3306 }
3307
3308 puts("");
3309 }
3310
3311 static void TestTimeZoneBug()
3312 {
3313 puts("\n*** testing for DST/timezone bug ***\n");
3314
3315 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
3316 for ( int i = 0; i < 31; i++ )
3317 {
3318 printf("Date %s: week day %s.\n",
3319 date.Format(_T("%d-%m-%Y")).c_str(),
3320 date.GetWeekDayName(date.GetWeekDay()).c_str());
3321
3322 date += wxDateSpan::Day();
3323 }
3324
3325 puts("");
3326 }
3327
3328 #if 0
3329
3330 // test compatibility with the old wxDate/wxTime classes
3331 static void TestTimeCompatibility()
3332 {
3333 puts("\n*** wxDateTime compatibility test ***");
3334
3335 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
3336 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
3337
3338 double jdnNow = wxDateTime::Now().GetJDN();
3339 long jdnMidnight = (long)(jdnNow - 0.5);
3340 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
3341
3342 jdnMidnight = wxDate().Set().GetJulianDate();
3343 printf("wxDateTime for today: %s\n",
3344 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
3345
3346 int flags = wxEUROPEAN;//wxFULL;
3347 wxDate date;
3348 date.Set();
3349 printf("Today is %s\n", date.FormatDate(flags).c_str());
3350 for ( int n = 0; n < 7; n++ )
3351 {
3352 printf("Previous %s is %s\n",
3353 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
3354 date.Previous(n + 1).FormatDate(flags).c_str());
3355 }
3356 }
3357
3358 #endif // 0
3359
3360 #endif // TEST_DATETIME
3361
3362 // ----------------------------------------------------------------------------
3363 // threads
3364 // ----------------------------------------------------------------------------
3365
3366 #ifdef TEST_THREADS
3367
3368 #include <wx/thread.h>
3369
3370 static size_t gs_counter = (size_t)-1;
3371 static wxCriticalSection gs_critsect;
3372 static wxCondition gs_cond;
3373
3374 class MyJoinableThread : public wxThread
3375 {
3376 public:
3377 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3378 { m_n = n; Create(); }
3379
3380 // thread execution starts here
3381 virtual ExitCode Entry();
3382
3383 private:
3384 size_t m_n;
3385 };
3386
3387 wxThread::ExitCode MyJoinableThread::Entry()
3388 {
3389 unsigned long res = 1;
3390 for ( size_t n = 1; n < m_n; n++ )
3391 {
3392 res *= n;
3393
3394 // it's a loooong calculation :-)
3395 Sleep(100);
3396 }
3397
3398 return (ExitCode)res;
3399 }
3400
3401 class MyDetachedThread : public wxThread
3402 {
3403 public:
3404 MyDetachedThread(size_t n, char ch)
3405 {
3406 m_n = n;
3407 m_ch = ch;
3408 m_cancelled = FALSE;
3409
3410 Create();
3411 }
3412
3413 // thread execution starts here
3414 virtual ExitCode Entry();
3415
3416 // and stops here
3417 virtual void OnExit();
3418
3419 private:
3420 size_t m_n; // number of characters to write
3421 char m_ch; // character to write
3422
3423 bool m_cancelled; // FALSE if we exit normally
3424 };
3425
3426 wxThread::ExitCode MyDetachedThread::Entry()
3427 {
3428 {
3429 wxCriticalSectionLocker lock(gs_critsect);
3430 if ( gs_counter == (size_t)-1 )
3431 gs_counter = 1;
3432 else
3433 gs_counter++;
3434 }
3435
3436 for ( size_t n = 0; n < m_n; n++ )
3437 {
3438 if ( TestDestroy() )
3439 {
3440 m_cancelled = TRUE;
3441
3442 break;
3443 }
3444
3445 putchar(m_ch);
3446 fflush(stdout);
3447
3448 wxThread::Sleep(100);
3449 }
3450
3451 return 0;
3452 }
3453
3454 void MyDetachedThread::OnExit()
3455 {
3456 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
3457
3458 wxCriticalSectionLocker lock(gs_critsect);
3459 if ( !--gs_counter && !m_cancelled )
3460 gs_cond.Signal();
3461 }
3462
3463 void TestDetachedThreads()
3464 {
3465 puts("\n*** Testing detached threads ***");
3466
3467 static const size_t nThreads = 3;
3468 MyDetachedThread *threads[nThreads];
3469 size_t n;
3470 for ( n = 0; n < nThreads; n++ )
3471 {
3472 threads[n] = new MyDetachedThread(10, 'A' + n);
3473 }
3474
3475 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3476 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3477
3478 for ( n = 0; n < nThreads; n++ )
3479 {
3480 threads[n]->Run();
3481 }
3482
3483 // wait until all threads terminate
3484 gs_cond.Wait();
3485
3486 puts("");
3487 }
3488
3489 void TestJoinableThreads()
3490 {
3491 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
3492
3493 // calc 10! in the background
3494 MyJoinableThread thread(10);
3495 thread.Run();
3496
3497 printf("\nThread terminated with exit code %lu.\n",
3498 (unsigned long)thread.Wait());
3499 }
3500
3501 void TestThreadSuspend()
3502 {
3503 puts("\n*** Testing thread suspend/resume functions ***");
3504
3505 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3506
3507 thread->Run();
3508
3509 // this is for this demo only, in a real life program we'd use another
3510 // condition variable which would be signaled from wxThread::Entry() to
3511 // tell us that the thread really started running - but here just wait a
3512 // bit and hope that it will be enough (the problem is, of course, that
3513 // the thread might still not run when we call Pause() which will result
3514 // in an error)
3515 wxThread::Sleep(300);
3516
3517 for ( size_t n = 0; n < 3; n++ )
3518 {
3519 thread->Pause();
3520
3521 puts("\nThread suspended");
3522 if ( n > 0 )
3523 {
3524 // don't sleep but resume immediately the first time
3525 wxThread::Sleep(300);
3526 }
3527 puts("Going to resume the thread");
3528
3529 thread->Resume();
3530 }
3531
3532 puts("Waiting until it terminates now");
3533
3534 // wait until the thread terminates
3535 gs_cond.Wait();
3536
3537 puts("");
3538 }
3539
3540 void TestThreadDelete()
3541 {
3542 // As above, using Sleep() is only for testing here - we must use some
3543 // synchronisation object instead to ensure that the thread is still
3544 // running when we delete it - deleting a detached thread which already
3545 // terminated will lead to a crash!
3546
3547 puts("\n*** Testing thread delete function ***");
3548
3549 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
3550
3551 thread0->Delete();
3552
3553 puts("\nDeleted a thread which didn't start to run yet.");
3554
3555 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
3556
3557 thread1->Run();
3558
3559 wxThread::Sleep(300);
3560
3561 thread1->Delete();
3562
3563 puts("\nDeleted a running thread.");
3564
3565 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
3566
3567 thread2->Run();
3568
3569 wxThread::Sleep(300);
3570
3571 thread2->Pause();
3572
3573 thread2->Delete();
3574
3575 puts("\nDeleted a sleeping thread.");
3576
3577 MyJoinableThread thread3(20);
3578 thread3.Run();
3579
3580 thread3.Delete();
3581
3582 puts("\nDeleted a joinable thread.");
3583
3584 MyJoinableThread thread4(2);
3585 thread4.Run();
3586
3587 wxThread::Sleep(300);
3588
3589 thread4.Delete();
3590
3591 puts("\nDeleted a joinable thread which already terminated.");
3592
3593 puts("");
3594 }
3595
3596 #endif // TEST_THREADS
3597
3598 // ----------------------------------------------------------------------------
3599 // arrays
3600 // ----------------------------------------------------------------------------
3601
3602 #ifdef TEST_ARRAYS
3603
3604 static void PrintArray(const char* name, const wxArrayString& array)
3605 {
3606 printf("Dump of the array '%s'\n", name);
3607
3608 size_t nCount = array.GetCount();
3609 for ( size_t n = 0; n < nCount; n++ )
3610 {
3611 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
3612 }
3613 }
3614
3615 static void PrintArray(const char* name, const wxArrayInt& array)
3616 {
3617 printf("Dump of the array '%s'\n", name);
3618
3619 size_t nCount = array.GetCount();
3620 for ( size_t n = 0; n < nCount; n++ )
3621 {
3622 printf("\t%s[%u] = %d\n", name, n, array[n]);
3623 }
3624 }
3625
3626 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
3627 const wxString& second)
3628 {
3629 return first.length() - second.length();
3630 }
3631
3632 int wxCMPFUNC_CONV IntCompare(int *first,
3633 int *second)
3634 {
3635 return *first - *second;
3636 }
3637
3638 int wxCMPFUNC_CONV IntRevCompare(int *first,
3639 int *second)
3640 {
3641 return *second - *first;
3642 }
3643
3644 static void TestArrayOfInts()
3645 {
3646 puts("*** Testing wxArrayInt ***\n");
3647
3648 wxArrayInt a;
3649 a.Add(1);
3650 a.Add(17);
3651 a.Add(5);
3652 a.Add(3);
3653
3654 puts("Initially:");
3655 PrintArray("a", a);
3656
3657 puts("After sort:");
3658 a.Sort(IntCompare);
3659 PrintArray("a", a);
3660
3661 puts("After reverse sort:");
3662 a.Sort(IntRevCompare);
3663 PrintArray("a", a);
3664 }
3665
3666 #include "wx/dynarray.h"
3667
3668 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
3669 #include "wx/arrimpl.cpp"
3670 WX_DEFINE_OBJARRAY(ArrayBars);
3671
3672 static void TestArrayOfObjects()
3673 {
3674 puts("*** Testing wxObjArray ***\n");
3675
3676 {
3677 ArrayBars bars;
3678 Bar bar("second bar");
3679
3680 printf("Initially: %u objects in the array, %u objects total.\n",
3681 bars.GetCount(), Bar::GetNumber());
3682
3683 bars.Add(new Bar("first bar"));
3684 bars.Add(bar);
3685
3686 printf("Now: %u objects in the array, %u objects total.\n",
3687 bars.GetCount(), Bar::GetNumber());
3688
3689 bars.Empty();
3690
3691 printf("After Empty(): %u objects in the array, %u objects total.\n",
3692 bars.GetCount(), Bar::GetNumber());
3693 }
3694
3695 printf("Finally: no more objects in the array, %u objects total.\n",
3696 Bar::GetNumber());
3697 }
3698
3699 #endif // TEST_ARRAYS
3700
3701 // ----------------------------------------------------------------------------
3702 // strings
3703 // ----------------------------------------------------------------------------
3704
3705 #ifdef TEST_STRINGS
3706
3707 #include "wx/timer.h"
3708 #include "wx/tokenzr.h"
3709
3710 static void TestStringConstruction()
3711 {
3712 puts("*** Testing wxString constructores ***");
3713
3714 #define TEST_CTOR(args, res) \
3715 { \
3716 wxString s args ; \
3717 printf("wxString%s = %s ", #args, s.c_str()); \
3718 if ( s == res ) \
3719 { \
3720 puts("(ok)"); \
3721 } \
3722 else \
3723 { \
3724 printf("(ERROR: should be %s)\n", res); \
3725 } \
3726 }
3727
3728 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
3729 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
3730 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
3731 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
3732
3733 static const wxChar *s = _T("?really!");
3734 const wxChar *start = wxStrchr(s, _T('r'));
3735 const wxChar *end = wxStrchr(s, _T('!'));
3736 TEST_CTOR((start, end), _T("really"));
3737
3738 puts("");
3739 }
3740
3741 static void TestString()
3742 {
3743 wxStopWatch sw;
3744
3745 wxString a, b, c;
3746
3747 a.reserve (128);
3748 b.reserve (128);
3749 c.reserve (128);
3750
3751 for (int i = 0; i < 1000000; ++i)
3752 {
3753 a = "Hello";
3754 b = " world";
3755 c = "! How'ya doin'?";
3756 a += b;
3757 a += c;
3758 c = "Hello world! What's up?";
3759 if (c != a)
3760 c = "Doh!";
3761 }
3762
3763 printf ("TestString elapsed time: %ld\n", sw.Time());
3764 }
3765
3766 static void TestPChar()
3767 {
3768 wxStopWatch sw;
3769
3770 char a [128];
3771 char b [128];
3772 char c [128];
3773
3774 for (int i = 0; i < 1000000; ++i)
3775 {
3776 strcpy (a, "Hello");
3777 strcpy (b, " world");
3778 strcpy (c, "! How'ya doin'?");
3779 strcat (a, b);
3780 strcat (a, c);
3781 strcpy (c, "Hello world! What's up?");
3782 if (strcmp (c, a) == 0)
3783 strcpy (c, "Doh!");
3784 }
3785
3786 printf ("TestPChar elapsed time: %ld\n", sw.Time());
3787 }
3788
3789 static void TestStringSub()
3790 {
3791 wxString s("Hello, world!");
3792
3793 puts("*** Testing wxString substring extraction ***");
3794
3795 printf("String = '%s'\n", s.c_str());
3796 printf("Left(5) = '%s'\n", s.Left(5).c_str());
3797 printf("Right(6) = '%s'\n", s.Right(6).c_str());
3798 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
3799 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
3800 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
3801 printf("substr(3) = '%s'\n", s.substr(3).c_str());
3802
3803 static const wxChar *prefixes[] =
3804 {
3805 _T("Hello"),
3806 _T("Hello, "),
3807 _T("Hello, world!"),
3808 _T("Hello, world!!!"),
3809 _T(""),
3810 _T("Goodbye"),
3811 _T("Hi"),
3812 };
3813
3814 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
3815 {
3816 wxString prefix = prefixes[n], rest;
3817 bool rc = s.StartsWith(prefix, &rest);
3818 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
3819 if ( rc )
3820 {
3821 printf(" (the rest is '%s')\n", rest.c_str());
3822 }
3823 else
3824 {
3825 putchar('\n');
3826 }
3827 }
3828
3829 puts("");
3830 }
3831
3832 static void TestStringFormat()
3833 {
3834 puts("*** Testing wxString formatting ***");
3835
3836 wxString s;
3837 s.Printf("%03d", 18);
3838
3839 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
3840 printf("Number 18: %s\n", s.c_str());
3841
3842 puts("");
3843 }
3844
3845 // returns "not found" for npos, value for all others
3846 static wxString PosToString(size_t res)
3847 {
3848 wxString s = res == wxString::npos ? wxString(_T("not found"))
3849 : wxString::Format(_T("%u"), res);
3850 return s;
3851 }
3852
3853 static void TestStringFind()
3854 {
3855 puts("*** Testing wxString find() functions ***");
3856
3857 static const wxChar *strToFind = _T("ell");
3858 static const struct StringFindTest
3859 {
3860 const wxChar *str;
3861 size_t start,
3862 result; // of searching "ell" in str
3863 } findTestData[] =
3864 {
3865 { _T("Well, hello world"), 0, 1 },
3866 { _T("Well, hello world"), 6, 7 },
3867 { _T("Well, hello world"), 9, wxString::npos },
3868 };
3869
3870 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
3871 {
3872 const StringFindTest& ft = findTestData[n];
3873 size_t res = wxString(ft.str).find(strToFind, ft.start);
3874
3875 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
3876 strToFind, ft.str, ft.start, PosToString(res).c_str());
3877
3878 size_t resTrue = ft.result;
3879 if ( res == resTrue )
3880 {
3881 puts(_T("(ok)"));
3882 }
3883 else
3884 {
3885 printf(_T("(ERROR: should be %s)\n"),
3886 PosToString(resTrue).c_str());
3887 }
3888 }
3889
3890 puts("");
3891 }
3892
3893 static void TestStringTokenizer()
3894 {
3895 puts("*** Testing wxStringTokenizer ***");
3896
3897 static const wxChar *modeNames[] =
3898 {
3899 _T("default"),
3900 _T("return empty"),
3901 _T("return all empty"),
3902 _T("with delims"),
3903 _T("like strtok"),
3904 };
3905
3906 static const struct StringTokenizerTest
3907 {
3908 const wxChar *str; // string to tokenize
3909 const wxChar *delims; // delimiters to use
3910 size_t count; // count of token
3911 wxStringTokenizerMode mode; // how should we tokenize it
3912 } tokenizerTestData[] =
3913 {
3914 { _T(""), _T(" "), 0 },
3915 { _T("Hello, world"), _T(" "), 2 },
3916 { _T("Hello, world "), _T(" "), 2 },
3917 { _T("Hello, world"), _T(","), 2 },
3918 { _T("Hello, world!"), _T(",!"), 2 },
3919 { _T("Hello,, world!"), _T(",!"), 3 },
3920 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
3921 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
3922 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
3923 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
3924 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
3925 { _T("01/02/99"), _T("/-"), 3 },
3926 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
3927 };
3928
3929 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
3930 {
3931 const StringTokenizerTest& tt = tokenizerTestData[n];
3932 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
3933
3934 size_t count = tkz.CountTokens();
3935 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
3936 MakePrintable(tt.str).c_str(),
3937 count,
3938 MakePrintable(tt.delims).c_str(),
3939 modeNames[tkz.GetMode()]);
3940 if ( count == tt.count )
3941 {
3942 puts(_T("(ok)"));
3943 }
3944 else
3945 {
3946 printf(_T("(ERROR: should be %u)\n"), tt.count);
3947
3948 continue;
3949 }
3950
3951 // if we emulate strtok(), check that we do it correctly
3952 wxChar *buf, *s = NULL, *last;
3953
3954 if ( tkz.GetMode() == wxTOKEN_STRTOK )
3955 {
3956 buf = new wxChar[wxStrlen(tt.str) + 1];
3957 wxStrcpy(buf, tt.str);
3958
3959 s = wxStrtok(buf, tt.delims, &last);
3960 }
3961 else
3962 {
3963 buf = NULL;
3964 }
3965
3966 // now show the tokens themselves
3967 size_t count2 = 0;
3968 while ( tkz.HasMoreTokens() )
3969 {
3970 wxString token = tkz.GetNextToken();
3971
3972 printf(_T("\ttoken %u: '%s'"),
3973 ++count2,
3974 MakePrintable(token).c_str());
3975
3976 if ( buf )
3977 {
3978 if ( token == s )
3979 {
3980 puts(" (ok)");
3981 }
3982 else
3983 {
3984 printf(" (ERROR: should be %s)\n", s);
3985 }
3986
3987 s = wxStrtok(NULL, tt.delims, &last);
3988 }
3989 else
3990 {
3991 // nothing to compare with
3992 puts("");
3993 }
3994 }
3995
3996 if ( count2 != count )
3997 {
3998 puts(_T("\tERROR: token count mismatch"));
3999 }
4000
4001 delete [] buf;
4002 }
4003
4004 puts("");
4005 }
4006
4007 static void TestStringReplace()
4008 {
4009 puts("*** Testing wxString::replace ***");
4010
4011 static const struct StringReplaceTestData
4012 {
4013 const wxChar *original; // original test string
4014 size_t start, len; // the part to replace
4015 const wxChar *replacement; // the replacement string
4016 const wxChar *result; // and the expected result
4017 } stringReplaceTestData[] =
4018 {
4019 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4020 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4021 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4022 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4023 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4024 };
4025
4026 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4027 {
4028 const StringReplaceTestData data = stringReplaceTestData[n];
4029
4030 wxString original = data.original;
4031 original.replace(data.start, data.len, data.replacement);
4032
4033 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4034 data.original, data.start, data.len, data.replacement,
4035 original.c_str());
4036
4037 if ( original == data.result )
4038 {
4039 puts("(ok)");
4040 }
4041 else
4042 {
4043 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4044 }
4045 }
4046
4047 puts("");
4048 }
4049
4050 #endif // TEST_STRINGS
4051
4052 // ----------------------------------------------------------------------------
4053 // entry point
4054 // ----------------------------------------------------------------------------
4055
4056 int main(int argc, char **argv)
4057 {
4058 if ( !wxInitialize() )
4059 {
4060 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
4061 }
4062
4063 #ifdef TEST_USLEEP
4064 puts("Sleeping for 3 seconds... z-z-z-z-z...");
4065 wxUsleep(3000);
4066 #endif // TEST_USLEEP
4067
4068 #ifdef TEST_CMDLINE
4069 static const wxCmdLineEntryDesc cmdLineDesc[] =
4070 {
4071 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4072 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4073
4074 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4075 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4076 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
4077 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
4078
4079 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4080 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4081
4082 { wxCMD_LINE_NONE }
4083 };
4084
4085 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4086
4087 parser.AddOption("project_name", "", "full path to project file",
4088 wxCMD_LINE_VAL_STRING,
4089 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4090
4091 switch ( parser.Parse() )
4092 {
4093 case -1:
4094 wxLogMessage("Help was given, terminating.");
4095 break;
4096
4097 case 0:
4098 ShowCmdLine(parser);
4099 break;
4100
4101 default:
4102 wxLogMessage("Syntax error detected, aborting.");
4103 break;
4104 }
4105 #endif // TEST_CMDLINE
4106
4107 #ifdef TEST_STRINGS
4108 if ( 0 )
4109 {
4110 TestPChar();
4111 TestString();
4112 }
4113 TestStringSub();
4114 if ( 0 )
4115 {
4116 TestStringConstruction();
4117 TestStringFormat();
4118 TestStringFind();
4119 TestStringTokenizer();
4120 TestStringReplace();
4121 }
4122 #endif // TEST_STRINGS
4123
4124 #ifdef TEST_ARRAYS
4125 if ( 0 )
4126 {
4127 wxArrayString a1;
4128 a1.Add("tiger");
4129 a1.Add("cat");
4130 a1.Add("lion");
4131 a1.Add("dog");
4132 a1.Add("human");
4133 a1.Add("ape");
4134
4135 puts("*** Initially:");
4136
4137 PrintArray("a1", a1);
4138
4139 wxArrayString a2(a1);
4140 PrintArray("a2", a2);
4141
4142 wxSortedArrayString a3(a1);
4143 PrintArray("a3", a3);
4144
4145 puts("*** After deleting a string from a1");
4146 a1.Remove(2);
4147
4148 PrintArray("a1", a1);
4149 PrintArray("a2", a2);
4150 PrintArray("a3", a3);
4151
4152 puts("*** After reassigning a1 to a2 and a3");
4153 a3 = a2 = a1;
4154 PrintArray("a2", a2);
4155 PrintArray("a3", a3);
4156
4157 puts("*** After sorting a1");
4158 a1.Sort();
4159 PrintArray("a1", a1);
4160
4161 puts("*** After sorting a1 in reverse order");
4162 a1.Sort(TRUE);
4163 PrintArray("a1", a1);
4164
4165 puts("*** After sorting a1 by the string length");
4166 a1.Sort(StringLenCompare);
4167 PrintArray("a1", a1);
4168
4169 TestArrayOfObjects();
4170 }
4171 TestArrayOfInts();
4172 #endif // TEST_ARRAYS
4173
4174 #ifdef TEST_DIR
4175 TestDirEnum();
4176 #endif // TEST_DIR
4177
4178 #ifdef TEST_DLLLOADER
4179 TestDllLoad();
4180 #endif // TEST_DLLLOADER
4181
4182 #ifdef TEST_ENVIRON
4183 TestEnvironment();
4184 #endif // TEST_ENVIRON
4185
4186 #ifdef TEST_EXECUTE
4187 TestExecute();
4188 #endif // TEST_EXECUTE
4189
4190 #ifdef TEST_FILECONF
4191 TestFileConfRead();
4192 #endif // TEST_FILECONF
4193
4194 #ifdef TEST_LIST
4195 TestListCtor();
4196 #endif // TEST_LIST
4197
4198 #ifdef TEST_LOG
4199 wxString s;
4200 for ( size_t n = 0; n < 8000; n++ )
4201 {
4202 s << (char)('A' + (n % 26));
4203 }
4204
4205 wxString msg;
4206 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
4207
4208 // this one shouldn't be truncated
4209 printf(msg);
4210
4211 // but this one will because log functions use fixed size buffer
4212 // (note that it doesn't need '\n' at the end neither - will be added
4213 // by wxLog anyhow)
4214 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
4215 #endif // TEST_LOG
4216
4217 #ifdef TEST_FILE
4218 if ( 0 )
4219 {
4220 TestFileRead();
4221 TestTextFileRead();
4222 }
4223 TestFileCopy();
4224 #endif // TEST_FILE
4225
4226 #ifdef TEST_FILENAME
4227 TestFileNameSplit();
4228 if ( 0 )
4229 {
4230 TestFileNameConstruction();
4231 TestFileNameCwd();
4232 TestFileNameComparison();
4233 TestFileNameOperations();
4234 }
4235 #endif // TEST_FILENAME
4236
4237 #ifdef TEST_THREADS
4238 int nCPUs = wxThread::GetCPUCount();
4239 printf("This system has %d CPUs\n", nCPUs);
4240 if ( nCPUs != -1 )
4241 wxThread::SetConcurrency(nCPUs);
4242
4243 if ( argc > 1 && argv[1][0] == 't' )
4244 wxLog::AddTraceMask("thread");
4245
4246 if ( 1 )
4247 TestDetachedThreads();
4248 if ( 1 )
4249 TestJoinableThreads();
4250 if ( 1 )
4251 TestThreadSuspend();
4252 if ( 1 )
4253 TestThreadDelete();
4254
4255 #endif // TEST_THREADS
4256
4257 #ifdef TEST_LONGLONG
4258 // seed pseudo random generator
4259 srand((unsigned)time(NULL));
4260
4261 if ( 0 )
4262 {
4263 TestSpeed();
4264 }
4265 if ( 0 )
4266 {
4267 TestMultiplication();
4268 TestDivision();
4269 TestAddition();
4270 TestLongLongConversion();
4271 TestBitOperations();
4272 }
4273 TestLongLongComparison();
4274 #endif // TEST_LONGLONG
4275
4276 #ifdef TEST_HASH
4277 TestHash();
4278 #endif // TEST_HASH
4279
4280 #ifdef TEST_MIME
4281 wxLog::AddTraceMask(_T("mime"));
4282 if ( 1 )
4283 {
4284 TestMimeEnum();
4285 TestMimeOverride();
4286 TestMimeFilename();
4287 }
4288 else
4289 TestMimeAssociate();
4290 #endif // TEST_MIME
4291
4292 #ifdef TEST_INFO_FUNCTIONS
4293 TestOsInfo();
4294 TestUserInfo();
4295 #endif // TEST_INFO_FUNCTIONS
4296
4297 #ifdef TEST_PATHLIST
4298 TestPathList();
4299 #endif // TEST_PATHLIST
4300
4301 #ifdef TEST_REGISTRY
4302 if ( 0 )
4303 TestRegistryRead();
4304 TestRegistryAssociation();
4305 #endif // TEST_REGISTRY
4306
4307 #ifdef TEST_SOCKETS
4308 if ( 0 )
4309 {
4310 TestSocketServer();
4311 }
4312 TestSocketClient();
4313 #endif // TEST_SOCKETS
4314
4315 #ifdef TEST_FTP
4316 wxLog::AddTraceMask(FTP_TRACE_MASK);
4317 if ( TestFtpConnect() )
4318 {
4319 TestFtpFileSize();
4320 if ( 0 )
4321 {
4322 TestFtpList();
4323 TestFtpDownload();
4324 TestFtpMisc();
4325 TestFtpUpload();
4326 }
4327 if ( 0 )
4328 TestFtpInteractive();
4329 }
4330 //else: connecting to the FTP server failed
4331
4332 if ( 0 )
4333 TestFtpWuFtpd();
4334 #endif // TEST_FTP
4335
4336 #ifdef TEST_STREAMS
4337 if ( 0 )
4338 TestFileStream();
4339 TestMemoryStream();
4340 #endif // TEST_STREAMS
4341
4342 #ifdef TEST_TIMER
4343 TestStopWatch();
4344 #endif // TEST_TIMER
4345
4346 #ifdef TEST_DATETIME
4347 if ( 1 )
4348 {
4349 TestTimeSet();
4350 TestTimeStatic();
4351 TestTimeRange();
4352 TestTimeZones();
4353 TestTimeTicks();
4354 TestTimeJDN();
4355 TestTimeDST();
4356 TestTimeWDays();
4357 TestTimeWNumber();
4358 TestTimeParse();
4359 TestTimeArithmetics();
4360 TestTimeHolidays();
4361 TestTimeFormat();
4362 TestTimeMS();
4363
4364 TestTimeZoneBug();
4365 }
4366 if ( 0 )
4367 TestDateTimeInteractive();
4368 #endif // TEST_DATETIME
4369
4370 #ifdef TEST_VCARD
4371 if ( 0 )
4372 TestVCardRead();
4373 TestVCardWrite();
4374 #endif // TEST_VCARD
4375
4376 #ifdef TEST_WCHAR
4377 TestUtf8();
4378 #endif // TEST_WCHAR
4379
4380 #ifdef TEST_ZIP
4381 TestZipStreamRead();
4382 #endif // TEST_ZIP
4383
4384 #ifdef TEST_ZLIB
4385 if ( 0 )
4386 TestZlibStreamWrite();
4387 TestZlibStreamRead();
4388 #endif // TEST_ZLIB
4389
4390 wxUninitialize();
4391
4392 return 0;
4393 }
4394