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