]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
compilation fix
[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
a8625337 47#define TEST_DATETIME
9a4232dc
VZ
48//#define TEST_DIR
49//#define TEST_DLLLOADER
50//#define TEST_ENVIRON
51//#define TEST_EXECUTE
52//#define TEST_FILE
53//#define TEST_FILECONF
54//#define TEST_FILENAME
55//#define TEST_FTP
56//#define TEST_HASH
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
a8625337 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"),
a8625337 4042 _T("or also %S seconds"),
df05cdc5
VZ
4043 };
4044
4045 wxTimeSpan ts1(1, 2, 3, 4),
4046 ts2(111, 222, 333);
4047 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4048 {
4049 printf("ts1 = %s\tts2 = %s\n",
4050 ts1.Format(formats[n]).c_str(),
4051 ts2.Format(formats[n]).c_str());
4052 }
4053
4054 puts("");
4055}
4056
68ee7c47
VZ
4057#if 0
4058
97e0ceea
VZ
4059// test compatibility with the old wxDate/wxTime classes
4060static void TestTimeCompatibility()
4061{
4062 puts("\n*** wxDateTime compatibility test ***");
4063
4064 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4065 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4066
4067 double jdnNow = wxDateTime::Now().GetJDN();
4068 long jdnMidnight = (long)(jdnNow - 0.5);
4069 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4070
4071 jdnMidnight = wxDate().Set().GetJulianDate();
4072 printf("wxDateTime for today: %s\n",
4073 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4074
4075 int flags = wxEUROPEAN;//wxFULL;
4076 wxDate date;
4077 date.Set();
4078 printf("Today is %s\n", date.FormatDate(flags).c_str());
4079 for ( int n = 0; n < 7; n++ )
4080 {
4081 printf("Previous %s is %s\n",
4082 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4083 date.Previous(n + 1).FormatDate(flags).c_str());
4084 }
4085}
4086
68ee7c47
VZ
4087#endif // 0
4088
d31b7b68 4089#endif // TEST_DATETIME
b76b015e 4090
e87271f3
VZ
4091// ----------------------------------------------------------------------------
4092// threads
4093// ----------------------------------------------------------------------------
4094
4095#ifdef TEST_THREADS
4096
bbfa0322 4097#include <wx/thread.h>
37667812 4098
bbfa0322
VZ
4099static size_t gs_counter = (size_t)-1;
4100static wxCriticalSection gs_critsect;
b568d04f 4101static wxCondition gs_cond;
bbfa0322 4102
b568d04f 4103class MyJoinableThread : public wxThread
bbfa0322
VZ
4104{
4105public:
b568d04f
VZ
4106 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4107 { m_n = n; Create(); }
bbfa0322
VZ
4108
4109 // thread execution starts here
b568d04f 4110 virtual ExitCode Entry();
bbfa0322 4111
b568d04f
VZ
4112private:
4113 size_t m_n;
bbfa0322
VZ
4114};
4115
b568d04f 4116wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 4117{
b568d04f
VZ
4118 unsigned long res = 1;
4119 for ( size_t n = 1; n < m_n; n++ )
4120 {
4121 res *= n;
4122
4123 // it's a loooong calculation :-)
4124 Sleep(100);
4125 }
bbfa0322 4126
b568d04f 4127 return (ExitCode)res;
bbfa0322
VZ
4128}
4129
b568d04f
VZ
4130class MyDetachedThread : public wxThread
4131{
4132public:
fcc3d7cb
VZ
4133 MyDetachedThread(size_t n, char ch)
4134 {
4135 m_n = n;
4136 m_ch = ch;
4137 m_cancelled = FALSE;
4138
4139 Create();
4140 }
b568d04f
VZ
4141
4142 // thread execution starts here
4143 virtual ExitCode Entry();
4144
4145 // and stops here
4146 virtual void OnExit();
4147
4148private:
9fc3ad34
VZ
4149 size_t m_n; // number of characters to write
4150 char m_ch; // character to write
fcc3d7cb
VZ
4151
4152 bool m_cancelled; // FALSE if we exit normally
b568d04f
VZ
4153};
4154
4155wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
4156{
4157 {
4158 wxCriticalSectionLocker lock(gs_critsect);
4159 if ( gs_counter == (size_t)-1 )
4160 gs_counter = 1;
4161 else
4162 gs_counter++;
4163 }
4164
9fc3ad34 4165 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
4166 {
4167 if ( TestDestroy() )
fcc3d7cb
VZ
4168 {
4169 m_cancelled = TRUE;
4170
bbfa0322 4171 break;
fcc3d7cb 4172 }
bbfa0322
VZ
4173
4174 putchar(m_ch);
4175 fflush(stdout);
4176
4177 wxThread::Sleep(100);
4178 }
4179
b568d04f 4180 return 0;
bbfa0322
VZ
4181}
4182
b568d04f 4183void MyDetachedThread::OnExit()
bbfa0322 4184{
9fc3ad34
VZ
4185 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4186
bbfa0322 4187 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 4188 if ( !--gs_counter && !m_cancelled )
b568d04f 4189 gs_cond.Signal();
bbfa0322
VZ
4190}
4191
9fc3ad34
VZ
4192void TestDetachedThreads()
4193{
2f02cb89 4194 puts("\n*** Testing detached threads ***");
9fc3ad34
VZ
4195
4196 static const size_t nThreads = 3;
4197 MyDetachedThread *threads[nThreads];
4198 size_t n;
4199 for ( n = 0; n < nThreads; n++ )
4200 {
4201 threads[n] = new MyDetachedThread(10, 'A' + n);
4202 }
4203
4204 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4205 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4206
4207 for ( n = 0; n < nThreads; n++ )
4208 {
4209 threads[n]->Run();
4210 }
4211
4212 // wait until all threads terminate
4213 gs_cond.Wait();
4214
4215 puts("");
4216}
4217
4218void TestJoinableThreads()
4219{
2f02cb89 4220 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
9fc3ad34
VZ
4221
4222 // calc 10! in the background
4223 MyJoinableThread thread(10);
4224 thread.Run();
4225
4226 printf("\nThread terminated with exit code %lu.\n",
4227 (unsigned long)thread.Wait());
4228}
4229
4230void TestThreadSuspend()
4231{
2f02cb89
VZ
4232 puts("\n*** Testing thread suspend/resume functions ***");
4233
4234 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
4235
4236 thread->Run();
4237
4238 // this is for this demo only, in a real life program we'd use another
4239 // condition variable which would be signaled from wxThread::Entry() to
4240 // tell us that the thread really started running - but here just wait a
4241 // bit and hope that it will be enough (the problem is, of course, that
4242 // the thread might still not run when we call Pause() which will result
4243 // in an error)
4244 wxThread::Sleep(300);
4245
4246 for ( size_t n = 0; n < 3; n++ )
4247 {
4248 thread->Pause();
4249
4250 puts("\nThread suspended");
4251 if ( n > 0 )
4252 {
4253 // don't sleep but resume immediately the first time
4254 wxThread::Sleep(300);
4255 }
4256 puts("Going to resume the thread");
4257
4258 thread->Resume();
4259 }
4260
4c460b34
VZ
4261 puts("Waiting until it terminates now");
4262
9fc3ad34
VZ
4263 // wait until the thread terminates
4264 gs_cond.Wait();
4265
4266 puts("");
4267}
4268
2f02cb89
VZ
4269void TestThreadDelete()
4270{
4271 // As above, using Sleep() is only for testing here - we must use some
4272 // synchronisation object instead to ensure that the thread is still
4273 // running when we delete it - deleting a detached thread which already
4274 // terminated will lead to a crash!
4275
4276 puts("\n*** Testing thread delete function ***");
4277
4c460b34
VZ
4278 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4279
4280 thread0->Delete();
4281
4282 puts("\nDeleted a thread which didn't start to run yet.");
4283
2f02cb89
VZ
4284 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4285
4286 thread1->Run();
4287
4288 wxThread::Sleep(300);
4289
4290 thread1->Delete();
4291
4292 puts("\nDeleted a running thread.");
4293
4294 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4295
4296 thread2->Run();
4297
4298 wxThread::Sleep(300);
4299
4300 thread2->Pause();
4301
4302 thread2->Delete();
4303
4304 puts("\nDeleted a sleeping thread.");
4305
4c460b34
VZ
4306 MyJoinableThread thread3(20);
4307 thread3.Run();
2f02cb89 4308
4c460b34 4309 thread3.Delete();
2f02cb89
VZ
4310
4311 puts("\nDeleted a joinable thread.");
4312
4c460b34
VZ
4313 MyJoinableThread thread4(2);
4314 thread4.Run();
2f02cb89
VZ
4315
4316 wxThread::Sleep(300);
4317
4c460b34 4318 thread4.Delete();
2f02cb89
VZ
4319
4320 puts("\nDeleted a joinable thread which already terminated.");
4321
4322 puts("");
4323}
4324
e87271f3
VZ
4325#endif // TEST_THREADS
4326
4327// ----------------------------------------------------------------------------
4328// arrays
4329// ----------------------------------------------------------------------------
4330
4331#ifdef TEST_ARRAYS
4332
f6bcfd97 4333static void PrintArray(const char* name, const wxArrayString& array)
e87271f3
VZ
4334{
4335 printf("Dump of the array '%s'\n", name);
4336
4337 size_t nCount = array.GetCount();
4338 for ( size_t n = 0; n < nCount; n++ )
4339 {
4340 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4341 }
4342}
4343
d6c9c1b7
VZ
4344static void PrintArray(const char* name, const wxArrayInt& array)
4345{
4346 printf("Dump of the array '%s'\n", name);
4347
4348 size_t nCount = array.GetCount();
4349 for ( size_t n = 0; n < nCount; n++ )
4350 {
4351 printf("\t%s[%u] = %d\n", name, n, array[n]);
4352 }
4353}
4354
4355int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4356 const wxString& second)
f6bcfd97
BP
4357{
4358 return first.length() - second.length();
4359}
4360
d6c9c1b7
VZ
4361int wxCMPFUNC_CONV IntCompare(int *first,
4362 int *second)
4363{
4364 return *first - *second;
4365}
4366
4367int wxCMPFUNC_CONV IntRevCompare(int *first,
4368 int *second)
4369{
4370 return *second - *first;
4371}
4372
4373static void TestArrayOfInts()
4374{
4375 puts("*** Testing wxArrayInt ***\n");
4376
4377 wxArrayInt a;
4378 a.Add(1);
4379 a.Add(17);
4380 a.Add(5);
4381 a.Add(3);
4382
4383 puts("Initially:");
4384 PrintArray("a", a);
4385
4386 puts("After sort:");
4387 a.Sort(IntCompare);
4388 PrintArray("a", a);
4389
4390 puts("After reverse sort:");
4391 a.Sort(IntRevCompare);
4392 PrintArray("a", a);
4393}
4394
f6bcfd97
BP
4395#include "wx/dynarray.h"
4396
4397WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4398#include "wx/arrimpl.cpp"
4399WX_DEFINE_OBJARRAY(ArrayBars);
4400
4401static void TestArrayOfObjects()
4402{
4403 puts("*** Testing wxObjArray ***\n");
4404
4405 {
4406 ArrayBars bars;
4407 Bar bar("second bar");
4408
4409 printf("Initially: %u objects in the array, %u objects total.\n",
4410 bars.GetCount(), Bar::GetNumber());
4411
4412 bars.Add(new Bar("first bar"));
4413 bars.Add(bar);
4414
4415 printf("Now: %u objects in the array, %u objects total.\n",
4416 bars.GetCount(), Bar::GetNumber());
4417
4418 bars.Empty();
4419
4420 printf("After Empty(): %u objects in the array, %u objects total.\n",
4421 bars.GetCount(), Bar::GetNumber());
4422 }
4423
4424 printf("Finally: no more objects in the array, %u objects total.\n",
4425 Bar::GetNumber());
4426}
4427
e87271f3
VZ
4428#endif // TEST_ARRAYS
4429
9fc3ad34
VZ
4430// ----------------------------------------------------------------------------
4431// strings
4432// ----------------------------------------------------------------------------
4433
4434#ifdef TEST_STRINGS
4435
4436#include "wx/timer.h"
bbf8fc53 4437#include "wx/tokenzr.h"
9fc3ad34 4438
7c968cee
VZ
4439static void TestStringConstruction()
4440{
4441 puts("*** Testing wxString constructores ***");
4442
4443 #define TEST_CTOR(args, res) \
4444 { \
4445 wxString s args ; \
4446 printf("wxString%s = %s ", #args, s.c_str()); \
4447 if ( s == res ) \
4448 { \
4449 puts("(ok)"); \
4450 } \
4451 else \
4452 { \
4453 printf("(ERROR: should be %s)\n", res); \
4454 } \
4455 }
4456
4457 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
4458 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
4459 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
4460 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
4461
4462 static const wxChar *s = _T("?really!");
4463 const wxChar *start = wxStrchr(s, _T('r'));
4464 const wxChar *end = wxStrchr(s, _T('!'));
4465 TEST_CTOR((start, end), _T("really"));
4466
4467 puts("");
4468}
4469
299fcbfe 4470static void TestString()
9fc3ad34
VZ
4471{
4472 wxStopWatch sw;
4473
4474 wxString a, b, c;
4475
4476 a.reserve (128);
4477 b.reserve (128);
4478 c.reserve (128);
4479
4480 for (int i = 0; i < 1000000; ++i)
4481 {
4482 a = "Hello";
4483 b = " world";
4484 c = "! How'ya doin'?";
4485 a += b;
4486 a += c;
4487 c = "Hello world! What's up?";
4488 if (c != a)
4489 c = "Doh!";
4490 }
4491
4492 printf ("TestString elapsed time: %ld\n", sw.Time());
4493}
4494
299fcbfe 4495static void TestPChar()
9fc3ad34
VZ
4496{
4497 wxStopWatch sw;
4498
4499 char a [128];
4500 char b [128];
4501 char c [128];
4502
4503 for (int i = 0; i < 1000000; ++i)
4504 {
4505 strcpy (a, "Hello");
4506 strcpy (b, " world");
4507 strcpy (c, "! How'ya doin'?");
4508 strcat (a, b);
4509 strcat (a, c);
4510 strcpy (c, "Hello world! What's up?");
4511 if (strcmp (c, a) == 0)
4512 strcpy (c, "Doh!");
4513 }
4514
4515 printf ("TestPChar elapsed time: %ld\n", sw.Time());
4516}
4517
299fcbfe
VZ
4518static void TestStringSub()
4519{
4520 wxString s("Hello, world!");
4521
4522 puts("*** Testing wxString substring extraction ***");
4523
4524 printf("String = '%s'\n", s.c_str());
4525 printf("Left(5) = '%s'\n", s.Left(5).c_str());
4526 printf("Right(6) = '%s'\n", s.Right(6).c_str());
4527 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
4528 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
4529 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
4530 printf("substr(3) = '%s'\n", s.substr(3).c_str());
4531
f6bcfd97
BP
4532 static const wxChar *prefixes[] =
4533 {
4534 _T("Hello"),
4535 _T("Hello, "),
4536 _T("Hello, world!"),
4537 _T("Hello, world!!!"),
4538 _T(""),
4539 _T("Goodbye"),
4540 _T("Hi"),
4541 };
4542
4543 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
4544 {
4545 wxString prefix = prefixes[n], rest;
4546 bool rc = s.StartsWith(prefix, &rest);
4547 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
4548 if ( rc )
4549 {
4550 printf(" (the rest is '%s')\n", rest.c_str());
4551 }
4552 else
4553 {
4554 putchar('\n');
4555 }
4556 }
4557
299fcbfe
VZ
4558 puts("");
4559}
4560
f0f951fa
VZ
4561static void TestStringFormat()
4562{
4563 puts("*** Testing wxString formatting ***");
4564
4565 wxString s;
4566 s.Printf("%03d", 18);
4567
4568 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
4569 printf("Number 18: %s\n", s.c_str());
4570
4571 puts("");
4572}
4573
d71fa6fb
VZ
4574// returns "not found" for npos, value for all others
4575static wxString PosToString(size_t res)
4576{
4577 wxString s = res == wxString::npos ? wxString(_T("not found"))
4578 : wxString::Format(_T("%u"), res);
4579 return s;
4580}
4581
4582static void TestStringFind()
4583{
4584 puts("*** Testing wxString find() functions ***");
4585
4586 static const wxChar *strToFind = _T("ell");
4587 static const struct StringFindTest
4588 {
4589 const wxChar *str;
4590 size_t start,
4591 result; // of searching "ell" in str
4592 } findTestData[] =
4593 {
4594 { _T("Well, hello world"), 0, 1 },
4595 { _T("Well, hello world"), 6, 7 },
4596 { _T("Well, hello world"), 9, wxString::npos },
4597 };
4598
4599 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
4600 {
4601 const StringFindTest& ft = findTestData[n];
4602 size_t res = wxString(ft.str).find(strToFind, ft.start);
4603
4604 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
4605 strToFind, ft.str, ft.start, PosToString(res).c_str());
4606
4607 size_t resTrue = ft.result;
4608 if ( res == resTrue )
4609 {
4610 puts(_T("(ok)"));
4611 }
4612 else
4613 {
4614 printf(_T("(ERROR: should be %s)\n"),
4615 PosToString(resTrue).c_str());
4616 }
4617 }
4618
4619 puts("");
4620}
4621
bbf8fc53
VZ
4622static void TestStringTokenizer()
4623{
4624 puts("*** Testing wxStringTokenizer ***");
4625
7c968cee
VZ
4626 static const wxChar *modeNames[] =
4627 {
4628 _T("default"),
4629 _T("return empty"),
4630 _T("return all empty"),
4631 _T("with delims"),
4632 _T("like strtok"),
4633 };
4634
bbf8fc53
VZ
4635 static const struct StringTokenizerTest
4636 {
7c968cee
VZ
4637 const wxChar *str; // string to tokenize
4638 const wxChar *delims; // delimiters to use
4639 size_t count; // count of token
4640 wxStringTokenizerMode mode; // how should we tokenize it
4641 } tokenizerTestData[] =
4642 {
4643 { _T(""), _T(" "), 0 },
4644 { _T("Hello, world"), _T(" "), 2 },
4645 { _T("Hello, world "), _T(" "), 2 },
4646 { _T("Hello, world"), _T(","), 2 },
4647 { _T("Hello, world!"), _T(",!"), 2 },
4648 { _T("Hello,, world!"), _T(",!"), 3 },
4649 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
4650 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
4651 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
4652 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
4653 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
4654 { _T("01/02/99"), _T("/-"), 3 },
4655 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
bbf8fc53
VZ
4656 };
4657
4658 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
4659 {
4660 const StringTokenizerTest& tt = tokenizerTestData[n];
7c968cee 4661 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
bbf8fc53
VZ
4662
4663 size_t count = tkz.CountTokens();
7c968cee
VZ
4664 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
4665 MakePrintable(tt.str).c_str(),
bbf8fc53 4666 count,
7c968cee
VZ
4667 MakePrintable(tt.delims).c_str(),
4668 modeNames[tkz.GetMode()]);
bbf8fc53
VZ
4669 if ( count == tt.count )
4670 {
4671 puts(_T("(ok)"));
4672 }
4673 else
4674 {
4675 printf(_T("(ERROR: should be %u)\n"), tt.count);
4676
4677 continue;
4678 }
4679
7c968cee 4680 // if we emulate strtok(), check that we do it correctly
f6bcfd97 4681 wxChar *buf, *s = NULL, *last;
7c968cee
VZ
4682
4683 if ( tkz.GetMode() == wxTOKEN_STRTOK )
4684 {
4685 buf = new wxChar[wxStrlen(tt.str) + 1];
4686 wxStrcpy(buf, tt.str);
4687
4688 s = wxStrtok(buf, tt.delims, &last);
4689 }
4690 else
4691 {
4692 buf = NULL;
4693 }
4694
bbf8fc53
VZ
4695 // now show the tokens themselves
4696 size_t count2 = 0;
4697 while ( tkz.HasMoreTokens() )
4698 {
7c968cee
VZ
4699 wxString token = tkz.GetNextToken();
4700
4701 printf(_T("\ttoken %u: '%s'"),
bbf8fc53 4702 ++count2,
7c968cee
VZ
4703 MakePrintable(token).c_str());
4704
4705 if ( buf )
4706 {
4707 if ( token == s )
4708 {
4709 puts(" (ok)");
4710 }
4711 else
4712 {
4713 printf(" (ERROR: should be %s)\n", s);
4714 }
4715
4716 s = wxStrtok(NULL, tt.delims, &last);
4717 }
4718 else
4719 {
4720 // nothing to compare with
4721 puts("");
4722 }
bbf8fc53
VZ
4723 }
4724
4725 if ( count2 != count )
4726 {
7c968cee 4727 puts(_T("\tERROR: token count mismatch"));
bbf8fc53 4728 }
7c968cee
VZ
4729
4730 delete [] buf;
bbf8fc53
VZ
4731 }
4732
4733 puts("");
4734}
4735
f6bcfd97
BP
4736static void TestStringReplace()
4737{
4738 puts("*** Testing wxString::replace ***");
4739
4740 static const struct StringReplaceTestData
4741 {
4742 const wxChar *original; // original test string
4743 size_t start, len; // the part to replace
4744 const wxChar *replacement; // the replacement string
4745 const wxChar *result; // and the expected result
4746 } stringReplaceTestData[] =
4747 {
4748 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
4749 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
4750 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
4751 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
4752 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
4753 };
4754
4755 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
4756 {
4757 const StringReplaceTestData data = stringReplaceTestData[n];
4758
4759 wxString original = data.original;
4760 original.replace(data.start, data.len, data.replacement);
4761
4762 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
4763 data.original, data.start, data.len, data.replacement,
4764 original.c_str());
4765
4766 if ( original == data.result )
4767 {
4768 puts("(ok)");
4769 }
4770 else
4771 {
4772 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
4773 }
4774 }
4775
4776 puts("");
4777}
4778
9a4232dc
VZ
4779static void TestStringMatch()
4780{
4781 wxPuts(_T("*** Testing wxString::Matches() ***"));
4782
4783 static const struct StringMatchTestData
4784 {
4785 const wxChar *text;
4786 const wxChar *wildcard;
4787 bool matches;
4788 } stringMatchTestData[] =
4789 {
4790 { _T("foobar"), _T("foo*"), 1 },
4791 { _T("foobar"), _T("*oo*"), 1 },
4792 { _T("foobar"), _T("*bar"), 1 },
4793 { _T("foobar"), _T("??????"), 1 },
4794 { _T("foobar"), _T("f??b*"), 1 },
4795 { _T("foobar"), _T("f?b*"), 0 },
4796 { _T("foobar"), _T("*goo*"), 0 },
4797 { _T("foobar"), _T("*foo"), 0 },
4798 { _T("foobarfoo"), _T("*foo"), 1 },
4799 { _T(""), _T("*"), 1 },
4800 { _T(""), _T("?"), 0 },
4801 };
4802
4803 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
4804 {
4805 const StringMatchTestData& data = stringMatchTestData[n];
4806 bool matches = wxString(data.text).Matches(data.wildcard);
4807 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
4808 data.wildcard,
4809 matches ? _T("matches") : _T("doesn't match"),
4810 data.text,
4811 matches == data.matches ? _T("ok") : _T("ERROR"));
4812 }
4813
4814 wxPuts(_T(""));
4815}
4816
9fc3ad34
VZ
4817#endif // TEST_STRINGS
4818
e87271f3
VZ
4819// ----------------------------------------------------------------------------
4820// entry point
4821// ----------------------------------------------------------------------------
4822
bbfa0322 4823int main(int argc, char **argv)
37667812 4824{
58b24a56
VZ
4825 wxInitializer initializer;
4826 if ( !initializer )
37667812
VZ
4827 {
4828 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
4829
4830 return -1;
4831 }
4832
4833#ifdef TEST_SNGLINST
b5299791
VZ
4834 wxSingleInstanceChecker checker;
4835 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 4836 {
b5299791
VZ
4837 if ( checker.IsAnotherRunning() )
4838 {
4839 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 4840
b5299791
VZ
4841 return 1;
4842 }
37667812 4843
b5299791
VZ
4844 // wait some time to give time to launch another instance
4845 wxPrintf(_T("Press \"Enter\" to continue..."));
4846 wxFgetc(stdin);
4847 }
4848 else // failed to create
4849 {
4850 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4851 }
58b24a56
VZ
4852#endif // TEST_SNGLINST
4853
551fe3a6
VZ
4854#ifdef TEST_CHARSET
4855 TestCharset();
4856#endif // TEST_CHARSET
0de868d9 4857
d34bce84
VZ
4858#ifdef TEST_CMDLINE
4859 static const wxCmdLineEntryDesc cmdLineDesc[] =
4860 {
4861 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
4862 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
4863
4864 { wxCMD_LINE_OPTION, "o", "output", "output file" },
4865 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
4866 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
1e245dc2 4867 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
d34bce84
VZ
4868
4869 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
4870 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4871
4872 { wxCMD_LINE_NONE }
4873 };
4874
4875 wxCmdLineParser parser(cmdLineDesc, argc, argv);
4876
f6bcfd97
BP
4877 parser.AddOption("project_name", "", "full path to project file",
4878 wxCMD_LINE_VAL_STRING,
4879 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4880
d34bce84
VZ
4881 switch ( parser.Parse() )
4882 {
4883 case -1:
4884 wxLogMessage("Help was given, terminating.");
4885 break;
4886
4887 case 0:
4888 ShowCmdLine(parser);
4889 break;
4890
4891 default:
4892 wxLogMessage("Syntax error detected, aborting.");
4893 break;
4894 }
4895#endif // TEST_CMDLINE
4896
9fc3ad34 4897#ifdef TEST_STRINGS
299fcbfe
VZ
4898 if ( 0 )
4899 {
4900 TestPChar();
4901 TestString();
f6bcfd97 4902 TestStringSub();
7c968cee 4903 TestStringConstruction();
d71fa6fb 4904 TestStringFormat();
bbf8fc53 4905 TestStringFind();
7c968cee 4906 TestStringTokenizer();
f6bcfd97 4907 TestStringReplace();
ee6e1b1d 4908 }
9a4232dc 4909 TestStringMatch();
9fc3ad34
VZ
4910#endif // TEST_STRINGS
4911
e87271f3 4912#ifdef TEST_ARRAYS
d6c9c1b7
VZ
4913 if ( 0 )
4914 {
e87271f3
VZ
4915 wxArrayString a1;
4916 a1.Add("tiger");
4917 a1.Add("cat");
4918 a1.Add("lion");
4919 a1.Add("dog");
4920 a1.Add("human");
4921 a1.Add("ape");
4922
4923 puts("*** Initially:");
4924
4925 PrintArray("a1", a1);
4926
4927 wxArrayString a2(a1);
4928 PrintArray("a2", a2);
4929
4930 wxSortedArrayString a3(a1);
4931 PrintArray("a3", a3);
4932
4933 puts("*** After deleting a string from a1");
4934 a1.Remove(2);
4935
4936 PrintArray("a1", a1);
4937 PrintArray("a2", a2);
4938 PrintArray("a3", a3);
4939
4940 puts("*** After reassigning a1 to a2 and a3");
4941 a3 = a2 = a1;
4942 PrintArray("a2", a2);
4943 PrintArray("a3", a3);
f6bcfd97
BP
4944
4945 puts("*** After sorting a1");
4946 a1.Sort();
4947 PrintArray("a1", a1);
4948
4949 puts("*** After sorting a1 in reverse order");
4950 a1.Sort(TRUE);
4951 PrintArray("a1", a1);
4952
4953 puts("*** After sorting a1 by the string length");
4954 a1.Sort(StringLenCompare);
4955 PrintArray("a1", a1);
4956
4957 TestArrayOfObjects();
d6c9c1b7
VZ
4958 }
4959 TestArrayOfInts();
e87271f3
VZ
4960#endif // TEST_ARRAYS
4961
1944c6bd 4962#ifdef TEST_DIR
35332784
VZ
4963 if ( 0 )
4964 TestDirEnum();
4965 TestDirTraverse();
1944c6bd
VZ
4966#endif // TEST_DIR
4967
f6bcfd97
BP
4968#ifdef TEST_DLLLOADER
4969 TestDllLoad();
4970#endif // TEST_DLLLOADER
4971
8fd0d89b
VZ
4972#ifdef TEST_ENVIRON
4973 TestEnvironment();
4974#endif // TEST_ENVIRON
4975
d93c719a
VZ
4976#ifdef TEST_EXECUTE
4977 TestExecute();
4978#endif // TEST_EXECUTE
4979
ee6e1b1d
VZ
4980#ifdef TEST_FILECONF
4981 TestFileConfRead();
4982#endif // TEST_FILECONF
4983
f6bcfd97
BP
4984#ifdef TEST_LIST
4985 TestListCtor();
4986#endif // TEST_LIST
4987
ec37df57
VZ
4988#ifdef TEST_LOCALE
4989 TestDefaultLang();
4990#endif // TEST_LOCALE
4991
378b05f7
VZ
4992#ifdef TEST_LOG
4993 wxString s;
4994 for ( size_t n = 0; n < 8000; n++ )
4995 {
4996 s << (char)('A' + (n % 26));
4997 }
4998
4999 wxString msg;
5000 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5001
5002 // this one shouldn't be truncated
5003 printf(msg);
5004
5005 // but this one will because log functions use fixed size buffer
b568d04f
VZ
5006 // (note that it doesn't need '\n' at the end neither - will be added
5007 // by wxLog anyhow)
5008 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
378b05f7
VZ
5009#endif // TEST_LOG
5010
f6bcfd97 5011#ifdef TEST_FILE
3ca6a5f0 5012 if ( 0 )
a339970a 5013 {
3ca6a5f0 5014 TestFileRead();
a339970a
VZ
5015 TestTextFileRead();
5016 }
5017 TestFileCopy();
f6bcfd97
BP
5018#endif // TEST_FILE
5019
844f90fb 5020#ifdef TEST_FILENAME
42b1f941 5021 TestFileNameSplit();
9e8d8607
VZ
5022 if ( 0 )
5023 {
42b1f941 5024 TestFileNameConstruction();
9e8d8607
VZ
5025 TestFileNameCwd();
5026 TestFileNameComparison();
5027 TestFileNameOperations();
5028 }
844f90fb
VZ
5029#endif // TEST_FILENAME
5030
07a56e45
VZ
5031#ifdef TEST_FTP
5032 wxLog::AddTraceMask(FTP_TRACE_MASK);
5033 if ( TestFtpConnect() )
5034 {
5035 TestFtpFileSize();
5036 if ( 0 )
5037 {
5038 TestFtpList();
5039 TestFtpDownload();
5040 TestFtpMisc();
5041 TestFtpUpload();
5042 }
5043 if ( 0 )
5044 TestFtpInteractive();
5045 }
5046 //else: connecting to the FTP server failed
5047
5048 if ( 0 )
5049 TestFtpWuFtpd();
5050#endif // TEST_FTP
5051
e87271f3 5052#ifdef TEST_THREADS
696e1ea0
VZ
5053 int nCPUs = wxThread::GetCPUCount();
5054 printf("This system has %d CPUs\n", nCPUs);
5055 if ( nCPUs != -1 )
5056 wxThread::SetConcurrency(nCPUs);
ef8d96c2 5057
9fc3ad34
VZ
5058 if ( argc > 1 && argv[1][0] == 't' )
5059 wxLog::AddTraceMask("thread");
b568d04f 5060
4c460b34 5061 if ( 1 )
2f02cb89 5062 TestDetachedThreads();
4c460b34 5063 if ( 1 )
2f02cb89 5064 TestJoinableThreads();
4c460b34 5065 if ( 1 )
2f02cb89
VZ
5066 TestThreadSuspend();
5067 if ( 1 )
5068 TestThreadDelete();
5069
e87271f3 5070#endif // TEST_THREADS
37667812 5071
b76b015e 5072#ifdef TEST_LONGLONG
2a310492
VZ
5073 // seed pseudo random generator
5074 srand((unsigned)time(NULL));
5075
b76b015e 5076 if ( 0 )
2a310492 5077 {
b76b015e 5078 TestSpeed();
2a310492 5079 }
2a310492
VZ
5080 if ( 0 )
5081 {
f6bcfd97 5082 TestMultiplication();
b76b015e 5083 TestDivision();
2a310492
VZ
5084 TestAddition();
5085 TestLongLongConversion();
5086 TestBitOperations();
5087 }
f6bcfd97 5088 TestLongLongComparison();
b76b015e
VZ
5089#endif // TEST_LONGLONG
5090
2c8e4738
VZ
5091#ifdef TEST_HASH
5092 TestHash();
5093#endif // TEST_HASH
5094
696e1ea0 5095#ifdef TEST_MIME
f6bcfd97 5096 wxLog::AddTraceMask(_T("mime"));
a6c65e88 5097 if ( 1 )
c7ce8392 5098 {
f6bcfd97 5099 TestMimeEnum();
c7ce8392
VZ
5100 TestMimeOverride();
5101 TestMimeFilename();
5102 }
a6c65e88
VZ
5103 else
5104 TestMimeAssociate();
696e1ea0
VZ
5105#endif // TEST_MIME
5106
89e60357
VZ
5107#ifdef TEST_INFO_FUNCTIONS
5108 TestOsInfo();
5109 TestUserInfo();
5110#endif // TEST_INFO_FUNCTIONS
5111
39189b9d
VZ
5112#ifdef TEST_PATHLIST
5113 TestPathList();
5114#endif // TEST_PATHLIST
5115
7ba4fbeb
VZ
5116#ifdef TEST_REGCONF
5117 TestRegConfWrite();
5118#endif // TEST_REGCONF
5119
07a56e45
VZ
5120#ifdef TEST_REGEX
5121 // TODO: write a real test using src/regex/tests file
5122 if ( 0 )
5123 {
5124 TestRegExCompile();
5125 TestRegExMatch();
5126 TestRegExSubmatch();
765624f7 5127 TestRegExInteractive();
07a56e45 5128 }
765624f7 5129 TestRegExReplacement();
07a56e45
VZ
5130#endif // TEST_REGEX
5131
6dfec4b8 5132#ifdef TEST_REGISTRY
6ba63600
VZ
5133 if ( 0 )
5134 TestRegistryRead();
5135 TestRegistryAssociation();
6dfec4b8
VZ
5136#endif // TEST_REGISTRY
5137
2c8e4738 5138#ifdef TEST_SOCKETS
ccdb23df 5139 if ( 0 )
8e907a13 5140 {
f6bcfd97 5141 TestSocketServer();
8dfea369 5142 }
2e907fab 5143 TestSocketClient();
2c8e4738
VZ
5144#endif // TEST_SOCKETS
5145
83141d3a 5146#ifdef TEST_STREAMS
24f25c8a
VZ
5147 if ( 0 )
5148 TestFileStream();
83141d3a
VZ
5149 TestMemoryStream();
5150#endif // TEST_STREAMS
5151
d31b7b68
VZ
5152#ifdef TEST_TIMER
5153 TestStopWatch();
5154#endif // TEST_TIMER
5155
5156#ifdef TEST_DATETIME
df05cdc5 5157 if ( 0 )
299fcbfe 5158 {
9d9b7755
VZ
5159 TestTimeSet();
5160 TestTimeStatic();
5161 TestTimeRange();
5162 TestTimeZones();
5163 TestTimeTicks();
5164 TestTimeJDN();
5165 TestTimeDST();
5166 TestTimeWDays();
5167 TestTimeWNumber();
5168 TestTimeParse();
9d9b7755 5169 TestTimeArithmetics();
f6bcfd97
BP
5170 TestTimeHolidays();
5171 TestTimeFormat();
3ca6a5f0 5172 TestTimeMS();
f6bcfd97
BP
5173
5174 TestTimeZoneBug();
41acf5c0 5175 }
df05cdc5 5176 TestTimeSpanFormat();
9d9b7755 5177 if ( 0 )
b92fd37c 5178 TestDateTimeInteractive();
d31b7b68 5179#endif // TEST_DATETIME
b76b015e 5180
551fe3a6
VZ
5181#ifdef TEST_USLEEP
5182 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5183 wxUsleep(3000);
5184#endif // TEST_USLEEP
5185
f6bcfd97
BP
5186#ifdef TEST_VCARD
5187 if ( 0 )
5188 TestVCardRead();
5189 TestVCardWrite();
5190#endif // TEST_VCARD
5191
5192#ifdef TEST_WCHAR
5193 TestUtf8();
5194#endif // TEST_WCHAR
5195
5196#ifdef TEST_ZIP
2ca8b884
VZ
5197 if ( 0 )
5198 TestZipStreamRead();
5199 TestZipFileSystem();
f6bcfd97
BP
5200#endif // TEST_ZIP
5201
3ca6a5f0
BP
5202#ifdef TEST_ZLIB
5203 if ( 0 )
5204 TestZlibStreamWrite();
5205 TestZlibStreamRead();
5206#endif // TEST_ZLIB
5207
37667812
VZ
5208 return 0;
5209}
f6bcfd97 5210