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