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