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