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