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