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