]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
backported fix for proper tree ctrl refershing after changing item colour/font from 2.2
[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
47//#define TEST_DATETIME
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
57//#define TEST_INFO_FUNCTIONS
58//#define TEST_LIST
59//#define TEST_LOCALE
60//#define TEST_LOG
61//#define TEST_LONGLONG
62//#define TEST_MIME
63//#define TEST_PATHLIST
64//#define TEST_REGCONF
07a56e45 65#define TEST_REGEX
9a4232dc
VZ
66//#define TEST_REGISTRY
67//#define TEST_SNGLINST
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
1367static void TestOsInfo()
1368{
1369 puts("*** Testing OS info functions ***\n");
1370
1371 int major, minor;
1372 wxGetOsVersion(&major, &minor);
1373 printf("Running under: %s, version %d.%d\n",
1374 wxGetOsDescription().c_str(), major, minor);
1375
bd3277fe 1376 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
89e60357
VZ
1377
1378 printf("Host name is %s (%s).\n",
1379 wxGetHostName().c_str(), wxGetFullHostName().c_str());
bd3277fe
VZ
1380
1381 puts("");
89e60357
VZ
1382}
1383
1384static void TestUserInfo()
1385{
1386 puts("*** Testing user info functions ***\n");
1387
1388 printf("User id is:\t%s\n", wxGetUserId().c_str());
1389 printf("User name is:\t%s\n", wxGetUserName().c_str());
1390 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
1391 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
bd3277fe
VZ
1392
1393 puts("");
89e60357
VZ
1394}
1395
1396#endif // TEST_INFO_FUNCTIONS
1397
b76b015e
VZ
1398// ----------------------------------------------------------------------------
1399// long long
1400// ----------------------------------------------------------------------------
1401
1402#ifdef TEST_LONGLONG
1403
1404#include <wx/longlong.h>
1405#include <wx/timer.h>
1406
2a310492
VZ
1407// make a 64 bit number from 4 16 bit ones
1408#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1409
1410// get a random 64 bit number
1411#define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1412
7d0bb74d 1413#if wxUSE_LONGLONG_WX
2a310492
VZ
1414inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
1415 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1416inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
1417 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
7d0bb74d 1418#endif // wxUSE_LONGLONG_WX
2a310492 1419
b76b015e
VZ
1420static void TestSpeed()
1421{
1422 static const long max = 100000000;
1423 long n;
9fc3ad34 1424
b76b015e
VZ
1425 {
1426 wxStopWatch sw;
1427
1428 long l = 0;
1429 for ( n = 0; n < max; n++ )
1430 {
1431 l += n;
1432 }
1433
1434 printf("Summing longs took %ld milliseconds.\n", sw.Time());
1435 }
1436
2ea24d9f 1437#if wxUSE_LONGLONG_NATIVE
b76b015e
VZ
1438 {
1439 wxStopWatch sw;
1440
2ea24d9f 1441 wxLongLong_t l = 0;
b76b015e
VZ
1442 for ( n = 0; n < max; n++ )
1443 {
1444 l += n;
1445 }
1446
2ea24d9f 1447 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
b76b015e 1448 }
2ea24d9f 1449#endif // wxUSE_LONGLONG_NATIVE
b76b015e
VZ
1450
1451 {
1452 wxStopWatch sw;
1453
1454 wxLongLong l;
1455 for ( n = 0; n < max; n++ )
1456 {
1457 l += n;
1458 }
1459
1460 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
1461 }
1462}
1463
2a310492 1464static void TestLongLongConversion()
b76b015e 1465{
2a310492
VZ
1466 puts("*** Testing wxLongLong conversions ***\n");
1467
1468 wxLongLong a;
1469 size_t nTested = 0;
1470 for ( size_t n = 0; n < 100000; n++ )
1471 {
1472 a = RAND_LL();
1473
1474#if wxUSE_LONGLONG_NATIVE
1475 wxLongLongNative b(a.GetHi(), a.GetLo());
5e6a0e83 1476
2a310492
VZ
1477 wxASSERT_MSG( a == b, "conversions failure" );
1478#else
1479 puts("Can't do it without native long long type, test skipped.");
b76b015e 1480
2a310492
VZ
1481 return;
1482#endif // wxUSE_LONGLONG_NATIVE
1483
1484 if ( !(nTested % 1000) )
1485 {
1486 putchar('.');
1487 fflush(stdout);
1488 }
1489
1490 nTested++;
1491 }
1492
1493 puts(" done!");
1494}
1495
1496static void TestMultiplication()
1497{
1498 puts("*** Testing wxLongLong multiplication ***\n");
1499
1500 wxLongLong a, b;
1501 size_t nTested = 0;
1502 for ( size_t n = 0; n < 100000; n++ )
1503 {
1504 a = RAND_LL();
1505 b = RAND_LL();
1506
1507#if wxUSE_LONGLONG_NATIVE
1508 wxLongLongNative aa(a.GetHi(), a.GetLo());
1509 wxLongLongNative bb(b.GetHi(), b.GetLo());
1510
1511 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
1512#else // !wxUSE_LONGLONG_NATIVE
1513 puts("Can't do it without native long long type, test skipped.");
1514
1515 return;
1516#endif // wxUSE_LONGLONG_NATIVE
1517
1518 if ( !(nTested % 1000) )
1519 {
1520 putchar('.');
1521 fflush(stdout);
1522 }
1523
1524 nTested++;
1525 }
1526
1527 puts(" done!");
1528}
1529
1530static void TestDivision()
1531{
1532 puts("*** Testing wxLongLong division ***\n");
2f02cb89 1533
2ea24d9f 1534 wxLongLong q, r;
2f02cb89 1535 size_t nTested = 0;
5e6a0e83 1536 for ( size_t n = 0; n < 100000; n++ )
2f02cb89
VZ
1537 {
1538 // get a random wxLongLong (shifting by 12 the MSB ensures that the
1539 // multiplication will not overflow)
1540 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
1541
2ea24d9f
VZ
1542 // get a random long (not wxLongLong for now) to divide it with
1543 long l = rand();
1544 q = ll / l;
1545 r = ll % l;
1546
2a310492
VZ
1547#if wxUSE_LONGLONG_NATIVE
1548 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1549
1550 wxLongLongNative p = m / l, s = m % l;
1551 wxASSERT_MSG( q == p && r == s, "division failure" );
1552#else // !wxUSE_LONGLONG_NATIVE
5e6a0e83 1553 // verify the result
2ea24d9f 1554 wxASSERT_MSG( ll == q*l + r, "division failure" );
2a310492 1555#endif // wxUSE_LONGLONG_NATIVE
2f02cb89 1556
5e6a0e83
VZ
1557 if ( !(nTested % 1000) )
1558 {
1559 putchar('.');
1560 fflush(stdout);
1561 }
1562
2f02cb89
VZ
1563 nTested++;
1564 }
1565
5e6a0e83 1566 puts(" done!");
2a310492 1567}
2f02cb89 1568
2a310492
VZ
1569static void TestAddition()
1570{
1571 puts("*** Testing wxLongLong addition ***\n");
1572
1573 wxLongLong a, b, c;
1574 size_t nTested = 0;
1575 for ( size_t n = 0; n < 100000; n++ )
1576 {
1577 a = RAND_LL();
1578 b = RAND_LL();
1579 c = a + b;
1580
1581#if wxUSE_LONGLONG_NATIVE
1582 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1583 wxLongLongNative(b.GetHi(), b.GetLo()),
7c968cee 1584 "addition failure" );
2a310492
VZ
1585#else // !wxUSE_LONGLONG_NATIVE
1586 wxASSERT_MSG( c - b == a, "addition failure" );
1587#endif // wxUSE_LONGLONG_NATIVE
1588
1589 if ( !(nTested % 1000) )
1590 {
1591 putchar('.');
1592 fflush(stdout);
1593 }
1594
1595 nTested++;
1596 }
1597
1598 puts(" done!");
b76b015e
VZ
1599}
1600
2a310492
VZ
1601static void TestBitOperations()
1602{
1603 puts("*** Testing wxLongLong bit operation ***\n");
1604
f6bcfd97 1605 wxLongLong ll;
2a310492
VZ
1606 size_t nTested = 0;
1607 for ( size_t n = 0; n < 100000; n++ )
1608 {
f6bcfd97 1609 ll = RAND_LL();
2a310492
VZ
1610
1611#if wxUSE_LONGLONG_NATIVE
1612 for ( size_t n = 0; n < 33; n++ )
1613 {
2a310492 1614 }
2a310492
VZ
1615#else // !wxUSE_LONGLONG_NATIVE
1616 puts("Can't do it without native long long type, test skipped.");
1617
1618 return;
1619#endif // wxUSE_LONGLONG_NATIVE
1620
1621 if ( !(nTested % 1000) )
1622 {
1623 putchar('.');
1624 fflush(stdout);
1625 }
1626
1627 nTested++;
1628 }
1629
1630 puts(" done!");
1631}
1632
f6bcfd97
BP
1633static void TestLongLongComparison()
1634{
2d3112ad 1635#if wxUSE_LONGLONG_WX
f6bcfd97
BP
1636 puts("*** Testing wxLongLong comparison ***\n");
1637
1638 static const long testLongs[] =
1639 {
1640 0,
1641 1,
1642 -1,
1643 LONG_MAX,
1644 LONG_MIN,
1645 0x1234,
1646 -0x1234
1647 };
1648
1649 static const long ls[2] =
1650 {
1651 0x1234,
1652 -0x1234,
1653 };
1654
1655 wxLongLongWx lls[2];
1656 lls[0] = ls[0];
1657 lls[1] = ls[1];
1658
1659 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
1660 {
1661 bool res;
1662
1663 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
1664 {
1665 res = lls[m] > testLongs[n];
1666 printf("0x%lx > 0x%lx is %s (%s)\n",
1667 ls[m], testLongs[n], res ? "true" : "false",
1668 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
1669
1670 res = lls[m] < testLongs[n];
1671 printf("0x%lx < 0x%lx is %s (%s)\n",
1672 ls[m], testLongs[n], res ? "true" : "false",
1673 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
1674
1675 res = lls[m] == testLongs[n];
1676 printf("0x%lx == 0x%lx is %s (%s)\n",
1677 ls[m], testLongs[n], res ? "true" : "false",
1678 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
1679 }
1680 }
2d3112ad 1681#endif // wxUSE_LONGLONG_WX
f6bcfd97
BP
1682}
1683
2a310492
VZ
1684#undef MAKE_LL
1685#undef RAND_LL
1686
b76b015e
VZ
1687#endif // TEST_LONGLONG
1688
39189b9d
VZ
1689// ----------------------------------------------------------------------------
1690// path list
1691// ----------------------------------------------------------------------------
1692
1693#ifdef TEST_PATHLIST
1694
1695static void TestPathList()
1696{
1697 puts("*** Testing wxPathList ***\n");
1698
1699 wxPathList pathlist;
1700 pathlist.AddEnvList("PATH");
1701 wxString path = pathlist.FindValidPath("ls");
1702 if ( path.empty() )
1703 {
1704 printf("ERROR: command not found in the path.\n");
1705 }
1706 else
1707 {
1708 printf("Command found in the path as '%s'.\n", path.c_str());
1709 }
1710}
1711
1712#endif // TEST_PATHLIST
1713
07a56e45
VZ
1714// ----------------------------------------------------------------------------
1715// regular expressions
1716// ----------------------------------------------------------------------------
1717
1718#ifdef TEST_REGEX
1719
1720#include <wx/regex.h>
1721
1722static void TestRegExCompile()
1723{
1724 wxPuts(_T("*** Testing RE compilation ***\n"));
1725
1726 static struct RegExCompTestData
1727 {
1728 const wxChar *pattern;
1729 bool correct;
1730 } regExCompTestData[] =
1731 {
1732 { _T("foo"), TRUE },
1733 { _T("foo("), FALSE },
1734 { _T("foo(bar"), FALSE },
1735 { _T("foo(bar)"), TRUE },
1736 { _T("foo["), FALSE },
1737 { _T("foo[bar"), FALSE },
1738 { _T("foo[bar]"), TRUE },
1739 { _T("foo{"), TRUE },
1740 { _T("foo{1"), FALSE },
1741 { _T("foo{bar"), TRUE },
1742 { _T("foo{1}"), TRUE },
1743 { _T("foo{1,2}"), TRUE },
1744 { _T("foo{bar}"), TRUE },
1745 { _T("foo*"), TRUE },
1746 { _T("foo**"), FALSE },
1747 { _T("foo+"), TRUE },
1748 { _T("foo++"), FALSE },
1749 { _T("foo?"), TRUE },
1750 { _T("foo??"), FALSE },
1751 { _T("foo?+"), FALSE },
1752 };
1753
1754 wxRegEx re;
1755 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
1756 {
1757 const RegExCompTestData& data = regExCompTestData[n];
1758 bool ok = re.Compile(data.pattern);
1759
1760 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
1761 data.pattern,
1762 ok ? _T("") : _T("not "),
1763 ok == data.correct ? _T("ok") : _T("ERROR"));
1764 }
1765}
1766
1767static void TestRegExMatch()
1768{
1769 wxPuts(_T("*** Testing RE matching ***\n"));
1770
1771 static struct RegExMatchTestData
1772 {
1773 const wxChar *pattern;
1774 const wxChar *text;
1775 bool correct;
1776 } regExMatchTestData[] =
1777 {
1778 { _T("foo"), _T("bar"), FALSE },
1779 { _T("foo"), _T("foobar"), TRUE },
1780 { _T("^foo"), _T("foobar"), TRUE },
1781 { _T("^foo"), _T("barfoo"), FALSE },
1782 { _T("bar$"), _T("barbar"), TRUE },
1783 { _T("bar$"), _T("barbar "), FALSE },
1784 };
1785
1786 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
1787 {
1788 const RegExMatchTestData& data = regExMatchTestData[n];
1789
1790 wxRegEx re(data.pattern);
1791 bool ok = re.Matches(data.text);
1792
1793 wxPrintf(_T("'%s' %s %s (%s)\n"),
1794 data.pattern,
1795 ok ? _T("matches") : _T("doesn't match"),
1796 data.text,
1797 ok == data.correct ? _T("ok") : _T("ERROR"));
1798 }
1799}
1800
1801static void TestRegExSubmatch()
1802{
1803 wxPuts(_T("*** Testing RE subexpressions ***\n"));
1804
1805 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
1806 if ( !re.IsValid() )
1807 {
1808 wxPuts(_T("ERROR: compilation failed."));
1809 return;
1810 }
1811
1812 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
1813
1814 if ( !re.Matches(text) )
1815 {
1816 wxPuts(_T("ERROR: match expected."));
1817 }
1818 else
1819 {
1820 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
1821
1822 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
1823 re.GetMatch(text, 3).c_str(),
1824 re.GetMatch(text, 2).c_str(),
1825 re.GetMatch(text, 4).c_str(),
1826 re.GetMatch(text, 1).c_str());
1827 }
1828}
1829
765624f7
VZ
1830static void TestRegExReplacement()
1831{
1832 wxPuts(_T("*** Testing RE replacement ***"));
1833
1834 static struct RegExReplTestData
1835 {
1836 const wxChar *text;
1837 const wxChar *repl;
1838 const wxChar *result;
1839 size_t count;
1840 } regExReplTestData[] =
1841 {
1842 { _T("foo123"), _T("bar"), _T("bar"), 1 },
1843 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
1844 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
1845 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
1846 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
1847 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
1848 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
1849 };
1850
1851 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
1852 wxRegEx re = pattern;
1853
1854 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
1855
1856 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
1857 {
1858 const RegExReplTestData& data = regExReplTestData[n];
1859
1860 wxString text = data.text;
1861 size_t nRepl = re.Replace(&text, data.repl);
1862
1863 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
1864 data.text, data.repl,
1865 nRepl, nRepl == 1 ? _T("") : _T("es"),
1866 text.c_str());
1867 if ( text == data.result && nRepl == data.count )
1868 {
1869 wxPuts(_T("ok)"));
1870 }
1871 else
1872 {
1873 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
1874 data.count, data.result);
1875 }
1876 }
1877}
1878
07a56e45
VZ
1879static void TestRegExInteractive()
1880{
1881 wxPuts(_T("*** Testing RE interactively ***"));
1882
1883 for ( ;; )
1884 {
1885 char pattern[128];
1886 printf("\nEnter a pattern: ");
1887 if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
1888 break;
1889
1890 // kill the last '\n'
1891 pattern[strlen(pattern) - 1] = 0;
1892
1893 wxRegEx re;
1894 if ( !re.Compile(pattern) )
1895 {
1896 continue;
1897 }
1898
1899 char text[128];
1900 for ( ;; )
1901 {
1902 printf("Enter text to match: ");
1903 if ( !fgets(text, WXSIZEOF(text), stdin) )
1904 break;
1905
1906 // kill the last '\n'
1907 text[strlen(text) - 1] = 0;
1908
1909 if ( !re.Matches(text) )
1910 {
1911 printf("No match.\n");
1912 }
1913 else
1914 {
1915 printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
1916
1917 size_t start, len;
1918 for ( size_t n = 1; ; n++ )
1919 {
1920 if ( !re.GetMatch(&start, &len, n) )
1921 {
1922 break;
1923 }
1924
1925 printf("Subexpr %u matched '%s'\n",
1926 n, wxString(text + start, len).c_str());
1927 }
1928 }
1929 }
1930 }
1931}
1932
1933#endif // TEST_REGEX
1934
6dfec4b8 1935// ----------------------------------------------------------------------------
7ba4fbeb 1936// registry and related stuff
6dfec4b8
VZ
1937// ----------------------------------------------------------------------------
1938
1939// this is for MSW only
1940#ifndef __WXMSW__
7ba4fbeb 1941 #undef TEST_REGCONF
6dfec4b8
VZ
1942 #undef TEST_REGISTRY
1943#endif
1944
7ba4fbeb
VZ
1945#ifdef TEST_REGCONF
1946
1947#include <wx/confbase.h>
1948#include <wx/msw/regconf.h>
1949
1950static void TestRegConfWrite()
1951{
1952 wxRegConfig regconf(_T("console"), _T("wxwindows"));
1953 regconf.Write(_T("Hello"), wxString(_T("world")));
1954}
1955
1956#endif // TEST_REGCONF
1957
6dfec4b8
VZ
1958#ifdef TEST_REGISTRY
1959
1960#include <wx/msw/registry.h>
1961
1962// I chose this one because I liked its name, but it probably only exists under
1963// NT
1964static const wxChar *TESTKEY =
1965 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
1966
1967static void TestRegistryRead()
1968{
1969 puts("*** testing registry reading ***");
1970
1971 wxRegKey key(TESTKEY);
1972 printf("The test key name is '%s'.\n", key.GetName().c_str());
1973 if ( !key.Open() )
1974 {
1975 puts("ERROR: test key can't be opened, aborting test.");
1976
1977 return;
1978 }
1979
1980 size_t nSubKeys, nValues;
1981 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
1982 {
1983 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
1984 }
1985
1986 printf("Enumerating values:\n");
1987
1988 long dummy;
1989 wxString value;
1990 bool cont = key.GetFirstValue(value, dummy);
1991 while ( cont )
1992 {
1993 printf("Value '%s': type ", value.c_str());
1994 switch ( key.GetValueType(value) )
1995 {
1996 case wxRegKey::Type_None: printf("ERROR (none)"); break;
1997 case wxRegKey::Type_String: printf("SZ"); break;
1998 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
1999 case wxRegKey::Type_Binary: printf("BINARY"); break;
2000 case wxRegKey::Type_Dword: printf("DWORD"); break;
2001 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
2002 default: printf("other (unknown)"); break;
2003 }
2004
2005 printf(", value = ");
2006 if ( key.IsNumericValue(value) )
2007 {
2008 long val;
2009 key.QueryValue(value, &val);
2010 printf("%ld", val);
2011 }
2012 else // string
2013 {
2014 wxString val;
2015 key.QueryValue(value, val);
2016 printf("'%s'", val.c_str());
2017
2018 key.QueryRawValue(value, val);
2019 printf(" (raw value '%s')", val.c_str());
2020 }
2021
2022 putchar('\n');
2023
2024 cont = key.GetNextValue(value, dummy);
2025 }
2026}
2027
6ba63600
VZ
2028static void TestRegistryAssociation()
2029{
2030 /*
2031 The second call to deleteself genertaes an error message, with a
2032 messagebox saying .flo is crucial to system operation, while the .ddf
2033 call also fails, but with no error message
2034 */
2035
2036 wxRegKey key;
2037
2038 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2039 key.Create();
2040 key = "ddxf_auto_file" ;
2041 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2042 key.Create();
2043 key = "ddxf_auto_file" ;
2044 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2045 key.Create();
2046 key = "program,0" ;
2047 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2048 key.Create();
2049 key = "program \"%1\"" ;
2050
2051 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2052 key.DeleteSelf();
2053 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2054 key.DeleteSelf();
2055 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2056 key.DeleteSelf();
2057 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2058 key.DeleteSelf();
2059}
2060
6dfec4b8
VZ
2061#endif // TEST_REGISTRY
2062
2c8e4738
VZ
2063// ----------------------------------------------------------------------------
2064// sockets
2065// ----------------------------------------------------------------------------
2066
2067#ifdef TEST_SOCKETS
2068
2069#include <wx/socket.h>
8e907a13 2070#include <wx/protocol/protocol.h>
8e907a13
VZ
2071#include <wx/protocol/http.h>
2072
2073static void TestSocketServer()
2074{
2075 puts("*** Testing wxSocketServer ***\n");
2076
ccdb23df
VZ
2077 static const int PORT = 3000;
2078
8e907a13 2079 wxIPV4address addr;
ccdb23df 2080 addr.Service(PORT);
8e907a13
VZ
2081
2082 wxSocketServer *server = new wxSocketServer(addr);
2083 if ( !server->Ok() )
2084 {
2085 puts("ERROR: failed to bind");
ccdb23df
VZ
2086
2087 return;
8e907a13 2088 }
8dfea369
VZ
2089
2090 for ( ;; )
2091 {
ccdb23df 2092 printf("Server: waiting for connection on port %d...\n", PORT);
8dfea369
VZ
2093
2094 wxSocketBase *socket = server->Accept();
2095 if ( !socket )
2096 {
2097 puts("ERROR: wxSocketServer::Accept() failed.");
2098 break;
2099 }
2100
2101 puts("Server: got a client.");
2102
ccdb23df
VZ
2103 server->SetTimeout(60); // 1 min
2104
2105 while ( socket->IsConnected() )
8dfea369 2106 {
ccdb23df
VZ
2107 wxString s;
2108 char ch = '\0';
2109 for ( ;; )
8dfea369 2110 {
ccdb23df
VZ
2111 if ( socket->Read(&ch, sizeof(ch)).Error() )
2112 {
2113 // don't log error if the client just close the connection
2114 if ( socket->IsConnected() )
2115 {
2116 puts("ERROR: in wxSocket::Read.");
2117 }
8dfea369 2118
ccdb23df
VZ
2119 break;
2120 }
8dfea369 2121
ccdb23df
VZ
2122 if ( ch == '\r' )
2123 continue;
8dfea369 2124
ccdb23df
VZ
2125 if ( ch == '\n' )
2126 break;
8dfea369 2127
ccdb23df
VZ
2128 s += ch;
2129 }
8dfea369 2130
ccdb23df
VZ
2131 if ( ch != '\n' )
2132 {
2133 break;
2134 }
8dfea369 2135
ccdb23df
VZ
2136 printf("Server: got '%s'.\n", s.c_str());
2137 if ( s == _T("bye") )
2138 {
2139 delete socket;
8dfea369 2140
ccdb23df
VZ
2141 break;
2142 }
2143
2144 socket->Write(s.MakeUpper().c_str(), s.length());
2145 socket->Write("\r\n", 2);
2146 printf("Server: wrote '%s'.\n", s.c_str());
8dfea369
VZ
2147 }
2148
ccdb23df 2149 puts("Server: lost a client.");
8dfea369 2150
ccdb23df 2151 socket->Destroy();
8dfea369 2152 }
9fc3cba7 2153
ccdb23df
VZ
2154 // same as "delete server" but is consistent with GUI programs
2155 server->Destroy();
8e907a13 2156}
2c8e4738
VZ
2157
2158static void TestSocketClient()
2159{
2160 puts("*** Testing wxSocketClient ***\n");
2161
8e907a13
VZ
2162 static const char *hostname = "www.wxwindows.org";
2163
2164 wxIPV4address addr;
2165 addr.Hostname(hostname);
2166 addr.Service(80);
2167
2168 printf("--- Attempting to connect to %s:80...\n", hostname);
2c8e4738
VZ
2169
2170 wxSocketClient client;
8e907a13 2171 if ( !client.Connect(addr) )
2c8e4738 2172 {
8e907a13 2173 printf("ERROR: failed to connect to %s\n", hostname);
2c8e4738
VZ
2174 }
2175 else
2176 {
8e907a13
VZ
2177 printf("--- Connected to %s:%u...\n",
2178 addr.Hostname().c_str(), addr.Service());
2179
2c8e4738
VZ
2180 char buf[8192];
2181
8e907a13
VZ
2182 // could use simply "GET" here I suppose
2183 wxString cmdGet =
2184 wxString::Format("GET http://%s/\r\n", hostname);
2185 client.Write(cmdGet, cmdGet.length());
2186 printf("--- Sent command '%s' to the server\n",
2187 MakePrintable(cmdGet).c_str());
2c8e4738 2188 client.Read(buf, WXSIZEOF(buf));
8e907a13
VZ
2189 printf("--- Server replied:\n%s", buf);
2190 }
2191}
2192
2e907fab
VZ
2193#endif // TEST_SOCKETS
2194
b92fd37c
VZ
2195// ----------------------------------------------------------------------------
2196// FTP
2197// ----------------------------------------------------------------------------
2198
2e907fab
VZ
2199#ifdef TEST_FTP
2200
2201#include <wx/protocol/ftp.h>
2202
b92fd37c
VZ
2203static wxFTP ftp;
2204
2205#define FTP_ANONYMOUS
2206
2207#ifdef FTP_ANONYMOUS
2208 static const char *directory = "/pub";
2209 static const char *filename = "welcome.msg";
2210#else
2211 static const char *directory = "/etc";
2212 static const char *filename = "issue";
2213#endif
2214
2215static bool TestFtpConnect()
8e907a13 2216{
b92fd37c 2217 puts("*** Testing FTP connect ***");
8e907a13 2218
b92fd37c
VZ
2219#ifdef FTP_ANONYMOUS
2220 static const char *hostname = "ftp.wxwindows.org";
2221
2222 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
2223#else // !FTP_ANONYMOUS
2224 static const char *hostname = "localhost";
2225
2226 char user[256];
2227 fgets(user, WXSIZEOF(user), stdin);
2228 user[strlen(user) - 1] = '\0'; // chop off '\n'
2229 ftp.SetUser(user);
2230
2231 char password[256];
2232 printf("Password for %s: ", password);
2233 fgets(password, WXSIZEOF(password), stdin);
2234 password[strlen(password) - 1] = '\0'; // chop off '\n'
2235 ftp.SetPassword(password);
2236
2237 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
2238#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2239
2240 if ( !ftp.Connect(hostname) )
2241 {
2242 printf("ERROR: failed to connect to %s\n", hostname);
2243
2244 return FALSE;
2245 }
2246 else
2247 {
2248 printf("--- Connected to %s, current directory is '%s'\n",
2249 hostname, ftp.Pwd().c_str());
2250 }
2251
2252 return TRUE;
2253}
b1229561 2254
b92fd37c
VZ
2255// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2256static void TestFtpWuFtpd()
2257{
2258 wxFTP ftp;
b1229561
VZ
2259 static const char *hostname = "ftp.eudora.com";
2260 if ( !ftp.Connect(hostname) )
2261 {
2262 printf("ERROR: failed to connect to %s\n", hostname);
2263 }
2264 else
2265 {
2266 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2267 wxInputStream *in = ftp.GetInputStream(filename);
2268 if ( !in )
2269 {
2270 printf("ERROR: couldn't get input stream for %s\n", filename);
2271 }
2272 else
2273 {
2274 size_t size = in->StreamSize();
2275 printf("Reading file %s (%u bytes)...", filename, size);
2276
2277 char *data = new char[size];
2278 if ( !in->Read(data, size) )
2279 {
2280 puts("ERROR: read error");
2281 }
2282 else
2283 {
2284 printf("Successfully retrieved the file.\n");
2285 }
2286
2287 delete [] data;
2288 delete in;
2289 }
2290 }
b92fd37c 2291}
b1229561 2292
b92fd37c
VZ
2293static void TestFtpList()
2294{
2295 puts("*** Testing wxFTP file listing ***\n");
8e907a13 2296
b92fd37c
VZ
2297 // test CWD
2298 if ( !ftp.ChDir(directory) )
2299 {
2300 printf("ERROR: failed to cd to %s\n", directory);
2301 }
2e907fab 2302
b92fd37c 2303 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2e907fab 2304
b92fd37c
VZ
2305 // test NLIST and LIST
2306 wxArrayString files;
2307 if ( !ftp.GetFilesList(files) )
8e907a13 2308 {
b92fd37c 2309 puts("ERROR: failed to get NLIST of files");
8e907a13
VZ
2310 }
2311 else
2312 {
b92fd37c
VZ
2313 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2314 size_t count = files.GetCount();
2315 for ( size_t n = 0; n < count; n++ )
8e907a13 2316 {
b92fd37c 2317 printf("\t%s\n", files[n].c_str());
8e907a13 2318 }
b92fd37c
VZ
2319 puts("End of the file list");
2320 }
8e907a13 2321
b92fd37c
VZ
2322 if ( !ftp.GetDirList(files) )
2323 {
2324 puts("ERROR: failed to get LIST of files");
2325 }
2326 else
2327 {
2328 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2329 size_t count = files.GetCount();
2330 for ( size_t n = 0; n < count; n++ )
8e907a13 2331 {
b92fd37c 2332 printf("\t%s\n", files[n].c_str());
2e907fab 2333 }
b92fd37c
VZ
2334 puts("End of the file list");
2335 }
2336
2337 if ( !ftp.ChDir(_T("..")) )
2338 {
2339 puts("ERROR: failed to cd to ..");
2340 }
2e907fab 2341
b92fd37c
VZ
2342 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2343}
2344
2345static void TestFtpDownload()
2346{
2347 puts("*** Testing wxFTP download ***\n");
2348
2349 // test RETR
2350 wxInputStream *in = ftp.GetInputStream(filename);
2351 if ( !in )
2352 {
2353 printf("ERROR: couldn't get input stream for %s\n", filename);
2354 }
2355 else
2356 {
2357 size_t size = in->StreamSize();
2358 printf("Reading file %s (%u bytes)...", filename, size);
2359 fflush(stdout);
2360
2361 char *data = new char[size];
2362 if ( !in->Read(data, size) )
2e907fab 2363 {
b92fd37c 2364 puts("ERROR: read error");
2e907fab
VZ
2365 }
2366 else
2367 {
b92fd37c 2368 printf("\nContents of %s:\n%s\n", filename, data);
8e907a13
VZ
2369 }
2370
b92fd37c
VZ
2371 delete [] data;
2372 delete in;
2373 }
2374}
8e907a13 2375
b92fd37c
VZ
2376static void TestFtpFileSize()
2377{
2378 puts("*** Testing FTP SIZE command ***");
2379
2380 if ( !ftp.ChDir(directory) )
2381 {
2382 printf("ERROR: failed to cd to %s\n", directory);
2383 }
2384
2385 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2386
2387 if ( ftp.FileExists(filename) )
2388 {
2389 int size = ftp.GetFileSize(filename);
2390 if ( size == -1 )
2391 printf("ERROR: couldn't get size of '%s'\n", filename);
8e907a13 2392 else
b92fd37c
VZ
2393 printf("Size of '%s' is %d bytes.\n", filename, size);
2394 }
2395 else
2396 {
2397 printf("ERROR: '%s' doesn't exist\n", filename);
2398 }
2399}
2400
2401static void TestFtpMisc()
2402{
2403 puts("*** Testing miscellaneous wxFTP functions ***");
2404
2405 if ( ftp.SendCommand("STAT") != '2' )
2406 {
2407 puts("ERROR: STAT failed");
2408 }
2409 else
2410 {
2411 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2412 }
2413
2414 if ( ftp.SendCommand("HELP SITE") != '2' )
2415 {
2416 puts("ERROR: HELP SITE failed");
2417 }
2418 else
2419 {
2420 printf("The list of site-specific commands:\n\n%s\n",
2421 ftp.GetLastResult().c_str());
2422 }
2423}
2424
2425static void TestFtpInteractive()
2426{
2427 puts("\n*** Interactive wxFTP test ***");
2428
2429 char buf[128];
2430
2431 for ( ;; )
2432 {
2433 printf("Enter FTP command: ");
2434 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2435 break;
2436
2437 // kill the last '\n'
2438 buf[strlen(buf) - 1] = 0;
2439
2440 // special handling of LIST and NLST as they require data connection
2441 wxString start(buf, 4);
2442 start.MakeUpper();
2443 if ( start == "LIST" || start == "NLST" )
8e907a13 2444 {
b92fd37c
VZ
2445 wxString wildcard;
2446 if ( strlen(buf) > 4 )
2447 wildcard = buf + 5;
8e907a13 2448
b92fd37c
VZ
2449 wxArrayString files;
2450 if ( !ftp.GetList(files, wildcard, start == "LIST") )
8e907a13 2451 {
b92fd37c 2452 printf("ERROR: failed to get %s of files\n", start.c_str());
8e907a13
VZ
2453 }
2454 else
2455 {
b92fd37c
VZ
2456 printf("--- %s of '%s' under '%s':\n",
2457 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2458 size_t count = files.GetCount();
2459 for ( size_t n = 0; n < count; n++ )
2460 {
2461 printf("\t%s\n", files[n].c_str());
2462 }
2463 puts("--- End of the file list");
8e907a13 2464 }
2e907fab 2465 }
b92fd37c 2466 else // !list
2e907fab 2467 {
b92fd37c
VZ
2468 char ch = ftp.SendCommand(buf);
2469 printf("Command %s", ch ? "succeeded" : "failed");
2470 if ( ch )
2471 {
2472 printf(" (return code %c)", ch);
2473 }
2e907fab 2474
b92fd37c 2475 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2e907fab 2476 }
2c8e4738 2477 }
b92fd37c
VZ
2478
2479 puts("\n*** done ***");
2c8e4738
VZ
2480}
2481
b92fd37c 2482static void TestFtpUpload()
f6bcfd97
BP
2483{
2484 puts("*** Testing wxFTP uploading ***\n");
2485
b92fd37c
VZ
2486 // upload a file
2487 static const char *file1 = "test1";
2488 static const char *file2 = "test2";
2489 wxOutputStream *out = ftp.GetOutputStream(file1);
2490 if ( out )
2491 {
2492 printf("--- Uploading to %s ---\n", file1);
2493 out->Write("First hello", 11);
2494 delete out;
2495 }
f6bcfd97 2496
b92fd37c
VZ
2497 // send a command to check the remote file
2498 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
f6bcfd97 2499 {
b92fd37c 2500 printf("ERROR: STAT %s failed\n", file1);
f6bcfd97
BP
2501 }
2502 else
2503 {
b92fd37c
VZ
2504 printf("STAT %s returned:\n\n%s\n",
2505 file1, ftp.GetLastResult().c_str());
2506 }
2e907fab 2507
b92fd37c
VZ
2508 out = ftp.GetOutputStream(file2);
2509 if ( out )
2510 {
2511 printf("--- Uploading to %s ---\n", file1);
2512 out->Write("Second hello", 12);
2513 delete out;
f6bcfd97
BP
2514 }
2515}
2516
2e907fab 2517#endif // TEST_FTP
2c8e4738 2518
83141d3a
VZ
2519// ----------------------------------------------------------------------------
2520// streams
2521// ----------------------------------------------------------------------------
2522
2523#ifdef TEST_STREAMS
2524
24f25c8a 2525#include <wx/wfstream.h>
83141d3a
VZ
2526#include <wx/mstream.h>
2527
24f25c8a
VZ
2528static void TestFileStream()
2529{
2530 puts("*** Testing wxFileInputStream ***");
2531
2532 static const wxChar *filename = _T("testdata.fs");
2533 {
2534 wxFileOutputStream fsOut(filename);
2535 fsOut.Write("foo", 3);
2536 }
2537
2538 wxFileInputStream fsIn(filename);
2539 printf("File stream size: %u\n", fsIn.GetSize());
2540 while ( !fsIn.Eof() )
2541 {
2542 putchar(fsIn.GetC());
2543 }
2544
2545 if ( !wxRemoveFile(filename) )
2546 {
2547 printf("ERROR: failed to remove the file '%s'.\n", filename);
2548 }
2549
2550 puts("\n*** wxFileInputStream test done ***");
2551}
2552
83141d3a
VZ
2553static void TestMemoryStream()
2554{
2555 puts("*** Testing wxMemoryInputStream ***");
2556
2557 wxChar buf[1024];
2558 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2559
2560 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2561 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2562 while ( !memInpStream.Eof() )
2563 {
2564 putchar(memInpStream.GetC());
2565 }
2566
2567 puts("\n*** wxMemoryInputStream test done ***");
2568}
2569
2570#endif // TEST_STREAMS
2571
d31b7b68
VZ
2572// ----------------------------------------------------------------------------
2573// timers
2574// ----------------------------------------------------------------------------
2575
2576#ifdef TEST_TIMER
2577
2578#include <wx/timer.h>
2579#include <wx/utils.h>
2580
2581static void TestStopWatch()
2582{
2583 puts("*** Testing wxStopWatch ***\n");
2584
2585 wxStopWatch sw;
2586 printf("Sleeping 3 seconds...");
2587 wxSleep(3);
87798c00 2588 printf("\telapsed time: %ldms\n", sw.Time());
d31b7b68
VZ
2589
2590 sw.Pause();
2591 printf("Sleeping 2 more seconds...");
2592 wxSleep(2);
87798c00 2593 printf("\telapsed time: %ldms\n", sw.Time());
d31b7b68
VZ
2594
2595 sw.Resume();
2596 printf("And 3 more seconds...");
2597 wxSleep(3);
87798c00
VZ
2598 printf("\telapsed time: %ldms\n", sw.Time());
2599
2600 wxStopWatch sw2;
2601 puts("\nChecking for 'backwards clock' bug...");
2602 for ( size_t n = 0; n < 70; n++ )
2603 {
2604 sw2.Start();
89e6463c
GRG
2605
2606 for ( size_t m = 0; m < 100000; m++ )
87798c00 2607 {
89e6463c
GRG
2608 if ( sw.Time() < 0 || sw2.Time() < 0 )
2609 {
2610 puts("\ntime is negative - ERROR!");
2611 }
87798c00
VZ
2612 }
2613
2614 putchar('.');
2615 }
2616
2617 puts(", ok.");
d31b7b68
VZ
2618}
2619
2620#endif // TEST_TIMER
2621
f6bcfd97
BP
2622// ----------------------------------------------------------------------------
2623// vCard support
2624// ----------------------------------------------------------------------------
2625
2626#ifdef TEST_VCARD
2627
2628#include <wx/vcard.h>
2629
2630static void DumpVObject(size_t level, const wxVCardObject& vcard)
2631{
2632 void *cookie;
2633 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2634 while ( vcObj )
2635 {
2636 printf("%s%s",
2637 wxString(_T('\t'), level).c_str(),
2638 vcObj->GetName().c_str());
2639
2640 wxString value;
2641 switch ( vcObj->GetType() )
2642 {
2643 case wxVCardObject::String:
2644 case wxVCardObject::UString:
2645 {
2646 wxString val;
2647 vcObj->GetValue(&val);
2648 value << _T('"') << val << _T('"');
2649 }
2650 break;
2651
2652 case wxVCardObject::Int:
2653 {
2654 unsigned int i;
2655 vcObj->GetValue(&i);
2656 value.Printf(_T("%u"), i);
2657 }
2658 break;
2659
2660 case wxVCardObject::Long:
2661 {
2662 unsigned long l;
2663 vcObj->GetValue(&l);
2664 value.Printf(_T("%lu"), l);
2665 }
2666 break;
2667
2668 case wxVCardObject::None:
2669 break;
2670
2671 case wxVCardObject::Object:
2672 value = _T("<node>");
2673 break;
2674
2675 default:
2676 value = _T("<unknown value type>");
2677 }
2678
2679 if ( !!value )
2680 printf(" = %s", value.c_str());
2681 putchar('\n');
2682
2683 DumpVObject(level + 1, *vcObj);
2684
2685 delete vcObj;
2686 vcObj = vcard.GetNextProp(&cookie);
2687 }
2688}
2689
2690static void DumpVCardAddresses(const wxVCard& vcard)
2691{
2692 puts("\nShowing all addresses from vCard:\n");
2693
2694 size_t nAdr = 0;
2695 void *cookie;
2696 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
2697 while ( addr )
2698 {
2699 wxString flagsStr;
2700 int flags = addr->GetFlags();
2701 if ( flags & wxVCardAddress::Domestic )
2702 {
2703 flagsStr << _T("domestic ");
2704 }
2705 if ( flags & wxVCardAddress::Intl )
2706 {
2707 flagsStr << _T("international ");
2708 }
2709 if ( flags & wxVCardAddress::Postal )
2710 {
2711 flagsStr << _T("postal ");
2712 }
2713 if ( flags & wxVCardAddress::Parcel )
2714 {
2715 flagsStr << _T("parcel ");
2716 }
2717 if ( flags & wxVCardAddress::Home )
2718 {
2719 flagsStr << _T("home ");
2720 }
2721 if ( flags & wxVCardAddress::Work )
2722 {
2723 flagsStr << _T("work ");
2724 }
2725
2726 printf("Address %u:\n"
2727 "\tflags = %s\n"
2728 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
2729 ++nAdr,
2730 flagsStr.c_str(),
2731 addr->GetPostOffice().c_str(),
2732 addr->GetExtAddress().c_str(),
2733 addr->GetStreet().c_str(),
2734 addr->GetLocality().c_str(),
2735 addr->GetRegion().c_str(),
2736 addr->GetPostalCode().c_str(),
2737 addr->GetCountry().c_str()
2738 );
2739
2740 delete addr;
2741 addr = vcard.GetNextAddress(&cookie);
2742 }
2743}
2744
2745static void DumpVCardPhoneNumbers(const wxVCard& vcard)
2746{
2747 puts("\nShowing all phone numbers from vCard:\n");
2748
2749 size_t nPhone = 0;
2750 void *cookie;
2751 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
2752 while ( phone )
2753 {
2754 wxString flagsStr;
2755 int flags = phone->GetFlags();
2756 if ( flags & wxVCardPhoneNumber::Voice )
2757 {
2758 flagsStr << _T("voice ");
2759 }
2760 if ( flags & wxVCardPhoneNumber::Fax )
2761 {
2762 flagsStr << _T("fax ");
2763 }
2764 if ( flags & wxVCardPhoneNumber::Cellular )
2765 {
2766 flagsStr << _T("cellular ");
2767 }
2768 if ( flags & wxVCardPhoneNumber::Modem )
2769 {
2770 flagsStr << _T("modem ");
2771 }
2772 if ( flags & wxVCardPhoneNumber::Home )
2773 {
2774 flagsStr << _T("home ");
2775 }
2776 if ( flags & wxVCardPhoneNumber::Work )
2777 {
2778 flagsStr << _T("work ");
2779 }
2780
2781 printf("Phone number %u:\n"
2782 "\tflags = %s\n"
2783 "\tvalue = %s\n",
2784 ++nPhone,
2785 flagsStr.c_str(),
2786 phone->GetNumber().c_str()
2787 );
2788
2789 delete phone;
2790 phone = vcard.GetNextPhoneNumber(&cookie);
2791 }
2792}
2793
2794static void TestVCardRead()
2795{
2796 puts("*** Testing wxVCard reading ***\n");
2797
2798 wxVCard vcard(_T("vcard.vcf"));
2799 if ( !vcard.IsOk() )
2800 {
2801 puts("ERROR: couldn't load vCard.");
2802 }
2803 else
2804 {
2805 // read individual vCard properties
2806 wxVCardObject *vcObj = vcard.GetProperty("FN");
2807 wxString value;
2808 if ( vcObj )
2809 {
2810 vcObj->GetValue(&value);
2811 delete vcObj;
2812 }
2813 else
2814 {
2815 value = _T("<none>");
2816 }
2817
2818 printf("Full name retrieved directly: %s\n", value.c_str());
2819
2820
2821 if ( !vcard.GetFullName(&value) )
2822 {
2823 value = _T("<none>");
2824 }
2825
2826 printf("Full name from wxVCard API: %s\n", value.c_str());
2827
2828 // now show how to deal with multiply occuring properties
2829 DumpVCardAddresses(vcard);
2830 DumpVCardPhoneNumbers(vcard);
2831
2832 // and finally show all
2833 puts("\nNow dumping the entire vCard:\n"
2834 "-----------------------------\n");
2835
2836 DumpVObject(0, vcard);
2837 }
2838}
2839
2840static void TestVCardWrite()
2841{
2842 puts("*** Testing wxVCard writing ***\n");
2843
2844 wxVCard vcard;
2845 if ( !vcard.IsOk() )
2846 {
2847 puts("ERROR: couldn't create vCard.");
2848 }
2849 else
2850 {
2851 // set some fields
2852 vcard.SetName("Zeitlin", "Vadim");
2853 vcard.SetFullName("Vadim Zeitlin");
2854 vcard.SetOrganization("wxWindows", "R&D");
2855
2856 // just dump the vCard back
2857 puts("Entire vCard follows:\n");
2858 puts(vcard.Write());
2859 }
2860}
2861
2862#endif // TEST_VCARD
2863
2864// ----------------------------------------------------------------------------
2865// wide char (Unicode) support
2866// ----------------------------------------------------------------------------
2867
2868#ifdef TEST_WCHAR
2869
2870#include <wx/strconv.h>
24f25c8a
VZ
2871#include <wx/fontenc.h>
2872#include <wx/encconv.h>
f6bcfd97
BP
2873#include <wx/buffer.h>
2874
2875static void TestUtf8()
2876{
2877 puts("*** Testing UTF8 support ***\n");
2878
24f25c8a
VZ
2879 static const char textInUtf8[] =
2880 {
2881 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
2882 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
2883 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
2884 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
2885 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
2886 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
2887 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
2888 };
f6bcfd97 2889
24f25c8a
VZ
2890 char buf[1024];
2891 wchar_t wbuf[1024];
2892 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
f6bcfd97 2893 {
24f25c8a 2894 puts("ERROR: UTF-8 decoding failed.");
f6bcfd97 2895 }
24f25c8a
VZ
2896 else
2897 {
2898 // using wxEncodingConverter
2899#if 0
2900 wxEncodingConverter ec;
2901 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
2902 ec.Convert(wbuf, buf);
2903#else // using wxCSConv
2904 wxCSConv conv(_T("koi8-r"));
2905 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
2906 {
2907 puts("ERROR: conversion to KOI8-R failed.");
2908 }
2909 else
2910#endif
f6bcfd97 2911
24f25c8a
VZ
2912 printf("The resulting string (in koi8-r): %s\n", buf);
2913 }
f6bcfd97
BP
2914}
2915
2916#endif // TEST_WCHAR
2917
2918// ----------------------------------------------------------------------------
2919// ZIP stream
2920// ----------------------------------------------------------------------------
2921
2922#ifdef TEST_ZIP
2923
2ca8b884
VZ
2924#include "wx/filesys.h"
2925#include "wx/fs_zip.h"
f6bcfd97
BP
2926#include "wx/zipstrm.h"
2927
2ca8b884
VZ
2928static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
2929
f6bcfd97
BP
2930static void TestZipStreamRead()
2931{
2932 puts("*** Testing ZIP reading ***\n");
2933
2ca8b884
VZ
2934 static const wxChar *filename = _T("foo");
2935 wxZipInputStream istr(TESTFILE_ZIP, filename);
f6bcfd97
BP
2936 printf("Archive size: %u\n", istr.GetSize());
2937
2ca8b884 2938 printf("Dumping the file '%s':\n", filename);
f6bcfd97
BP
2939 while ( !istr.Eof() )
2940 {
2941 putchar(istr.GetC());
2942 fflush(stdout);
2943 }
2944
2945 puts("\n----- done ------");
2946}
2947
2ca8b884
VZ
2948static void DumpZipDirectory(wxFileSystem& fs,
2949 const wxString& dir,
2950 const wxString& indent)
2951{
2952 wxString prefix = wxString::Format(_T("%s#zip:%s"),
2953 TESTFILE_ZIP, dir.c_str());
2954 wxString wildcard = prefix + _T("/*");
2955
2956 wxString dirname = fs.FindFirst(wildcard, wxDIR);
2957 while ( !dirname.empty() )
2958 {
2959 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
2960 {
2961 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2962
2963 break;
2964 }
2965
2966 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
2967
2968 DumpZipDirectory(fs, dirname,
2969 indent + wxString(_T(' '), 4));
2970
2971 dirname = fs.FindNext();
2972 }
2973
2974 wxString filename = fs.FindFirst(wildcard, wxFILE);
2975 while ( !filename.empty() )
2976 {
2977 if ( !filename.StartsWith(prefix, &filename) )
2978 {
2979 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
2980
2981 break;
2982 }
2983
2984 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
2985
2986 filename = fs.FindNext();
2987 }
2988}
2989
2990static void TestZipFileSystem()
2991{
2992 puts("*** Testing ZIP file system ***\n");
2993
2994 wxFileSystem::AddHandler(new wxZipFSHandler);
2995 wxFileSystem fs;
2996 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
2997
2998 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
2999}
3000
f6bcfd97
BP
3001#endif // TEST_ZIP
3002
3ca6a5f0
BP
3003// ----------------------------------------------------------------------------
3004// ZLIB stream
3005// ----------------------------------------------------------------------------
3006
3007#ifdef TEST_ZLIB
3008
3009#include <wx/zstream.h>
3010#include <wx/wfstream.h>
3011
3012static const wxChar *FILENAME_GZ = _T("test.gz");
3013static const char *TEST_DATA = "hello and hello again";
3014
3015static void TestZlibStreamWrite()
3016{
3017 puts("*** Testing Zlib stream reading ***\n");
3018
3019 wxFileOutputStream fileOutStream(FILENAME_GZ);
3020 wxZlibOutputStream ostr(fileOutStream, 0);
3021 printf("Compressing the test string... ");
3022 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3023 if ( !ostr )
3024 {
3025 puts("(ERROR: failed)");
3026 }
3027 else
3028 {
3029 puts("(ok)");
3030 }
3031
3032 puts("\n----- done ------");
3033}
3034
3035static void TestZlibStreamRead()
3036{
3037 puts("*** Testing Zlib stream reading ***\n");
3038
3039 wxFileInputStream fileInStream(FILENAME_GZ);
3040 wxZlibInputStream istr(fileInStream);
3041 printf("Archive size: %u\n", istr.GetSize());
3042
3043 puts("Dumping the file:");
3044 while ( !istr.Eof() )
3045 {
3046 putchar(istr.GetC());
3047 fflush(stdout);
3048 }
3049
3050 puts("\n----- done ------");
3051}
3052
3053#endif // TEST_ZLIB
3054
b76b015e
VZ
3055// ----------------------------------------------------------------------------
3056// date time
3057// ----------------------------------------------------------------------------
3058
d31b7b68 3059#ifdef TEST_DATETIME
b76b015e 3060
551fe3a6
VZ
3061#include <math.h>
3062
97e0ceea
VZ
3063#include <wx/date.h>
3064
b76b015e
VZ
3065#include <wx/datetime.h>
3066
299fcbfe
VZ
3067// the test data
3068struct Date
3069{
3070 wxDateTime::wxDateTime_t day;
3071 wxDateTime::Month month;
3072 int year;
3073 wxDateTime::wxDateTime_t hour, min, sec;
3074 double jdn;
211c2250 3075 wxDateTime::WeekDay wday;
299fcbfe
VZ
3076 time_t gmticks, ticks;
3077
3078 void Init(const wxDateTime::Tm& tm)
3079 {
3080 day = tm.mday;
3081 month = tm.mon;
3082 year = tm.year;
3083 hour = tm.hour;
3084 min = tm.min;
3085 sec = tm.sec;
3086 jdn = 0.0;
3087 gmticks = ticks = -1;
3088 }
3089
3090 wxDateTime DT() const
3091 { return wxDateTime(day, month, year, hour, min, sec); }
3092
239446b4
VZ
3093 bool SameDay(const wxDateTime::Tm& tm) const
3094 {
3095 return day == tm.mday && month == tm.mon && year == tm.year;
3096 }
3097
299fcbfe
VZ
3098 wxString Format() const
3099 {
3100 wxString s;
3101 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3102 hour, min, sec,
3103 wxDateTime::GetMonthName(month).c_str(),
3104 day,
3105 abs(wxDateTime::ConvertYearToBC(year)),
3106 year > 0 ? "AD" : "BC");
3107 return s;
3108 }
239446b4
VZ
3109
3110 wxString FormatDate() const
3111 {
3112 wxString s;
3113 s.Printf("%02d-%s-%4d%s",
3114 day,
f0f951fa 3115 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
239446b4
VZ
3116 abs(wxDateTime::ConvertYearToBC(year)),
3117 year > 0 ? "AD" : "BC");
3118 return s;
3119 }
299fcbfe
VZ
3120};
3121
3122static const Date testDates[] =
3123{
211c2250
VZ
3124 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3125 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3126 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3127 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3128 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3129 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3130 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3131 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3132 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3133 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
239446b4
VZ
3134 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3135 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3136 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3137 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
211c2250 3138 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
299fcbfe
VZ
3139};
3140
2f02cb89
VZ
3141// this test miscellaneous static wxDateTime functions
3142static void TestTimeStatic()
3143{
3144 puts("\n*** wxDateTime static methods test ***");
3145
3146 // some info about the current date
3147 int year = wxDateTime::GetCurrentYear();
3148 printf("Current year %d is %sa leap one and has %d days.\n",
3149 year,
3150 wxDateTime::IsLeapYear(year) ? "" : "not ",
3151 wxDateTime::GetNumberOfDays(year));
3152
3153 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3154 printf("Current month is '%s' ('%s') and it has %d days\n",
f0f951fa 3155 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2f02cb89
VZ
3156 wxDateTime::GetMonthName(month).c_str(),
3157 wxDateTime::GetNumberOfDays(month));
3158
3159 // leap year logic
fcc3d7cb
VZ
3160 static const size_t nYears = 5;
3161 static const size_t years[2][nYears] =
2f02cb89
VZ
3162 {
3163 // first line: the years to test
3164 { 1990, 1976, 2000, 2030, 1984, },
3165
3166 // second line: TRUE if leap, FALSE otherwise
3167 { FALSE, TRUE, TRUE, FALSE, TRUE }
3168 };
3169
3170 for ( size_t n = 0; n < nYears; n++ )
3171 {
3172 int year = years[0][n];
239446b4
VZ
3173 bool should = years[1][n] != 0,
3174 is = wxDateTime::IsLeapYear(year);
2f02cb89 3175
239446b4 3176 printf("Year %d is %sa leap year (%s)\n",
2f02cb89 3177 year,
239446b4
VZ
3178 is ? "" : "not ",
3179 should == is ? "ok" : "ERROR");
2f02cb89
VZ
3180
3181 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3182 }
3183}
3184
3185// test constructing wxDateTime objects
3186static void TestTimeSet()
3187{
3188 puts("\n*** wxDateTime construction test ***");
3189
299fcbfe
VZ
3190 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3191 {
3192 const Date& d1 = testDates[n];
3193 wxDateTime dt = d1.DT();
3194
3195 Date d2;
3196 d2.Init(dt.GetTm());
3197
3198 wxString s1 = d1.Format(),
3199 s2 = d2.Format();
3200
3201 printf("Date: %s == %s (%s)\n",
3202 s1.c_str(), s2.c_str(),
3203 s1 == s2 ? "ok" : "ERROR");
3204 }
2f02cb89
VZ
3205}
3206
fcc3d7cb
VZ
3207// test time zones stuff
3208static void TestTimeZones()
3209{
3210 puts("\n*** wxDateTime timezone test ***");
3211
3212 wxDateTime now = wxDateTime::Now();
3213
299fcbfe
VZ
3214 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3215 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3216 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3217 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3218 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3219 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
9d9b7755
VZ
3220
3221 wxDateTime::Tm tm = now.GetTm();
3222 if ( wxDateTime(tm) != now )
3223 {
3224 printf("ERROR: got %s instead of %s\n",
3225 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3226 }
fcc3d7cb
VZ
3227}
3228
e6ec579c
VZ
3229// test some minimal support for the dates outside the standard range
3230static void TestTimeRange()
3231{
3232 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3233
211c2250
VZ
3234 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3235
1ef54dcf 3236 printf("Unix epoch:\t%s\n",
211c2250 3237 wxDateTime(2440587.5).Format(fmt).c_str());
1ef54dcf 3238 printf("Feb 29, 0: \t%s\n",
211c2250 3239 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
e6ec579c 3240 printf("JDN 0: \t%s\n",
211c2250 3241 wxDateTime(0.0).Format(fmt).c_str());
e6ec579c 3242 printf("Jan 1, 1AD:\t%s\n",
211c2250 3243 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
e6ec579c 3244 printf("May 29, 2099:\t%s\n",
211c2250 3245 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
e6ec579c
VZ
3246}
3247
299fcbfe 3248static void TestTimeTicks()
e6ec579c 3249{
299fcbfe 3250 puts("\n*** wxDateTime ticks test ***");
e6ec579c 3251
299fcbfe 3252 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1ef54dcf 3253 {
299fcbfe
VZ
3254 const Date& d = testDates[n];
3255 if ( d.ticks == -1 )
3256 continue;
1ef54dcf 3257
299fcbfe
VZ
3258 wxDateTime dt = d.DT();
3259 long ticks = (dt.GetValue() / 1000).ToLong();
3260 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3261 if ( ticks == d.ticks )
3262 {
3263 puts(" (ok)");
3264 }
3265 else
3266 {
3267 printf(" (ERROR: should be %ld, delta = %ld)\n",
3268 d.ticks, ticks - d.ticks);
3269 }
3270
3271 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3272 ticks = (dt.GetValue() / 1000).ToLong();
3273 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3274 if ( ticks == d.gmticks )
3275 {
3276 puts(" (ok)");
3277 }
3278 else
3279 {
3280 printf(" (ERROR: should be %ld, delta = %ld)\n",
3281 d.gmticks, ticks - d.gmticks);
3282 }
3283 }
3284
3285 puts("");
3286}
3287
3288// test conversions to JDN &c
3289static void TestTimeJDN()
3290{
3291 puts("\n*** wxDateTime to JDN test ***");
1ef54dcf
VZ
3292
3293 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3294 {
3295 const Date& d = testDates[n];
299fcbfe 3296 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1ef54dcf
VZ
3297 double jdn = dt.GetJulianDayNumber();
3298
299fcbfe 3299 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
1ef54dcf
VZ
3300 if ( jdn == d.jdn )
3301 {
3302 puts(" (ok)");
3303 }
3304 else
3305 {
3306 printf(" (ERROR: should be %f, delta = %f)\n",
3307 d.jdn, jdn - d.jdn);
3308 }
3309 }
e6ec579c
VZ
3310}
3311
211c2250
VZ
3312// test week days computation
3313static void TestTimeWDays()
3314{
3315 puts("\n*** wxDateTime weekday test ***");
3316
239446b4
VZ
3317 // test GetWeekDay()
3318 size_t n;
3319 for ( n = 0; n < WXSIZEOF(testDates); n++ )
211c2250
VZ
3320 {
3321 const Date& d = testDates[n];
3322 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3323
3324 wxDateTime::WeekDay wday = dt.GetWeekDay();
3325 printf("%s is: %s",
3326 d.Format().c_str(),
239446b4 3327 wxDateTime::GetWeekDayName(wday).c_str());
211c2250
VZ
3328 if ( wday == d.wday )
3329 {
3330 puts(" (ok)");
3331 }
3332 else
3333 {
3334 printf(" (ERROR: should be %s)\n",
239446b4
VZ
3335 wxDateTime::GetWeekDayName(d.wday).c_str());
3336 }
3337 }
3338
3339 puts("");
3340
3341 // test SetToWeekDay()
3342 struct WeekDateTestData
3343 {
3344 Date date; // the real date (precomputed)
3345 int nWeek; // its week index in the month
3346 wxDateTime::WeekDay wday; // the weekday
3347 wxDateTime::Month month; // the month
3348 int year; // and the year
3349
3350 wxString Format() const
3351 {
3352 wxString s, which;
3353 switch ( nWeek < -1 ? -nWeek : nWeek )
3354 {
3355 case 1: which = "first"; break;
3356 case 2: which = "second"; break;
3357 case 3: which = "third"; break;
3358 case 4: which = "fourth"; break;
3359 case 5: which = "fifth"; break;
3360
3361 case -1: which = "last"; break;
3362 }
3363
3364 if ( nWeek < -1 )
3365 {
3366 which += " from end";
3367 }
3368
3369 s.Printf("The %s %s of %s in %d",
3370 which.c_str(),
3371 wxDateTime::GetWeekDayName(wday).c_str(),
3372 wxDateTime::GetMonthName(month).c_str(),
3373 year);
3374
3375 return s;
3376 }
3377 };
3378
3379 // the array data was generated by the following python program
3380 /*
3381from DateTime import *
3382from whrandom import *
3383from string import *
3384
3385monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3386wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3387
3388week = DateTimeDelta(7)
3389
3390for n in range(20):
3391 year = randint(1900, 2100)
3392 month = randint(1, 12)
3393 day = randint(1, 28)
3394 dt = DateTime(year, month, day)
3395 wday = dt.day_of_week
3396
3397 countFromEnd = choice([-1, 1])
3398 weekNum = 0;
3399
3400 while dt.month is month:
3401 dt = dt - countFromEnd * week
3402 weekNum = weekNum + countFromEnd
3403
3404 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
97e0ceea 3405
239446b4
VZ
3406 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3407 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
97e0ceea 3408 */
239446b4
VZ
3409
3410 static const WeekDateTestData weekDatesTestData[] =
3411 {
3412 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3413 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3414 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3415 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3416 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3417 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3418 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3419 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3420 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3421 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3422 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3423 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3424 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3425 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3426 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3427 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3428 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3429 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3430 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3431 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3432 };
3433
3434 static const char *fmt = "%d-%b-%Y";
3435
3436 wxDateTime dt;
3437 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3438 {
3439 const WeekDateTestData& wd = weekDatesTestData[n];
3440
3441 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3442
3443 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3444
3445 const Date& d = wd.date;
3446 if ( d.SameDay(dt.GetTm()) )
3447 {
3448 puts(" (ok)");
3449 }
3450 else
3451 {
3452 dt.Set(d.day, d.month, d.year);
3453
3454 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
211c2250
VZ
3455 }
3456 }
3457}
3458
239446b4
VZ
3459// test the computation of (ISO) week numbers
3460static void TestTimeWNumber()
3461{
3462 puts("\n*** wxDateTime week number test ***");
3463
3464 struct WeekNumberTestData
3465 {
3466 Date date; // the date
9d9b7755
VZ
3467 wxDateTime::wxDateTime_t week; // the week number in the year
3468 wxDateTime::wxDateTime_t wmon; // the week number in the month
3469 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
239446b4
VZ
3470 wxDateTime::wxDateTime_t dnum; // day number in the year
3471 };
3472
3473 // data generated with the following python script:
3474 /*
3475from DateTime import *
3476from whrandom import *
3477from string import *
3478
3479monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3480wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3481
9d9b7755
VZ
3482def GetMonthWeek(dt):
3483 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3484 if weekNumMonth < 0:
3485 weekNumMonth = weekNumMonth + 53
3486 return weekNumMonth
7c968cee 3487
9d9b7755
VZ
3488def GetLastSundayBefore(dt):
3489 if dt.iso_week[2] == 7:
3490 return dt
3491 else:
3492 return dt - DateTimeDelta(dt.iso_week[2])
3493
239446b4
VZ
3494for n in range(20):
3495 year = randint(1900, 2100)
3496 month = randint(1, 12)
3497 day = randint(1, 28)
3498 dt = DateTime(year, month, day)
3499 dayNum = dt.day_of_year
3500 weekNum = dt.iso_week[1]
9d9b7755
VZ
3501 weekNumMonth = GetMonthWeek(dt)
3502
3503 weekNumMonth2 = 0
3504 dtSunday = GetLastSundayBefore(dt)
3505
3506 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3507 weekNumMonth2 = weekNumMonth2 + 1
3508 dtSunday = dtSunday - DateTimeDelta(7)
3509
3510 data = { 'day': rjust(`day`, 2), \
3511 'month': monthNames[month - 1], \
3512 'year': year, \
3513 'weekNum': rjust(`weekNum`, 2), \
3514 'weekNumMonth': weekNumMonth, \
3515 'weekNumMonth2': weekNumMonth2, \
3516 'dayNum': rjust(`dayNum`, 3) }
3517
3518 print " { { %(day)s, "\
3519 "wxDateTime::%(month)s, "\
3520 "%(year)d }, "\
3521 "%(weekNum)s, "\
3522 "%(weekNumMonth)s, "\
3523 "%(weekNumMonth2)s, "\
239446b4 3524 "%(dayNum)s }," % data
9d9b7755 3525
239446b4
VZ
3526 */
3527 static const WeekNumberTestData weekNumberTestDates[] =
3528 {
9d9b7755
VZ
3529 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3530 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3531 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3532 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3533 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3534 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3535 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3536 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3537 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3538 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3539 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3540 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3541 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3542 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3543 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3544 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3545 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3546 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3547 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3548 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
239446b4
VZ
3549 };
3550
3551 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3552 {
3553 const WeekNumberTestData& wn = weekNumberTestDates[n];
3554 const Date& d = wn.date;
3555
3556 wxDateTime dt = d.DT();
3557
9d9b7755
VZ
3558 wxDateTime::wxDateTime_t
3559 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3560 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3561 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3562 dnum = dt.GetDayOfYear();
239446b4
VZ
3563
3564 printf("%s: the day number is %d",
3565 d.FormatDate().c_str(), dnum);
3566 if ( dnum == wn.dnum )
3567 {
3568 printf(" (ok)");
3569 }
3570 else
3571 {
3572 printf(" (ERROR: should be %d)", wn.dnum);
3573 }
3574
9d9b7755
VZ
3575 printf(", week in month is %d", wmon);
3576 if ( wmon == wn.wmon )
3577 {
3578 printf(" (ok)");
3579 }
3580 else
3581 {
3582 printf(" (ERROR: should be %d)", wn.wmon);
3583 }
3584
3585 printf(" or %d", wmon2);
3586 if ( wmon2 == wn.wmon2 )
3587 {
3588 printf(" (ok)");
3589 }
3590 else
3591 {
3592 printf(" (ERROR: should be %d)", wn.wmon2);
3593 }
3594
3595 printf(", week in year is %d", week);
239446b4
VZ
3596 if ( week == wn.week )
3597 {
3598 puts(" (ok)");
3599 }
3600 else
3601 {
3602 printf(" (ERROR: should be %d)\n", wn.week);
3603 }
3604 }
3605}
3606
3607// test DST calculations
3608static void TestTimeDST()
3609{
3610 puts("\n*** wxDateTime DST test ***");
3611
3612 printf("DST is%s in effect now.\n\n",
3613 wxDateTime::Now().IsDST() ? "" : " not");
3614
3615 // taken from http://www.energy.ca.gov/daylightsaving.html
3616 static const Date datesDST[2][2004 - 1900 + 1] =
3617 {
3618 {
3619 { 1, wxDateTime::Apr, 1990 },
3620 { 7, wxDateTime::Apr, 1991 },
3621 { 5, wxDateTime::Apr, 1992 },
3622 { 4, wxDateTime::Apr, 1993 },
3623 { 3, wxDateTime::Apr, 1994 },
3624 { 2, wxDateTime::Apr, 1995 },
3625 { 7, wxDateTime::Apr, 1996 },
3626 { 6, wxDateTime::Apr, 1997 },
3627 { 5, wxDateTime::Apr, 1998 },
3628 { 4, wxDateTime::Apr, 1999 },
3629 { 2, wxDateTime::Apr, 2000 },
3630 { 1, wxDateTime::Apr, 2001 },
3631 { 7, wxDateTime::Apr, 2002 },
3632 { 6, wxDateTime::Apr, 2003 },
3633 { 4, wxDateTime::Apr, 2004 },
3634 },
3635 {
3636 { 28, wxDateTime::Oct, 1990 },
3637 { 27, wxDateTime::Oct, 1991 },
3638 { 25, wxDateTime::Oct, 1992 },
3639 { 31, wxDateTime::Oct, 1993 },
3640 { 30, wxDateTime::Oct, 1994 },
3641 { 29, wxDateTime::Oct, 1995 },
3642 { 27, wxDateTime::Oct, 1996 },
3643 { 26, wxDateTime::Oct, 1997 },
3644 { 25, wxDateTime::Oct, 1998 },
3645 { 31, wxDateTime::Oct, 1999 },
3646 { 29, wxDateTime::Oct, 2000 },
3647 { 28, wxDateTime::Oct, 2001 },
3648 { 27, wxDateTime::Oct, 2002 },
3649 { 26, wxDateTime::Oct, 2003 },
3650 { 31, wxDateTime::Oct, 2004 },
3651 }
3652 };
3653
3654 int year;
3655 for ( year = 1990; year < 2005; year++ )
3656 {
3657 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
3658 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
3659
3660 printf("DST period in the US for year %d: from %s to %s",
3661 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
3662
3663 size_t n = year - 1990;
3664 const Date& dBegin = datesDST[0][n];
3665 const Date& dEnd = datesDST[1][n];
97e0ceea 3666
239446b4
VZ
3667 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
3668 {
3669 puts(" (ok)");
3670 }
3671 else
3672 {
3673 printf(" (ERROR: should be %s %d to %s %d)\n",
3674 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
3675 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
3676 }
3677 }
3678
3679 puts("");
3680
3681 for ( year = 1990; year < 2005; year++ )
3682 {
3683 printf("DST period in Europe for year %d: from %s to %s\n",
3684 year,
3685 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3686 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3687 }
3688}
3689
68ee7c47
VZ
3690// test wxDateTime -> text conversion
3691static void TestTimeFormat()
3692{
3693 puts("\n*** wxDateTime formatting test ***");
3694
b38e2f7d
VZ
3695 // some information may be lost during conversion, so store what kind
3696 // of info should we recover after a round trip
3697 enum CompareKind
68ee7c47 3698 {
b38e2f7d
VZ
3699 CompareNone, // don't try comparing
3700 CompareBoth, // dates and times should be identical
3701 CompareDate, // dates only
3702 CompareTime // time only
3703 };
3704
3705 static const struct
3706 {
3707 CompareKind compareKind;
3708 const char *format;
3709 } formatTestFormats[] =
3710 {
3711 { CompareBoth, "---> %c" },
3712 { CompareDate, "Date is %A, %d of %B, in year %Y" },
3713 { CompareBoth, "Date is %x, time is %X" },
3714 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
3715 { CompareNone, "The day of year: %j, the week of year: %W" },
f6bcfd97 3716 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
68ee7c47
VZ
3717 };
3718
3719 static const Date formatTestDates[] =
3720 {
68ee7c47
VZ
3721 { 29, wxDateTime::May, 1976, 18, 30, 00 },
3722 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
b38e2f7d
VZ
3723#if 0
3724 // this test can't work for other centuries because it uses two digit
3725 // years in formats, so don't even try it
68ee7c47
VZ
3726 { 29, wxDateTime::May, 2076, 18, 30, 00 },
3727 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
3728 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
b38e2f7d 3729#endif
68ee7c47
VZ
3730 };
3731
3732 // an extra test (as it doesn't depend on date, don't do it in the loop)
3733 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
3734
b38e2f7d 3735 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
68ee7c47
VZ
3736 {
3737 puts("");
3738
b38e2f7d 3739 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
68ee7c47
VZ
3740 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
3741 {
b38e2f7d 3742 wxString s = dt.Format(formatTestFormats[n].format);
f0f951fa
VZ
3743 printf("%s", s.c_str());
3744
b38e2f7d
VZ
3745 // what can we recover?
3746 int kind = formatTestFormats[n].compareKind;
3747
f0f951fa
VZ
3748 // convert back
3749 wxDateTime dt2;
b38e2f7d 3750 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
f0f951fa
VZ
3751 if ( !result )
3752 {
b38e2f7d
VZ
3753 // converion failed - should it have?
3754 if ( kind == CompareNone )
3755 puts(" (ok)");
3756 else
3757 puts(" (ERROR: conversion back failed)");
f0f951fa
VZ
3758 }
3759 else if ( *result )
3760 {
3761 // should have parsed the entire string
3762 puts(" (ERROR: conversion back stopped too soon)");
3763 }
f0f951fa
VZ
3764 else
3765 {
b38e2f7d
VZ
3766 bool equal = FALSE; // suppress compilaer warning
3767 switch ( kind )
3768 {
3769 case CompareBoth:
3770 equal = dt2 == dt;
3771 break;
3772
3773 case CompareDate:
3774 equal = dt.IsSameDate(dt2);
3775 break;
3776
3777 case CompareTime:
3778 equal = dt.IsSameTime(dt2);
3779 break;
3780 }
3781
3782 if ( !equal )
3783 {
3784 printf(" (ERROR: got back '%s' instead of '%s')\n",
3785 dt2.Format().c_str(), dt.Format().c_str());
3786 }
3787 else
3788 {
3789 puts(" (ok)");
3790 }
f0f951fa 3791 }
68ee7c47
VZ
3792 }
3793 }
3794}
3795
97e0ceea
VZ
3796// test text -> wxDateTime conversion
3797static void TestTimeParse()
3798{
3799 puts("\n*** wxDateTime parse test ***");
3800
3801 struct ParseTestData
3802 {
3803 const char *format;
3804 Date date;
3805 bool good;
3806 };
3807
3808 static const ParseTestData parseTestDates[] =
3809 {
68ee7c47
VZ
3810 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
3811 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
97e0ceea
VZ
3812 };
3813
3814 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
3815 {
3816 const char *format = parseTestDates[n].format;
3817
3818 printf("%s => ", format);
3819
3820 wxDateTime dt;
3821 if ( dt.ParseRfc822Date(format) )
3822 {
3823 printf("%s ", dt.Format().c_str());
3824
3825 if ( parseTestDates[n].good )
3826 {
3827 wxDateTime dtReal = parseTestDates[n].date.DT();
3828 if ( dt == dtReal )
3829 {
3830 puts("(ok)");
3831 }
3832 else
3833 {
3834 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
3835 }
3836 }
3837 else
3838 {
3839 puts("(ERROR: bad format)");
3840 }
3841 }
3842 else
3843 {
3844 printf("bad format (%s)\n",
3845 parseTestDates[n].good ? "ERROR" : "ok");
3846 }
3847 }
3848}
3849
b92fd37c 3850static void TestDateTimeInteractive()
9d9b7755
VZ
3851{
3852 puts("\n*** interactive wxDateTime tests ***");
3853
3854 char buf[128];
3855
3856 for ( ;; )
3857 {
3858 printf("Enter a date: ");
3859 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
3860 break;
3861
f6bcfd97
BP
3862 // kill the last '\n'
3863 buf[strlen(buf) - 1] = 0;
3864
9d9b7755 3865 wxDateTime dt;
f6bcfd97
BP
3866 const char *p = dt.ParseDate(buf);
3867 if ( !p )
9d9b7755 3868 {
f6bcfd97 3869 printf("ERROR: failed to parse the date '%s'.\n", buf);
9d9b7755
VZ
3870
3871 continue;
3872 }
f6bcfd97
BP
3873 else if ( *p )
3874 {
3875 printf("WARNING: parsed only first %u characters.\n", p - buf);
3876 }
9d9b7755
VZ
3877
3878 printf("%s: day %u, week of month %u/%u, week of year %u\n",
f6bcfd97 3879 dt.Format("%b %d, %Y").c_str(),
9d9b7755
VZ
3880 dt.GetDayOfYear(),
3881 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3882 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3883 dt.GetWeekOfYear(wxDateTime::Monday_First));
3884 }
3885
3886 puts("\n*** done ***");
3887}
3888
f6bcfd97
BP
3889static void TestTimeMS()
3890{
3891 puts("*** testing millisecond-resolution support in wxDateTime ***");
3892
3893 wxDateTime dt1 = wxDateTime::Now(),
3894 dt2 = wxDateTime::UNow();
3895
3896 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
3897 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3ca6a5f0
BP
3898 printf("Dummy loop: ");
3899 for ( int i = 0; i < 6000; i++ )
3900 {
3901 //for ( int j = 0; j < 10; j++ )
3902 {
3903 wxString s;
3904 s.Printf("%g", sqrt(i));
3905 }
3906
3907 if ( !(i % 100) )
3908 putchar('.');
3909 }
3910 puts(", done");
3911
3912 dt1 = dt2;
3913 dt2 = wxDateTime::UNow();
3914 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3915
3916 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
f6bcfd97
BP
3917
3918 puts("\n*** done ***");
3919}
3920
9d9b7755
VZ
3921static void TestTimeArithmetics()
3922{
3923 puts("\n*** testing arithmetic operations on wxDateTime ***");
3924
f6bcfd97 3925 static const struct ArithmData
9d9b7755 3926 {
f6bcfd97
BP
3927 ArithmData(const wxDateSpan& sp, const char *nam)
3928 : span(sp), name(nam) { }
3929
9d9b7755
VZ
3930 wxDateSpan span;
3931 const char *name;
7c968cee 3932 } testArithmData[] =
9d9b7755 3933 {
f6bcfd97
BP
3934 ArithmData(wxDateSpan::Day(), "day"),
3935 ArithmData(wxDateSpan::Week(), "week"),
3936 ArithmData(wxDateSpan::Month(), "month"),
3937 ArithmData(wxDateSpan::Year(), "year"),
3938 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
9d9b7755 3939 };
7c968cee 3940
9d9b7755
VZ
3941 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
3942
3943 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
3944 {
3945 wxDateSpan span = testArithmData[n].span;
3946 dt1 = dt + span;
3947 dt2 = dt - span;
3948
3949 const char *name = testArithmData[n].name;
3950 printf("%s + %s = %s, %s - %s = %s\n",
3951 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
3952 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
3953
3954 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
3955 if ( dt1 - span == dt )
3956 {
3957 puts(" (ok)");
3958 }
3959 else
3960 {
3961 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3962 }
3963
3964 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
3965 if ( dt2 + span == dt )
3966 {
3967 puts(" (ok)");
3968 }
3969 else
3970 {
3971 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
3972 }
3973
3974 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
3975 if ( dt2 + 2*span == dt1 )
3976 {
3977 puts(" (ok)");
3978 }
3979 else
3980 {
3981 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
3982 }
3983
3984 puts("");
3985 }
3986}
3987
0de868d9
VZ
3988static void TestTimeHolidays()
3989{
3990 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
3991
3992 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3993 wxDateTime dtStart(1, tm.mon, tm.year),
3994 dtEnd = dtStart.GetLastMonthDay();
3995
3996 wxDateTimeArray hol;
3997 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3998
3999 const wxChar *format = "%d-%b-%Y (%a)";
4000
4001 printf("All holidays between %s and %s:\n",
4002 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4003
4004 size_t count = hol.GetCount();
4005 for ( size_t n = 0; n < count; n++ )
4006 {
4007 printf("\t%s\n", hol[n].Format(format).c_str());
4008 }
4009
4010 puts("");
4011}
4012
f6bcfd97
BP
4013static void TestTimeZoneBug()
4014{
4015 puts("\n*** testing for DST/timezone bug ***\n");
4016
4017 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4018 for ( int i = 0; i < 31; i++ )
4019 {
4020 printf("Date %s: week day %s.\n",
4021 date.Format(_T("%d-%m-%Y")).c_str(),
4022 date.GetWeekDayName(date.GetWeekDay()).c_str());
4023
4024 date += wxDateSpan::Day();
4025 }
4026
4027 puts("");
4028}
4029
df05cdc5
VZ
4030static void TestTimeSpanFormat()
4031{
4032 puts("\n*** wxTimeSpan tests ***");
4033
4034 static const char *formats[] =
4035 {
4036 _T("(default) %H:%M:%S"),
4037 _T("%E weeks and %D days"),
4038 _T("%l milliseconds"),
4039 _T("(with ms) %H:%M:%S:%l"),
4040 _T("100%% of minutes is %M"), // test "%%"
4041 _T("%D days and %H hours"),
4042 };
4043
4044 wxTimeSpan ts1(1, 2, 3, 4),
4045 ts2(111, 222, 333);
4046 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4047 {
4048 printf("ts1 = %s\tts2 = %s\n",
4049 ts1.Format(formats[n]).c_str(),
4050 ts2.Format(formats[n]).c_str());
4051 }
4052
4053 puts("");
4054}
4055
68ee7c47
VZ
4056#if 0
4057
97e0ceea
VZ
4058// test compatibility with the old wxDate/wxTime classes
4059static void TestTimeCompatibility()
4060{
4061 puts("\n*** wxDateTime compatibility test ***");
4062
4063 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4064 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4065
4066 double jdnNow = wxDateTime::Now().GetJDN();
4067 long jdnMidnight = (long)(jdnNow - 0.5);
4068 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4069
4070 jdnMidnight = wxDate().Set().GetJulianDate();
4071 printf("wxDateTime for today: %s\n",
4072 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4073
4074 int flags = wxEUROPEAN;//wxFULL;
4075 wxDate date;
4076 date.Set();
4077 printf("Today is %s\n", date.FormatDate(flags).c_str());
4078 for ( int n = 0; n < 7; n++ )
4079 {
4080 printf("Previous %s is %s\n",
4081 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4082 date.Previous(n + 1).FormatDate(flags).c_str());
4083 }
4084}
4085
68ee7c47
VZ
4086#endif // 0
4087
d31b7b68 4088#endif // TEST_DATETIME
b76b015e 4089
e87271f3
VZ
4090// ----------------------------------------------------------------------------
4091// threads
4092// ----------------------------------------------------------------------------
4093
4094#ifdef TEST_THREADS
4095
bbfa0322 4096#include <wx/thread.h>
37667812 4097
bbfa0322
VZ
4098static size_t gs_counter = (size_t)-1;
4099static wxCriticalSection gs_critsect;
b568d04f 4100static wxCondition gs_cond;
bbfa0322 4101
b568d04f 4102class MyJoinableThread : public wxThread
bbfa0322
VZ
4103{
4104public:
b568d04f
VZ
4105 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4106 { m_n = n; Create(); }
bbfa0322
VZ
4107
4108 // thread execution starts here
b568d04f 4109 virtual ExitCode Entry();
bbfa0322 4110
b568d04f
VZ
4111private:
4112 size_t m_n;
bbfa0322
VZ
4113};
4114
b568d04f 4115wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 4116{
b568d04f
VZ
4117 unsigned long res = 1;
4118 for ( size_t n = 1; n < m_n; n++ )
4119 {
4120 res *= n;
4121
4122 // it's a loooong calculation :-)
4123 Sleep(100);
4124 }
bbfa0322 4125
b568d04f 4126 return (ExitCode)res;
bbfa0322
VZ
4127}
4128
b568d04f
VZ
4129class MyDetachedThread : public wxThread
4130{
4131public:
fcc3d7cb
VZ
4132 MyDetachedThread(size_t n, char ch)
4133 {
4134 m_n = n;
4135 m_ch = ch;
4136 m_cancelled = FALSE;
4137
4138 Create();
4139 }
b568d04f
VZ
4140
4141 // thread execution starts here
4142 virtual ExitCode Entry();
4143
4144 // and stops here
4145 virtual void OnExit();
4146
4147private:
9fc3ad34
VZ
4148 size_t m_n; // number of characters to write
4149 char m_ch; // character to write
fcc3d7cb
VZ
4150
4151 bool m_cancelled; // FALSE if we exit normally
b568d04f
VZ
4152};
4153
4154wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
4155{
4156 {
4157 wxCriticalSectionLocker lock(gs_critsect);
4158 if ( gs_counter == (size_t)-1 )
4159 gs_counter = 1;
4160 else
4161 gs_counter++;
4162 }
4163
9fc3ad34 4164 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
4165 {
4166 if ( TestDestroy() )
fcc3d7cb
VZ
4167 {
4168 m_cancelled = TRUE;
4169
bbfa0322 4170 break;
fcc3d7cb 4171 }
bbfa0322
VZ
4172
4173 putchar(m_ch);
4174 fflush(stdout);
4175
4176 wxThread::Sleep(100);
4177 }
4178
b568d04f 4179 return 0;
bbfa0322
VZ
4180}
4181
b568d04f 4182void MyDetachedThread::OnExit()
bbfa0322 4183{
9fc3ad34
VZ
4184 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4185
bbfa0322 4186 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 4187 if ( !--gs_counter && !m_cancelled )
b568d04f 4188 gs_cond.Signal();
bbfa0322
VZ
4189}
4190
9fc3ad34
VZ
4191void TestDetachedThreads()
4192{
2f02cb89 4193 puts("\n*** Testing detached threads ***");
9fc3ad34
VZ
4194
4195 static const size_t nThreads = 3;
4196 MyDetachedThread *threads[nThreads];
4197 size_t n;
4198 for ( n = 0; n < nThreads; n++ )
4199 {
4200 threads[n] = new MyDetachedThread(10, 'A' + n);
4201 }
4202
4203 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4204 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4205
4206 for ( n = 0; n < nThreads; n++ )
4207 {
4208 threads[n]->Run();
4209 }
4210
4211 // wait until all threads terminate
4212 gs_cond.Wait();
4213
4214 puts("");
4215}
4216
4217void TestJoinableThreads()
4218{
2f02cb89 4219 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
9fc3ad34
VZ
4220
4221 // calc 10! in the background
4222 MyJoinableThread thread(10);
4223 thread.Run();
4224
4225 printf("\nThread terminated with exit code %lu.\n",
4226 (unsigned long)thread.Wait());
4227}
4228
4229void TestThreadSuspend()
4230{
2f02cb89
VZ
4231 puts("\n*** Testing thread suspend/resume functions ***");
4232
4233 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
4234
4235 thread->Run();
4236
4237 // this is for this demo only, in a real life program we'd use another
4238 // condition variable which would be signaled from wxThread::Entry() to
4239 // tell us that the thread really started running - but here just wait a
4240 // bit and hope that it will be enough (the problem is, of course, that
4241 // the thread might still not run when we call Pause() which will result
4242 // in an error)
4243 wxThread::Sleep(300);
4244
4245 for ( size_t n = 0; n < 3; n++ )
4246 {
4247 thread->Pause();
4248
4249 puts("\nThread suspended");
4250 if ( n > 0 )
4251 {
4252 // don't sleep but resume immediately the first time
4253 wxThread::Sleep(300);
4254 }
4255 puts("Going to resume the thread");
4256
4257 thread->Resume();
4258 }
4259
4c460b34
VZ
4260 puts("Waiting until it terminates now");
4261
9fc3ad34
VZ
4262 // wait until the thread terminates
4263 gs_cond.Wait();
4264
4265 puts("");
4266}
4267
2f02cb89
VZ
4268void TestThreadDelete()
4269{
4270 // As above, using Sleep() is only for testing here - we must use some
4271 // synchronisation object instead to ensure that the thread is still
4272 // running when we delete it - deleting a detached thread which already
4273 // terminated will lead to a crash!
4274
4275 puts("\n*** Testing thread delete function ***");
4276
4c460b34
VZ
4277 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4278
4279 thread0->Delete();
4280
4281 puts("\nDeleted a thread which didn't start to run yet.");
4282
2f02cb89
VZ
4283 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4284
4285 thread1->Run();
4286
4287 wxThread::Sleep(300);
4288
4289 thread1->Delete();
4290
4291 puts("\nDeleted a running thread.");
4292
4293 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4294
4295 thread2->Run();
4296
4297 wxThread::Sleep(300);
4298
4299 thread2->Pause();
4300
4301 thread2->Delete();
4302
4303 puts("\nDeleted a sleeping thread.");
4304
4c460b34
VZ
4305 MyJoinableThread thread3(20);
4306 thread3.Run();
2f02cb89 4307
4c460b34 4308 thread3.Delete();
2f02cb89
VZ
4309
4310 puts("\nDeleted a joinable thread.");
4311
4c460b34
VZ
4312 MyJoinableThread thread4(2);
4313 thread4.Run();
2f02cb89
VZ
4314
4315 wxThread::Sleep(300);
4316
4c460b34 4317 thread4.Delete();
2f02cb89
VZ
4318
4319 puts("\nDeleted a joinable thread which already terminated.");
4320
4321 puts("");
4322}
4323
e87271f3
VZ
4324#endif // TEST_THREADS
4325
4326// ----------------------------------------------------------------------------
4327// arrays
4328// ----------------------------------------------------------------------------
4329
4330#ifdef TEST_ARRAYS
4331
f6bcfd97 4332static void PrintArray(const char* name, const wxArrayString& array)
e87271f3
VZ
4333{
4334 printf("Dump of the array '%s'\n", name);
4335
4336 size_t nCount = array.GetCount();
4337 for ( size_t n = 0; n < nCount; n++ )
4338 {
4339 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4340 }
4341}
4342
d6c9c1b7
VZ
4343static void PrintArray(const char* name, const wxArrayInt& array)
4344{
4345 printf("Dump of the array '%s'\n", name);
4346
4347 size_t nCount = array.GetCount();
4348 for ( size_t n = 0; n < nCount; n++ )
4349 {
4350 printf("\t%s[%u] = %d\n", name, n, array[n]);
4351 }
4352}
4353
4354int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4355 const wxString& second)
f6bcfd97
BP
4356{
4357 return first.length() - second.length();
4358}
4359
d6c9c1b7
VZ
4360int wxCMPFUNC_CONV IntCompare(int *first,
4361 int *second)
4362{
4363 return *first - *second;
4364}
4365
4366int wxCMPFUNC_CONV IntRevCompare(int *first,
4367 int *second)
4368{
4369 return *second - *first;
4370}
4371
4372static void TestArrayOfInts()
4373{
4374 puts("*** Testing wxArrayInt ***\n");
4375
4376 wxArrayInt a;
4377 a.Add(1);
4378 a.Add(17);
4379 a.Add(5);
4380 a.Add(3);
4381
4382 puts("Initially:");
4383 PrintArray("a", a);
4384
4385 puts("After sort:");
4386 a.Sort(IntCompare);
4387 PrintArray("a", a);
4388
4389 puts("After reverse sort:");
4390 a.Sort(IntRevCompare);
4391 PrintArray("a", a);
4392}
4393
f6bcfd97
BP
4394#include "wx/dynarray.h"
4395
4396WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4397#include "wx/arrimpl.cpp"
4398WX_DEFINE_OBJARRAY(ArrayBars);
4399
4400static void TestArrayOfObjects()
4401{
4402 puts("*** Testing wxObjArray ***\n");
4403
4404 {
4405 ArrayBars bars;
4406 Bar bar("second bar");
4407
4408 printf("Initially: %u objects in the array, %u objects total.\n",
4409 bars.GetCount(), Bar::GetNumber());
4410
4411 bars.Add(new Bar("first bar"));
4412 bars.Add(bar);
4413
4414 printf("Now: %u objects in the array, %u objects total.\n",
4415 bars.GetCount(), Bar::GetNumber());
4416
4417 bars.Empty();
4418
4419 printf("After Empty(): %u objects in the array, %u objects total.\n",
4420 bars.GetCount(), Bar::GetNumber());
4421 }
4422
4423 printf("Finally: no more objects in the array, %u objects total.\n",
4424 Bar::GetNumber());
4425}
4426
e87271f3
VZ
4427#endif // TEST_ARRAYS
4428
9fc3ad34
VZ
4429// ----------------------------------------------------------------------------
4430// strings
4431// ----------------------------------------------------------------------------
4432
4433#ifdef TEST_STRINGS
4434
4435#include "wx/timer.h"
bbf8fc53 4436#include "wx/tokenzr.h"
9fc3ad34 4437
7c968cee
VZ
4438static void TestStringConstruction()
4439{
4440 puts("*** Testing wxString constructores ***");
4441
4442 #define TEST_CTOR(args, res) \
4443 { \
4444 wxString s args ; \
4445 printf("wxString%s = %s ", #args, s.c_str()); \
4446 if ( s == res ) \
4447 { \
4448 puts("(ok)"); \
4449 } \
4450 else \
4451 { \
4452 printf("(ERROR: should be %s)\n", res); \
4453 } \
4454 }
4455
4456 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
4457 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
4458 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
4459 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
4460
4461 static const wxChar *s = _T("?really!");
4462 const wxChar *start = wxStrchr(s, _T('r'));
4463 const wxChar *end = wxStrchr(s, _T('!'));
4464 TEST_CTOR((start, end), _T("really"));
4465
4466 puts("");
4467}
4468
299fcbfe 4469static void TestString()
9fc3ad34
VZ
4470{
4471 wxStopWatch sw;
4472
4473 wxString a, b, c;
4474
4475 a.reserve (128);
4476 b.reserve (128);
4477 c.reserve (128);
4478
4479 for (int i = 0; i < 1000000; ++i)
4480 {
4481 a = "Hello";
4482 b = " world";
4483 c = "! How'ya doin'?";
4484 a += b;
4485 a += c;
4486 c = "Hello world! What's up?";
4487 if (c != a)
4488 c = "Doh!";
4489 }
4490
4491 printf ("TestString elapsed time: %ld\n", sw.Time());
4492}
4493
299fcbfe 4494static void TestPChar()
9fc3ad34
VZ
4495{
4496 wxStopWatch sw;
4497
4498 char a [128];
4499 char b [128];
4500 char c [128];
4501
4502 for (int i = 0; i < 1000000; ++i)
4503 {
4504 strcpy (a, "Hello");
4505 strcpy (b, " world");
4506 strcpy (c, "! How'ya doin'?");
4507 strcat (a, b);
4508 strcat (a, c);
4509 strcpy (c, "Hello world! What's up?");
4510 if (strcmp (c, a) == 0)
4511 strcpy (c, "Doh!");
4512 }
4513
4514 printf ("TestPChar elapsed time: %ld\n", sw.Time());
4515}
4516
299fcbfe
VZ
4517static void TestStringSub()
4518{
4519 wxString s("Hello, world!");
4520
4521 puts("*** Testing wxString substring extraction ***");
4522
4523 printf("String = '%s'\n", s.c_str());
4524 printf("Left(5) = '%s'\n", s.Left(5).c_str());
4525 printf("Right(6) = '%s'\n", s.Right(6).c_str());
4526 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
4527 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
4528 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
4529 printf("substr(3) = '%s'\n", s.substr(3).c_str());
4530
f6bcfd97
BP
4531 static const wxChar *prefixes[] =
4532 {
4533 _T("Hello"),
4534 _T("Hello, "),
4535 _T("Hello, world!"),
4536 _T("Hello, world!!!"),
4537 _T(""),
4538 _T("Goodbye"),
4539 _T("Hi"),
4540 };
4541
4542 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
4543 {
4544 wxString prefix = prefixes[n], rest;
4545 bool rc = s.StartsWith(prefix, &rest);
4546 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
4547 if ( rc )
4548 {
4549 printf(" (the rest is '%s')\n", rest.c_str());
4550 }
4551 else
4552 {
4553 putchar('\n');
4554 }
4555 }
4556
299fcbfe
VZ
4557 puts("");
4558}
4559
f0f951fa
VZ
4560static void TestStringFormat()
4561{
4562 puts("*** Testing wxString formatting ***");
4563
4564 wxString s;
4565 s.Printf("%03d", 18);
4566
4567 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
4568 printf("Number 18: %s\n", s.c_str());
4569
4570 puts("");
4571}
4572
d71fa6fb
VZ
4573// returns "not found" for npos, value for all others
4574static wxString PosToString(size_t res)
4575{
4576 wxString s = res == wxString::npos ? wxString(_T("not found"))
4577 : wxString::Format(_T("%u"), res);
4578 return s;
4579}
4580
4581static void TestStringFind()
4582{
4583 puts("*** Testing wxString find() functions ***");
4584
4585 static const wxChar *strToFind = _T("ell");
4586 static const struct StringFindTest
4587 {
4588 const wxChar *str;
4589 size_t start,
4590 result; // of searching "ell" in str
4591 } findTestData[] =
4592 {
4593 { _T("Well, hello world"), 0, 1 },
4594 { _T("Well, hello world"), 6, 7 },
4595 { _T("Well, hello world"), 9, wxString::npos },
4596 };
4597
4598 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
4599 {
4600 const StringFindTest& ft = findTestData[n];
4601 size_t res = wxString(ft.str).find(strToFind, ft.start);
4602
4603 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
4604 strToFind, ft.str, ft.start, PosToString(res).c_str());
4605
4606 size_t resTrue = ft.result;
4607 if ( res == resTrue )
4608 {
4609 puts(_T("(ok)"));
4610 }
4611 else
4612 {
4613 printf(_T("(ERROR: should be %s)\n"),
4614 PosToString(resTrue).c_str());
4615 }
4616 }
4617
4618 puts("");
4619}
4620
bbf8fc53
VZ
4621static void TestStringTokenizer()
4622{
4623 puts("*** Testing wxStringTokenizer ***");
4624
7c968cee
VZ
4625 static const wxChar *modeNames[] =
4626 {
4627 _T("default"),
4628 _T("return empty"),
4629 _T("return all empty"),
4630 _T("with delims"),
4631 _T("like strtok"),
4632 };
4633
bbf8fc53
VZ
4634 static const struct StringTokenizerTest
4635 {
7c968cee
VZ
4636 const wxChar *str; // string to tokenize
4637 const wxChar *delims; // delimiters to use
4638 size_t count; // count of token
4639 wxStringTokenizerMode mode; // how should we tokenize it
4640 } tokenizerTestData[] =
4641 {
4642 { _T(""), _T(" "), 0 },
4643 { _T("Hello, world"), _T(" "), 2 },
4644 { _T("Hello, world "), _T(" "), 2 },
4645 { _T("Hello, world"), _T(","), 2 },
4646 { _T("Hello, world!"), _T(",!"), 2 },
4647 { _T("Hello,, world!"), _T(",!"), 3 },
4648 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
4649 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
4650 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
4651 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
4652 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
4653 { _T("01/02/99"), _T("/-"), 3 },
4654 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
bbf8fc53
VZ
4655 };
4656
4657 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
4658 {
4659 const StringTokenizerTest& tt = tokenizerTestData[n];
7c968cee 4660 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
bbf8fc53
VZ
4661
4662 size_t count = tkz.CountTokens();
7c968cee
VZ
4663 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
4664 MakePrintable(tt.str).c_str(),
bbf8fc53 4665 count,
7c968cee
VZ
4666 MakePrintable(tt.delims).c_str(),
4667 modeNames[tkz.GetMode()]);
bbf8fc53
VZ
4668 if ( count == tt.count )
4669 {
4670 puts(_T("(ok)"));
4671 }
4672 else
4673 {
4674 printf(_T("(ERROR: should be %u)\n"), tt.count);
4675
4676 continue;
4677 }
4678
7c968cee 4679 // if we emulate strtok(), check that we do it correctly
f6bcfd97 4680 wxChar *buf, *s = NULL, *last;
7c968cee
VZ
4681
4682 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4683 {
4684 buf = new wxChar[wxStrlen(tt.str) + 1];
4685 wxStrcpy(buf, tt.str);
4686
4687 s = wxStrtok(buf, tt.delims, &last);
4688 }
4689 else
4690 {
4691 buf = NULL;
4692 }
4693
bbf8fc53
VZ
4694 // now show the tokens themselves
4695 size_t count2 = 0;
4696 while ( tkz.HasMoreTokens() )
4697 {
7c968cee
VZ
4698 wxString token = tkz.GetNextToken();
4699
4700 printf(_T("\ttoken %u: '%s'"),
bbf8fc53 4701 ++count2,
7c968cee
VZ
4702 MakePrintable(token).c_str());
4703
4704 if ( buf )
4705 {
4706 if ( token == s )
4707 {
4708 puts(" (ok)");
4709 }
4710 else
4711 {
4712 printf(" (ERROR: should be %s)\n", s);
4713 }
4714
4715 s = wxStrtok(NULL, tt.delims, &last);
4716 }
4717 else
4718 {
4719 // nothing to compare with
4720 puts("");
4721 }
bbf8fc53
VZ
4722 }
4723
4724 if ( count2 != count )
4725 {
7c968cee 4726 puts(_T("\tERROR: token count mismatch"));
bbf8fc53 4727 }
7c968cee
VZ
4728
4729 delete [] buf;
bbf8fc53
VZ
4730 }
4731
4732 puts("");
4733}
4734
f6bcfd97
BP
4735static void TestStringReplace()
4736{
4737 puts("*** Testing wxString::replace ***");
4738
4739 static const struct StringReplaceTestData
4740 {
4741 const wxChar *original; // original test string
4742 size_t start, len; // the part to replace
4743 const wxChar *replacement; // the replacement string
4744 const wxChar *result; // and the expected result
4745 } stringReplaceTestData[] =
4746 {
4747 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4748 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4749 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4750 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4751 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4752 };
4753
4754 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4755 {
4756 const StringReplaceTestData data = stringReplaceTestData[n];
4757
4758 wxString original = data.original;
4759 original.replace(data.start, data.len, data.replacement);
4760
4761 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4762 data.original, data.start, data.len, data.replacement,
4763 original.c_str());
4764
4765 if ( original == data.result )
4766 {
4767 puts("(ok)");
4768 }
4769 else
4770 {
4771 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4772 }
4773 }
4774
4775 puts("");
4776}
4777
9a4232dc
VZ
4778static void TestStringMatch()
4779{
4780 wxPuts(_T("*** Testing wxString::Matches() ***"));
4781
4782 static const struct StringMatchTestData
4783 {
4784 const wxChar *text;
4785 const wxChar *wildcard;
4786 bool matches;
4787 } stringMatchTestData[] =
4788 {
4789 { _T("foobar"), _T("foo*"), 1 },
4790 { _T("foobar"), _T("*oo*"), 1 },
4791 { _T("foobar"), _T("*bar"), 1 },
4792 { _T("foobar"), _T("??????"), 1 },
4793 { _T("foobar"), _T("f??b*"), 1 },
4794 { _T("foobar"), _T("f?b*"), 0 },
4795 { _T("foobar"), _T("*goo*"), 0 },
4796 { _T("foobar"), _T("*foo"), 0 },
4797 { _T("foobarfoo"), _T("*foo"), 1 },
4798 { _T(""), _T("*"), 1 },
4799 { _T(""), _T("?"), 0 },
4800 };
4801
4802 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
4803 {
4804 const StringMatchTestData& data = stringMatchTestData[n];
4805 bool matches = wxString(data.text).Matches(data.wildcard);
4806 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
4807 data.wildcard,
4808 matches ? _T("matches") : _T("doesn't match"),
4809 data.text,
4810 matches == data.matches ? _T("ok") : _T("ERROR"));
4811 }
4812
4813 wxPuts(_T(""));
4814}
4815
9fc3ad34
VZ
4816#endif // TEST_STRINGS
4817
e87271f3
VZ
4818// ----------------------------------------------------------------------------
4819// entry point
4820// ----------------------------------------------------------------------------
4821
bbfa0322 4822int main(int argc, char **argv)
37667812 4823{
58b24a56
VZ
4824 wxInitializer initializer;
4825 if ( !initializer )
37667812
VZ
4826 {
4827 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
4828
4829 return -1;
4830 }
4831
4832#ifdef TEST_SNGLINST
b5299791
VZ
4833 wxSingleInstanceChecker checker;
4834 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 4835 {
b5299791
VZ
4836 if ( checker.IsAnotherRunning() )
4837 {
4838 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 4839
b5299791
VZ
4840 return 1;
4841 }
37667812 4842
b5299791
VZ
4843 // wait some time to give time to launch another instance
4844 wxPrintf(_T("Press \"Enter\" to continue..."));
4845 wxFgetc(stdin);
4846 }
4847 else // failed to create
4848 {
4849 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4850 }
58b24a56
VZ
4851#endif // TEST_SNGLINST
4852
551fe3a6
VZ
4853#ifdef TEST_CHARSET
4854 TestCharset();
4855#endif // TEST_CHARSET
0de868d9 4856
d34bce84
VZ
4857#ifdef TEST_CMDLINE
4858 static const wxCmdLineEntryDesc cmdLineDesc[] =
4859 {
4860 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4861 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4862
4863 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4864 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4865 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
1e245dc2 4866 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
d34bce84
VZ
4867
4868 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4869 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4870
4871 { wxCMD_LINE_NONE }
4872 };
4873
4874 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4875
f6bcfd97
BP
4876 parser.AddOption("project_name", "", "full path to project file",
4877 wxCMD_LINE_VAL_STRING,
4878 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4879
d34bce84
VZ
4880 switch ( parser.Parse() )
4881 {
4882 case -1:
4883 wxLogMessage("Help was given, terminating.");
4884 break;
4885
4886 case 0:
4887 ShowCmdLine(parser);
4888 break;
4889
4890 default:
4891 wxLogMessage("Syntax error detected, aborting.");
4892 break;
4893 }
4894#endif // TEST_CMDLINE
4895
9fc3ad34 4896#ifdef TEST_STRINGS
299fcbfe
VZ
4897 if ( 0 )
4898 {
4899 TestPChar();
4900 TestString();
f6bcfd97 4901 TestStringSub();
7c968cee 4902 TestStringConstruction();
d71fa6fb 4903 TestStringFormat();
bbf8fc53 4904 TestStringFind();
7c968cee 4905 TestStringTokenizer();
f6bcfd97 4906 TestStringReplace();
ee6e1b1d 4907 }
9a4232dc 4908 TestStringMatch();
9fc3ad34
VZ
4909#endif // TEST_STRINGS
4910
e87271f3 4911#ifdef TEST_ARRAYS
d6c9c1b7
VZ
4912 if ( 0 )
4913 {
e87271f3
VZ
4914 wxArrayString a1;
4915 a1.Add("tiger");
4916 a1.Add("cat");
4917 a1.Add("lion");
4918 a1.Add("dog");
4919 a1.Add("human");
4920 a1.Add("ape");
4921
4922 puts("*** Initially:");
4923
4924 PrintArray("a1", a1);
4925
4926 wxArrayString a2(a1);
4927 PrintArray("a2", a2);
4928
4929 wxSortedArrayString a3(a1);
4930 PrintArray("a3", a3);
4931
4932 puts("*** After deleting a string from a1");
4933 a1.Remove(2);
4934
4935 PrintArray("a1", a1);
4936 PrintArray("a2", a2);
4937 PrintArray("a3", a3);
4938
4939 puts("*** After reassigning a1 to a2 and a3");
4940 a3 = a2 = a1;
4941 PrintArray("a2", a2);
4942 PrintArray("a3", a3);
f6bcfd97
BP
4943
4944 puts("*** After sorting a1");
4945 a1.Sort();
4946 PrintArray("a1", a1);
4947
4948 puts("*** After sorting a1 in reverse order");
4949 a1.Sort(TRUE);
4950 PrintArray("a1", a1);
4951
4952 puts("*** After sorting a1 by the string length");
4953 a1.Sort(StringLenCompare);
4954 PrintArray("a1", a1);
4955
4956 TestArrayOfObjects();
d6c9c1b7
VZ
4957 }
4958 TestArrayOfInts();
e87271f3
VZ
4959#endif // TEST_ARRAYS
4960
1944c6bd 4961#ifdef TEST_DIR
35332784
VZ
4962 if ( 0 )
4963 TestDirEnum();
4964 TestDirTraverse();
1944c6bd
VZ
4965#endif // TEST_DIR
4966
f6bcfd97
BP
4967#ifdef TEST_DLLLOADER
4968 TestDllLoad();
4969#endif // TEST_DLLLOADER
4970
8fd0d89b
VZ
4971#ifdef TEST_ENVIRON
4972 TestEnvironment();
4973#endif // TEST_ENVIRON
4974
d93c719a
VZ
4975#ifdef TEST_EXECUTE
4976 TestExecute();
4977#endif // TEST_EXECUTE
4978
ee6e1b1d
VZ
4979#ifdef TEST_FILECONF
4980 TestFileConfRead();
4981#endif // TEST_FILECONF
4982
f6bcfd97
BP
4983#ifdef TEST_LIST
4984 TestListCtor();
4985#endif // TEST_LIST
4986
ec37df57
VZ
4987#ifdef TEST_LOCALE
4988 TestDefaultLang();
4989#endif // TEST_LOCALE
4990
378b05f7
VZ
4991#ifdef TEST_LOG
4992 wxString s;
4993 for ( size_t n = 0; n < 8000; n++ )
4994 {
4995 s << (char)('A' + (n % 26));
4996 }
4997
4998 wxString msg;
4999 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5000
5001 // this one shouldn't be truncated
5002 printf(msg);
5003
5004 // but this one will because log functions use fixed size buffer
b568d04f
VZ
5005 // (note that it doesn't need '\n' at the end neither - will be added
5006 // by wxLog anyhow)
5007 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
378b05f7
VZ
5008#endif // TEST_LOG
5009
f6bcfd97 5010#ifdef TEST_FILE
3ca6a5f0 5011 if ( 0 )
a339970a 5012 {
3ca6a5f0 5013 TestFileRead();
a339970a
VZ
5014 TestTextFileRead();
5015 }
5016 TestFileCopy();
f6bcfd97
BP
5017#endif // TEST_FILE
5018
844f90fb 5019#ifdef TEST_FILENAME
42b1f941 5020 TestFileNameSplit();
9e8d8607
VZ
5021 if ( 0 )
5022 {
42b1f941 5023 TestFileNameConstruction();
9e8d8607
VZ
5024 TestFileNameCwd();
5025 TestFileNameComparison();
5026 TestFileNameOperations();
5027 }
844f90fb
VZ
5028#endif // TEST_FILENAME
5029
07a56e45
VZ
5030#ifdef TEST_FTP
5031 wxLog::AddTraceMask(FTP_TRACE_MASK);
5032 if ( TestFtpConnect() )
5033 {
5034 TestFtpFileSize();
5035 if ( 0 )
5036 {
5037 TestFtpList();
5038 TestFtpDownload();
5039 TestFtpMisc();
5040 TestFtpUpload();
5041 }
5042 if ( 0 )
5043 TestFtpInteractive();
5044 }
5045 //else: connecting to the FTP server failed
5046
5047 if ( 0 )
5048 TestFtpWuFtpd();
5049#endif // TEST_FTP
5050
e87271f3 5051#ifdef TEST_THREADS
696e1ea0
VZ
5052 int nCPUs = wxThread::GetCPUCount();
5053 printf("This system has %d CPUs\n", nCPUs);
5054 if ( nCPUs != -1 )
5055 wxThread::SetConcurrency(nCPUs);
ef8d96c2 5056
9fc3ad34
VZ
5057 if ( argc > 1 && argv[1][0] == 't' )
5058 wxLog::AddTraceMask("thread");
b568d04f 5059
4c460b34 5060 if ( 1 )
2f02cb89 5061 TestDetachedThreads();
4c460b34 5062 if ( 1 )
2f02cb89 5063 TestJoinableThreads();
4c460b34 5064 if ( 1 )
2f02cb89
VZ
5065 TestThreadSuspend();
5066 if ( 1 )
5067 TestThreadDelete();
5068
e87271f3 5069#endif // TEST_THREADS
37667812 5070
b76b015e 5071#ifdef TEST_LONGLONG
2a310492
VZ
5072 // seed pseudo random generator
5073 srand((unsigned)time(NULL));
5074
b76b015e 5075 if ( 0 )
2a310492 5076 {
b76b015e 5077 TestSpeed();
2a310492 5078 }
2a310492
VZ
5079 if ( 0 )
5080 {
f6bcfd97 5081 TestMultiplication();
b76b015e 5082 TestDivision();
2a310492
VZ
5083 TestAddition();
5084 TestLongLongConversion();
5085 TestBitOperations();
5086 }
f6bcfd97 5087 TestLongLongComparison();
b76b015e
VZ
5088#endif // TEST_LONGLONG
5089
2c8e4738
VZ
5090#ifdef TEST_HASH
5091 TestHash();
5092#endif // TEST_HASH
5093
696e1ea0 5094#ifdef TEST_MIME
f6bcfd97 5095 wxLog::AddTraceMask(_T("mime"));
a6c65e88 5096 if ( 1 )
c7ce8392 5097 {
f6bcfd97 5098 TestMimeEnum();
c7ce8392
VZ
5099 TestMimeOverride();
5100 TestMimeFilename();
5101 }
a6c65e88
VZ
5102 else
5103 TestMimeAssociate();
696e1ea0
VZ
5104#endif // TEST_MIME
5105
89e60357
VZ
5106#ifdef TEST_INFO_FUNCTIONS
5107 TestOsInfo();
5108 TestUserInfo();
5109#endif // TEST_INFO_FUNCTIONS
5110
39189b9d
VZ
5111#ifdef TEST_PATHLIST
5112 TestPathList();
5113#endif // TEST_PATHLIST
5114
7ba4fbeb
VZ
5115#ifdef TEST_REGCONF
5116 TestRegConfWrite();
5117#endif // TEST_REGCONF
5118
07a56e45
VZ
5119#ifdef TEST_REGEX
5120 // TODO: write a real test using src/regex/tests file
5121 if ( 0 )
5122 {
5123 TestRegExCompile();
5124 TestRegExMatch();
5125 TestRegExSubmatch();
765624f7 5126 TestRegExInteractive();
07a56e45 5127 }
765624f7 5128 TestRegExReplacement();
07a56e45
VZ
5129#endif // TEST_REGEX
5130
6dfec4b8 5131#ifdef TEST_REGISTRY
6ba63600
VZ
5132 if ( 0 )
5133 TestRegistryRead();
5134 TestRegistryAssociation();
6dfec4b8
VZ
5135#endif // TEST_REGISTRY
5136
2c8e4738 5137#ifdef TEST_SOCKETS
ccdb23df 5138 if ( 0 )
8e907a13 5139 {
f6bcfd97 5140 TestSocketServer();
8dfea369 5141 }
2e907fab 5142 TestSocketClient();
2c8e4738
VZ
5143#endif // TEST_SOCKETS
5144
83141d3a 5145#ifdef TEST_STREAMS
24f25c8a
VZ
5146 if ( 0 )
5147 TestFileStream();
83141d3a
VZ
5148 TestMemoryStream();
5149#endif // TEST_STREAMS
5150
d31b7b68
VZ
5151#ifdef TEST_TIMER
5152 TestStopWatch();
5153#endif // TEST_TIMER
5154
5155#ifdef TEST_DATETIME
df05cdc5 5156 if ( 0 )
299fcbfe 5157 {
9d9b7755
VZ
5158 TestTimeSet();
5159 TestTimeStatic();
5160 TestTimeRange();
5161 TestTimeZones();
5162 TestTimeTicks();
5163 TestTimeJDN();
5164 TestTimeDST();
5165 TestTimeWDays();
5166 TestTimeWNumber();
5167 TestTimeParse();
9d9b7755 5168 TestTimeArithmetics();
f6bcfd97
BP
5169 TestTimeHolidays();
5170 TestTimeFormat();
3ca6a5f0 5171 TestTimeMS();
f6bcfd97
BP
5172
5173 TestTimeZoneBug();
41acf5c0 5174 }
df05cdc5 5175 TestTimeSpanFormat();
9d9b7755 5176 if ( 0 )
b92fd37c 5177 TestDateTimeInteractive();
d31b7b68 5178#endif // TEST_DATETIME
b76b015e 5179
551fe3a6
VZ
5180#ifdef TEST_USLEEP
5181 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5182 wxUsleep(3000);
5183#endif // TEST_USLEEP
5184
f6bcfd97
BP
5185#ifdef TEST_VCARD
5186 if ( 0 )
5187 TestVCardRead();
5188 TestVCardWrite();
5189#endif // TEST_VCARD
5190
5191#ifdef TEST_WCHAR
5192 TestUtf8();
5193#endif // TEST_WCHAR
5194
5195#ifdef TEST_ZIP
2ca8b884
VZ
5196 if ( 0 )
5197 TestZipStreamRead();
5198 TestZipFileSystem();
f6bcfd97
BP
5199#endif // TEST_ZIP
5200
3ca6a5f0
BP
5201#ifdef TEST_ZLIB
5202 if ( 0 )
5203 TestZlibStreamWrite();
5204 TestZlibStreamRead();
5205#endif // TEST_ZLIB
5206
37667812
VZ
5207 return 0;
5208}
f6bcfd97 5209