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