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