]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
added (woefully incomplete) Japanese translations
[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
e84010cf 20#include "wx/defs.h"
b11a23f3
VZ
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
e84010cf
GD
28#include "wx/string.h"
29#include "wx/file.h"
30#include "wx/app.h"
e046e5f1 31#include "wx/log.h"
e87271f3 32
d31b7b68
VZ
33// without this pragma, the stupid compiler precompiles #defines below so that
34// changing them doesn't "take place" later!
35#ifdef __VISUALC__
36 #pragma hdrstop
37#endif
38
e87271f3
VZ
39// ----------------------------------------------------------------------------
40// conditional compilation
41// ----------------------------------------------------------------------------
42
daa2c7d9
VZ
43/*
44 A note about all these conditional compilation macros: this file is used
45 both as a test suite for various non-GUI wxWindows classes and as a
46 scratchpad for quick tests. So there are two compilation modes: if you
47 define TEST_ALL all tests are run, otherwise you may enable the individual
48 tests individually in the "#else" branch below.
49 */
50
31f6de22 51// what to test (in alphabetic order)? uncomment the line below to do all tests
2b5f62a0 52//#define TEST_ALL
31f6de22
VZ
53#ifdef TEST_ALL
54 #define TEST_ARRAYS
55 #define TEST_CHARSET
56 #define TEST_CMDLINE
57 #define TEST_DATETIME
58 #define TEST_DIR
59 #define TEST_DLLLOADER
60 #define TEST_ENVIRON
61 #define TEST_EXECUTE
62 #define TEST_FILE
63 #define TEST_FILECONF
64 #define TEST_FILENAME
65 #define TEST_FILETIME
66 #define TEST_FTP
67 #define TEST_HASH
0508ba2a 68 #define TEST_HASHMAP
31f6de22
VZ
69 #define TEST_INFO_FUNCTIONS
70 #define TEST_LIST
71 #define TEST_LOCALE
72 #define TEST_LOG
73 #define TEST_LONGLONG
74 #define TEST_MIME
75 #define TEST_PATHLIST
8d5eff60 76 #define TEST_ODBC
7aeebdcd 77 #define TEST_PRINTF
31f6de22
VZ
78 #define TEST_REGCONF
79 #define TEST_REGEX
80 #define TEST_REGISTRY
81 #define TEST_SNGLINST
82 #define TEST_SOCKETS
83 #define TEST_STREAMS
84 #define TEST_STRINGS
39937656 85 #define TEST_TEXTSTREAM
31f6de22
VZ
86 #define TEST_THREADS
87 #define TEST_TIMER
e7d41190 88 #define TEST_UNICODE
31f6de22 89 // #define TEST_VCARD -- don't enable this (VZ)
0e2c5534 90 #define TEST_VOLUME
31f6de22
VZ
91 #define TEST_WCHAR
92 #define TEST_ZIP
93 #define TEST_ZLIB
daa2c7d9
VZ
94
95 #undef TEST_ALL
cab8f76e 96 static const bool TEST_ALL = true;
31f6de22 97#else
cab8f76e 98 #define TEST_SOCKETS
daa2c7d9 99
cab8f76e 100 static const bool TEST_ALL = false;
31f6de22 101#endif
f6bcfd97 102
daa2c7d9
VZ
103// some tests are interactive, define this to run them
104#ifdef TEST_INTERACTIVE
105 #undef TEST_INTERACTIVE
106
cab8f76e 107 static const bool TEST_INTERACTIVE = true;
daa2c7d9 108#else
cab8f76e 109 static const bool TEST_INTERACTIVE = false;
daa2c7d9 110#endif
58b24a56 111
f6bcfd97
BP
112// ----------------------------------------------------------------------------
113// test class for container objects
114// ----------------------------------------------------------------------------
115
116#if defined(TEST_ARRAYS) || defined(TEST_LIST)
117
118class Bar // Foo is already taken in the hash test
119{
120public:
121 Bar(const wxString& name) : m_name(name) { ms_bars++; }
3dc01741 122 Bar(const Bar& bar) : m_name(bar.m_name) { ms_bars++; }
f6bcfd97
BP
123 ~Bar() { ms_bars--; }
124
125 static size_t GetNumber() { return ms_bars; }
126
456ae26d 127 const wxChar *GetName() const { return m_name; }
f6bcfd97
BP
128
129private:
130 wxString m_name;
131
132 static size_t ms_bars;
133};
134
135size_t Bar::ms_bars = 0;
136
137#endif // defined(TEST_ARRAYS) || defined(TEST_LIST)
e87271f3
VZ
138
139// ============================================================================
140// implementation
141// ============================================================================
142
8e907a13
VZ
143// ----------------------------------------------------------------------------
144// helper functions
145// ----------------------------------------------------------------------------
146
147#if defined(TEST_STRINGS) || defined(TEST_SOCKETS)
148
149// replace TABs with \t and CRs with \n
150static wxString MakePrintable(const wxChar *s)
151{
152 wxString str(s);
153 (void)str.Replace(_T("\t"), _T("\\t"));
154 (void)str.Replace(_T("\n"), _T("\\n"));
155 (void)str.Replace(_T("\r"), _T("\\r"));
156
157 return str;
158}
159
160#endif // MakePrintable() is used
161
551fe3a6
VZ
162// ----------------------------------------------------------------------------
163// wxFontMapper::CharsetToEncoding
164// ----------------------------------------------------------------------------
165
166#ifdef TEST_CHARSET
167
e84010cf 168#include "wx/fontmap.h"
551fe3a6
VZ
169
170static void TestCharset()
171{
172 static const wxChar *charsets[] =
173 {
174 // some vali charsets
175 _T("us-ascii "),
176 _T("iso8859-1 "),
177 _T("iso-8859-12 "),
178 _T("koi8-r "),
179 _T("utf-7 "),
180 _T("cp1250 "),
181 _T("windows-1252"),
182
183 // and now some bogus ones
184 _T(" "),
185 _T("cp1249 "),
186 _T("iso--8859-1 "),
187 _T("iso-8859-19 "),
188 };
189
190 for ( size_t n = 0; n < WXSIZEOF(charsets); n++ )
191 {
142b3bc2 192 wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charsets[n]);
551fe3a6
VZ
193 wxPrintf(_T("Charset: %s\tEncoding: %s (%s)\n"),
194 charsets[n],
142b3bc2
VS
195 wxFontMapper::Get()->GetEncodingName(enc).c_str(),
196 wxFontMapper::Get()->GetEncodingDescription(enc).c_str());
551fe3a6
VZ
197 }
198}
199
200#endif // TEST_CHARSET
201
d34bce84
VZ
202// ----------------------------------------------------------------------------
203// wxCmdLineParser
204// ----------------------------------------------------------------------------
205
d31b7b68
VZ
206#ifdef TEST_CMDLINE
207
e84010cf
GD
208#include "wx/cmdline.h"
209#include "wx/datetime.h"
d34bce84 210
31f6de22
VZ
211#if wxUSE_CMDLINE_PARSER
212
d34bce84
VZ
213static void ShowCmdLine(const wxCmdLineParser& parser)
214{
456ae26d 215 wxString s = _T("Input files: ");
d34bce84
VZ
216
217 size_t count = parser.GetParamCount();
218 for ( size_t param = 0; param < count; param++ )
219 {
220 s << parser.GetParam(param) << ' ';
221 }
222
223 s << '\n'
456ae26d
VZ
224 << _T("Verbose:\t") << (parser.Found(_T("v")) ? _T("yes") : _T("no")) << '\n'
225 << _T("Quiet:\t") << (parser.Found(_T("q")) ? _T("yes") : _T("no")) << '\n';
d34bce84
VZ
226
227 wxString strVal;
228 long lVal;
229 wxDateTime dt;
456ae26d
VZ
230 if ( parser.Found(_T("o"), &strVal) )
231 s << _T("Output file:\t") << strVal << '\n';
232 if ( parser.Found(_T("i"), &strVal) )
233 s << _T("Input dir:\t") << strVal << '\n';
234 if ( parser.Found(_T("s"), &lVal) )
235 s << _T("Size:\t") << lVal << '\n';
236 if ( parser.Found(_T("d"), &dt) )
237 s << _T("Date:\t") << dt.FormatISODate() << '\n';
238 if ( parser.Found(_T("project_name"), &strVal) )
239 s << _T("Project:\t") << strVal << '\n';
d34bce84
VZ
240
241 wxLogMessage(s);
242}
243
31f6de22
VZ
244#endif // wxUSE_CMDLINE_PARSER
245
246static void TestCmdLineConvert()
247{
456ae26d 248 static const wxChar *cmdlines[] =
31f6de22 249 {
456ae26d
VZ
250 _T("arg1 arg2"),
251 _T("-a \"-bstring 1\" -c\"string 2\" \"string 3\""),
252 _T("literal \\\" and \"\""),
31f6de22
VZ
253 };
254
255 for ( size_t n = 0; n < WXSIZEOF(cmdlines); n++ )
256 {
456ae26d
VZ
257 const wxChar *cmdline = cmdlines[n];
258 wxPrintf(_T("Parsing: %s\n"), cmdline);
31f6de22
VZ
259 wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdline);
260
261 size_t count = args.GetCount();
456ae26d 262 wxPrintf(_T("\targc = %u\n"), count);
31f6de22
VZ
263 for ( size_t arg = 0; arg < count; arg++ )
264 {
456ae26d 265 wxPrintf(_T("\targv[%u] = %s\n"), arg, args[arg].c_str());
31f6de22
VZ
266 }
267 }
268}
269
d34bce84
VZ
270#endif // TEST_CMDLINE
271
1944c6bd
VZ
272// ----------------------------------------------------------------------------
273// wxDir
274// ----------------------------------------------------------------------------
275
276#ifdef TEST_DIR
277
e84010cf 278#include "wx/dir.h"
1944c6bd 279
35332784
VZ
280#ifdef __UNIX__
281 static const wxChar *ROOTDIR = _T("/");
2f0c19d0 282 static const wxChar *TESTDIR = _T("/usr/local/share");
35332784
VZ
283#elif defined(__WXMSW__)
284 static const wxChar *ROOTDIR = _T("c:\\");
285 static const wxChar *TESTDIR = _T("d:\\");
286#else
287 #error "don't know where the root directory is"
288#endif
289
1944c6bd
VZ
290static void TestDirEnumHelper(wxDir& dir,
291 int flags = wxDIR_DEFAULT,
292 const wxString& filespec = wxEmptyString)
293{
294 wxString filename;
295
296 if ( !dir.IsOpened() )
297 return;
298
299 bool cont = dir.GetFirst(&filename, filespec, flags);
300 while ( cont )
301 {
456ae26d 302 wxPrintf(_T("\t%s\n"), filename.c_str());
1944c6bd
VZ
303
304 cont = dir.GetNext(&filename);
305 }
306
456ae26d 307 wxPuts(_T(""));
1944c6bd
VZ
308}
309
310static void TestDirEnum()
311{
456ae26d 312 wxPuts(_T("*** Testing wxDir::GetFirst/GetNext ***"));
35332784 313
149147e1 314 wxString cwd = wxGetCwd();
9475670f 315 if ( !wxDir::Exists(cwd) )
149147e1 316 {
456ae26d 317 wxPrintf(_T("ERROR: current directory '%s' doesn't exist?\n"), cwd.c_str());
149147e1
VZ
318 return;
319 }
320
ee3ef281 321 wxDir dir(cwd);
149147e1
VZ
322 if ( !dir.IsOpened() )
323 {
456ae26d 324 wxPrintf(_T("ERROR: failed to open current directory '%s'.\n"), cwd.c_str());
149147e1
VZ
325 return;
326 }
1944c6bd 327
456ae26d 328 wxPuts(_T("Enumerating everything in current directory:"));
1944c6bd
VZ
329 TestDirEnumHelper(dir);
330
456ae26d 331 wxPuts(_T("Enumerating really everything in current directory:"));
1944c6bd
VZ
332 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
333
456ae26d 334 wxPuts(_T("Enumerating object files in current directory:"));
ee3ef281 335 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o*");
1944c6bd 336
456ae26d 337 wxPuts(_T("Enumerating directories in current directory:"));
1944c6bd
VZ
338 TestDirEnumHelper(dir, wxDIR_DIRS);
339
456ae26d 340 wxPuts(_T("Enumerating files in current directory:"));
1944c6bd
VZ
341 TestDirEnumHelper(dir, wxDIR_FILES);
342
456ae26d 343 wxPuts(_T("Enumerating files including hidden in current directory:"));
1944c6bd
VZ
344 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
345
35332784 346 dir.Open(ROOTDIR);
1944c6bd 347
456ae26d 348 wxPuts(_T("Enumerating everything in root directory:"));
1944c6bd
VZ
349 TestDirEnumHelper(dir, wxDIR_DEFAULT);
350
456ae26d 351 wxPuts(_T("Enumerating directories in root directory:"));
1944c6bd
VZ
352 TestDirEnumHelper(dir, wxDIR_DIRS);
353
456ae26d 354 wxPuts(_T("Enumerating files in root directory:"));
1944c6bd
VZ
355 TestDirEnumHelper(dir, wxDIR_FILES);
356
456ae26d 357 wxPuts(_T("Enumerating files including hidden in root directory:"));
1944c6bd
VZ
358 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
359
456ae26d 360 wxPuts(_T("Enumerating files in non existing directory:"));
1944c6bd
VZ
361 wxDir dirNo("nosuchdir");
362 TestDirEnumHelper(dirNo);
363}
364
35332784
VZ
365class DirPrintTraverser : public wxDirTraverser
366{
367public:
368 virtual wxDirTraverseResult OnFile(const wxString& filename)
369 {
370 return wxDIR_CONTINUE;
371 }
372
373 virtual wxDirTraverseResult OnDir(const wxString& dirname)
374 {
375 wxString path, name, ext;
376 wxSplitPath(dirname, &path, &name, &ext);
377
378 if ( !ext.empty() )
379 name << _T('.') << ext;
380
381 wxString indent;
382 for ( const wxChar *p = path.c_str(); *p; p++ )
383 {
384 if ( wxIsPathSeparator(*p) )
385 indent += _T(" ");
386 }
387
456ae26d 388 wxPrintf(_T("%s%s\n"), indent.c_str(), name.c_str());
35332784
VZ
389
390 return wxDIR_CONTINUE;
391 }
392};
393
394static void TestDirTraverse()
395{
456ae26d 396 wxPuts(_T("*** Testing wxDir::Traverse() ***"));
35332784
VZ
397
398 // enum all files
399 wxArrayString files;
400 size_t n = wxDir::GetAllFiles(TESTDIR, &files);
456ae26d 401 wxPrintf(_T("There are %u files under '%s'\n"), n, TESTDIR);
35332784
VZ
402 if ( n > 1 )
403 {
456ae26d
VZ
404 wxPrintf(_T("First one is '%s'\n"), files[0u].c_str());
405 wxPrintf(_T(" last one is '%s'\n"), files[n - 1].c_str());
35332784
VZ
406 }
407
408 // enum again with custom traverser
2f0c19d0 409 wxPuts(_T("Now enumerating directories:"));
35332784
VZ
410 wxDir dir(TESTDIR);
411 DirPrintTraverser traverser;
412 dir.Traverse(traverser, _T(""), wxDIR_DIRS | wxDIR_HIDDEN);
413}
414
149147e1
VZ
415static void TestDirExists()
416{
417 wxPuts(_T("*** Testing wxDir::Exists() ***"));
418
456ae26d 419 static const wxChar *dirnames[] =
149147e1
VZ
420 {
421 _T("."),
422#if defined(__WXMSW__)
423 _T("c:"),
424 _T("c:\\"),
425 _T("\\\\share\\file"),
426 _T("c:\\dos"),
427 _T("c:\\dos\\"),
428 _T("c:\\dos\\\\"),
429 _T("c:\\autoexec.bat"),
430#elif defined(__UNIX__)
431 _T("/"),
432 _T("//"),
433 _T("/usr/bin"),
434 _T("/usr//bin"),
435 _T("/usr///bin"),
436#endif
437 };
438
439 for ( size_t n = 0; n < WXSIZEOF(dirnames); n++ )
440 {
456ae26d
VZ
441 wxPrintf(_T("%-40s: %s\n"),
442 dirnames[n],
443 wxDir::Exists(dirnames[n]) ? _T("exists")
444 : _T("doesn't exist"));
149147e1
VZ
445 }
446}
447
1944c6bd
VZ
448#endif // TEST_DIR
449
f6bcfd97
BP
450// ----------------------------------------------------------------------------
451// wxDllLoader
452// ----------------------------------------------------------------------------
453
454#ifdef TEST_DLLLOADER
455
e84010cf 456#include "wx/dynlib.h"
f6bcfd97
BP
457
458static void TestDllLoad()
459{
460#if defined(__WXMSW__)
461 static const wxChar *LIB_NAME = _T("kernel32.dll");
462 static const wxChar *FUNC_NAME = _T("lstrlenA");
463#elif defined(__UNIX__)
464 // weird: using just libc.so does *not* work!
465 static const wxChar *LIB_NAME = _T("/lib/libc-2.0.7.so");
466 static const wxChar *FUNC_NAME = _T("strlen");
467#else
468 #error "don't know how to test wxDllLoader on this platform"
469#endif
470
456ae26d 471 wxPuts(_T("*** testing wxDllLoader ***\n"));
f6bcfd97 472
456ae26d
VZ
473 wxDynamicLibrary lib(LIB_NAME);
474 if ( !lib.IsLoaded() )
f6bcfd97
BP
475 {
476 wxPrintf(_T("ERROR: failed to load '%s'.\n"), LIB_NAME);
477 }
478 else
479 {
456ae26d
VZ
480 typedef int (*wxStrlenType)(const char *);
481 wxStrlenType pfnStrlen = (wxStrlenType)lib.GetSymbol(FUNC_NAME);
f6bcfd97
BP
482 if ( !pfnStrlen )
483 {
484 wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
485 FUNC_NAME, LIB_NAME);
486 }
487 else
488 {
489 if ( pfnStrlen("foo") != 3 )
490 {
456ae26d 491 wxPrintf(_T("ERROR: loaded function is not wxStrlen()!\n"));
f6bcfd97
BP
492 }
493 else
494 {
456ae26d 495 wxPuts(_T("... ok"));
f6bcfd97
BP
496 }
497 }
f6bcfd97
BP
498 }
499}
500
501#endif // TEST_DLLLOADER
502
8fd0d89b
VZ
503// ----------------------------------------------------------------------------
504// wxGet/SetEnv
505// ----------------------------------------------------------------------------
506
507#ifdef TEST_ENVIRON
508
e84010cf 509#include "wx/utils.h"
8fd0d89b 510
308978f6
VZ
511static wxString MyGetEnv(const wxString& var)
512{
513 wxString val;
514 if ( !wxGetEnv(var, &val) )
515 val = _T("<empty>");
516 else
517 val = wxString(_T('\'')) + val + _T('\'');
518
519 return val;
520}
521
8fd0d89b
VZ
522static void TestEnvironment()
523{
524 const wxChar *var = _T("wxTestVar");
525
456ae26d 526 wxPuts(_T("*** testing environment access functions ***"));
8fd0d89b 527
456ae26d 528 wxPrintf(_T("Initially getenv(%s) = %s\n"), var, MyGetEnv(var).c_str());
8fd0d89b 529 wxSetEnv(var, _T("value for wxTestVar"));
456ae26d 530 wxPrintf(_T("After wxSetEnv: getenv(%s) = %s\n"), var, MyGetEnv(var).c_str());
8fd0d89b 531 wxSetEnv(var, _T("another value"));
456ae26d 532 wxPrintf(_T("After 2nd wxSetEnv: getenv(%s) = %s\n"), var, MyGetEnv(var).c_str());
8fd0d89b 533 wxUnsetEnv(var);
456ae26d
VZ
534 wxPrintf(_T("After wxUnsetEnv: getenv(%s) = %s\n"), var, MyGetEnv(var).c_str());
535 wxPrintf(_T("PATH = %s\n"), MyGetEnv(_T("PATH")).c_str());
8fd0d89b
VZ
536}
537
538#endif // TEST_ENVIRON
539
d93c719a
VZ
540// ----------------------------------------------------------------------------
541// wxExecute
542// ----------------------------------------------------------------------------
543
544#ifdef TEST_EXECUTE
545
e84010cf 546#include "wx/utils.h"
d93c719a
VZ
547
548static void TestExecute()
549{
456ae26d 550 wxPuts(_T("*** testing wxExecute ***"));
d93c719a
VZ
551
552#ifdef __UNIX__
a1f79c1e 553 #define COMMAND "cat -n ../../Makefile" // "echo hi"
2c8e4738 554 #define SHELL_COMMAND "echo hi from shell"
a1f79c1e 555 #define REDIRECT_COMMAND COMMAND // "date"
d93c719a 556#elif defined(__WXMSW__)
50ded68d 557 #define COMMAND "command.com /c echo hi"
2c8e4738
VZ
558 #define SHELL_COMMAND "echo hi"
559 #define REDIRECT_COMMAND COMMAND
d93c719a
VZ
560#else
561 #error "no command to exec"
562#endif // OS
563
456ae26d 564 wxPrintf(_T("Testing wxShell: "));
2c8e4738
VZ
565 fflush(stdout);
566 if ( wxShell(SHELL_COMMAND) )
456ae26d 567 wxPuts(_T("Ok."));
d93c719a 568 else
456ae26d 569 wxPuts(_T("ERROR."));
2c8e4738 570
456ae26d 571 wxPrintf(_T("Testing wxExecute: "));
2c8e4738 572 fflush(stdout);
cab8f76e 573 if ( wxExecute(COMMAND, true /* sync */) == 0 )
456ae26d 574 wxPuts(_T("Ok."));
2c8e4738 575 else
456ae26d 576 wxPuts(_T("ERROR."));
2c8e4738
VZ
577
578#if 0 // no, it doesn't work (yet?)
456ae26d 579 wxPrintf(_T("Testing async wxExecute: "));
2c8e4738
VZ
580 fflush(stdout);
581 if ( wxExecute(COMMAND) != 0 )
456ae26d 582 wxPuts(_T("Ok (command launched)."));
2c8e4738 583 else
456ae26d 584 wxPuts(_T("ERROR."));
2c8e4738
VZ
585#endif // 0
586
456ae26d 587 wxPrintf(_T("Testing wxExecute with redirection:\n"));
2c8e4738
VZ
588 wxArrayString output;
589 if ( wxExecute(REDIRECT_COMMAND, output) != 0 )
590 {
456ae26d 591 wxPuts(_T("ERROR."));
2c8e4738
VZ
592 }
593 else
594 {
595 size_t count = output.GetCount();
596 for ( size_t n = 0; n < count; n++ )
597 {
456ae26d 598 wxPrintf(_T("\t%s\n"), output[n].c_str());
2c8e4738
VZ
599 }
600
456ae26d 601 wxPuts(_T("Ok."));
2c8e4738 602 }
d93c719a
VZ
603}
604
605#endif // TEST_EXECUTE
606
f6bcfd97
BP
607// ----------------------------------------------------------------------------
608// file
609// ----------------------------------------------------------------------------
610
611#ifdef TEST_FILE
612
e84010cf
GD
613#include "wx/file.h"
614#include "wx/ffile.h"
615#include "wx/textfile.h"
f6bcfd97
BP
616
617static void TestFileRead()
618{
456ae26d 619 wxPuts(_T("*** wxFile read test ***"));
f6bcfd97
BP
620
621 wxFile file(_T("testdata.fc"));
622 if ( file.IsOpened() )
623 {
456ae26d 624 wxPrintf(_T("File length: %lu\n"), file.Length());
f6bcfd97 625
456ae26d 626 wxPuts(_T("File dump:\n----------"));
f6bcfd97 627
3ca6a5f0 628 static const off_t len = 1024;
456ae26d 629 wxChar buf[len];
f6bcfd97
BP
630 for ( ;; )
631 {
632 off_t nRead = file.Read(buf, len);
633 if ( nRead == wxInvalidOffset )
634 {
456ae26d 635 wxPrintf(_T("Failed to read the file."));
f6bcfd97
BP
636 break;
637 }
638
639 fwrite(buf, nRead, 1, stdout);
640
641 if ( nRead < len )
642 break;
643 }
644
456ae26d 645 wxPuts(_T("----------"));
f6bcfd97
BP
646 }
647 else
648 {
456ae26d 649 wxPrintf(_T("ERROR: can't open test file.\n"));
f6bcfd97
BP
650 }
651
456ae26d 652 wxPuts(_T(""));
f6bcfd97
BP
653}
654
655static void TestTextFileRead()
656{
456ae26d 657 wxPuts(_T("*** wxTextFile read test ***"));
f6bcfd97
BP
658
659 wxTextFile file(_T("testdata.fc"));
660 if ( file.Open() )
661 {
456ae26d
VZ
662 wxPrintf(_T("Number of lines: %u\n"), file.GetLineCount());
663 wxPrintf(_T("Last line: '%s'\n"), file.GetLastLine().c_str());
3ca6a5f0
BP
664
665 wxString s;
666
456ae26d 667 wxPuts(_T("\nDumping the entire file:"));
3ca6a5f0
BP
668 for ( s = file.GetFirstLine(); !file.Eof(); s = file.GetNextLine() )
669 {
456ae26d 670 wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
3ca6a5f0 671 }
456ae26d 672 wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
3ca6a5f0 673
456ae26d 674 wxPuts(_T("\nAnd now backwards:"));
3ca6a5f0
BP
675 for ( s = file.GetLastLine();
676 file.GetCurrentLine() != 0;
677 s = file.GetPrevLine() )
678 {
456ae26d 679 wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
3ca6a5f0 680 }
456ae26d 681 wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
f6bcfd97
BP
682 }
683 else
684 {
456ae26d 685 wxPrintf(_T("ERROR: can't open '%s'\n"), file.GetName());
f6bcfd97
BP
686 }
687
456ae26d 688 wxPuts(_T(""));
f6bcfd97
BP
689}
690
a339970a
VZ
691static void TestFileCopy()
692{
456ae26d 693 wxPuts(_T("*** Testing wxCopyFile ***"));
a339970a
VZ
694
695 static const wxChar *filename1 = _T("testdata.fc");
696 static const wxChar *filename2 = _T("test2");
697 if ( !wxCopyFile(filename1, filename2) )
698 {
456ae26d 699 wxPuts(_T("ERROR: failed to copy file"));
a339970a
VZ
700 }
701 else
702 {
703 wxFFile f1(filename1, "rb"),
704 f2(filename2, "rb");
705
706 if ( !f1.IsOpened() || !f2.IsOpened() )
707 {
456ae26d 708 wxPuts(_T("ERROR: failed to open file(s)"));
a339970a
VZ
709 }
710 else
711 {
712 wxString s1, s2;
713 if ( !f1.ReadAll(&s1) || !f2.ReadAll(&s2) )
714 {
456ae26d 715 wxPuts(_T("ERROR: failed to read file(s)"));
a339970a
VZ
716 }
717 else
718 {
719 if ( (s1.length() != s2.length()) ||
720 (memcmp(s1.c_str(), s2.c_str(), s1.length()) != 0) )
721 {
456ae26d 722 wxPuts(_T("ERROR: copy error!"));
a339970a
VZ
723 }
724 else
725 {
456ae26d 726 wxPuts(_T("File was copied ok."));
a339970a
VZ
727 }
728 }
729 }
730 }
731
732 if ( !wxRemoveFile(filename2) )
733 {
456ae26d 734 wxPuts(_T("ERROR: failed to remove the file"));
a339970a
VZ
735 }
736
456ae26d 737 wxPuts(_T(""));
a339970a
VZ
738}
739
f6bcfd97
BP
740#endif // TEST_FILE
741
ee6e1b1d
VZ
742// ----------------------------------------------------------------------------
743// wxFileConfig
744// ----------------------------------------------------------------------------
745
746#ifdef TEST_FILECONF
747
e84010cf
GD
748#include "wx/confbase.h"
749#include "wx/fileconf.h"
ee6e1b1d
VZ
750
751static const struct FileConfTestData
752{
753 const wxChar *name; // value name
754 const wxChar *value; // the value from the file
755} fcTestData[] =
756{
757 { _T("value1"), _T("one") },
758 { _T("value2"), _T("two") },
759 { _T("novalue"), _T("default") },
760};
761
762static void TestFileConfRead()
763{
456ae26d 764 wxPuts(_T("*** testing wxFileConfig loading/reading ***"));
ee6e1b1d
VZ
765
766 wxFileConfig fileconf(_T("test"), wxEmptyString,
767 _T("testdata.fc"), wxEmptyString,
768 wxCONFIG_USE_RELATIVE_PATH);
769
770 // test simple reading
456ae26d 771 wxPuts(_T("\nReading config file:"));
ee6e1b1d
VZ
772 wxString defValue(_T("default")), value;
773 for ( size_t n = 0; n < WXSIZEOF(fcTestData); n++ )
774 {
775 const FileConfTestData& data = fcTestData[n];
776 value = fileconf.Read(data.name, defValue);
456ae26d 777 wxPrintf(_T("\t%s = %s "), data.name, value.c_str());
ee6e1b1d
VZ
778 if ( value == data.value )
779 {
456ae26d 780 wxPuts(_T("(ok)"));
ee6e1b1d
VZ
781 }
782 else
783 {
456ae26d 784 wxPrintf(_T("(ERROR: should be %s)\n"), data.value);
ee6e1b1d
VZ
785 }
786 }
787
788 // test enumerating the entries
456ae26d 789 wxPuts(_T("\nEnumerating all root entries:"));
ee6e1b1d
VZ
790 long dummy;
791 wxString name;
792 bool cont = fileconf.GetFirstEntry(name, dummy);
793 while ( cont )
794 {
456ae26d 795 wxPrintf(_T("\t%s = %s\n"),
ee6e1b1d
VZ
796 name.c_str(),
797 fileconf.Read(name.c_str(), _T("ERROR")).c_str());
798
799 cont = fileconf.GetNextEntry(name, dummy);
800 }
801}
802
803#endif // TEST_FILECONF
804
844f90fb
VZ
805// ----------------------------------------------------------------------------
806// wxFileName
807// ----------------------------------------------------------------------------
808
809#ifdef TEST_FILENAME
810
e84010cf 811#include "wx/filename.h"
844f90fb 812
81f25632
VZ
813static void DumpFileName(const wxFileName& fn)
814{
815 wxString full = fn.GetFullPath();
816
817 wxString vol, path, name, ext;
818 wxFileName::SplitPath(full, &vol, &path, &name, &ext);
819
a5b7374f 820 wxPrintf(_T("'%s'-> vol '%s', path '%s', name '%s', ext '%s'\n"),
81f25632 821 full.c_str(), vol.c_str(), path.c_str(), name.c_str(), ext.c_str());
a5b7374f
VZ
822
823 wxFileName::SplitPath(full, &path, &name, &ext);
824 wxPrintf(_T("or\t\t-> path '%s', name '%s', ext '%s'\n"),
825 path.c_str(), name.c_str(), ext.c_str());
826
827 wxPrintf(_T("path is also:\t'%s'\n"), fn.GetPath().c_str());
828 wxPrintf(_T("with volume: \t'%s'\n"),
829 fn.GetPath(wxPATH_GET_VOLUME).c_str());
830 wxPrintf(_T("with separator:\t'%s'\n"),
831 fn.GetPath(wxPATH_GET_SEPARATOR).c_str());
832 wxPrintf(_T("with both: \t'%s'\n"),
833 fn.GetPath(wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME).c_str());
9cb47ea2
VZ
834
835 wxPuts(_T("The directories in the path are:"));
836 wxArrayString dirs = fn.GetDirs();
837 size_t count = dirs.GetCount();
838 for ( size_t n = 0; n < count; n++ )
839 {
840 wxPrintf(_T("\t%u: %s\n"), n, dirs[n].c_str());
841 }
81f25632
VZ
842}
843
8e7dda21 844static struct FileNameInfo
42b1f941 845{
8e7dda21 846 const wxChar *fullname;
a874db92 847 const wxChar *volume;
8e7dda21
VZ
848 const wxChar *path;
849 const wxChar *name;
850 const wxChar *ext;
a874db92
VZ
851 bool isAbsolute;
852 wxPathFormat format;
8e7dda21
VZ
853} filenames[] =
854{
a874db92 855 // Unix file names
cab8f76e
VZ
856 { _T("/usr/bin/ls"), _T(""), _T("/usr/bin"), _T("ls"), _T(""), true, wxPATH_UNIX },
857 { _T("/usr/bin/"), _T(""), _T("/usr/bin"), _T(""), _T(""), true, wxPATH_UNIX },
858 { _T("~/.zshrc"), _T(""), _T("~"), _T(".zshrc"), _T(""), true, wxPATH_UNIX },
859 { _T("../../foo"), _T(""), _T("../.."), _T("foo"), _T(""), false, wxPATH_UNIX },
860 { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_UNIX },
861 { _T("~/foo.bar"), _T(""), _T("~"), _T("foo"), _T("bar"), true, wxPATH_UNIX },
862 { _T("/foo"), _T(""), _T("/"), _T("foo"), _T(""), true, wxPATH_UNIX },
863 { _T("Mahogany-0.60/foo.bar"), _T(""), _T("Mahogany-0.60"), _T("foo"), _T("bar"), false, wxPATH_UNIX },
864 { _T("/tmp/wxwin.tar.bz"), _T(""), _T("/tmp"), _T("wxwin.tar"), _T("bz"), true, wxPATH_UNIX },
a874db92
VZ
865
866 // Windows file names
cab8f76e
VZ
867 { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS },
868 { _T("\\foo.bar"), _T(""), _T("\\"), _T("foo"), _T("bar"), false, wxPATH_DOS },
869 { _T("c:foo.bar"), _T("c"), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS },
870 { _T("c:\\foo.bar"), _T("c"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS },
871 { _T("c:\\Windows\\command.com"), _T("c"), _T("\\Windows"), _T("command"), _T("com"), true, wxPATH_DOS },
872 { _T("\\\\server\\foo.bar"), _T("server"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS },
873 { _T("\\\\server\\dir\\foo.bar"), _T("server"), _T("\\dir"), _T("foo"), _T("bar"), true, wxPATH_DOS },
a874db92 874
2db991f4 875 // wxFileName support for Mac file names is broken currently
a2fa5040 876#if 0
a874db92 877 // Mac file names
cab8f76e
VZ
878 { _T("Volume:Dir:File"), _T("Volume"), _T("Dir"), _T("File"), _T(""), true, wxPATH_MAC },
879 { _T("Volume:Dir:Subdir:File"), _T("Volume"), _T("Dir:Subdir"), _T("File"), _T(""), true, wxPATH_MAC },
880 { _T("Volume:"), _T("Volume"), _T(""), _T(""), _T(""), true, wxPATH_MAC },
881 { _T(":Dir:File"), _T(""), _T("Dir"), _T("File"), _T(""), false, wxPATH_MAC },
882 { _T(":File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC },
883 { _T("File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC },
a2fa5040 884#endif // 0
a874db92
VZ
885
886 // VMS file names
cab8f76e
VZ
887 { _T("device:[dir1.dir2.dir3]file.txt"), _T("device"), _T("dir1.dir2.dir3"), _T("file"), _T("txt"), true, wxPATH_VMS },
888 { _T("file.txt"), _T(""), _T(""), _T("file"), _T("txt"), false, wxPATH_VMS },
42b1f941
VZ
889};
890
844f90fb
VZ
891static void TestFileNameConstruction()
892{
456ae26d 893 wxPuts(_T("*** testing wxFileName construction ***"));
844f90fb 894
844f90fb
VZ
895 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
896 {
a874db92
VZ
897 const FileNameInfo& fni = filenames[n];
898
899 wxFileName fn(fni.fullname, fni.format);
900
901 wxString fullname = fn.GetFullPath(fni.format);
902 if ( fullname != fni.fullname )
903 {
456ae26d 904 wxPrintf(_T("ERROR: fullname should be '%s'\n"), fni.fullname);
a874db92 905 }
844f90fb 906
a2fa5040 907 bool isAbsolute = fn.IsAbsolute(fni.format);
456ae26d 908 wxPrintf(_T("'%s' is %s (%s)\n\t"),
a874db92
VZ
909 fullname.c_str(),
910 isAbsolute ? "absolute" : "relative",
911 isAbsolute == fni.isAbsolute ? "ok" : "ERROR");
912
913 if ( !fn.Normalize(wxPATH_NORM_ALL, _T(""), fni.format) )
844f90fb 914 {
456ae26d 915 wxPuts(_T("ERROR (couldn't be normalized)"));
844f90fb
VZ
916 }
917 else
918 {
456ae26d 919 wxPrintf(_T("normalized: '%s'\n"), fn.GetFullPath(fni.format).c_str());
844f90fb
VZ
920 }
921 }
922
456ae26d 923 wxPuts(_T(""));
844f90fb
VZ
924}
925
42b1f941
VZ
926static void TestFileNameSplit()
927{
456ae26d 928 wxPuts(_T("*** testing wxFileName splitting ***"));
42b1f941
VZ
929
930 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
931 {
a874db92
VZ
932 const FileNameInfo& fni = filenames[n];
933 wxString volume, path, name, ext;
934 wxFileName::SplitPath(fni.fullname,
935 &volume, &path, &name, &ext, fni.format);
936
456ae26d 937 wxPrintf(_T("%s -> volume = '%s', path = '%s', name = '%s', ext = '%s'"),
a874db92
VZ
938 fni.fullname,
939 volume.c_str(), path.c_str(), name.c_str(), ext.c_str());
8e7dda21 940
a874db92 941 if ( volume != fni.volume )
456ae26d 942 wxPrintf(_T(" (ERROR: volume = '%s')"), fni.volume);
8e7dda21 943 if ( path != fni.path )
456ae26d 944 wxPrintf(_T(" (ERROR: path = '%s')"), fni.path);
8e7dda21 945 if ( name != fni.name )
456ae26d 946 wxPrintf(_T(" (ERROR: name = '%s')"), fni.name);
8e7dda21 947 if ( ext != fni.ext )
456ae26d 948 wxPrintf(_T(" (ERROR: ext = '%s')"), fni.ext);
a874db92 949
456ae26d 950 wxPuts(_T(""));
42b1f941 951 }
42b1f941
VZ
952}
953
ade35f11
VZ
954static void TestFileNameTemp()
955{
456ae26d 956 wxPuts(_T("*** testing wxFileName temp file creation ***"));
ade35f11 957
456ae26d 958 static const wxChar *tmpprefixes[] =
ade35f11 959 {
456ae26d
VZ
960 _T(""),
961 _T("foo"),
962 _T(".."),
963 _T("../bar"),
a2fa5040 964#ifdef __UNIX__
456ae26d
VZ
965 _T("/tmp/foo"),
966 _T("/tmp/foo/bar"), // this one must be an error
a2fa5040 967#endif // __UNIX__
ade35f11
VZ
968 };
969
970 for ( size_t n = 0; n < WXSIZEOF(tmpprefixes); n++ )
971 {
972 wxString path = wxFileName::CreateTempFileName(tmpprefixes[n]);
2db991f4
VZ
973 if ( path.empty() )
974 {
975 // "error" is not in upper case because it may be ok
456ae26d 976 wxPrintf(_T("Prefix '%s'\t-> error\n"), tmpprefixes[n]);
2db991f4
VZ
977 }
978 else
ade35f11 979 {
456ae26d 980 wxPrintf(_T("Prefix '%s'\t-> temp file '%s'\n"),
ade35f11
VZ
981 tmpprefixes[n], path.c_str());
982
983 if ( !wxRemoveFile(path) )
984 {
456ae26d
VZ
985 wxLogWarning(_T("Failed to remove temp file '%s'"),
986 path.c_str());
ade35f11
VZ
987 }
988 }
989 }
990}
991
f7d886af
VZ
992static void TestFileNameMakeRelative()
993{
456ae26d 994 wxPuts(_T("*** testing wxFileName::MakeRelativeTo() ***"));
f7d886af
VZ
995
996 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
997 {
998 const FileNameInfo& fni = filenames[n];
999
1000 wxFileName fn(fni.fullname, fni.format);
1001
1002 // choose the base dir of the same format
1003 wxString base;
1004 switch ( fni.format )
1005 {
1006 case wxPATH_UNIX:
1007 base = "/usr/bin/";
1008 break;
1009
1010 case wxPATH_DOS:
1011 base = "c:\\";
1012 break;
1013
1014 case wxPATH_MAC:
1015 case wxPATH_VMS:
1016 // TODO: I don't know how this is supposed to work there
1017 continue;
daa2c7d9
VZ
1018
1019 case wxPATH_NATIVE: // make gcc happy
1020 default:
1021 wxFAIL_MSG( "unexpected path format" );
f7d886af
VZ
1022 }
1023
456ae26d 1024 wxPrintf(_T("'%s' relative to '%s': "),
f7d886af
VZ
1025 fn.GetFullPath(fni.format).c_str(), base.c_str());
1026
1027 if ( !fn.MakeRelativeTo(base, fni.format) )
1028 {
456ae26d 1029 wxPuts(_T("unchanged"));
f7d886af
VZ
1030 }
1031 else
1032 {
456ae26d 1033 wxPrintf(_T("'%s'\n"), fn.GetFullPath(fni.format).c_str());
f7d886af
VZ
1034 }
1035 }
1036}
1037
e7266247
VS
1038static void TestFileNameMakeAbsolute()
1039{
1040 wxPuts(_T("*** testing wxFileName::MakeAbsolute() ***"));
1041
1042 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
1043 {
1044 const FileNameInfo& fni = filenames[n];
1045 wxFileName fn(fni.fullname, fni.format);
1046
1047 wxPrintf(_T("'%s' absolutized: "),
1048 fn.GetFullPath(fni.format).c_str());
1049 fn.MakeAbsolute();
1050 wxPrintf(_T("'%s'\n"), fn.GetFullPath(fni.format).c_str());
1051 }
1052
1053 wxPuts(_T(""));
1054}
1055
844f90fb
VZ
1056static void TestFileNameComparison()
1057{
1058 // TODO!
1059}
1060
1061static void TestFileNameOperations()
1062{
1063 // TODO!
1064}
1065
1066static void TestFileNameCwd()
1067{
1068 // TODO!
1069}
1070
1071#endif // TEST_FILENAME
1072
d56e2b97
VZ
1073// ----------------------------------------------------------------------------
1074// wxFileName time functions
1075// ----------------------------------------------------------------------------
1076
1077#ifdef TEST_FILETIME
1078
1079#include <wx/filename.h>
1080#include <wx/datetime.h>
1081
1082static void TestFileGetTimes()
1083{
1084 wxFileName fn(_T("testdata.fc"));
1085
6dbb903b
VZ
1086 wxDateTime dtAccess, dtMod, dtCreate;
1087 if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) )
d56e2b97
VZ
1088 {
1089 wxPrintf(_T("ERROR: GetTimes() failed.\n"));
1090 }
1091 else
1092 {
1093 static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S");
1094
1095 wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str());
6dbb903b
VZ
1096 wxPrintf(_T("Creation: \t%s\n"), dtCreate.Format(fmt).c_str());
1097 wxPrintf(_T("Last read: \t%s\n"), dtAccess.Format(fmt).c_str());
1098 wxPrintf(_T("Last write: \t%s\n"), dtMod.Format(fmt).c_str());
d56e2b97
VZ
1099 }
1100}
1101
1102static void TestFileSetTimes()
1103{
1104 wxFileName fn(_T("testdata.fc"));
1105
d56e2b97
VZ
1106 if ( !fn.Touch() )
1107 {
1108 wxPrintf(_T("ERROR: Touch() failed.\n"));
1109 }
1110}
1111
1112#endif // TEST_FILETIME
1113
2c8e4738
VZ
1114// ----------------------------------------------------------------------------
1115// wxHashTable
1116// ----------------------------------------------------------------------------
1117
1118#ifdef TEST_HASH
1119
e84010cf 1120#include "wx/hash.h"
2c8e4738
VZ
1121
1122struct Foo
1123{
1124 Foo(int n_) { n = n_; count++; }
1125 ~Foo() { count--; }
1126
1127 int n;
1128
1129 static size_t count;
1130};
1131
1132size_t Foo::count = 0;
1133
1134WX_DECLARE_LIST(Foo, wxListFoos);
1135WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
1136
e84010cf 1137#include "wx/listimpl.cpp"
2c8e4738
VZ
1138
1139WX_DEFINE_LIST(wxListFoos);
1140
1141static void TestHash()
1142{
456ae26d 1143 wxPuts(_T("*** Testing wxHashTable ***\n"));
2c8e4738
VZ
1144
1145 {
1146 wxHashFoos hash;
cab8f76e 1147 hash.DeleteContents(true);
2c8e4738 1148
456ae26d 1149 wxPrintf(_T("Hash created: %u foos in hash, %u foos totally\n"),
2c8e4738
VZ
1150 hash.GetCount(), Foo::count);
1151
1152 static const int hashTestData[] =
1153 {
1154 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
1155 };
1156
1157 size_t n;
1158 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
1159 {
1160 hash.Put(hashTestData[n], n, new Foo(n));
1161 }
1162
456ae26d 1163 wxPrintf(_T("Hash filled: %u foos in hash, %u foos totally\n"),
2c8e4738
VZ
1164 hash.GetCount(), Foo::count);
1165
456ae26d 1166 wxPuts(_T("Hash access test:"));
2c8e4738
VZ
1167 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
1168 {
456ae26d 1169 wxPrintf(_T("\tGetting element with key %d, value %d: "),
2c8e4738
VZ
1170 hashTestData[n], n);
1171 Foo *foo = hash.Get(hashTestData[n], n);
1172 if ( !foo )
1173 {
456ae26d 1174 wxPrintf(_T("ERROR, not found.\n"));
2c8e4738
VZ
1175 }
1176 else
1177 {
456ae26d 1178 wxPrintf(_T("%d (%s)\n"), foo->n,
2c8e4738
VZ
1179 (size_t)foo->n == n ? "ok" : "ERROR");
1180 }
1181 }
1182
456ae26d 1183 wxPrintf(_T("\nTrying to get an element not in hash: "));
2c8e4738
VZ
1184
1185 if ( hash.Get(1234) || hash.Get(1, 0) )
1186 {
456ae26d 1187 wxPuts(_T("ERROR: found!"));
2c8e4738
VZ
1188 }
1189 else
1190 {
456ae26d 1191 wxPuts(_T("ok (not found)"));
2c8e4738
VZ
1192 }
1193 }
1194
456ae26d 1195 wxPrintf(_T("Hash destroyed: %u foos left\n"), Foo::count);
2c8e4738
VZ
1196}
1197
1198#endif // TEST_HASH
1199
0508ba2a
MB
1200// ----------------------------------------------------------------------------
1201// wxHashMap
1202// ----------------------------------------------------------------------------
1203
1204#ifdef TEST_HASHMAP
1205
1206#include "wx/hashmap.h"
1207
1208// test compilation of basic map types
1209WX_DECLARE_HASH_MAP( int*, int*, wxPointerHash, wxPointerEqual, myPtrHashMap );
1210WX_DECLARE_HASH_MAP( long, long, wxIntegerHash, wxIntegerEqual, myLongHashMap );
1211WX_DECLARE_HASH_MAP( unsigned long, unsigned, wxIntegerHash, wxIntegerEqual,
1212 myUnsignedHashMap );
1213WX_DECLARE_HASH_MAP( unsigned int, unsigned, wxIntegerHash, wxIntegerEqual,
1214 myTestHashMap1 );
1215WX_DECLARE_HASH_MAP( int, unsigned, wxIntegerHash, wxIntegerEqual,
1216 myTestHashMap2 );
1217WX_DECLARE_HASH_MAP( short, unsigned, wxIntegerHash, wxIntegerEqual,
1218 myTestHashMap3 );
1219WX_DECLARE_HASH_MAP( unsigned short, unsigned, wxIntegerHash, wxIntegerEqual,
1220 myTestHashMap4 );
60ce696e
VZ
1221
1222// same as:
1223// WX_DECLARE_HASH_MAP( wxString, wxString, wxStringHash, wxStringEqual,
1224// myStringHashMap );
1225WX_DECLARE_STRING_HASH_MAP(wxString, myStringHashMap);
0508ba2a
MB
1226
1227typedef myStringHashMap::iterator Itor;
1228
1229static void TestHashMap()
1230{
456ae26d 1231 wxPuts(_T("*** Testing wxHashMap ***\n"));
0508ba2a
MB
1232 myStringHashMap sh(0); // as small as possible
1233 wxString buf;
1234 size_t i;
1235 const size_t count = 10000;
1236
1237 // init with some data
1238 for( i = 0; i < count; ++i )
1239 {
1240 buf.Printf(wxT("%d"), i );
1241 sh[buf] = wxT("A") + buf + wxT("C");
1242 }
1243
1244 // test that insertion worked
1245 if( sh.size() != count )
1246 {
456ae26d 1247 wxPrintf(_T("*** ERROR: %u ELEMENTS, SHOULD BE %u ***\n"), sh.size(), count);
0508ba2a
MB
1248 }
1249
1250 for( i = 0; i < count; ++i )
1251 {
1252 buf.Printf(wxT("%d"), i );
1253 if( sh[buf] != wxT("A") + buf + wxT("C") )
1254 {
456ae26d 1255 wxPrintf(_T("*** ERROR INSERTION BROKEN! STOPPING NOW! ***\n"));
0508ba2a
MB
1256 return;
1257 }
1258 }
1259
1260 // check that iterators work
1261 Itor it;
1262 for( i = 0, it = sh.begin(); it != sh.end(); ++it, ++i )
1263 {
1264 if( i == count )
1265 {
456ae26d 1266 wxPrintf(_T("*** ERROR ITERATORS DO NOT TERMINATE! STOPPING NOW! ***\n"));
0508ba2a
MB
1267 return;
1268 }
1269
1270 if( it->second != sh[it->first] )
1271 {
456ae26d 1272 wxPrintf(_T("*** ERROR ITERATORS BROKEN! STOPPING NOW! ***\n"));
0508ba2a
MB
1273 return;
1274 }
1275 }
1276
1277 if( sh.size() != i )
1278 {
456ae26d 1279 wxPrintf(_T("*** ERROR: %u ELEMENTS ITERATED, SHOULD BE %u ***\n"), i, count);
0508ba2a
MB
1280 }
1281
1282 // test copy ctor, assignment operator
1283 myStringHashMap h1( sh ), h2( 0 );
1284 h2 = sh;
1285
1286 for( i = 0, it = sh.begin(); it != sh.end(); ++it, ++i )
1287 {
1288 if( h1[it->first] != it->second )
1289 {
456ae26d 1290 wxPrintf(_T("*** ERROR: COPY CTOR BROKEN %s ***\n"), it->first.c_str());
0508ba2a
MB
1291 }
1292
1293 if( h2[it->first] != it->second )
1294 {
456ae26d 1295 wxPrintf(_T("*** ERROR: OPERATOR= BROKEN %s ***\n"), it->first.c_str());
0508ba2a
MB
1296 }
1297 }
1298
1299 // other tests
1300 for( i = 0; i < count; ++i )
1301 {
1302 buf.Printf(wxT("%d"), i );
1303 size_t sz = sh.size();
1304
1305 // test find() and erase(it)
1306 if( i < 100 )
1307 {
1308 it = sh.find( buf );
1309 if( it != sh.end() )
1310 {
1311 sh.erase( it );
1312
1313 if( sh.find( buf ) != sh.end() )
1314 {
456ae26d 1315 wxPrintf(_T("*** ERROR: FOUND DELETED ELEMENT %u ***\n"), i);
0508ba2a
MB
1316 }
1317 }
1318 else
456ae26d 1319 wxPrintf(_T("*** ERROR: CANT FIND ELEMENT %u ***\n"), i);
0508ba2a
MB
1320 }
1321 else
1322 // test erase(key)
1323 {
1324 size_t c = sh.erase( buf );
1325 if( c != 1 )
456ae26d 1326 wxPrintf(_T("*** ERROR: SHOULD RETURN 1 ***\n"));
0508ba2a
MB
1327
1328 if( sh.find( buf ) != sh.end() )
1329 {
456ae26d 1330 wxPrintf(_T("*** ERROR: FOUND DELETED ELEMENT %u ***\n"), i);
0508ba2a
MB
1331 }
1332 }
1333
1334 // count should decrease
1335 if( sh.size() != sz - 1 )
1336 {
456ae26d 1337 wxPrintf(_T("*** ERROR: COUNT DID NOT DECREASE ***\n"));
0508ba2a
MB
1338 }
1339 }
1340
456ae26d 1341 wxPrintf(_T("*** Finished testing wxHashMap ***\n"));
0508ba2a
MB
1342}
1343
60ce696e 1344#endif // TEST_HASHMAP
0508ba2a 1345
f6bcfd97
BP
1346// ----------------------------------------------------------------------------
1347// wxList
1348// ----------------------------------------------------------------------------
1349
1350#ifdef TEST_LIST
1351
e84010cf 1352#include "wx/list.h"
f6bcfd97
BP
1353
1354WX_DECLARE_LIST(Bar, wxListBars);
e84010cf 1355#include "wx/listimpl.cpp"
f6bcfd97
BP
1356WX_DEFINE_LIST(wxListBars);
1357
1358static void TestListCtor()
1359{
456ae26d 1360 wxPuts(_T("*** Testing wxList construction ***\n"));
f6bcfd97
BP
1361
1362 {
1363 wxListBars list1;
1364 list1.Append(new Bar(_T("first")));
1365 list1.Append(new Bar(_T("second")));
1366
456ae26d 1367 wxPrintf(_T("After 1st list creation: %u objects in the list, %u objects total.\n"),
f6bcfd97
BP
1368 list1.GetCount(), Bar::GetNumber());
1369
1370 wxListBars list2;
1371 list2 = list1;
1372
456ae26d 1373 wxPrintf(_T("After 2nd list creation: %u and %u objects in the lists, %u objects total.\n"),
f6bcfd97
BP
1374 list1.GetCount(), list2.GetCount(), Bar::GetNumber());
1375
cab8f76e 1376 list1.DeleteContents(true);
f6bcfd97
BP
1377 }
1378
456ae26d 1379 wxPrintf(_T("After list destruction: %u objects left.\n"), Bar::GetNumber());
f6bcfd97
BP
1380}
1381
1382#endif // TEST_LIST
1383
ec37df57
VZ
1384// ----------------------------------------------------------------------------
1385// wxLocale
1386// ----------------------------------------------------------------------------
1387
1388#ifdef TEST_LOCALE
1389
1390#include "wx/intl.h"
1391#include "wx/utils.h" // for wxSetEnv
1392
1393static wxLocale gs_localeDefault(wxLANGUAGE_ENGLISH);
1394
1395// find the name of the language from its value
456ae26d
VZ
1396static const wxChar *GetLangName(int lang)
1397{
1398 static const wxChar *languageNames[] =
1399 {
1400 _T("DEFAULT"),
1401 _T("UNKNOWN"),
1402 _T("ABKHAZIAN"),
1403 _T("AFAR"),
1404 _T("AFRIKAANS"),
1405 _T("ALBANIAN"),
1406 _T("AMHARIC"),
1407 _T("ARABIC"),
1408 _T("ARABIC_ALGERIA"),
1409 _T("ARABIC_BAHRAIN"),
1410 _T("ARABIC_EGYPT"),
1411 _T("ARABIC_IRAQ"),
1412 _T("ARABIC_JORDAN"),
1413 _T("ARABIC_KUWAIT"),
1414 _T("ARABIC_LEBANON"),
1415 _T("ARABIC_LIBYA"),
1416 _T("ARABIC_MOROCCO"),
1417 _T("ARABIC_OMAN"),
1418 _T("ARABIC_QATAR"),
1419 _T("ARABIC_SAUDI_ARABIA"),
1420 _T("ARABIC_SUDAN"),
1421 _T("ARABIC_SYRIA"),
1422 _T("ARABIC_TUNISIA"),
1423 _T("ARABIC_UAE"),
1424 _T("ARABIC_YEMEN"),
1425 _T("ARMENIAN"),
1426 _T("ASSAMESE"),
1427 _T("AYMARA"),
1428 _T("AZERI"),
1429 _T("AZERI_CYRILLIC"),
1430 _T("AZERI_LATIN"),
1431 _T("BASHKIR"),
1432 _T("BASQUE"),
1433 _T("BELARUSIAN"),
1434 _T("BENGALI"),
1435 _T("BHUTANI"),
1436 _T("BIHARI"),
1437 _T("BISLAMA"),
1438 _T("BRETON"),
1439 _T("BULGARIAN"),
1440 _T("BURMESE"),
1441 _T("CAMBODIAN"),
1442 _T("CATALAN"),
1443 _T("CHINESE"),
1444 _T("CHINESE_SIMPLIFIED"),
1445 _T("CHINESE_TRADITIONAL"),
1446 _T("CHINESE_HONGKONG"),
1447 _T("CHINESE_MACAU"),
1448 _T("CHINESE_SINGAPORE"),
1449 _T("CHINESE_TAIWAN"),
1450 _T("CORSICAN"),
1451 _T("CROATIAN"),
1452 _T("CZECH"),
1453 _T("DANISH"),
1454 _T("DUTCH"),
1455 _T("DUTCH_BELGIAN"),
1456 _T("ENGLISH"),
1457 _T("ENGLISH_UK"),
1458 _T("ENGLISH_US"),
1459 _T("ENGLISH_AUSTRALIA"),
1460 _T("ENGLISH_BELIZE"),
1461 _T("ENGLISH_BOTSWANA"),
1462 _T("ENGLISH_CANADA"),
1463 _T("ENGLISH_CARIBBEAN"),
1464 _T("ENGLISH_DENMARK"),
1465 _T("ENGLISH_EIRE"),
1466 _T("ENGLISH_JAMAICA"),
1467 _T("ENGLISH_NEW_ZEALAND"),
1468 _T("ENGLISH_PHILIPPINES"),
1469 _T("ENGLISH_SOUTH_AFRICA"),
1470 _T("ENGLISH_TRINIDAD"),
1471 _T("ENGLISH_ZIMBABWE"),
1472 _T("ESPERANTO"),
1473 _T("ESTONIAN"),
1474 _T("FAEROESE"),
1475 _T("FARSI"),
1476 _T("FIJI"),
1477 _T("FINNISH"),
1478 _T("FRENCH"),
1479 _T("FRENCH_BELGIAN"),
1480 _T("FRENCH_CANADIAN"),
1481 _T("FRENCH_LUXEMBOURG"),
1482 _T("FRENCH_MONACO"),
1483 _T("FRENCH_SWISS"),
1484 _T("FRISIAN"),
1485 _T("GALICIAN"),
1486 _T("GEORGIAN"),
1487 _T("GERMAN"),
1488 _T("GERMAN_AUSTRIAN"),
1489 _T("GERMAN_BELGIUM"),
1490 _T("GERMAN_LIECHTENSTEIN"),
1491 _T("GERMAN_LUXEMBOURG"),
1492 _T("GERMAN_SWISS"),
1493 _T("GREEK"),
1494 _T("GREENLANDIC"),
1495 _T("GUARANI"),
1496 _T("GUJARATI"),
1497 _T("HAUSA"),
1498 _T("HEBREW"),
1499 _T("HINDI"),
1500 _T("HUNGARIAN"),
1501 _T("ICELANDIC"),
1502 _T("INDONESIAN"),
1503 _T("INTERLINGUA"),
1504 _T("INTERLINGUE"),
1505 _T("INUKTITUT"),
1506 _T("INUPIAK"),
1507 _T("IRISH"),
1508 _T("ITALIAN"),
1509 _T("ITALIAN_SWISS"),
1510 _T("JAPANESE"),
1511 _T("JAVANESE"),
1512 _T("KANNADA"),
1513 _T("KASHMIRI"),
1514 _T("KASHMIRI_INDIA"),
1515 _T("KAZAKH"),
1516 _T("KERNEWEK"),
1517 _T("KINYARWANDA"),
1518 _T("KIRGHIZ"),
1519 _T("KIRUNDI"),
1520 _T("KONKANI"),
1521 _T("KOREAN"),
1522 _T("KURDISH"),
1523 _T("LAOTHIAN"),
1524 _T("LATIN"),
1525 _T("LATVIAN"),
1526 _T("LINGALA"),
1527 _T("LITHUANIAN"),
1528 _T("MACEDONIAN"),
1529 _T("MALAGASY"),
1530 _T("MALAY"),
1531 _T("MALAYALAM"),
1532 _T("MALAY_BRUNEI_DARUSSALAM"),
1533 _T("MALAY_MALAYSIA"),
1534 _T("MALTESE"),
1535 _T("MANIPURI"),
1536 _T("MAORI"),
1537 _T("MARATHI"),
1538 _T("MOLDAVIAN"),
1539 _T("MONGOLIAN"),
1540 _T("NAURU"),
1541 _T("NEPALI"),
1542 _T("NEPALI_INDIA"),
1543 _T("NORWEGIAN_BOKMAL"),
1544 _T("NORWEGIAN_NYNORSK"),
1545 _T("OCCITAN"),
1546 _T("ORIYA"),
1547 _T("OROMO"),
1548 _T("PASHTO"),
1549 _T("POLISH"),
1550 _T("PORTUGUESE"),
1551 _T("PORTUGUESE_BRAZILIAN"),
1552 _T("PUNJABI"),
1553 _T("QUECHUA"),
1554 _T("RHAETO_ROMANCE"),
1555 _T("ROMANIAN"),
1556 _T("RUSSIAN"),
1557 _T("RUSSIAN_UKRAINE"),
1558 _T("SAMOAN"),
1559 _T("SANGHO"),
1560 _T("SANSKRIT"),
1561 _T("SCOTS_GAELIC"),
1562 _T("SERBIAN"),
1563 _T("SERBIAN_CYRILLIC"),
1564 _T("SERBIAN_LATIN"),
1565 _T("SERBO_CROATIAN"),
1566 _T("SESOTHO"),
1567 _T("SETSWANA"),
1568 _T("SHONA"),
1569 _T("SINDHI"),
1570 _T("SINHALESE"),
1571 _T("SISWATI"),
1572 _T("SLOVAK"),
1573 _T("SLOVENIAN"),
1574 _T("SOMALI"),
1575 _T("SPANISH"),
1576 _T("SPANISH_ARGENTINA"),
1577 _T("SPANISH_BOLIVIA"),
1578 _T("SPANISH_CHILE"),
1579 _T("SPANISH_COLOMBIA"),
1580 _T("SPANISH_COSTA_RICA"),
1581 _T("SPANISH_DOMINICAN_REPUBLIC"),
1582 _T("SPANISH_ECUADOR"),
1583 _T("SPANISH_EL_SALVADOR"),
1584 _T("SPANISH_GUATEMALA"),
1585 _T("SPANISH_HONDURAS"),
1586 _T("SPANISH_MEXICAN"),
1587 _T("SPANISH_MODERN"),
1588 _T("SPANISH_NICARAGUA"),
1589 _T("SPANISH_PANAMA"),
1590 _T("SPANISH_PARAGUAY"),
1591 _T("SPANISH_PERU"),
1592 _T("SPANISH_PUERTO_RICO"),
1593 _T("SPANISH_URUGUAY"),
1594 _T("SPANISH_US"),
1595 _T("SPANISH_VENEZUELA"),
1596 _T("SUNDANESE"),
1597 _T("SWAHILI"),
1598 _T("SWEDISH"),
1599 _T("SWEDISH_FINLAND"),
1600 _T("TAGALOG"),
1601 _T("TAJIK"),
1602 _T("TAMIL"),
1603 _T("TATAR"),
1604 _T("TELUGU"),
1605 _T("THAI"),
1606 _T("TIBETAN"),
1607 _T("TIGRINYA"),
1608 _T("TONGA"),
1609 _T("TSONGA"),
1610 _T("TURKISH"),
1611 _T("TURKMEN"),
1612 _T("TWI"),
1613 _T("UIGHUR"),
1614 _T("UKRAINIAN"),
1615 _T("URDU"),
1616 _T("URDU_INDIA"),
1617 _T("URDU_PAKISTAN"),
1618 _T("UZBEK"),
1619 _T("UZBEK_CYRILLIC"),
1620 _T("UZBEK_LATIN"),
1621 _T("VIETNAMESE"),
1622 _T("VOLAPUK"),
1623 _T("WELSH"),
1624 _T("WOLOF"),
1625 _T("XHOSA"),
1626 _T("YIDDISH"),
1627 _T("YORUBA"),
1628 _T("ZHUANG"),
1629 _T("ZULU"),
ec37df57
VZ
1630 };
1631
1632 if ( (size_t)lang < WXSIZEOF(languageNames) )
1633 return languageNames[lang];
1634 else
456ae26d 1635 return _T("INVALID");
ec37df57
VZ
1636}
1637
1638static void TestDefaultLang()
1639{
456ae26d 1640 wxPuts(_T("*** Testing wxLocale::GetSystemLanguage ***"));
ec37df57
VZ
1641
1642 static const wxChar *langStrings[] =
1643 {
1644 NULL, // system default
1645 _T("C"),
1646 _T("fr"),
1647 _T("fr_FR"),
1648 _T("en"),
1649 _T("en_GB"),
1650 _T("en_US"),
1651 _T("de_DE.iso88591"),
1652 _T("german"),
1653 _T("?"), // invalid lang spec
1654 _T("klingonese"), // I bet on some systems it does exist...
1655 };
1656
dccce9ea
VZ
1657 wxPrintf(_T("The default system encoding is %s (%d)\n"),
1658 wxLocale::GetSystemEncodingName().c_str(),
1659 wxLocale::GetSystemEncoding());
1660
ec37df57
VZ
1661 for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ )
1662 {
456ae26d 1663 const wxChar *langStr = langStrings[n];
ec37df57 1664 if ( langStr )
dccce9ea
VZ
1665 {
1666 // FIXME: this doesn't do anything at all under Windows, we need
1667 // to create a new wxLocale!
ec37df57 1668 wxSetEnv(_T("LC_ALL"), langStr);
dccce9ea 1669 }
ec37df57
VZ
1670
1671 int lang = gs_localeDefault.GetSystemLanguage();
456ae26d
VZ
1672 wxPrintf(_T("Locale for '%s' is %s.\n"),
1673 langStr ? langStr : _T("system default"), GetLangName(lang));
ec37df57
VZ
1674 }
1675}
1676
1677#endif // TEST_LOCALE
1678
696e1ea0
VZ
1679// ----------------------------------------------------------------------------
1680// MIME types
1681// ----------------------------------------------------------------------------
1682
1683#ifdef TEST_MIME
1684
e84010cf 1685#include "wx/mimetype.h"
696e1ea0
VZ
1686
1687static void TestMimeEnum()
1688{
a6c65e88
VZ
1689 wxPuts(_T("*** Testing wxMimeTypesManager::EnumAllFileTypes() ***\n"));
1690
696e1ea0
VZ
1691 wxArrayString mimetypes;
1692
39189b9d 1693 size_t count = wxTheMimeTypesManager->EnumAllFileTypes(mimetypes);
696e1ea0 1694
456ae26d 1695 wxPrintf(_T("*** All %u known filetypes: ***\n"), count);
696e1ea0
VZ
1696
1697 wxArrayString exts;
1698 wxString desc;
1699
1700 for ( size_t n = 0; n < count; n++ )
1701 {
39189b9d
VZ
1702 wxFileType *filetype =
1703 wxTheMimeTypesManager->GetFileTypeFromMimeType(mimetypes[n]);
696e1ea0 1704 if ( !filetype )
c61f4f6d 1705 {
456ae26d 1706 wxPrintf(_T("nothing known about the filetype '%s'!\n"),
97e0ceea 1707 mimetypes[n].c_str());
696e1ea0 1708 continue;
c61f4f6d
VZ
1709 }
1710
696e1ea0
VZ
1711 filetype->GetDescription(&desc);
1712 filetype->GetExtensions(exts);
1713
299fcbfe
VZ
1714 filetype->GetIcon(NULL);
1715
696e1ea0
VZ
1716 wxString extsAll;
1717 for ( size_t e = 0; e < exts.GetCount(); e++ )
1718 {
1719 if ( e > 0 )
1720 extsAll << _T(", ");
1721 extsAll += exts[e];
1722 }
1723
456ae26d 1724 wxPrintf(_T("\t%s: %s (%s)\n"),
54acce90 1725 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
696e1ea0 1726 }
39189b9d 1727
456ae26d 1728 wxPuts(_T(""));
696e1ea0
VZ
1729}
1730
f6bcfd97
BP
1731static void TestMimeOverride()
1732{
1733 wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
1734
39189b9d
VZ
1735 static const wxChar *mailcap = _T("/tmp/mailcap");
1736 static const wxChar *mimetypes = _T("/tmp/mime.types");
1737
1738 if ( wxFile::Exists(mailcap) )
1739 wxPrintf(_T("Loading mailcap from '%s': %s\n"),
1740 mailcap,
1741 wxTheMimeTypesManager->ReadMailcap(mailcap) ? _T("ok") : _T("ERROR"));
1742 else
1743 wxPrintf(_T("WARN: mailcap file '%s' doesn't exist, not loaded.\n"),
1744 mailcap);
f6bcfd97 1745
39189b9d
VZ
1746 if ( wxFile::Exists(mimetypes) )
1747 wxPrintf(_T("Loading mime.types from '%s': %s\n"),
1748 mimetypes,
1749 wxTheMimeTypesManager->ReadMimeTypes(mimetypes) ? _T("ok") : _T("ERROR"));
1750 else
1751 wxPrintf(_T("WARN: mime.types file '%s' doesn't exist, not loaded.\n"),
1752 mimetypes);
1753
456ae26d 1754 wxPuts(_T(""));
f6bcfd97
BP
1755}
1756
1757static void TestMimeFilename()
1758{
1759 wxPuts(_T("*** Testing MIME type from filename query ***\n"));
1760
1761 static const wxChar *filenames[] =
1762 {
1763 _T("readme.txt"),
1764 _T("document.pdf"),
1765 _T("image.gif"),
f06ef5f4 1766 _T("picture.jpeg"),
f6bcfd97
BP
1767 };
1768
1769 for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
1770 {
1771 const wxString fname = filenames[n];
1772 wxString ext = fname.AfterLast(_T('.'));
39189b9d 1773 wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
f6bcfd97
BP
1774 if ( !ft )
1775 {
1776 wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext.c_str());
1777 }
1778 else
1779 {
1780 wxString desc;
1781 if ( !ft->GetDescription(&desc) )
1782 desc = _T("<no description>");
1783
1784 wxString cmd;
1785 if ( !ft->GetOpenCommand(&cmd,
1786 wxFileType::MessageParameters(fname, _T(""))) )
1787 cmd = _T("<no command available>");
7aeebdcd 1788 else
2b5f62a0 1789 cmd = wxString(_T('"')) + cmd + _T('"');
f6bcfd97 1790
7aeebdcd 1791 wxPrintf(_T("To open %s (%s) do %s.\n"),
f6bcfd97
BP
1792 fname.c_str(), desc.c_str(), cmd.c_str());
1793
1794 delete ft;
1795 }
1796 }
39189b9d 1797
456ae26d 1798 wxPuts(_T(""));
f6bcfd97
BP
1799}
1800
c7ce8392
VZ
1801static void TestMimeAssociate()
1802{
1803 wxPuts(_T("*** Testing creation of filetype association ***\n"));
1804
a6c65e88
VZ
1805 wxFileTypeInfo ftInfo(
1806 _T("application/x-xyz"),
1807 _T("xyzview '%s'"), // open cmd
1808 _T(""), // print cmd
df0dc216
VZ
1809 _T("XYZ File"), // description
1810 _T(".xyz"), // extensions
1811 NULL // end of extensions
a6c65e88
VZ
1812 );
1813 ftInfo.SetShortDesc(_T("XYZFile")); // used under Win32 only
1814
39189b9d 1815 wxFileType *ft = wxTheMimeTypesManager->Associate(ftInfo);
c7ce8392
VZ
1816 if ( !ft )
1817 {
1818 wxPuts(_T("ERROR: failed to create association!"));
1819 }
1820 else
1821 {
a6c65e88 1822 // TODO: read it back
c7ce8392
VZ
1823 delete ft;
1824 }
39189b9d 1825
456ae26d 1826 wxPuts(_T(""));
c7ce8392
VZ
1827}
1828
696e1ea0
VZ
1829#endif // TEST_MIME
1830
89e60357
VZ
1831// ----------------------------------------------------------------------------
1832// misc information functions
1833// ----------------------------------------------------------------------------
1834
1835#ifdef TEST_INFO_FUNCTIONS
1836
e84010cf 1837#include "wx/utils.h"
89e60357 1838
3a994742
VZ
1839static void TestDiskInfo()
1840{
456ae26d 1841 wxPuts(_T("*** Testing wxGetDiskSpace() ***"));
3a994742
VZ
1842
1843 for ( ;; )
1844 {
456ae26d
VZ
1845 wxChar pathname[128];
1846 wxPrintf(_T("\nEnter a directory name: "));
1847 if ( !wxFgets(pathname, WXSIZEOF(pathname), stdin) )
3a994742
VZ
1848 break;
1849
1850 // kill the last '\n'
456ae26d 1851 pathname[wxStrlen(pathname) - 1] = 0;
3a994742
VZ
1852
1853 wxLongLong total, free;
1854 if ( !wxGetDiskSpace(pathname, &total, &free) )
1855 {
1856 wxPuts(_T("ERROR: wxGetDiskSpace failed."));
1857 }
1858 else
1859 {
eadd7bd2
VZ
1860 wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"),
1861 (total / 1024).ToString().c_str(),
1862 (free / 1024).ToString().c_str(),
3a994742
VZ
1863 pathname);
1864 }
1865 }
1866}
1867
89e60357
VZ
1868static void TestOsInfo()
1869{
456ae26d 1870 wxPuts(_T("*** Testing OS info functions ***\n"));
89e60357
VZ
1871
1872 int major, minor;
1873 wxGetOsVersion(&major, &minor);
456ae26d 1874 wxPrintf(_T("Running under: %s, version %d.%d\n"),
89e60357
VZ
1875 wxGetOsDescription().c_str(), major, minor);
1876
456ae26d 1877 wxPrintf(_T("%ld free bytes of memory left.\n"), wxGetFreeMemory());
89e60357 1878
456ae26d 1879 wxPrintf(_T("Host name is %s (%s).\n"),
89e60357 1880 wxGetHostName().c_str(), wxGetFullHostName().c_str());
bd3277fe 1881
456ae26d 1882 wxPuts(_T(""));
89e60357
VZ
1883}
1884
1885static void TestUserInfo()
1886{
456ae26d 1887 wxPuts(_T("*** Testing user info functions ***\n"));
89e60357 1888
456ae26d
VZ
1889 wxPrintf(_T("User id is:\t%s\n"), wxGetUserId().c_str());
1890 wxPrintf(_T("User name is:\t%s\n"), wxGetUserName().c_str());
1891 wxPrintf(_T("Home dir is:\t%s\n"), wxGetHomeDir().c_str());
1892 wxPrintf(_T("Email address:\t%s\n"), wxGetEmailAddress().c_str());
bd3277fe 1893
456ae26d 1894 wxPuts(_T(""));
89e60357
VZ
1895}
1896
1897#endif // TEST_INFO_FUNCTIONS
1898
b76b015e
VZ
1899// ----------------------------------------------------------------------------
1900// long long
1901// ----------------------------------------------------------------------------
1902
1903#ifdef TEST_LONGLONG
1904
e84010cf
GD
1905#include "wx/longlong.h"
1906#include "wx/timer.h"
b76b015e 1907
2a310492
VZ
1908// make a 64 bit number from 4 16 bit ones
1909#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1910
1911// get a random 64 bit number
1912#define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1913
3a994742
VZ
1914static const long testLongs[] =
1915{
1916 0,
1917 1,
1918 -1,
1919 LONG_MAX,
1920 LONG_MIN,
1921 0x1234,
1922 -0x1234
1923};
1924
7d0bb74d 1925#if wxUSE_LONGLONG_WX
2a310492
VZ
1926inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
1927 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
1928inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
1929 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
7d0bb74d 1930#endif // wxUSE_LONGLONG_WX
2a310492 1931
b76b015e
VZ
1932static void TestSpeed()
1933{
1934 static const long max = 100000000;
1935 long n;
9fc3ad34 1936
b76b015e
VZ
1937 {
1938 wxStopWatch sw;
1939
1940 long l = 0;
1941 for ( n = 0; n < max; n++ )
1942 {
1943 l += n;
1944 }
1945
456ae26d 1946 wxPrintf(_T("Summing longs took %ld milliseconds.\n"), sw.Time());
b76b015e
VZ
1947 }
1948
2ea24d9f 1949#if wxUSE_LONGLONG_NATIVE
b76b015e
VZ
1950 {
1951 wxStopWatch sw;
1952
2ea24d9f 1953 wxLongLong_t l = 0;
b76b015e
VZ
1954 for ( n = 0; n < max; n++ )
1955 {
1956 l += n;
1957 }
1958
456ae26d 1959 wxPrintf(_T("Summing wxLongLong_t took %ld milliseconds.\n"), sw.Time());
b76b015e 1960 }
2ea24d9f 1961#endif // wxUSE_LONGLONG_NATIVE
b76b015e
VZ
1962
1963 {
1964 wxStopWatch sw;
1965
1966 wxLongLong l;
1967 for ( n = 0; n < max; n++ )
1968 {
1969 l += n;
1970 }
1971
456ae26d 1972 wxPrintf(_T("Summing wxLongLongs took %ld milliseconds.\n"), sw.Time());
b76b015e
VZ
1973 }
1974}
1975
2a310492 1976static void TestLongLongConversion()
b76b015e 1977{
456ae26d 1978 wxPuts(_T("*** Testing wxLongLong conversions ***\n"));
2a310492
VZ
1979
1980 wxLongLong a;
1981 size_t nTested = 0;
1982 for ( size_t n = 0; n < 100000; n++ )
1983 {
1984 a = RAND_LL();
1985
1986#if wxUSE_LONGLONG_NATIVE
1987 wxLongLongNative b(a.GetHi(), a.GetLo());
5e6a0e83 1988
2a310492
VZ
1989 wxASSERT_MSG( a == b, "conversions failure" );
1990#else
456ae26d 1991 wxPuts(_T("Can't do it without native long long type, test skipped."));
b76b015e 1992
2a310492
VZ
1993 return;
1994#endif // wxUSE_LONGLONG_NATIVE
1995
1996 if ( !(nTested % 1000) )
1997 {
1998 putchar('.');
1999 fflush(stdout);
2000 }
2001
2002 nTested++;
2003 }
2004
456ae26d 2005 wxPuts(_T(" done!"));
2a310492
VZ
2006}
2007
2008static void TestMultiplication()
2009{
456ae26d 2010 wxPuts(_T("*** Testing wxLongLong multiplication ***\n"));
2a310492
VZ
2011
2012 wxLongLong a, b;
2013 size_t nTested = 0;
2014 for ( size_t n = 0; n < 100000; n++ )
2015 {
2016 a = RAND_LL();
2017 b = RAND_LL();
2018
2019#if wxUSE_LONGLONG_NATIVE
2020 wxLongLongNative aa(a.GetHi(), a.GetLo());
2021 wxLongLongNative bb(b.GetHi(), b.GetLo());
2022
2023 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
2024#else // !wxUSE_LONGLONG_NATIVE
456ae26d 2025 wxPuts(_T("Can't do it without native long long type, test skipped."));
2a310492
VZ
2026
2027 return;
2028#endif // wxUSE_LONGLONG_NATIVE
2029
2030 if ( !(nTested % 1000) )
2031 {
2032 putchar('.');
2033 fflush(stdout);
2034 }
2035
2036 nTested++;
2037 }
2038
456ae26d 2039 wxPuts(_T(" done!"));
2a310492
VZ
2040}
2041
2042static void TestDivision()
2043{
456ae26d 2044 wxPuts(_T("*** Testing wxLongLong division ***\n"));
2f02cb89 2045
2ea24d9f 2046 wxLongLong q, r;
2f02cb89 2047 size_t nTested = 0;
5e6a0e83 2048 for ( size_t n = 0; n < 100000; n++ )
2f02cb89
VZ
2049 {
2050 // get a random wxLongLong (shifting by 12 the MSB ensures that the
2051 // multiplication will not overflow)
2052 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
2053
19f45995
VZ
2054 // get a random (but non null) long (not wxLongLong for now) to divide
2055 // it with
2056 long l;
2057 do
2058 {
2059 l = rand();
2060 }
2061 while ( !l );
2062
2ea24d9f
VZ
2063 q = ll / l;
2064 r = ll % l;
2065
2a310492
VZ
2066#if wxUSE_LONGLONG_NATIVE
2067 wxLongLongNative m(ll.GetHi(), ll.GetLo());
2068
2069 wxLongLongNative p = m / l, s = m % l;
2070 wxASSERT_MSG( q == p && r == s, "division failure" );
2071#else // !wxUSE_LONGLONG_NATIVE
5e6a0e83 2072 // verify the result
2ea24d9f 2073 wxASSERT_MSG( ll == q*l + r, "division failure" );
2a310492 2074#endif // wxUSE_LONGLONG_NATIVE
2f02cb89 2075
5e6a0e83
VZ
2076 if ( !(nTested % 1000) )
2077 {
2078 putchar('.');
2079 fflush(stdout);
2080 }
2081
2f02cb89
VZ
2082 nTested++;
2083 }
2084
456ae26d 2085 wxPuts(_T(" done!"));
2a310492 2086}
2f02cb89 2087
2a310492
VZ
2088static void TestAddition()
2089{
456ae26d 2090 wxPuts(_T("*** Testing wxLongLong addition ***\n"));
2a310492
VZ
2091
2092 wxLongLong a, b, c;
2093 size_t nTested = 0;
2094 for ( size_t n = 0; n < 100000; n++ )
2095 {
2096 a = RAND_LL();
2097 b = RAND_LL();
2098 c = a + b;
2099
2100#if wxUSE_LONGLONG_NATIVE
2101 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
2102 wxLongLongNative(b.GetHi(), b.GetLo()),
7c968cee 2103 "addition failure" );
2a310492
VZ
2104#else // !wxUSE_LONGLONG_NATIVE
2105 wxASSERT_MSG( c - b == a, "addition failure" );
2106#endif // wxUSE_LONGLONG_NATIVE
2107
2108 if ( !(nTested % 1000) )
2109 {
2110 putchar('.');
2111 fflush(stdout);
2112 }
2113
2114 nTested++;
2115 }
2116
456ae26d 2117 wxPuts(_T(" done!"));
b76b015e
VZ
2118}
2119
2a310492
VZ
2120static void TestBitOperations()
2121{
456ae26d 2122 wxPuts(_T("*** Testing wxLongLong bit operation ***\n"));
2a310492 2123
f6bcfd97 2124 wxLongLong ll;
2a310492
VZ
2125 size_t nTested = 0;
2126 for ( size_t n = 0; n < 100000; n++ )
2127 {
f6bcfd97 2128 ll = RAND_LL();
2a310492
VZ
2129
2130#if wxUSE_LONGLONG_NATIVE
2131 for ( size_t n = 0; n < 33; n++ )
2132 {
2a310492 2133 }
2a310492 2134#else // !wxUSE_LONGLONG_NATIVE
456ae26d 2135 wxPuts(_T("Can't do it without native long long type, test skipped."));
2a310492
VZ
2136
2137 return;
2138#endif // wxUSE_LONGLONG_NATIVE
2139
2140 if ( !(nTested % 1000) )
2141 {
2142 putchar('.');
2143 fflush(stdout);
2144 }
2145
2146 nTested++;
2147 }
2148
456ae26d 2149 wxPuts(_T(" done!"));
2a310492
VZ
2150}
2151
f6bcfd97
BP
2152static void TestLongLongComparison()
2153{
2d3112ad 2154#if wxUSE_LONGLONG_WX
456ae26d 2155 wxPuts(_T("*** Testing wxLongLong comparison ***\n"));
f6bcfd97 2156
f6bcfd97
BP
2157 static const long ls[2] =
2158 {
2159 0x1234,
2160 -0x1234,
2161 };
2162
2163 wxLongLongWx lls[2];
2164 lls[0] = ls[0];
3a994742 2165 lls[1] = ls[1];
f6bcfd97
BP
2166
2167 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2168 {
2169 bool res;
2170
2171 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
2172 {
2173 res = lls[m] > testLongs[n];
456ae26d 2174 wxPrintf(_T("0x%lx > 0x%lx is %s (%s)\n"),
f6bcfd97
BP
2175 ls[m], testLongs[n], res ? "true" : "false",
2176 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
2177
2178 res = lls[m] < testLongs[n];
456ae26d 2179 wxPrintf(_T("0x%lx < 0x%lx is %s (%s)\n"),
f6bcfd97
BP
2180 ls[m], testLongs[n], res ? "true" : "false",
2181 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
2182
2183 res = lls[m] == testLongs[n];
456ae26d 2184 wxPrintf(_T("0x%lx == 0x%lx is %s (%s)\n"),
f6bcfd97
BP
2185 ls[m], testLongs[n], res ? "true" : "false",
2186 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
2187 }
2188 }
2d3112ad 2189#endif // wxUSE_LONGLONG_WX
f6bcfd97
BP
2190}
2191
2b5f62a0 2192static void TestLongLongToString()
3a994742 2193{
2b5f62a0 2194 wxPuts(_T("*** Testing wxLongLong::ToString() ***\n"));
3a994742
VZ
2195
2196 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2197 {
2198 wxLongLong ll = testLongs[n];
2199 wxPrintf(_T("%ld == %s\n"), testLongs[n], ll.ToString().c_str());
2200 }
2201
2202 wxLongLong ll(0x12345678, 0x87654321);
2203 wxPrintf(_T("0x1234567887654321 = %s\n"), ll.ToString().c_str());
2204
2205 ll.Negate();
2206 wxPrintf(_T("-0x1234567887654321 = %s\n"), ll.ToString().c_str());
2207}
2208
4c51b688
VZ
2209static void TestLongLongPrintf()
2210{
2211 wxPuts(_T("*** Testing wxLongLong printing ***\n"));
2212
2213#ifdef wxLongLongFmtSpec
2214 wxLongLong ll = wxLL(0x1234567890abcdef);
2b5f62a0 2215 wxString s = wxString::Format(_T("%") wxLongLongFmtSpec _T("x"), ll);
4c51b688
VZ
2216 wxPrintf(_T("0x1234567890abcdef -> %s (%s)\n"),
2217 s.c_str(), s == _T("1234567890abcdef") ? _T("ok") : _T("ERROR"));
2218#else // !wxLongLongFmtSpec
2219 #error "wxLongLongFmtSpec not defined for this compiler/platform"
2220#endif
2221}
2222
2a310492
VZ
2223#undef MAKE_LL
2224#undef RAND_LL
2225
b76b015e
VZ
2226#endif // TEST_LONGLONG
2227
39189b9d
VZ
2228// ----------------------------------------------------------------------------
2229// path list
2230// ----------------------------------------------------------------------------
2231
2232#ifdef TEST_PATHLIST
2233
ee3ef281
VZ
2234#ifdef __UNIX__
2235 #define CMD_IN_PATH _T("ls")
2236#else
2237 #define CMD_IN_PATH _T("command.com")
2238#endif
2239
39189b9d
VZ
2240static void TestPathList()
2241{
456ae26d 2242 wxPuts(_T("*** Testing wxPathList ***\n"));
39189b9d
VZ
2243
2244 wxPathList pathlist;
ee3ef281
VZ
2245 pathlist.AddEnvList(_T("PATH"));
2246 wxString path = pathlist.FindValidPath(CMD_IN_PATH);
39189b9d
VZ
2247 if ( path.empty() )
2248 {
456ae26d 2249 wxPrintf(_T("ERROR: command not found in the path.\n"));
39189b9d
VZ
2250 }
2251 else
2252 {
456ae26d 2253 wxPrintf(_T("Command found in the path as '%s'.\n"), path.c_str());
39189b9d
VZ
2254 }
2255}
2256
2257#endif // TEST_PATHLIST
2258
07a56e45
VZ
2259// ----------------------------------------------------------------------------
2260// regular expressions
2261// ----------------------------------------------------------------------------
2262
2263#ifdef TEST_REGEX
2264
e84010cf 2265#include "wx/regex.h"
07a56e45
VZ
2266
2267static void TestRegExCompile()
2268{
2269 wxPuts(_T("*** Testing RE compilation ***\n"));
2270
2271 static struct RegExCompTestData
2272 {
2273 const wxChar *pattern;
2274 bool correct;
2275 } regExCompTestData[] =
2276 {
cab8f76e
VZ
2277 { _T("foo"), true },
2278 { _T("foo("), false },
2279 { _T("foo(bar"), false },
2280 { _T("foo(bar)"), true },
2281 { _T("foo["), false },
2282 { _T("foo[bar"), false },
2283 { _T("foo[bar]"), true },
2284 { _T("foo{"), true },
2285 { _T("foo{1"), false },
2286 { _T("foo{bar"), true },
2287 { _T("foo{1}"), true },
2288 { _T("foo{1,2}"), true },
2289 { _T("foo{bar}"), true },
2290 { _T("foo*"), true },
2291 { _T("foo**"), false },
2292 { _T("foo+"), true },
2293 { _T("foo++"), false },
2294 { _T("foo?"), true },
2295 { _T("foo??"), false },
2296 { _T("foo?+"), false },
07a56e45
VZ
2297 };
2298
2299 wxRegEx re;
2300 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
2301 {
2302 const RegExCompTestData& data = regExCompTestData[n];
2303 bool ok = re.Compile(data.pattern);
2304
2305 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
2306 data.pattern,
2307 ok ? _T("") : _T("not "),
2308 ok == data.correct ? _T("ok") : _T("ERROR"));
2309 }
2310}
2311
2312static void TestRegExMatch()
2313{
2314 wxPuts(_T("*** Testing RE matching ***\n"));
2315
2316 static struct RegExMatchTestData
2317 {
2318 const wxChar *pattern;
2319 const wxChar *text;
2320 bool correct;
2321 } regExMatchTestData[] =
2322 {
cab8f76e
VZ
2323 { _T("foo"), _T("bar"), false },
2324 { _T("foo"), _T("foobar"), true },
2325 { _T("^foo"), _T("foobar"), true },
2326 { _T("^foo"), _T("barfoo"), false },
2327 { _T("bar$"), _T("barbar"), true },
2328 { _T("bar$"), _T("barbar "), false },
07a56e45
VZ
2329 };
2330
2331 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
2332 {
2333 const RegExMatchTestData& data = regExMatchTestData[n];
2334
2335 wxRegEx re(data.pattern);
2336 bool ok = re.Matches(data.text);
2337
2338 wxPrintf(_T("'%s' %s %s (%s)\n"),
2339 data.pattern,
2340 ok ? _T("matches") : _T("doesn't match"),
2341 data.text,
2342 ok == data.correct ? _T("ok") : _T("ERROR"));
2343 }
2344}
2345
2346static void TestRegExSubmatch()
2347{
2348 wxPuts(_T("*** Testing RE subexpressions ***\n"));
2349
2350 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
2351 if ( !re.IsValid() )
2352 {
2353 wxPuts(_T("ERROR: compilation failed."));
2354 return;
2355 }
2356
2357 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
2358
2359 if ( !re.Matches(text) )
2360 {
2361 wxPuts(_T("ERROR: match expected."));
2362 }
2363 else
2364 {
2365 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
2366
2367 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
2368 re.GetMatch(text, 3).c_str(),
2369 re.GetMatch(text, 2).c_str(),
2370 re.GetMatch(text, 4).c_str(),
2371 re.GetMatch(text, 1).c_str());
2372 }
2373}
2374
765624f7
VZ
2375static void TestRegExReplacement()
2376{
2377 wxPuts(_T("*** Testing RE replacement ***"));
2378
2379 static struct RegExReplTestData
2380 {
2381 const wxChar *text;
2382 const wxChar *repl;
2383 const wxChar *result;
2384 size_t count;
2385 } regExReplTestData[] =
2386 {
2387 { _T("foo123"), _T("bar"), _T("bar"), 1 },
2388 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
2389 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
2390 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
2391 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
2392 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
2393 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
2394 };
2395
2396 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
daa2c7d9 2397 wxRegEx re(pattern);
765624f7
VZ
2398
2399 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
2400
2401 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
2402 {
2403 const RegExReplTestData& data = regExReplTestData[n];
2404
2405 wxString text = data.text;
2406 size_t nRepl = re.Replace(&text, data.repl);
2407
2408 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
2409 data.text, data.repl,
2410 nRepl, nRepl == 1 ? _T("") : _T("es"),
2411 text.c_str());
2412 if ( text == data.result && nRepl == data.count )
2413 {
2414 wxPuts(_T("ok)"));
2415 }
2416 else
2417 {
2418 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
2419 data.count, data.result);
2420 }
2421 }
2422}
2423
07a56e45
VZ
2424static void TestRegExInteractive()
2425{
2426 wxPuts(_T("*** Testing RE interactively ***"));
2427
2428 for ( ;; )
2429 {
456ae26d
VZ
2430 wxChar pattern[128];
2431 wxPrintf(_T("\nEnter a pattern: "));
2432 if ( !wxFgets(pattern, WXSIZEOF(pattern), stdin) )
07a56e45
VZ
2433 break;
2434
2435 // kill the last '\n'
456ae26d 2436 pattern[wxStrlen(pattern) - 1] = 0;
07a56e45
VZ
2437
2438 wxRegEx re;
2439 if ( !re.Compile(pattern) )
2440 {
2441 continue;
2442 }
2443
456ae26d 2444 wxChar text[128];
07a56e45
VZ
2445 for ( ;; )
2446 {
456ae26d
VZ
2447 wxPrintf(_T("Enter text to match: "));
2448 if ( !wxFgets(text, WXSIZEOF(text), stdin) )
07a56e45
VZ
2449 break;
2450
2451 // kill the last '\n'
456ae26d 2452 text[wxStrlen(text) - 1] = 0;
07a56e45
VZ
2453
2454 if ( !re.Matches(text) )
2455 {
456ae26d 2456 wxPrintf(_T("No match.\n"));
07a56e45
VZ
2457 }
2458 else
2459 {
456ae26d 2460 wxPrintf(_T("Pattern matches at '%s'\n"), re.GetMatch(text).c_str());
07a56e45
VZ
2461
2462 size_t start, len;
2463 for ( size_t n = 1; ; n++ )
2464 {
2465 if ( !re.GetMatch(&start, &len, n) )
2466 {
2467 break;
2468 }
2469
456ae26d
VZ
2470 wxPrintf(_T("Subexpr %u matched '%s'\n"),
2471 n, wxString(text + start, len).c_str());
07a56e45
VZ
2472 }
2473 }
2474 }
2475 }
2476}
2477
2478#endif // TEST_REGEX
2479
8d5eff60
VZ
2480// ----------------------------------------------------------------------------
2481// database
2482// ----------------------------------------------------------------------------
2483
ba6ea19e
VZ
2484#if !wxUSE_ODBC
2485 #undef TEST_ODBC
2486#endif
2487
8d5eff60
VZ
2488#ifdef TEST_ODBC
2489
2490#include <wx/db.h>
2491
2492static void TestDbOpen()
2493{
2494 HENV henv;
2495 wxDb db(henv);
2496}
2497
2498#endif // TEST_ODBC
2499
7aeebdcd
VZ
2500// ----------------------------------------------------------------------------
2501// printf() tests
2502// ----------------------------------------------------------------------------
2503
2504/*
2505 NB: this stuff was taken from the glibc test suite and modified to build
2506 in wxWindows: if I read the copyright below properly, this shouldn't
2507 be a problem
2508 */
2509
2510#ifdef TEST_PRINTF
2511
2512#ifdef wxTEST_PRINTF
2513 // use our functions from wxchar.cpp
2514 #undef wxPrintf
2515 #undef wxSprintf
2516
2517 // NB: do _not_ use ATTRIBUTE_PRINTF here, we have some invalid formats
2518 // in the tests below
2519 int wxPrintf( const wxChar *format, ... );
2520 int wxSprintf( wxChar *str, const wxChar *format, ... );
2521#endif
2522
f1389d46
VZ
2523#include "wx/longlong.h"
2524
7aeebdcd
VZ
2525#include <float.h>
2526
2527static void rfg1 (void);
2528static void rfg2 (void);
2529
2530
2531static void
2532fmtchk (const wxChar *fmt)
2533{
2534 (void) wxPrintf(_T("%s:\t`"), fmt);
2535 (void) wxPrintf(fmt, 0x12);
2536 (void) wxPrintf(_T("'\n"));
2537}
2538
2539static void
2540fmtst1chk (const wxChar *fmt)
2541{
2542 (void) wxPrintf(_T("%s:\t`"), fmt);
2543 (void) wxPrintf(fmt, 4, 0x12);
2544 (void) wxPrintf(_T("'\n"));
2545}
2546
2547static void
2548fmtst2chk (const wxChar *fmt)
2549{
2550 (void) wxPrintf(_T("%s:\t`"), fmt);
2551 (void) wxPrintf(fmt, 4, 4, 0x12);
2552 (void) wxPrintf(_T("'\n"));
2553}
2554
2555/* This page is covered by the following copyright: */
2556
2557/* (C) Copyright C E Chew
2558 *
2559 * Feel free to copy, use and distribute this software provided:
2560 *
2561 * 1. you do not pretend that you wrote it
2562 * 2. you leave this copyright notice intact.
2563 */
2564
2565/*
2566 * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
2567 */
2568
2569#define DEC -123
2570#define INT 255
2571#define UNS (~0)
2572
2573/* Formatted Output Test
2574 *
2575 * This exercises the output formatting code.
2576 */
2577
2578static void
2579fp_test (void)
2580{
2581 int i, j, k, l;
2582 wxChar buf[7];
2583 wxChar *prefix = buf;
2584 wxChar tp[20];
2585
2586 wxPuts(_T("\nFormatted output test"));
2587 wxPrintf(_T("prefix 6d 6o 6x 6X 6u\n"));
2588 wxStrcpy(prefix, _T("%"));
2589 for (i = 0; i < 2; i++) {
2590 for (j = 0; j < 2; j++) {
2591 for (k = 0; k < 2; k++) {
2592 for (l = 0; l < 2; l++) {
2593 wxStrcpy(prefix, _T("%"));
2594 if (i == 0) wxStrcat(prefix, _T("-"));
2595 if (j == 0) wxStrcat(prefix, _T("+"));
2596 if (k == 0) wxStrcat(prefix, _T("#"));
2597 if (l == 0) wxStrcat(prefix, _T("0"));
2598 wxPrintf(_T("%5s |"), prefix);
2599 wxStrcpy(tp, prefix);
2600 wxStrcat(tp, _T("6d |"));
2601 wxPrintf(tp, DEC);
2602 wxStrcpy(tp, prefix);
2603 wxStrcat(tp, _T("6o |"));
2604 wxPrintf(tp, INT);
2605 wxStrcpy(tp, prefix);
2606 wxStrcat(tp, _T("6x |"));
2607 wxPrintf(tp, INT);
2608 wxStrcpy(tp, prefix);
2609 wxStrcat(tp, _T("6X |"));
2610 wxPrintf(tp, INT);
2611 wxStrcpy(tp, prefix);
2612 wxStrcat(tp, _T("6u |"));
2613 wxPrintf(tp, UNS);
2614 wxPrintf(_T("\n"));
2615 }
2616 }
2617 }
2618 }
2619 wxPrintf(_T("%10s\n"), (wxChar *) NULL);
2620 wxPrintf(_T("%-10s\n"), (wxChar *) NULL);
2621}
2622
2623static void TestPrintf()
2624{
2625 static wxChar shortstr[] = _T("Hi, Z.");
f1389d46
VZ
2626 static wxChar longstr[] = _T("Good morning, Doctor Chandra. This is Hal. \
2627I am ready for my first lesson today.");
7aeebdcd
VZ
2628 int result = 0;
2629
2630 fmtchk(_T("%.4x"));
2631 fmtchk(_T("%04x"));
2632 fmtchk(_T("%4.4x"));
2633 fmtchk(_T("%04.4x"));
2634 fmtchk(_T("%4.3x"));
2635 fmtchk(_T("%04.3x"));
2636
2637 fmtst1chk(_T("%.*x"));
2638 fmtst1chk(_T("%0*x"));
2639 fmtst2chk(_T("%*.*x"));
2640 fmtst2chk(_T("%0*.*x"));
2641
2642 wxPrintf(_T("bad format:\t\"%b\"\n"));
2643 wxPrintf(_T("nil pointer (padded):\t\"%10p\"\n"), (void *) NULL);
2644
2645 wxPrintf(_T("decimal negative:\t\"%d\"\n"), -2345);
2646 wxPrintf(_T("octal negative:\t\"%o\"\n"), -2345);
2647 wxPrintf(_T("hex negative:\t\"%x\"\n"), -2345);
2648 wxPrintf(_T("long decimal number:\t\"%ld\"\n"), -123456L);
2649 wxPrintf(_T("long octal negative:\t\"%lo\"\n"), -2345L);
2650 wxPrintf(_T("long unsigned decimal number:\t\"%lu\"\n"), -123456L);
2651 wxPrintf(_T("zero-padded LDN:\t\"%010ld\"\n"), -123456L);
2652 wxPrintf(_T("left-adjusted ZLDN:\t\"%-010ld\"\n"), -123456);
2653 wxPrintf(_T("space-padded LDN:\t\"%10ld\"\n"), -123456L);
2654 wxPrintf(_T("left-adjusted SLDN:\t\"%-10ld\"\n"), -123456L);
2655
2656 wxPrintf(_T("zero-padded string:\t\"%010s\"\n"), shortstr);
2657 wxPrintf(_T("left-adjusted Z string:\t\"%-010s\"\n"), shortstr);
2658 wxPrintf(_T("space-padded string:\t\"%10s\"\n"), shortstr);
2659 wxPrintf(_T("left-adjusted S string:\t\"%-10s\"\n"), shortstr);
2660 wxPrintf(_T("null string:\t\"%s\"\n"), (wxChar *)NULL);
2661 wxPrintf(_T("limited string:\t\"%.22s\"\n"), longstr);
2662
2663 wxPrintf(_T("e-style >= 1:\t\"%e\"\n"), 12.34);
2664 wxPrintf(_T("e-style >= .1:\t\"%e\"\n"), 0.1234);
2665 wxPrintf(_T("e-style < .1:\t\"%e\"\n"), 0.001234);
2666 wxPrintf(_T("e-style big:\t\"%.60e\"\n"), 1e20);
2667 wxPrintf(_T("e-style == .1:\t\"%e\"\n"), 0.1);
2668 wxPrintf(_T("f-style >= 1:\t\"%f\"\n"), 12.34);
2669 wxPrintf(_T("f-style >= .1:\t\"%f\"\n"), 0.1234);
2670 wxPrintf(_T("f-style < .1:\t\"%f\"\n"), 0.001234);
2671 wxPrintf(_T("g-style >= 1:\t\"%g\"\n"), 12.34);
2672 wxPrintf(_T("g-style >= .1:\t\"%g\"\n"), 0.1234);
2673 wxPrintf(_T("g-style < .1:\t\"%g\"\n"), 0.001234);
2674 wxPrintf(_T("g-style big:\t\"%.60g\"\n"), 1e20);
2675
2676 wxPrintf (_T(" %6.5f\n"), .099999999860301614);
2677 wxPrintf (_T(" %6.5f\n"), .1);
2678 wxPrintf (_T("x%5.4fx\n"), .5);
2679
2680 wxPrintf (_T("%#03x\n"), 1);
2681
2682 //wxPrintf (_T("something really insane: %.10000f\n"), 1.0);
2683
2684 {
2685 double d = FLT_MIN;
2686 int niter = 17;
2687
2688 while (niter-- != 0)
2689 wxPrintf (_T("%.17e\n"), d / 2);
2690 fflush (stdout);
2691 }
2692
2693 wxPrintf (_T("%15.5e\n"), 4.9406564584124654e-324);
2694
2695#define FORMAT _T("|%12.4f|%12.4e|%12.4g|\n")
2696 wxPrintf (FORMAT, 0.0, 0.0, 0.0);
2697 wxPrintf (FORMAT, 1.0, 1.0, 1.0);
2698 wxPrintf (FORMAT, -1.0, -1.0, -1.0);
2699 wxPrintf (FORMAT, 100.0, 100.0, 100.0);
2700 wxPrintf (FORMAT, 1000.0, 1000.0, 1000.0);
2701 wxPrintf (FORMAT, 10000.0, 10000.0, 10000.0);
2702 wxPrintf (FORMAT, 12345.0, 12345.0, 12345.0);
2703 wxPrintf (FORMAT, 100000.0, 100000.0, 100000.0);
2704 wxPrintf (FORMAT, 123456.0, 123456.0, 123456.0);
2705#undef FORMAT
2706
2707 {
2708 wxChar buf[20];
2709 int rc = wxSnprintf (buf, WXSIZEOF(buf), _T("%30s"), _T("foo"));
2710
2711 wxPrintf(_T("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n"),
2712 rc, WXSIZEOF(buf), buf);
2713#if 0
2714 wxChar buf2[512];
2715 wxPrintf ("snprintf (\"%%.999999u\", 10)\n",
2716 wxSnprintf(buf2, WXSIZEOFbuf2), "%.999999u", 10));
2717#endif
2718 }
2719
2720 fp_test ();
2721
2722 wxPrintf (_T("%e should be 1.234568e+06\n"), 1234567.8);
2723 wxPrintf (_T("%f should be 1234567.800000\n"), 1234567.8);
2724 wxPrintf (_T("%g should be 1.23457e+06\n"), 1234567.8);
2725 wxPrintf (_T("%g should be 123.456\n"), 123.456);
2726 wxPrintf (_T("%g should be 1e+06\n"), 1000000.0);
2727 wxPrintf (_T("%g should be 10\n"), 10.0);
2728 wxPrintf (_T("%g should be 0.02\n"), 0.02);
2729
2730 {
2731 double x=1.0;
2732 wxPrintf(_T("%.17f\n"),(1.0/x/10.0+1.0)*x-x);
2733 }
2734
2735 {
2736 wxChar buf[200];
2737
2738 wxSprintf(buf,_T("%*s%*s%*s"),-1,_T("one"),-20,_T("two"),-30,_T("three"));
2739
2740 result |= wxStrcmp (buf,
2741 _T("onetwo three "));
2742
2743 wxPuts (result != 0 ? _T("Test failed!") : _T("Test ok."));
2744 }
2745
f1389d46 2746#ifdef wxLongLong_t
7aeebdcd 2747 {
f1389d46 2748 wxChar buf[200];
7aeebdcd 2749
2b5f62a0 2750 wxSprintf(buf, _T("%07") wxLongLongFmtSpec _T("o"), wxLL(040000000000));
f1389d46 2751 wxPrintf (_T("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s"), buf);
7aeebdcd 2752
f1389d46 2753 if (wxStrcmp (buf, _T("40000000000")) != 0)
7aeebdcd 2754 {
f1389d46
VZ
2755 result = 1;
2756 wxPuts (_T("\tFAILED"));
7aeebdcd 2757 }
f1389d46 2758 wxPuts (_T(""));
7aeebdcd 2759 }
f1389d46 2760#endif // wxLongLong_t
7aeebdcd
VZ
2761
2762 wxPrintf (_T("printf (\"%%hhu\", %u) = %hhu\n"), UCHAR_MAX + 2, UCHAR_MAX + 2);
2763 wxPrintf (_T("printf (\"%%hu\", %u) = %hu\n"), USHRT_MAX + 2, USHRT_MAX + 2);
2764
2765 wxPuts (_T("--- Should be no further output. ---"));
2766 rfg1 ();
2767 rfg2 ();
2768
2769#if 0
2770 {
2771 wxChar bytes[7];
2772 wxChar buf[20];
2773
2774 memset (bytes, '\xff', sizeof bytes);
2775 wxSprintf (buf, _T("foo%hhn\n"), &bytes[3]);
2776 if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
2777 || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
2778 {
2779 wxPuts (_T("%hhn overwrite more bytes"));
2780 result = 1;
2781 }
2782 if (bytes[3] != 3)
2783 {
2784 wxPuts (_T("%hhn wrote incorrect value"));
2785 result = 1;
2786 }
2787 }
2788#endif
2789}
2790
2791static void
2792rfg1 (void)
2793{
2794 wxChar buf[100];
2795
2796 wxSprintf (buf, _T("%5.s"), _T("xyz"));
2797 if (wxStrcmp (buf, _T(" ")) != 0)
2798 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" "));
2799 wxSprintf (buf, _T("%5.f"), 33.3);
2800 if (wxStrcmp (buf, _T(" 33")) != 0)
2801 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 33"));
2802 wxSprintf (buf, _T("%8.e"), 33.3e7);
2803 if (wxStrcmp (buf, _T(" 3e+08")) != 0)
2804 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3e+08"));
2805 wxSprintf (buf, _T("%8.E"), 33.3e7);
2806 if (wxStrcmp (buf, _T(" 3E+08")) != 0)
2807 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3E+08"));
2808 wxSprintf (buf, _T("%.g"), 33.3);
2809 if (wxStrcmp (buf, _T("3e+01")) != 0)
2810 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3e+01"));
2811 wxSprintf (buf, _T("%.G"), 33.3);
2812 if (wxStrcmp (buf, _T("3E+01")) != 0)
2813 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3E+01"));
2814}
2815
2816static void
2817rfg2 (void)
2818{
2819 int prec;
2820 wxChar buf[100];
2821
2822 prec = 0;
2823 wxSprintf (buf, _T("%.*g"), prec, 3.3);
2824 if (wxStrcmp (buf, _T("3")) != 0)
2825 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2826 prec = 0;
2827 wxSprintf (buf, _T("%.*G"), prec, 3.3);
2828 if (wxStrcmp (buf, _T("3")) != 0)
2829 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2830 prec = 0;
2831 wxSprintf (buf, _T("%7.*G"), prec, 3.33);
2832 if (wxStrcmp (buf, _T(" 3")) != 0)
2833 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3"));
2834 prec = 3;
2835 wxSprintf (buf, _T("%04.*o"), prec, 33);
2836 if (wxStrcmp (buf, _T(" 041")) != 0)
2837 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 041"));
2838 prec = 7;
2839 wxSprintf (buf, _T("%09.*u"), prec, 33);
2840 if (wxStrcmp (buf, _T(" 0000033")) != 0)
2841 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 0000033"));
2842 prec = 3;
2843 wxSprintf (buf, _T("%04.*x"), prec, 33);
2844 if (wxStrcmp (buf, _T(" 021")) != 0)
2845 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2846 prec = 3;
2847 wxSprintf (buf, _T("%04.*X"), prec, 33);
2848 if (wxStrcmp (buf, _T(" 021")) != 0)
2849 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2850}
2851
2852#endif // TEST_PRINTF
2853
6dfec4b8 2854// ----------------------------------------------------------------------------
7ba4fbeb 2855// registry and related stuff
6dfec4b8
VZ
2856// ----------------------------------------------------------------------------
2857
2858// this is for MSW only
2859#ifndef __WXMSW__
7ba4fbeb 2860 #undef TEST_REGCONF
6dfec4b8
VZ
2861 #undef TEST_REGISTRY
2862#endif
2863
7ba4fbeb
VZ
2864#ifdef TEST_REGCONF
2865
e84010cf
GD
2866#include "wx/confbase.h"
2867#include "wx/msw/regconf.h"
7ba4fbeb
VZ
2868
2869static void TestRegConfWrite()
2870{
2871 wxRegConfig regconf(_T("console"), _T("wxwindows"));
2872 regconf.Write(_T("Hello"), wxString(_T("world")));
2873}
2874
2875#endif // TEST_REGCONF
2876
6dfec4b8
VZ
2877#ifdef TEST_REGISTRY
2878
e84010cf 2879#include "wx/msw/registry.h"
6dfec4b8
VZ
2880
2881// I chose this one because I liked its name, but it probably only exists under
2882// NT
2883static const wxChar *TESTKEY =
2884 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2885
2886static void TestRegistryRead()
2887{
456ae26d 2888 wxPuts(_T("*** testing registry reading ***"));
6dfec4b8
VZ
2889
2890 wxRegKey key(TESTKEY);
456ae26d 2891 wxPrintf(_T("The test key name is '%s'.\n"), key.GetName().c_str());
6dfec4b8
VZ
2892 if ( !key.Open() )
2893 {
456ae26d 2894 wxPuts(_T("ERROR: test key can't be opened, aborting test."));
6dfec4b8
VZ
2895
2896 return;
2897 }
2898
2899 size_t nSubKeys, nValues;
2900 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2901 {
456ae26d 2902 wxPrintf(_T("It has %u subkeys and %u values.\n"), nSubKeys, nValues);
6dfec4b8
VZ
2903 }
2904
456ae26d 2905 wxPrintf(_T("Enumerating values:\n"));
6dfec4b8
VZ
2906
2907 long dummy;
2908 wxString value;
2909 bool cont = key.GetFirstValue(value, dummy);
2910 while ( cont )
2911 {
456ae26d 2912 wxPrintf(_T("Value '%s': type "), value.c_str());
6dfec4b8
VZ
2913 switch ( key.GetValueType(value) )
2914 {
456ae26d
VZ
2915 case wxRegKey::Type_None: wxPrintf(_T("ERROR (none)")); break;
2916 case wxRegKey::Type_String: wxPrintf(_T("SZ")); break;
2917 case wxRegKey::Type_Expand_String: wxPrintf(_T("EXPAND_SZ")); break;
2918 case wxRegKey::Type_Binary: wxPrintf(_T("BINARY")); break;
2919 case wxRegKey::Type_Dword: wxPrintf(_T("DWORD")); break;
2920 case wxRegKey::Type_Multi_String: wxPrintf(_T("MULTI_SZ")); break;
2921 default: wxPrintf(_T("other (unknown)")); break;
6dfec4b8
VZ
2922 }
2923
456ae26d 2924 wxPrintf(_T(", value = "));
6dfec4b8
VZ
2925 if ( key.IsNumericValue(value) )
2926 {
2927 long val;
2928 key.QueryValue(value, &val);
456ae26d 2929 wxPrintf(_T("%ld"), val);
6dfec4b8
VZ
2930 }
2931 else // string
2932 {
2933 wxString val;
2934 key.QueryValue(value, val);
456ae26d 2935 wxPrintf(_T("'%s'"), val.c_str());
6dfec4b8
VZ
2936
2937 key.QueryRawValue(value, val);
456ae26d 2938 wxPrintf(_T(" (raw value '%s')"), val.c_str());
6dfec4b8
VZ
2939 }
2940
2941 putchar('\n');
2942
2943 cont = key.GetNextValue(value, dummy);
2944 }
2945}
2946
6ba63600
VZ
2947static void TestRegistryAssociation()
2948{
2949 /*
2950 The second call to deleteself genertaes an error message, with a
2951 messagebox saying .flo is crucial to system operation, while the .ddf
2952 call also fails, but with no error message
2953 */
2954
2955 wxRegKey key;
2956
2957 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2958 key.Create();
2959 key = "ddxf_auto_file" ;
2960 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2961 key.Create();
2962 key = "ddxf_auto_file" ;
2963 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2964 key.Create();
2965 key = "program,0" ;
2966 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2967 key.Create();
2968 key = "program \"%1\"" ;
2969
2970 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2971 key.DeleteSelf();
2972 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2973 key.DeleteSelf();
2974 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2975 key.DeleteSelf();
2976 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2977 key.DeleteSelf();
2978}
2979
6dfec4b8
VZ
2980#endif // TEST_REGISTRY
2981
2c8e4738
VZ
2982// ----------------------------------------------------------------------------
2983// sockets
2984// ----------------------------------------------------------------------------
2985
2986#ifdef TEST_SOCKETS
2987
e84010cf
GD
2988#include "wx/socket.h"
2989#include "wx/protocol/protocol.h"
2990#include "wx/protocol/http.h"
8e907a13
VZ
2991
2992static void TestSocketServer()
2993{
456ae26d 2994 wxPuts(_T("*** Testing wxSocketServer ***\n"));
8e907a13 2995
ccdb23df
VZ
2996 static const int PORT = 3000;
2997
8e907a13 2998 wxIPV4address addr;
ccdb23df 2999 addr.Service(PORT);
8e907a13
VZ
3000
3001 wxSocketServer *server = new wxSocketServer(addr);
3002 if ( !server->Ok() )
3003 {
456ae26d 3004 wxPuts(_T("ERROR: failed to bind"));
ccdb23df
VZ
3005
3006 return;
8e907a13 3007 }
8dfea369 3008
cab8f76e
VZ
3009 bool quit = false;
3010 while ( !quit )
8dfea369 3011 {
456ae26d 3012 wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT);
8dfea369
VZ
3013
3014 wxSocketBase *socket = server->Accept();
3015 if ( !socket )
3016 {
456ae26d 3017 wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
8dfea369
VZ
3018 break;
3019 }
3020
456ae26d 3021 wxPuts(_T("Server: got a client."));
8dfea369 3022
ccdb23df
VZ
3023 server->SetTimeout(60); // 1 min
3024
cab8f76e
VZ
3025 bool close = false;
3026 while ( !close && socket->IsConnected() )
8dfea369 3027 {
ccdb23df 3028 wxString s;
456ae26d 3029 wxChar ch = _T('\0');
ccdb23df 3030 for ( ;; )
8dfea369 3031 {
ccdb23df
VZ
3032 if ( socket->Read(&ch, sizeof(ch)).Error() )
3033 {
3034 // don't log error if the client just close the connection
3035 if ( socket->IsConnected() )
3036 {
456ae26d 3037 wxPuts(_T("ERROR: in wxSocket::Read."));
ccdb23df 3038 }
8dfea369 3039
ccdb23df
VZ
3040 break;
3041 }
8dfea369 3042
ccdb23df
VZ
3043 if ( ch == '\r' )
3044 continue;
8dfea369 3045
ccdb23df
VZ
3046 if ( ch == '\n' )
3047 break;
8dfea369 3048
ccdb23df
VZ
3049 s += ch;
3050 }
8dfea369 3051
ccdb23df
VZ
3052 if ( ch != '\n' )
3053 {
3054 break;
3055 }
8dfea369 3056
456ae26d 3057 wxPrintf(_T("Server: got '%s'.\n"), s.c_str());
cab8f76e 3058 if ( s == _T("close") )
ccdb23df 3059 {
cab8f76e 3060 wxPuts(_T("Closing connection"));
8dfea369 3061
cab8f76e 3062 close = true;
ccdb23df 3063 }
cab8f76e
VZ
3064 else if ( s == _T("quit") )
3065 {
3066 close =
3067 quit = true;
ccdb23df 3068
cab8f76e
VZ
3069 wxPuts(_T("Shutting down the server"));
3070 }
3071 else // not a special command
3072 {
3073 socket->Write(s.MakeUpper().c_str(), s.length());
3074 socket->Write("\r\n", 2);
3075 wxPrintf(_T("Server: wrote '%s'.\n"), s.c_str());
3076 }
8dfea369
VZ
3077 }
3078
cab8f76e
VZ
3079 if ( !close )
3080 {
3081 wxPuts(_T("Server: lost a client unexpectedly."));
3082 }
8dfea369 3083
ccdb23df 3084 socket->Destroy();
8dfea369 3085 }
9fc3cba7 3086
ccdb23df
VZ
3087 // same as "delete server" but is consistent with GUI programs
3088 server->Destroy();
8e907a13 3089}
2c8e4738
VZ
3090
3091static void TestSocketClient()
3092{
456ae26d 3093 wxPuts(_T("*** Testing wxSocketClient ***\n"));
2c8e4738 3094
456ae26d 3095 static const wxChar *hostname = _T("www.wxwindows.org");
8e907a13
VZ
3096
3097 wxIPV4address addr;
3098 addr.Hostname(hostname);
3099 addr.Service(80);
3100
456ae26d 3101 wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname);
2c8e4738
VZ
3102
3103 wxSocketClient client;
8e907a13 3104 if ( !client.Connect(addr) )
2c8e4738 3105 {
456ae26d 3106 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2c8e4738
VZ
3107 }
3108 else
3109 {
456ae26d 3110 wxPrintf(_T("--- Connected to %s:%u...\n"),
8e907a13
VZ
3111 addr.Hostname().c_str(), addr.Service());
3112
456ae26d 3113 wxChar buf[8192];
2c8e4738 3114
8e907a13
VZ
3115 // could use simply "GET" here I suppose
3116 wxString cmdGet =
456ae26d 3117 wxString::Format(_T("GET http://%s/\r\n"), hostname);
8e907a13 3118 client.Write(cmdGet, cmdGet.length());
456ae26d 3119 wxPrintf(_T("--- Sent command '%s' to the server\n"),
8e907a13 3120 MakePrintable(cmdGet).c_str());
2c8e4738 3121 client.Read(buf, WXSIZEOF(buf));
456ae26d 3122 wxPrintf(_T("--- Server replied:\n%s"), buf);
8e907a13
VZ
3123 }
3124}
3125
2e907fab
VZ
3126#endif // TEST_SOCKETS
3127
b92fd37c
VZ
3128// ----------------------------------------------------------------------------
3129// FTP
3130// ----------------------------------------------------------------------------
3131
2e907fab
VZ
3132#ifdef TEST_FTP
3133
e84010cf 3134#include "wx/protocol/ftp.h"
2e907fab 3135
b92fd37c
VZ
3136static wxFTP ftp;
3137
3138#define FTP_ANONYMOUS
3139
3140#ifdef FTP_ANONYMOUS
456ae26d
VZ
3141 static const wxChar *directory = _T("/pub");
3142 static const wxChar *filename = _T("welcome.msg");
b92fd37c 3143#else
456ae26d
VZ
3144 static const wxChar *directory = _T("/etc");
3145 static const wxChar *filename = _T("issue");
b92fd37c
VZ
3146#endif
3147
3148static bool TestFtpConnect()
8e907a13 3149{
456ae26d 3150 wxPuts(_T("*** Testing FTP connect ***"));
8e907a13 3151
b92fd37c 3152#ifdef FTP_ANONYMOUS
456ae26d 3153 static const wxChar *hostname = _T("ftp.wxwindows.org");
b92fd37c 3154
456ae26d 3155 wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname);
b92fd37c 3156#else // !FTP_ANONYMOUS
456ae26d 3157 static const wxChar *hostname = "localhost";
b92fd37c 3158
456ae26d
VZ
3159 wxChar user[256];
3160 wxFgets(user, WXSIZEOF(user), stdin);
3161 user[wxStrlen(user) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3162 ftp.SetUser(user);
3163
456ae26d
VZ
3164 wxChar password[256];
3165 wxPrintf(_T("Password for %s: "), password);
3166 wxFgets(password, WXSIZEOF(password), stdin);
3167 password[wxStrlen(password) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3168 ftp.SetPassword(password);
3169
456ae26d 3170 wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname, user);
b92fd37c
VZ
3171#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
3172
3173 if ( !ftp.Connect(hostname) )
3174 {
456ae26d 3175 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b92fd37c 3176
cab8f76e 3177 return false;
b92fd37c
VZ
3178 }
3179 else
3180 {
456ae26d 3181 wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
b92fd37c
VZ
3182 hostname, ftp.Pwd().c_str());
3183 }
3184
cab8f76e 3185 return true;
b92fd37c 3186}
b1229561 3187
b92fd37c
VZ
3188// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
3189static void TestFtpWuFtpd()
3190{
3191 wxFTP ftp;
456ae26d 3192 static const wxChar *hostname = _T("ftp.eudora.com");
b1229561
VZ
3193 if ( !ftp.Connect(hostname) )
3194 {
456ae26d 3195 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b1229561
VZ
3196 }
3197 else
3198 {
456ae26d 3199 static const wxChar *filename = _T("eudora/pubs/draft-gellens-submit-09.txt");
b1229561
VZ
3200 wxInputStream *in = ftp.GetInputStream(filename);
3201 if ( !in )
3202 {
456ae26d 3203 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b1229561
VZ
3204 }
3205 else
3206 {
4c51b688 3207 size_t size = in->GetSize();
456ae26d 3208 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b1229561 3209
456ae26d 3210 wxChar *data = new wxChar[size];
b1229561
VZ
3211 if ( !in->Read(data, size) )
3212 {
456ae26d 3213 wxPuts(_T("ERROR: read error"));
b1229561
VZ
3214 }
3215 else
3216 {
456ae26d 3217 wxPrintf(_T("Successfully retrieved the file.\n"));
b1229561
VZ
3218 }
3219
3220 delete [] data;
3221 delete in;
3222 }
3223 }
b92fd37c 3224}
b1229561 3225
b92fd37c
VZ
3226static void TestFtpList()
3227{
456ae26d 3228 wxPuts(_T("*** Testing wxFTP file listing ***\n"));
8e907a13 3229
b92fd37c
VZ
3230 // test CWD
3231 if ( !ftp.ChDir(directory) )
3232 {
456ae26d 3233 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c 3234 }
2e907fab 3235
456ae26d 3236 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2e907fab 3237
b92fd37c
VZ
3238 // test NLIST and LIST
3239 wxArrayString files;
3240 if ( !ftp.GetFilesList(files) )
8e907a13 3241 {
456ae26d 3242 wxPuts(_T("ERROR: failed to get NLIST of files"));
8e907a13
VZ
3243 }
3244 else
3245 {
456ae26d 3246 wxPrintf(_T("Brief list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3247 size_t count = files.GetCount();
3248 for ( size_t n = 0; n < count; n++ )
8e907a13 3249 {
456ae26d 3250 wxPrintf(_T("\t%s\n"), files[n].c_str());
8e907a13 3251 }
456ae26d 3252 wxPuts(_T("End of the file list"));
b92fd37c 3253 }
8e907a13 3254
b92fd37c
VZ
3255 if ( !ftp.GetDirList(files) )
3256 {
456ae26d 3257 wxPuts(_T("ERROR: failed to get LIST of files"));
b92fd37c
VZ
3258 }
3259 else
3260 {
456ae26d 3261 wxPrintf(_T("Detailed list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3262 size_t count = files.GetCount();
3263 for ( size_t n = 0; n < count; n++ )
8e907a13 3264 {
456ae26d 3265 wxPrintf(_T("\t%s\n"), files[n].c_str());
2e907fab 3266 }
456ae26d 3267 wxPuts(_T("End of the file list"));
b92fd37c
VZ
3268 }
3269
3270 if ( !ftp.ChDir(_T("..")) )
3271 {
456ae26d 3272 wxPuts(_T("ERROR: failed to cd to .."));
b92fd37c 3273 }
2e907fab 3274
456ae26d 3275 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3276}
3277
3278static void TestFtpDownload()
3279{
456ae26d 3280 wxPuts(_T("*** Testing wxFTP download ***\n"));
b92fd37c
VZ
3281
3282 // test RETR
3283 wxInputStream *in = ftp.GetInputStream(filename);
3284 if ( !in )
3285 {
456ae26d 3286 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b92fd37c
VZ
3287 }
3288 else
3289 {
4c51b688 3290 size_t size = in->GetSize();
456ae26d 3291 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b92fd37c
VZ
3292 fflush(stdout);
3293
456ae26d 3294 wxChar *data = new wxChar[size];
b92fd37c 3295 if ( !in->Read(data, size) )
2e907fab 3296 {
456ae26d 3297 wxPuts(_T("ERROR: read error"));
2e907fab
VZ
3298 }
3299 else
3300 {
456ae26d 3301 wxPrintf(_T("\nContents of %s:\n%s\n"), filename, data);
8e907a13
VZ
3302 }
3303
b92fd37c
VZ
3304 delete [] data;
3305 delete in;
3306 }
3307}
8e907a13 3308
b92fd37c
VZ
3309static void TestFtpFileSize()
3310{
456ae26d 3311 wxPuts(_T("*** Testing FTP SIZE command ***"));
b92fd37c
VZ
3312
3313 if ( !ftp.ChDir(directory) )
3314 {
456ae26d 3315 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c
VZ
3316 }
3317
456ae26d 3318 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3319
3320 if ( ftp.FileExists(filename) )
3321 {
3322 int size = ftp.GetFileSize(filename);
3323 if ( size == -1 )
456ae26d 3324 wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename);
8e907a13 3325 else
456ae26d 3326 wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename, size);
b92fd37c
VZ
3327 }
3328 else
3329 {
456ae26d 3330 wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename);
b92fd37c
VZ
3331 }
3332}
3333
3334static void TestFtpMisc()
3335{
456ae26d 3336 wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
b92fd37c
VZ
3337
3338 if ( ftp.SendCommand("STAT") != '2' )
3339 {
456ae26d 3340 wxPuts(_T("ERROR: STAT failed"));
b92fd37c
VZ
3341 }
3342 else
3343 {
456ae26d 3344 wxPrintf(_T("STAT returned:\n\n%s\n"), ftp.GetLastResult().c_str());
b92fd37c
VZ
3345 }
3346
3347 if ( ftp.SendCommand("HELP SITE") != '2' )
3348 {
456ae26d 3349 wxPuts(_T("ERROR: HELP SITE failed"));
b92fd37c
VZ
3350 }
3351 else
3352 {
456ae26d 3353 wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
b92fd37c
VZ
3354 ftp.GetLastResult().c_str());
3355 }
3356}
3357
3358static void TestFtpInteractive()
3359{
456ae26d 3360 wxPuts(_T("\n*** Interactive wxFTP test ***"));
b92fd37c 3361
456ae26d 3362 wxChar buf[128];
b92fd37c
VZ
3363
3364 for ( ;; )
3365 {
456ae26d
VZ
3366 wxPrintf(_T("Enter FTP command: "));
3367 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
b92fd37c
VZ
3368 break;
3369
3370 // kill the last '\n'
456ae26d 3371 buf[wxStrlen(buf) - 1] = 0;
b92fd37c
VZ
3372
3373 // special handling of LIST and NLST as they require data connection
3374 wxString start(buf, 4);
3375 start.MakeUpper();
3376 if ( start == "LIST" || start == "NLST" )
8e907a13 3377 {
b92fd37c 3378 wxString wildcard;
456ae26d 3379 if ( wxStrlen(buf) > 4 )
b92fd37c 3380 wildcard = buf + 5;
8e907a13 3381
b92fd37c
VZ
3382 wxArrayString files;
3383 if ( !ftp.GetList(files, wildcard, start == "LIST") )
8e907a13 3384 {
456ae26d 3385 wxPrintf(_T("ERROR: failed to get %s of files\n"), start.c_str());
8e907a13
VZ
3386 }
3387 else
3388 {
456ae26d 3389 wxPrintf(_T("--- %s of '%s' under '%s':\n"),
b92fd37c
VZ
3390 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
3391 size_t count = files.GetCount();
3392 for ( size_t n = 0; n < count; n++ )
3393 {
456ae26d 3394 wxPrintf(_T("\t%s\n"), files[n].c_str());
b92fd37c 3395 }
456ae26d 3396 wxPuts(_T("--- End of the file list"));
8e907a13 3397 }
2e907fab 3398 }
b92fd37c 3399 else // !list
2e907fab 3400 {
456ae26d
VZ
3401 wxChar ch = ftp.SendCommand(buf);
3402 wxPrintf(_T("Command %s"), ch ? _T("succeeded") : _T("failed"));
b92fd37c
VZ
3403 if ( ch )
3404 {
456ae26d 3405 wxPrintf(_T(" (return code %c)"), ch);
b92fd37c 3406 }
2e907fab 3407
456ae26d 3408 wxPrintf(_T(", server reply:\n%s\n\n"), ftp.GetLastResult().c_str());
2e907fab 3409 }
2c8e4738 3410 }
b92fd37c 3411
456ae26d 3412 wxPuts(_T("\n*** done ***"));
2c8e4738
VZ
3413}
3414
b92fd37c 3415static void TestFtpUpload()
f6bcfd97 3416{
456ae26d 3417 wxPuts(_T("*** Testing wxFTP uploading ***\n"));
f6bcfd97 3418
b92fd37c 3419 // upload a file
456ae26d
VZ
3420 static const wxChar *file1 = _T("test1");
3421 static const wxChar *file2 = _T("test2");
b92fd37c
VZ
3422 wxOutputStream *out = ftp.GetOutputStream(file1);
3423 if ( out )
3424 {
456ae26d 3425 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3426 out->Write("First hello", 11);
3427 delete out;
3428 }
f6bcfd97 3429
b92fd37c
VZ
3430 // send a command to check the remote file
3431 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
f6bcfd97 3432 {
456ae26d 3433 wxPrintf(_T("ERROR: STAT %s failed\n"), file1);
f6bcfd97
BP
3434 }
3435 else
3436 {
456ae26d 3437 wxPrintf(_T("STAT %s returned:\n\n%s\n"),
b92fd37c
VZ
3438 file1, ftp.GetLastResult().c_str());
3439 }
2e907fab 3440
b92fd37c
VZ
3441 out = ftp.GetOutputStream(file2);
3442 if ( out )
3443 {
456ae26d 3444 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3445 out->Write("Second hello", 12);
3446 delete out;
f6bcfd97
BP
3447 }
3448}
3449
2e907fab 3450#endif // TEST_FTP
2c8e4738 3451
83141d3a
VZ
3452// ----------------------------------------------------------------------------
3453// streams
3454// ----------------------------------------------------------------------------
3455
3456#ifdef TEST_STREAMS
3457
e84010cf
GD
3458#include "wx/wfstream.h"
3459#include "wx/mstream.h"
83141d3a 3460
24f25c8a
VZ
3461static void TestFileStream()
3462{
456ae26d 3463 wxPuts(_T("*** Testing wxFileInputStream ***"));
24f25c8a
VZ
3464
3465 static const wxChar *filename = _T("testdata.fs");
3466 {
3467 wxFileOutputStream fsOut(filename);
3468 fsOut.Write("foo", 3);
3469 }
3470
3471 wxFileInputStream fsIn(filename);
456ae26d 3472 wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
24f25c8a
VZ
3473 while ( !fsIn.Eof() )
3474 {
3475 putchar(fsIn.GetC());
3476 }
3477
3478 if ( !wxRemoveFile(filename) )
3479 {
456ae26d 3480 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename);
24f25c8a
VZ
3481 }
3482
456ae26d 3483 wxPuts(_T("\n*** wxFileInputStream test done ***"));
24f25c8a
VZ
3484}
3485
83141d3a
VZ
3486static void TestMemoryStream()
3487{
99a5af7f
VZ
3488 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
3489
3490 wxMemoryOutputStream memOutStream;
3491 wxPrintf(_T("Initially out stream offset: %lu\n"),
3492 (unsigned long)memOutStream.TellO());
3493
3494 for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
3495 {
3496 memOutStream.PutC(*p);
3497 }
3498
3499 wxPrintf(_T("Final out stream offset: %lu\n"),
3500 (unsigned long)memOutStream.TellO());
3501
3502 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
83141d3a
VZ
3503
3504 wxChar buf[1024];
99a5af7f 3505 size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
83141d3a 3506
99a5af7f
VZ
3507 wxMemoryInputStream memInpStream(buf, len);
3508 wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
83141d3a
VZ
3509 while ( !memInpStream.Eof() )
3510 {
3511 putchar(memInpStream.GetC());
3512 }
3513
456ae26d 3514 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
83141d3a
VZ
3515}
3516
3517#endif // TEST_STREAMS
3518
d31b7b68
VZ
3519// ----------------------------------------------------------------------------
3520// timers
3521// ----------------------------------------------------------------------------
3522
3523#ifdef TEST_TIMER
3524
e84010cf
GD
3525#include "wx/timer.h"
3526#include "wx/utils.h"
d31b7b68
VZ
3527
3528static void TestStopWatch()
3529{
456ae26d 3530 wxPuts(_T("*** Testing wxStopWatch ***\n"));
d31b7b68
VZ
3531
3532 wxStopWatch sw;
677eff07 3533 sw.Pause();
456ae26d 3534 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
677eff07
VZ
3535 fflush(stdout);
3536 wxSleep(2);
456ae26d 3537 wxPrintf(_T("\t%ldms\n"), sw.Time());
677eff07 3538
456ae26d 3539 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
677eff07
VZ
3540 fflush(stdout);
3541 sw.Resume();
d31b7b68 3542 wxSleep(3);
456ae26d 3543 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3544
3545 sw.Pause();
456ae26d 3546 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
677eff07 3547 fflush(stdout);
d31b7b68 3548 wxSleep(2);
456ae26d 3549 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3550
3551 sw.Resume();
456ae26d 3552 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
677eff07
VZ
3553 fflush(stdout);
3554 wxSleep(2);
456ae26d 3555 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
87798c00
VZ
3556
3557 wxStopWatch sw2;
456ae26d 3558 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
87798c00
VZ
3559 for ( size_t n = 0; n < 70; n++ )
3560 {
3561 sw2.Start();
89e6463c
GRG
3562
3563 for ( size_t m = 0; m < 100000; m++ )
87798c00 3564 {
89e6463c
GRG
3565 if ( sw.Time() < 0 || sw2.Time() < 0 )
3566 {
456ae26d 3567 wxPuts(_T("\ntime is negative - ERROR!"));
89e6463c 3568 }
87798c00
VZ
3569 }
3570
3571 putchar('.');
677eff07 3572 fflush(stdout);
87798c00
VZ
3573 }
3574
456ae26d 3575 wxPuts(_T(", ok."));
d31b7b68
VZ
3576}
3577
3578#endif // TEST_TIMER
3579
f6bcfd97
BP
3580// ----------------------------------------------------------------------------
3581// vCard support
3582// ----------------------------------------------------------------------------
3583
3584#ifdef TEST_VCARD
3585
e84010cf 3586#include "wx/vcard.h"
f6bcfd97
BP
3587
3588static void DumpVObject(size_t level, const wxVCardObject& vcard)
3589{
3590 void *cookie;
3591 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3592 while ( vcObj )
3593 {
456ae26d 3594 wxPrintf(_T("%s%s"),
f6bcfd97
BP
3595 wxString(_T('\t'), level).c_str(),
3596 vcObj->GetName().c_str());
3597
3598 wxString value;
3599 switch ( vcObj->GetType() )
3600 {
3601 case wxVCardObject::String:
3602 case wxVCardObject::UString:
3603 {
3604 wxString val;
3605 vcObj->GetValue(&val);
3606 value << _T('"') << val << _T('"');
3607 }
3608 break;
3609
3610 case wxVCardObject::Int:
3611 {
3612 unsigned int i;
3613 vcObj->GetValue(&i);
3614 value.Printf(_T("%u"), i);
3615 }
3616 break;
3617
3618 case wxVCardObject::Long:
3619 {
3620 unsigned long l;
3621 vcObj->GetValue(&l);
3622 value.Printf(_T("%lu"), l);
3623 }
3624 break;
3625
3626 case wxVCardObject::None:
3627 break;
3628
3629 case wxVCardObject::Object:
3630 value = _T("<node>");
3631 break;
3632
3633 default:
3634 value = _T("<unknown value type>");
3635 }
3636
3637 if ( !!value )
456ae26d 3638 wxPrintf(_T(" = %s"), value.c_str());
f6bcfd97
BP
3639 putchar('\n');
3640
3641 DumpVObject(level + 1, *vcObj);
3642
3643 delete vcObj;
3644 vcObj = vcard.GetNextProp(&cookie);
3645 }
3646}
3647
3648static void DumpVCardAddresses(const wxVCard& vcard)
3649{
456ae26d 3650 wxPuts(_T("\nShowing all addresses from vCard:\n"));
f6bcfd97
BP
3651
3652 size_t nAdr = 0;
3653 void *cookie;
3654 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3655 while ( addr )
3656 {
3657 wxString flagsStr;
3658 int flags = addr->GetFlags();
3659 if ( flags & wxVCardAddress::Domestic )
3660 {
3661 flagsStr << _T("domestic ");
3662 }
3663 if ( flags & wxVCardAddress::Intl )
3664 {
3665 flagsStr << _T("international ");
3666 }
3667 if ( flags & wxVCardAddress::Postal )
3668 {
3669 flagsStr << _T("postal ");
3670 }
3671 if ( flags & wxVCardAddress::Parcel )
3672 {
3673 flagsStr << _T("parcel ");
3674 }
3675 if ( flags & wxVCardAddress::Home )
3676 {
3677 flagsStr << _T("home ");
3678 }
3679 if ( flags & wxVCardAddress::Work )
3680 {
3681 flagsStr << _T("work ");
3682 }
3683
456ae26d 3684 wxPrintf(_T("Address %u:\n")
f6bcfd97
BP
3685 "\tflags = %s\n"
3686 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3687 ++nAdr,
3688 flagsStr.c_str(),
3689 addr->GetPostOffice().c_str(),
3690 addr->GetExtAddress().c_str(),
3691 addr->GetStreet().c_str(),
3692 addr->GetLocality().c_str(),
3693 addr->GetRegion().c_str(),
3694 addr->GetPostalCode().c_str(),
3695 addr->GetCountry().c_str()
3696 );
3697
3698 delete addr;
3699 addr = vcard.GetNextAddress(&cookie);
3700 }
3701}
3702
3703static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3704{
456ae26d 3705 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
f6bcfd97
BP
3706
3707 size_t nPhone = 0;
3708 void *cookie;
3709 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3710 while ( phone )
3711 {
3712 wxString flagsStr;
3713 int flags = phone->GetFlags();
3714 if ( flags & wxVCardPhoneNumber::Voice )
3715 {
3716 flagsStr << _T("voice ");
3717 }
3718 if ( flags & wxVCardPhoneNumber::Fax )
3719 {
3720 flagsStr << _T("fax ");
3721 }
3722 if ( flags & wxVCardPhoneNumber::Cellular )
3723 {
3724 flagsStr << _T("cellular ");
3725 }
3726 if ( flags & wxVCardPhoneNumber::Modem )
3727 {
3728 flagsStr << _T("modem ");
3729 }
3730 if ( flags & wxVCardPhoneNumber::Home )
3731 {
3732 flagsStr << _T("home ");
3733 }
3734 if ( flags & wxVCardPhoneNumber::Work )
3735 {
3736 flagsStr << _T("work ");
3737 }
3738
456ae26d 3739 wxPrintf(_T("Phone number %u:\n")
f6bcfd97
BP
3740 "\tflags = %s\n"
3741 "\tvalue = %s\n",
3742 ++nPhone,
3743 flagsStr.c_str(),
3744 phone->GetNumber().c_str()
3745 );
3746
3747 delete phone;
3748 phone = vcard.GetNextPhoneNumber(&cookie);
3749 }
3750}
3751
3752static void TestVCardRead()
3753{
456ae26d 3754 wxPuts(_T("*** Testing wxVCard reading ***\n"));
f6bcfd97
BP
3755
3756 wxVCard vcard(_T("vcard.vcf"));
3757 if ( !vcard.IsOk() )
3758 {
456ae26d 3759 wxPuts(_T("ERROR: couldn't load vCard."));
f6bcfd97
BP
3760 }
3761 else
3762 {
3763 // read individual vCard properties
3764 wxVCardObject *vcObj = vcard.GetProperty("FN");
3765 wxString value;
3766 if ( vcObj )
3767 {
3768 vcObj->GetValue(&value);
3769 delete vcObj;
3770 }
3771 else
3772 {
3773 value = _T("<none>");
3774 }
3775
456ae26d 3776 wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
f6bcfd97
BP
3777
3778
3779 if ( !vcard.GetFullName(&value) )
3780 {
3781 value = _T("<none>");
3782 }
3783
456ae26d 3784 wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
f6bcfd97
BP
3785
3786 // now show how to deal with multiply occuring properties
3787 DumpVCardAddresses(vcard);
3788 DumpVCardPhoneNumbers(vcard);
3789
3790 // and finally show all
456ae26d 3791 wxPuts(_T("\nNow dumping the entire vCard:\n")
f6bcfd97
BP
3792 "-----------------------------\n");
3793
3794 DumpVObject(0, vcard);
3795 }
3796}
3797
3798static void TestVCardWrite()
3799{
456ae26d 3800 wxPuts(_T("*** Testing wxVCard writing ***\n"));
f6bcfd97
BP
3801
3802 wxVCard vcard;
3803 if ( !vcard.IsOk() )
3804 {
456ae26d 3805 wxPuts(_T("ERROR: couldn't create vCard."));
f6bcfd97
BP
3806 }
3807 else
3808 {
3809 // set some fields
3810 vcard.SetName("Zeitlin", "Vadim");
3811 vcard.SetFullName("Vadim Zeitlin");
3812 vcard.SetOrganization("wxWindows", "R&D");
3813
3814 // just dump the vCard back
456ae26d
VZ
3815 wxPuts(_T("Entire vCard follows:\n"));
3816 wxPuts(vcard.Write());
f6bcfd97
BP
3817 }
3818}
3819
3820#endif // TEST_VCARD
3821
0e2c5534
VZ
3822// ----------------------------------------------------------------------------
3823// wxVolume tests
3824// ----------------------------------------------------------------------------
3825
ba6ea19e 3826#if !defined(__WIN32__) || !wxUSE_FSVOLUME
0e2c5534
VZ
3827 #undef TEST_VOLUME
3828#endif
3829
3830#ifdef TEST_VOLUME
3831
3832#include "wx/volume.h"
3833
3834static const wxChar *volumeKinds[] =
3835{
3836 _T("floppy"),
3837 _T("hard disk"),
3838 _T("CD-ROM"),
3839 _T("DVD-ROM"),
3840 _T("network volume"),
3841 _T("other volume"),
3842};
3843
3844static void TestFSVolume()
3845{
3846 wxPuts(_T("*** Testing wxFSVolume class ***"));
3847
3848 wxArrayString volumes = wxFSVolume::GetVolumes();
3849 size_t count = volumes.GetCount();
3850
3851 if ( !count )
3852 {
3853 wxPuts(_T("ERROR: no mounted volumes?"));
3854 return;
3855 }
3856
3857 wxPrintf(_T("%u mounted volumes found:\n"), count);
3858
3859 for ( size_t n = 0; n < count; n++ )
3860 {
3861 wxFSVolume vol(volumes[n]);
3862 if ( !vol.IsOk() )
3863 {
3864 wxPuts(_T("ERROR: couldn't create volume"));
3865 continue;
3866 }
3867
3868 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3869 n + 1,
3870 vol.GetDisplayName().c_str(),
3871 vol.GetName().c_str(),
3872 volumeKinds[vol.GetKind()],
3873 vol.IsWritable() ? _T("rw") : _T("ro"),
3874 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3875 : _T("fixed"));
3876 }
3877}
3878
3879#endif // TEST_VOLUME
3880
f6bcfd97 3881// ----------------------------------------------------------------------------
e7d41190 3882// wide char and Unicode support
f6bcfd97
BP
3883// ----------------------------------------------------------------------------
3884
e7d41190
VZ
3885#ifdef TEST_UNICODE
3886
3887static void TestUnicodeToFromAscii()
3888{
3889 wxPuts(_T("Testing wxString::To/FromAscii()\n"));
3890
3891 static const char *msg = "Hello, world!";
3892 wxString s = wxString::FromAscii(msg);
3893
3894 wxPrintf(_T("Message in Unicode: %s\n"), s.c_str());
7aeebdcd 3895 printf("Message in ASCII: %s\n", (const char *)s.ToAscii());
e7d41190
VZ
3896
3897 wxPutchar(_T('\n'));
3898}
3899
3900#endif // TEST_UNICODE
3901
f6bcfd97
BP
3902#ifdef TEST_WCHAR
3903
e84010cf
GD
3904#include "wx/strconv.h"
3905#include "wx/fontenc.h"
3906#include "wx/encconv.h"
3907#include "wx/buffer.h"
f6bcfd97 3908
2b5f62a0 3909static const unsigned char utf8koi8r[] =
ac511156
VZ
3910{
3911 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3912 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3913 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3914 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3915 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3916 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3917 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3918};
3919
2b5f62a0
VZ
3920static const unsigned char utf8iso8859_1[] =
3921{
3922 0x53, 0x79, 0x73, 0x74, 0xc3, 0xa8, 0x6d, 0x65, 0x73, 0x20, 0x49, 0x6e,
3923 0x74, 0xc3, 0xa9, 0x67, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x65,
3924 0x6e, 0x20, 0x4d, 0xc3, 0xa9, 0x63, 0x61, 0x6e, 0x69, 0x71, 0x75, 0x65,
3925 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x71, 0x75, 0x65, 0x20, 0x65,
3926 0x74, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x71, 0x75, 0x65, 0
3927};
3928
3929static const unsigned char utf8Invalid[] =
3930{
3931 0x3c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3e, 0x32, 0x30, 0x30,
3932 0x32, 0xe5, 0xb9, 0xb4, 0x30, 0x39, 0xe6, 0x9c, 0x88, 0x32, 0x35, 0xe6,
3933 0x97, 0xa5, 0x20, 0x30, 0x37, 0xe6, 0x99, 0x82, 0x33, 0x39, 0xe5, 0x88,
3934 0x86, 0x35, 0x37, 0xe7, 0xa7, 0x92, 0x3c, 0x2f, 0x64, 0x69, 0x73, 0x70,
3935 0x6c, 0x61, 0x79, 0
3936};
3937
3938static const struct Utf8Data
3939{
3940 const unsigned char *text;
3941 size_t len;
3942 const wxChar *charset;
3943 wxFontEncoding encoding;
3944} utf8data[] =
3945{
3946 { utf8Invalid, WXSIZEOF(utf8Invalid), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3947 { utf8koi8r, WXSIZEOF(utf8koi8r), _T("koi8-r"), wxFONTENCODING_KOI8 },
3948 { utf8iso8859_1, WXSIZEOF(utf8iso8859_1), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3949};
456ae26d 3950
f6bcfd97
BP
3951static void TestUtf8()
3952{
456ae26d 3953 wxPuts(_T("*** Testing UTF8 support ***\n"));
f6bcfd97 3954
24f25c8a
VZ
3955 char buf[1024];
3956 wchar_t wbuf[1024];
2b5f62a0
VZ
3957
3958 for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
24f25c8a 3959 {
2b5f62a0
VZ
3960 const Utf8Data& u8d = utf8data[n];
3961 if ( wxConvUTF8.MB2WC(wbuf, (const char *)u8d.text,
3962 WXSIZEOF(wbuf)) == (size_t)-1 )
24f25c8a 3963 {
2b5f62a0 3964 wxPuts(_T("ERROR: UTF-8 decoding failed."));
24f25c8a
VZ
3965 }
3966 else
ac511156 3967 {
2b5f62a0
VZ
3968 wxCSConv conv(u8d.charset);
3969 if ( conv.WC2MB(buf, wbuf, WXSIZEOF(buf)) == (size_t)-1 )
3970 {
3971 wxPrintf(_T("ERROR: conversion to %s failed.\n"), u8d.charset);
3972 }
3973 else
3974 {
3975 wxPrintf(_T("String in %s: %s\n"), u8d.charset, buf);
3976 }
ac511156 3977 }
ac511156 3978
2b5f62a0
VZ
3979 wxString s(wxConvUTF8.cMB2WC((const char *)u8d.text), *wxConvCurrent);
3980 if ( s.empty() )
3981 s = _T("<< conversion failed >>");
3982 wxPrintf(_T("String in current cset: %s\n"), s.c_str());
3983
ac511156
VZ
3984 }
3985
456ae26d 3986 wxPuts(_T(""));
ac511156 3987}
f6bcfd97 3988
ac511156
VZ
3989static void TestEncodingConverter()
3990{
3991 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3992
3993 // using wxEncodingConverter should give the same result as above
3994 char buf[1024];
3995 wchar_t wbuf[1024];
2b5f62a0
VZ
3996 if ( wxConvUTF8.MB2WC(wbuf, (const char *)utf8koi8r,
3997 WXSIZEOF(utf8koi8r)) == (size_t)-1 )
ac511156 3998 {
456ae26d 3999 wxPuts(_T("ERROR: UTF-8 decoding failed."));
ac511156
VZ
4000 }
4001 else
4002 {
4003 wxEncodingConverter ec;
4004 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
4005 ec.Convert(wbuf, buf);
2b5f62a0 4006 wxPrintf(_T("The same KOI8-R string using wxEC: %s\n"), buf);
24f25c8a 4007 }
ac511156 4008
456ae26d 4009 wxPuts(_T(""));
f6bcfd97
BP
4010}
4011
4012#endif // TEST_WCHAR
4013
4014// ----------------------------------------------------------------------------
4015// ZIP stream
4016// ----------------------------------------------------------------------------
4017
4018#ifdef TEST_ZIP
4019
2ca8b884
VZ
4020#include "wx/filesys.h"
4021#include "wx/fs_zip.h"
f6bcfd97
BP
4022#include "wx/zipstrm.h"
4023
2ca8b884
VZ
4024static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
4025
f6bcfd97
BP
4026static void TestZipStreamRead()
4027{
456ae26d 4028 wxPuts(_T("*** Testing ZIP reading ***\n"));
f6bcfd97 4029
2ca8b884
VZ
4030 static const wxChar *filename = _T("foo");
4031 wxZipInputStream istr(TESTFILE_ZIP, filename);
456ae26d 4032 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
f6bcfd97 4033
456ae26d 4034 wxPrintf(_T("Dumping the file '%s':\n"), filename);
f6bcfd97
BP
4035 while ( !istr.Eof() )
4036 {
4037 putchar(istr.GetC());
4038 fflush(stdout);
4039 }
4040
456ae26d 4041 wxPuts(_T("\n----- done ------"));
f6bcfd97
BP
4042}
4043
2ca8b884
VZ
4044static void DumpZipDirectory(wxFileSystem& fs,
4045 const wxString& dir,
4046 const wxString& indent)
4047{
4048 wxString prefix = wxString::Format(_T("%s#zip:%s"),
4049 TESTFILE_ZIP, dir.c_str());
4050 wxString wildcard = prefix + _T("/*");
4051
4052 wxString dirname = fs.FindFirst(wildcard, wxDIR);
4053 while ( !dirname.empty() )
4054 {
4055 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
4056 {
4057 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4058
4059 break;
4060 }
4061
4062 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
4063
4064 DumpZipDirectory(fs, dirname,
4065 indent + wxString(_T(' '), 4));
4066
4067 dirname = fs.FindNext();
4068 }
4069
4070 wxString filename = fs.FindFirst(wildcard, wxFILE);
4071 while ( !filename.empty() )
4072 {
4073 if ( !filename.StartsWith(prefix, &filename) )
4074 {
4075 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4076
4077 break;
4078 }
4079
4080 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
4081
4082 filename = fs.FindNext();
4083 }
4084}
4085
4086static void TestZipFileSystem()
4087{
456ae26d 4088 wxPuts(_T("*** Testing ZIP file system ***\n"));
2ca8b884
VZ
4089
4090 wxFileSystem::AddHandler(new wxZipFSHandler);
4091 wxFileSystem fs;
4092 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
4093
4094 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
4095}
4096
f6bcfd97
BP
4097#endif // TEST_ZIP
4098
3ca6a5f0
BP
4099// ----------------------------------------------------------------------------
4100// ZLIB stream
4101// ----------------------------------------------------------------------------
4102
4103#ifdef TEST_ZLIB
4104
e84010cf
GD
4105#include "wx/zstream.h"
4106#include "wx/wfstream.h"
3ca6a5f0
BP
4107
4108static const wxChar *FILENAME_GZ = _T("test.gz");
456ae26d 4109static const wxChar *TEST_DATA = _T("hello and hello and hello and hello and hello");
3ca6a5f0
BP
4110
4111static void TestZlibStreamWrite()
4112{
456ae26d 4113 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4114
4115 wxFileOutputStream fileOutStream(FILENAME_GZ);
2104ba31 4116 wxZlibOutputStream ostr(fileOutStream);
456ae26d
VZ
4117 wxPrintf(_T("Compressing the test string... "));
4118 ostr.Write(TEST_DATA, wxStrlen(TEST_DATA) + 1);
3ca6a5f0
BP
4119 if ( !ostr )
4120 {
456ae26d 4121 wxPuts(_T("(ERROR: failed)"));
3ca6a5f0
BP
4122 }
4123 else
4124 {
456ae26d 4125 wxPuts(_T("(ok)"));
3ca6a5f0
BP
4126 }
4127
456ae26d 4128 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4129}
4130
4131static void TestZlibStreamRead()
4132{
456ae26d 4133 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4134
4135 wxFileInputStream fileInStream(FILENAME_GZ);
4136 wxZlibInputStream istr(fileInStream);
456ae26d 4137 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3ca6a5f0 4138
456ae26d 4139 wxPuts(_T("Dumping the file:"));
3ca6a5f0
BP
4140 while ( !istr.Eof() )
4141 {
4142 putchar(istr.GetC());
4143 fflush(stdout);
4144 }
4145
456ae26d 4146 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4147}
4148
4149#endif // TEST_ZLIB
4150
b76b015e
VZ
4151// ----------------------------------------------------------------------------
4152// date time
4153// ----------------------------------------------------------------------------
4154
d31b7b68 4155#ifdef TEST_DATETIME
b76b015e 4156
551fe3a6
VZ
4157#include <math.h>
4158
e84010cf
GD
4159#include "wx/date.h"
4160#include "wx/datetime.h"
b76b015e 4161
299fcbfe
VZ
4162// the test data
4163struct Date
4164{
4165 wxDateTime::wxDateTime_t day;
4166 wxDateTime::Month month;
4167 int year;
4168 wxDateTime::wxDateTime_t hour, min, sec;
4169 double jdn;
211c2250 4170 wxDateTime::WeekDay wday;
299fcbfe
VZ
4171 time_t gmticks, ticks;
4172
4173 void Init(const wxDateTime::Tm& tm)
4174 {
4175 day = tm.mday;
4176 month = tm.mon;
4177 year = tm.year;
4178 hour = tm.hour;
4179 min = tm.min;
4180 sec = tm.sec;
4181 jdn = 0.0;
4182 gmticks = ticks = -1;
4183 }
4184
4185 wxDateTime DT() const
4186 { return wxDateTime(day, month, year, hour, min, sec); }
4187
239446b4
VZ
4188 bool SameDay(const wxDateTime::Tm& tm) const
4189 {
4190 return day == tm.mday && month == tm.mon && year == tm.year;
4191 }
4192
299fcbfe
VZ
4193 wxString Format() const
4194 {
4195 wxString s;
456ae26d 4196 s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"),
299fcbfe
VZ
4197 hour, min, sec,
4198 wxDateTime::GetMonthName(month).c_str(),
4199 day,
4200 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4201 year > 0 ? _T("AD") : _T("BC"));
299fcbfe
VZ
4202 return s;
4203 }
239446b4
VZ
4204
4205 wxString FormatDate() const
4206 {
4207 wxString s;
456ae26d 4208 s.Printf(_T("%02d-%s-%4d%s"),
239446b4 4209 day,
f0f951fa 4210 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
239446b4 4211 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4212 year > 0 ? _T("AD") : _T("BC"));
239446b4
VZ
4213 return s;
4214 }
299fcbfe
VZ
4215};
4216
4217static const Date testDates[] =
4218{
211c2250 4219 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
e7d41190
VZ
4220 { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 },
4221 { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 },
4222 { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 },
4223 { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 },
211c2250
VZ
4224 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
4225 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
4226 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
4227 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
4228 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
4229 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
4230 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
4231 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
4232 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
239446b4
VZ
4233 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
4234 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
4235 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
4236 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
211c2250 4237 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
299fcbfe
VZ
4238};
4239
2f02cb89
VZ
4240// this test miscellaneous static wxDateTime functions
4241static void TestTimeStatic()
4242{
456ae26d 4243 wxPuts(_T("\n*** wxDateTime static methods test ***"));
2f02cb89
VZ
4244
4245 // some info about the current date
4246 int year = wxDateTime::GetCurrentYear();
456ae26d 4247 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
2f02cb89
VZ
4248 year,
4249 wxDateTime::IsLeapYear(year) ? "" : "not ",
4250 wxDateTime::GetNumberOfDays(year));
4251
4252 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
456ae26d 4253 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
f0f951fa 4254 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2f02cb89
VZ
4255 wxDateTime::GetMonthName(month).c_str(),
4256 wxDateTime::GetNumberOfDays(month));
4257
4258 // leap year logic
fcc3d7cb
VZ
4259 static const size_t nYears = 5;
4260 static const size_t years[2][nYears] =
2f02cb89
VZ
4261 {
4262 // first line: the years to test
4263 { 1990, 1976, 2000, 2030, 1984, },
4264
cab8f76e
VZ
4265 // second line: true if leap, false otherwise
4266 { false, true, true, false, true }
2f02cb89
VZ
4267 };
4268
4269 for ( size_t n = 0; n < nYears; n++ )
4270 {
4271 int year = years[0][n];
239446b4
VZ
4272 bool should = years[1][n] != 0,
4273 is = wxDateTime::IsLeapYear(year);
2f02cb89 4274
456ae26d 4275 wxPrintf(_T("Year %d is %sa leap year (%s)\n"),
2f02cb89 4276 year,
239446b4
VZ
4277 is ? "" : "not ",
4278 should == is ? "ok" : "ERROR");
2f02cb89
VZ
4279
4280 wxASSERT( should == wxDateTime::IsLeapYear(year) );
4281 }
4282}
4283
4284// test constructing wxDateTime objects
4285static void TestTimeSet()
4286{
456ae26d 4287 wxPuts(_T("\n*** wxDateTime construction test ***"));
2f02cb89 4288
299fcbfe
VZ
4289 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4290 {
4291 const Date& d1 = testDates[n];
4292 wxDateTime dt = d1.DT();
4293
4294 Date d2;
4295 d2.Init(dt.GetTm());
4296
4297 wxString s1 = d1.Format(),
4298 s2 = d2.Format();
4299
456ae26d
VZ
4300 wxPrintf(_T("Date: %s == %s (%s)\n"),
4301 s1.c_str(), s2.c_str(),
4302 s1 == s2 ? _T("ok") : _T("ERROR"));
299fcbfe 4303 }
2f02cb89
VZ
4304}
4305
fcc3d7cb
VZ
4306// test time zones stuff
4307static void TestTimeZones()
4308{
456ae26d 4309 wxPuts(_T("\n*** wxDateTime timezone test ***"));
fcc3d7cb
VZ
4310
4311 wxDateTime now = wxDateTime::Now();
4312
456ae26d
VZ
4313 wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
4314 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
4315 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
4316 wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
4317 wxPrintf(_T(" Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
4318 wxPrintf(_T(" New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
9d9b7755
VZ
4319
4320 wxDateTime::Tm tm = now.GetTm();
4321 if ( wxDateTime(tm) != now )
4322 {
456ae26d
VZ
4323 wxPrintf(_T("ERROR: got %s instead of %s\n"),
4324 wxDateTime(tm).Format().c_str(), now.Format().c_str());
9d9b7755 4325 }
fcc3d7cb
VZ
4326}
4327
e6ec579c
VZ
4328// test some minimal support for the dates outside the standard range
4329static void TestTimeRange()
4330{
456ae26d 4331 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
e6ec579c 4332
456ae26d 4333 static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
211c2250 4334
456ae26d
VZ
4335 wxPrintf(_T("Unix epoch:\t%s\n"),
4336 wxDateTime(2440587.5).Format(fmt).c_str());
4337 wxPrintf(_T("Feb 29, 0: \t%s\n"),
4338 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
4339 wxPrintf(_T("JDN 0: \t%s\n"),
4340 wxDateTime(0.0).Format(fmt).c_str());
4341 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
4342 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
4343 wxPrintf(_T("May 29, 2099:\t%s\n"),
4344 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
e6ec579c
VZ
4345}
4346
299fcbfe 4347static void TestTimeTicks()
e6ec579c 4348{
456ae26d 4349 wxPuts(_T("\n*** wxDateTime ticks test ***"));
e6ec579c 4350
299fcbfe 4351 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1ef54dcf 4352 {
299fcbfe
VZ
4353 const Date& d = testDates[n];
4354 if ( d.ticks == -1 )
4355 continue;
1ef54dcf 4356
299fcbfe
VZ
4357 wxDateTime dt = d.DT();
4358 long ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4359 wxPrintf(_T("Ticks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4360 if ( ticks == d.ticks )
4361 {
456ae26d 4362 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4363 }
4364 else
4365 {
456ae26d
VZ
4366 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4367 (long)d.ticks, (long)(ticks - d.ticks));
299fcbfe
VZ
4368 }
4369
4370 dt = d.DT().ToTimezone(wxDateTime::GMT0);
4371 ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4372 wxPrintf(_T("GMtks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4373 if ( ticks == d.gmticks )
4374 {
456ae26d 4375 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4376 }
4377 else
4378 {
456ae26d
VZ
4379 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4380 (long)d.gmticks, (long)(ticks - d.gmticks));
299fcbfe
VZ
4381 }
4382 }
4383
456ae26d 4384 wxPuts(_T(""));
299fcbfe
VZ
4385}
4386
4387// test conversions to JDN &c
4388static void TestTimeJDN()
4389{
456ae26d 4390 wxPuts(_T("\n*** wxDateTime to JDN test ***"));
1ef54dcf
VZ
4391
4392 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4393 {
4394 const Date& d = testDates[n];
299fcbfe 4395 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1ef54dcf
VZ
4396 double jdn = dt.GetJulianDayNumber();
4397
456ae26d 4398 wxPrintf(_T("JDN of %s is:\t% 15.6f"), d.Format().c_str(), jdn);
1ef54dcf
VZ
4399 if ( jdn == d.jdn )
4400 {
456ae26d 4401 wxPuts(_T(" (ok)"));
1ef54dcf
VZ
4402 }
4403 else
4404 {
456ae26d
VZ
4405 wxPrintf(_T(" (ERROR: should be %f, delta = %f)\n"),
4406 d.jdn, jdn - d.jdn);
1ef54dcf
VZ
4407 }
4408 }
e6ec579c
VZ
4409}
4410
211c2250
VZ
4411// test week days computation
4412static void TestTimeWDays()
4413{
456ae26d 4414 wxPuts(_T("\n*** wxDateTime weekday test ***"));
211c2250 4415
239446b4
VZ
4416 // test GetWeekDay()
4417 size_t n;
4418 for ( n = 0; n < WXSIZEOF(testDates); n++ )
211c2250
VZ
4419 {
4420 const Date& d = testDates[n];
4421 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
4422
4423 wxDateTime::WeekDay wday = dt.GetWeekDay();
456ae26d
VZ
4424 wxPrintf(_T("%s is: %s"),
4425 d.Format().c_str(),
4426 wxDateTime::GetWeekDayName(wday).c_str());
211c2250
VZ
4427 if ( wday == d.wday )
4428 {
456ae26d 4429 wxPuts(_T(" (ok)"));
211c2250
VZ
4430 }
4431 else
4432 {
456ae26d
VZ
4433 wxPrintf(_T(" (ERROR: should be %s)\n"),
4434 wxDateTime::GetWeekDayName(d.wday).c_str());
239446b4
VZ
4435 }
4436 }
4437
456ae26d 4438 wxPuts(_T(""));
239446b4
VZ
4439
4440 // test SetToWeekDay()
4441 struct WeekDateTestData
4442 {
4443 Date date; // the real date (precomputed)
4444 int nWeek; // its week index in the month
4445 wxDateTime::WeekDay wday; // the weekday
4446 wxDateTime::Month month; // the month
4447 int year; // and the year
4448
4449 wxString Format() const
4450 {
4451 wxString s, which;
4452 switch ( nWeek < -1 ? -nWeek : nWeek )
4453 {
456ae26d
VZ
4454 case 1: which = _T("first"); break;
4455 case 2: which = _T("second"); break;
4456 case 3: which = _T("third"); break;
4457 case 4: which = _T("fourth"); break;
4458 case 5: which = _T("fifth"); break;
239446b4 4459
456ae26d 4460 case -1: which = _T("last"); break;
239446b4
VZ
4461 }
4462
4463 if ( nWeek < -1 )
4464 {
456ae26d 4465 which += _T(" from end");
239446b4
VZ
4466 }
4467
456ae26d 4468 s.Printf(_T("The %s %s of %s in %d"),
239446b4
VZ
4469 which.c_str(),
4470 wxDateTime::GetWeekDayName(wday).c_str(),
4471 wxDateTime::GetMonthName(month).c_str(),
4472 year);
4473
4474 return s;
4475 }
4476 };
4477
4478 // the array data was generated by the following python program
4479 /*
4480from DateTime import *
4481from whrandom import *
4482from string import *
4483
4484monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4485wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4486
4487week = DateTimeDelta(7)
4488
4489for n in range(20):
4490 year = randint(1900, 2100)
4491 month = randint(1, 12)
4492 day = randint(1, 28)
4493 dt = DateTime(year, month, day)
4494 wday = dt.day_of_week
4495
4496 countFromEnd = choice([-1, 1])
4497 weekNum = 0;
4498
4499 while dt.month is month:
4500 dt = dt - countFromEnd * week
4501 weekNum = weekNum + countFromEnd
4502
4503 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
97e0ceea 4504
239446b4
VZ
4505 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
4506 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
97e0ceea 4507 */
239446b4
VZ
4508
4509 static const WeekDateTestData weekDatesTestData[] =
4510 {
4511 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
4512 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
4513 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
4514 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
4515 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
4516 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
4517 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
4518 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
4519 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
4520 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
4521 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
4522 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
4523 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
4524 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
4525 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
4526 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
4527 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
4528 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
4529 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
4530 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
4531 };
4532
456ae26d 4533 static const wxChar *fmt = _T("%d-%b-%Y");
239446b4
VZ
4534
4535 wxDateTime dt;
4536 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
4537 {
4538 const WeekDateTestData& wd = weekDatesTestData[n];
4539
4540 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
4541
456ae26d 4542 wxPrintf(_T("%s is %s"), wd.Format().c_str(), dt.Format(fmt).c_str());
239446b4
VZ
4543
4544 const Date& d = wd.date;
4545 if ( d.SameDay(dt.GetTm()) )
4546 {
456ae26d 4547 wxPuts(_T(" (ok)"));
239446b4
VZ
4548 }
4549 else
4550 {
4551 dt.Set(d.day, d.month, d.year);
4552
456ae26d 4553 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.Format(fmt).c_str());
211c2250
VZ
4554 }
4555 }
4556}
4557
239446b4
VZ
4558// test the computation of (ISO) week numbers
4559static void TestTimeWNumber()
4560{
456ae26d 4561 wxPuts(_T("\n*** wxDateTime week number test ***"));
239446b4
VZ
4562
4563 struct WeekNumberTestData
4564 {
4565 Date date; // the date
9d9b7755
VZ
4566 wxDateTime::wxDateTime_t week; // the week number in the year
4567 wxDateTime::wxDateTime_t wmon; // the week number in the month
4568 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
239446b4
VZ
4569 wxDateTime::wxDateTime_t dnum; // day number in the year
4570 };
4571
4572 // data generated with the following python script:
4573 /*
4574from DateTime import *
4575from whrandom import *
4576from string import *
4577
4578monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4579wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4580
9d9b7755
VZ
4581def GetMonthWeek(dt):
4582 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4583 if weekNumMonth < 0:
4584 weekNumMonth = weekNumMonth + 53
4585 return weekNumMonth
7c968cee 4586
9d9b7755
VZ
4587def GetLastSundayBefore(dt):
4588 if dt.iso_week[2] == 7:
4589 return dt
4590 else:
4591 return dt - DateTimeDelta(dt.iso_week[2])
4592
239446b4
VZ
4593for n in range(20):
4594 year = randint(1900, 2100)
4595 month = randint(1, 12)
4596 day = randint(1, 28)
4597 dt = DateTime(year, month, day)
4598 dayNum = dt.day_of_year
4599 weekNum = dt.iso_week[1]
9d9b7755
VZ
4600 weekNumMonth = GetMonthWeek(dt)
4601
4602 weekNumMonth2 = 0
4603 dtSunday = GetLastSundayBefore(dt)
4604
4605 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4606 weekNumMonth2 = weekNumMonth2 + 1
4607 dtSunday = dtSunday - DateTimeDelta(7)
4608
4609 data = { 'day': rjust(`day`, 2), \
4610 'month': monthNames[month - 1], \
4611 'year': year, \
4612 'weekNum': rjust(`weekNum`, 2), \
4613 'weekNumMonth': weekNumMonth, \
4614 'weekNumMonth2': weekNumMonth2, \
4615 'dayNum': rjust(`dayNum`, 3) }
4616
4617 print " { { %(day)s, "\
4618 "wxDateTime::%(month)s, "\
4619 "%(year)d }, "\
4620 "%(weekNum)s, "\
4621 "%(weekNumMonth)s, "\
4622 "%(weekNumMonth2)s, "\
239446b4 4623 "%(dayNum)s }," % data
9d9b7755 4624
239446b4
VZ
4625 */
4626 static const WeekNumberTestData weekNumberTestDates[] =
4627 {
9d9b7755
VZ
4628 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
4629 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
4630 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
4631 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
4632 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
4633 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
4634 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
4635 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
4636 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
4637 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
4638 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
4639 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
4640 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
4641 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
4642 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
4643 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
4644 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
4645 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
4646 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
4647 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
239446b4
VZ
4648 };
4649
4650 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
4651 {
4652 const WeekNumberTestData& wn = weekNumberTestDates[n];
4653 const Date& d = wn.date;
4654
4655 wxDateTime dt = d.DT();
4656
9d9b7755
VZ
4657 wxDateTime::wxDateTime_t
4658 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
4659 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
4660 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4661 dnum = dt.GetDayOfYear();
239446b4 4662
456ae26d 4663 wxPrintf(_T("%s: the day number is %d"), d.FormatDate().c_str(), dnum);
239446b4
VZ
4664 if ( dnum == wn.dnum )
4665 {
456ae26d 4666 wxPrintf(_T(" (ok)"));
239446b4
VZ
4667 }
4668 else
4669 {
456ae26d 4670 wxPrintf(_T(" (ERROR: should be %d)"), wn.dnum);
239446b4
VZ
4671 }
4672
2b5f62a0
VZ
4673 wxPrintf(_T(", week in month = %d"), wmon);
4674 if ( wmon != wn.wmon )
9d9b7755 4675 {
456ae26d 4676 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon);
9d9b7755
VZ
4677 }
4678
456ae26d 4679 wxPrintf(_T(" or %d"), wmon2);
9d9b7755
VZ
4680 if ( wmon2 == wn.wmon2 )
4681 {
456ae26d 4682 wxPrintf(_T(" (ok)"));
9d9b7755
VZ
4683 }
4684 else
4685 {
456ae26d 4686 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon2);
9d9b7755
VZ
4687 }
4688
2b5f62a0
VZ
4689 wxPrintf(_T(", week in year = %d"), week);
4690 if ( week != wn.week )
239446b4 4691 {
2b5f62a0 4692 wxPrintf(_T(" (ERROR: should be %d)"), wn.week);
239446b4 4693 }
2b5f62a0
VZ
4694
4695 wxPutchar(_T('\n'));
4696
4697 wxDateTime dt2(1, wxDateTime::Jan, d.year);
4698 dt2.SetToTheWeek(wn.week, dt.GetWeekDay());
4699 if ( dt2 != dt )
239446b4 4700 {
2b5f62a0
VZ
4701 Date d2;
4702 d2.Init(dt2.GetTm());
4703 wxPrintf(_T("ERROR: SetToTheWeek() returned %s\n"),
4704 d2.FormatDate().c_str());
239446b4
VZ
4705 }
4706 }
4707}
4708
4709// test DST calculations
4710static void TestTimeDST()
4711{
456ae26d 4712 wxPuts(_T("\n*** wxDateTime DST test ***"));
239446b4 4713
456ae26d
VZ
4714 wxPrintf(_T("DST is%s in effect now.\n\n"),
4715 wxDateTime::Now().IsDST() ? _T("") : _T(" not"));
239446b4
VZ
4716
4717 // taken from http://www.energy.ca.gov/daylightsaving.html
4718 static const Date datesDST[2][2004 - 1900 + 1] =
4719 {
4720 {
4721 { 1, wxDateTime::Apr, 1990 },
4722 { 7, wxDateTime::Apr, 1991 },
4723 { 5, wxDateTime::Apr, 1992 },
4724 { 4, wxDateTime::Apr, 1993 },
4725 { 3, wxDateTime::Apr, 1994 },
4726 { 2, wxDateTime::Apr, 1995 },
4727 { 7, wxDateTime::Apr, 1996 },
4728 { 6, wxDateTime::Apr, 1997 },
4729 { 5, wxDateTime::Apr, 1998 },
4730 { 4, wxDateTime::Apr, 1999 },
4731 { 2, wxDateTime::Apr, 2000 },
4732 { 1, wxDateTime::Apr, 2001 },
4733 { 7, wxDateTime::Apr, 2002 },
4734 { 6, wxDateTime::Apr, 2003 },
4735 { 4, wxDateTime::Apr, 2004 },
4736 },
4737 {
4738 { 28, wxDateTime::Oct, 1990 },
4739 { 27, wxDateTime::Oct, 1991 },
4740 { 25, wxDateTime::Oct, 1992 },
4741 { 31, wxDateTime::Oct, 1993 },
4742 { 30, wxDateTime::Oct, 1994 },
4743 { 29, wxDateTime::Oct, 1995 },
4744 { 27, wxDateTime::Oct, 1996 },
4745 { 26, wxDateTime::Oct, 1997 },
4746 { 25, wxDateTime::Oct, 1998 },
4747 { 31, wxDateTime::Oct, 1999 },
4748 { 29, wxDateTime::Oct, 2000 },
4749 { 28, wxDateTime::Oct, 2001 },
4750 { 27, wxDateTime::Oct, 2002 },
4751 { 26, wxDateTime::Oct, 2003 },
4752 { 31, wxDateTime::Oct, 2004 },
4753 }
4754 };
4755
4756 int year;
4757 for ( year = 1990; year < 2005; year++ )
4758 {
4759 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4760 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4761
456ae26d
VZ
4762 wxPrintf(_T("DST period in the US for year %d: from %s to %s"),
4763 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
239446b4
VZ
4764
4765 size_t n = year - 1990;
4766 const Date& dBegin = datesDST[0][n];
4767 const Date& dEnd = datesDST[1][n];
97e0ceea 4768
239446b4
VZ
4769 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4770 {
456ae26d 4771 wxPuts(_T(" (ok)"));
239446b4
VZ
4772 }
4773 else
4774 {
456ae26d
VZ
4775 wxPrintf(_T(" (ERROR: should be %s %d to %s %d)\n"),
4776 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4777 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
239446b4
VZ
4778 }
4779 }
4780
456ae26d 4781 wxPuts(_T(""));
239446b4
VZ
4782
4783 for ( year = 1990; year < 2005; year++ )
4784 {
456ae26d
VZ
4785 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
4786 year,
4787 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4788 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
239446b4
VZ
4789 }
4790}
4791
68ee7c47
VZ
4792// test wxDateTime -> text conversion
4793static void TestTimeFormat()
4794{
456ae26d 4795 wxPuts(_T("\n*** wxDateTime formatting test ***"));
68ee7c47 4796
b38e2f7d
VZ
4797 // some information may be lost during conversion, so store what kind
4798 // of info should we recover after a round trip
4799 enum CompareKind
68ee7c47 4800 {
b38e2f7d
VZ
4801 CompareNone, // don't try comparing
4802 CompareBoth, // dates and times should be identical
4803 CompareDate, // dates only
4804 CompareTime // time only
4805 };
4806
4807 static const struct
4808 {
4809 CompareKind compareKind;
456ae26d 4810 const wxChar *format;
b38e2f7d
VZ
4811 } formatTestFormats[] =
4812 {
456ae26d
VZ
4813 { CompareBoth, _T("---> %c") },
4814 { CompareDate, _T("Date is %A, %d of %B, in year %Y") },
4815 { CompareBoth, _T("Date is %x, time is %X") },
4816 { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") },
4817 { CompareNone, _T("The day of year: %j, the week of year: %W") },
ee3ef281 4818 { CompareDate, _T("ISO date without separators: %Y%m%d") },
68ee7c47
VZ
4819 };
4820
4821 static const Date formatTestDates[] =
4822 {
68ee7c47
VZ
4823 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4824 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
b38e2f7d
VZ
4825#if 0
4826 // this test can't work for other centuries because it uses two digit
4827 // years in formats, so don't even try it
68ee7c47
VZ
4828 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4829 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4830 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
b38e2f7d 4831#endif
68ee7c47
VZ
4832 };
4833
4834 // an extra test (as it doesn't depend on date, don't do it in the loop)
456ae26d 4835 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
68ee7c47 4836
b38e2f7d 4837 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
68ee7c47 4838 {
456ae26d 4839 wxPuts(_T(""));
68ee7c47 4840
b38e2f7d 4841 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
68ee7c47
VZ
4842 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4843 {
b38e2f7d 4844 wxString s = dt.Format(formatTestFormats[n].format);
456ae26d 4845 wxPrintf(_T("%s"), s.c_str());
f0f951fa 4846
b38e2f7d
VZ
4847 // what can we recover?
4848 int kind = formatTestFormats[n].compareKind;
4849
f0f951fa
VZ
4850 // convert back
4851 wxDateTime dt2;
b38e2f7d 4852 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
f0f951fa
VZ
4853 if ( !result )
4854 {
b38e2f7d
VZ
4855 // converion failed - should it have?
4856 if ( kind == CompareNone )
456ae26d 4857 wxPuts(_T(" (ok)"));
b38e2f7d 4858 else
456ae26d 4859 wxPuts(_T(" (ERROR: conversion back failed)"));
f0f951fa
VZ
4860 }
4861 else if ( *result )
4862 {
4863 // should have parsed the entire string
456ae26d 4864 wxPuts(_T(" (ERROR: conversion back stopped too soon)"));
f0f951fa 4865 }
f0f951fa
VZ
4866 else
4867 {
cab8f76e 4868 bool equal = false; // suppress compilaer warning
b38e2f7d
VZ
4869 switch ( kind )
4870 {
4871 case CompareBoth:
4872 equal = dt2 == dt;
4873 break;
4874
4875 case CompareDate:
4876 equal = dt.IsSameDate(dt2);
4877 break;
4878
4879 case CompareTime:
4880 equal = dt.IsSameTime(dt2);
4881 break;
4882 }
4883
4884 if ( !equal )
4885 {
456ae26d 4886 wxPrintf(_T(" (ERROR: got back '%s' instead of '%s')\n"),
b38e2f7d
VZ
4887 dt2.Format().c_str(), dt.Format().c_str());
4888 }
4889 else
4890 {
456ae26d 4891 wxPuts(_T(" (ok)"));
b38e2f7d 4892 }
f0f951fa 4893 }
68ee7c47
VZ
4894 }
4895 }
4896}
4897
97e0ceea
VZ
4898// test text -> wxDateTime conversion
4899static void TestTimeParse()
4900{
456ae26d 4901 wxPuts(_T("\n*** wxDateTime parse test ***"));
97e0ceea
VZ
4902
4903 struct ParseTestData
4904 {
456ae26d 4905 const wxChar *format;
97e0ceea
VZ
4906 Date date;
4907 bool good;
4908 };
4909
4910 static const ParseTestData parseTestDates[] =
4911 {
cab8f76e
VZ
4912 { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, true },
4913 { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, true },
97e0ceea
VZ
4914 };
4915
4916 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4917 {
456ae26d 4918 const wxChar *format = parseTestDates[n].format;
97e0ceea 4919
456ae26d 4920 wxPrintf(_T("%s => "), format);
97e0ceea
VZ
4921
4922 wxDateTime dt;
4923 if ( dt.ParseRfc822Date(format) )
4924 {
456ae26d 4925 wxPrintf(_T("%s "), dt.Format().c_str());
97e0ceea
VZ
4926
4927 if ( parseTestDates[n].good )
4928 {
4929 wxDateTime dtReal = parseTestDates[n].date.DT();
4930 if ( dt == dtReal )
4931 {
456ae26d 4932 wxPuts(_T("(ok)"));
97e0ceea
VZ
4933 }
4934 else
4935 {
456ae26d 4936 wxPrintf(_T("(ERROR: should be %s)\n"), dtReal.Format().c_str());
97e0ceea
VZ
4937 }
4938 }
4939 else
4940 {
456ae26d 4941 wxPuts(_T("(ERROR: bad format)"));
97e0ceea
VZ
4942 }
4943 }
4944 else
4945 {
456ae26d 4946 wxPrintf(_T("bad format (%s)\n"),
97e0ceea
VZ
4947 parseTestDates[n].good ? "ERROR" : "ok");
4948 }
4949 }
4950}
4951
b92fd37c 4952static void TestDateTimeInteractive()
9d9b7755 4953{
456ae26d 4954 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
9d9b7755 4955
456ae26d 4956 wxChar buf[128];
9d9b7755
VZ
4957
4958 for ( ;; )
4959 {
456ae26d
VZ
4960 wxPrintf(_T("Enter a date: "));
4961 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
9d9b7755
VZ
4962 break;
4963
f6bcfd97 4964 // kill the last '\n'
456ae26d 4965 buf[wxStrlen(buf) - 1] = 0;
f6bcfd97 4966
9d9b7755 4967 wxDateTime dt;
456ae26d 4968 const wxChar *p = dt.ParseDate(buf);
f6bcfd97 4969 if ( !p )
9d9b7755 4970 {
456ae26d 4971 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
9d9b7755
VZ
4972
4973 continue;
4974 }
f6bcfd97
BP
4975 else if ( *p )
4976 {
456ae26d 4977 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
f6bcfd97 4978 }
9d9b7755 4979
456ae26d
VZ
4980 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
4981 dt.Format(_T("%b %d, %Y")).c_str(),
4982 dt.GetDayOfYear(),
4983 dt.GetWeekOfMonth(wxDateTime::Monday_First),
4984 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4985 dt.GetWeekOfYear(wxDateTime::Monday_First));
9d9b7755
VZ
4986 }
4987
456ae26d 4988 wxPuts(_T("\n*** done ***"));
9d9b7755
VZ
4989}
4990
f6bcfd97
BP
4991static void TestTimeMS()
4992{
456ae26d 4993 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
f6bcfd97
BP
4994
4995 wxDateTime dt1 = wxDateTime::Now(),
4996 dt2 = wxDateTime::UNow();
4997
456ae26d
VZ
4998 wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
4999 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
5000 wxPrintf(_T("Dummy loop: "));
3ca6a5f0
BP
5001 for ( int i = 0; i < 6000; i++ )
5002 {
5003 //for ( int j = 0; j < 10; j++ )
5004 {
5005 wxString s;
456ae26d 5006 s.Printf(_T("%g"), sqrt(i));
3ca6a5f0
BP
5007 }
5008
5009 if ( !(i % 100) )
5010 putchar('.');
5011 }
456ae26d 5012 wxPuts(_T(", done"));
3ca6a5f0
BP
5013
5014 dt1 = dt2;
5015 dt2 = wxDateTime::UNow();
456ae26d 5016 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3ca6a5f0 5017
456ae26d 5018 wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
f6bcfd97 5019
456ae26d 5020 wxPuts(_T("\n*** done ***"));
f6bcfd97
BP
5021}
5022
9d9b7755
VZ
5023static void TestTimeArithmetics()
5024{
456ae26d 5025 wxPuts(_T("\n*** testing arithmetic operations on wxDateTime ***"));
9d9b7755 5026
f6bcfd97 5027 static const struct ArithmData
9d9b7755 5028 {
456ae26d 5029 ArithmData(const wxDateSpan& sp, const wxChar *nam)
f6bcfd97
BP
5030 : span(sp), name(nam) { }
5031
9d9b7755 5032 wxDateSpan span;
456ae26d 5033 const wxChar *name;
7c968cee 5034 } testArithmData[] =
9d9b7755 5035 {
456ae26d
VZ
5036 ArithmData(wxDateSpan::Day(), _T("day")),
5037 ArithmData(wxDateSpan::Week(), _T("week")),
5038 ArithmData(wxDateSpan::Month(), _T("month")),
5039 ArithmData(wxDateSpan::Year(), _T("year")),
5040 ArithmData(wxDateSpan(1, 2, 3, 4), _T("year, 2 months, 3 weeks, 4 days")),
9d9b7755 5041 };
7c968cee 5042
9d9b7755
VZ
5043 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
5044
5045 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
5046 {
5047 wxDateSpan span = testArithmData[n].span;
5048 dt1 = dt + span;
5049 dt2 = dt - span;
5050
456ae26d
VZ
5051 const wxChar *name = testArithmData[n].name;
5052 wxPrintf(_T("%s + %s = %s, %s - %s = %s\n"),
9d9b7755
VZ
5053 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
5054 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
5055
456ae26d 5056 wxPrintf(_T("Going back: %s"), (dt1 - span).FormatISODate().c_str());
9d9b7755
VZ
5057 if ( dt1 - span == dt )
5058 {
456ae26d 5059 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5060 }
5061 else
5062 {
456ae26d 5063 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5064 }
5065
456ae26d 5066 wxPrintf(_T("Going forward: %s"), (dt2 + span).FormatISODate().c_str());
9d9b7755
VZ
5067 if ( dt2 + span == dt )
5068 {
456ae26d 5069 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5070 }
5071 else
5072 {
456ae26d 5073 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5074 }
5075
456ae26d 5076 wxPrintf(_T("Double increment: %s"), (dt2 + 2*span).FormatISODate().c_str());
9d9b7755
VZ
5077 if ( dt2 + 2*span == dt1 )
5078 {
456ae26d 5079 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5080 }
5081 else
5082 {
456ae26d 5083 wxPrintf(_T(" (ERROR: should be %s)\n"), dt2.FormatISODate().c_str());
9d9b7755
VZ
5084 }
5085
456ae26d 5086 wxPuts(_T(""));
9d9b7755
VZ
5087 }
5088}
5089
0de868d9
VZ
5090static void TestTimeHolidays()
5091{
456ae26d 5092 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
0de868d9
VZ
5093
5094 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
5095 wxDateTime dtStart(1, tm.mon, tm.year),
5096 dtEnd = dtStart.GetLastMonthDay();
5097
5098 wxDateTimeArray hol;
5099 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
5100
456ae26d 5101 const wxChar *format = _T("%d-%b-%Y (%a)");
0de868d9 5102
456ae26d 5103 wxPrintf(_T("All holidays between %s and %s:\n"),
0de868d9
VZ
5104 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
5105
5106 size_t count = hol.GetCount();
5107 for ( size_t n = 0; n < count; n++ )
5108 {
456ae26d 5109 wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
0de868d9
VZ
5110 }
5111
456ae26d 5112 wxPuts(_T(""));
0de868d9
VZ
5113}
5114
f6bcfd97
BP
5115static void TestTimeZoneBug()
5116{
456ae26d 5117 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
f6bcfd97
BP
5118
5119 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
5120 for ( int i = 0; i < 31; i++ )
5121 {
456ae26d 5122 wxPrintf(_T("Date %s: week day %s.\n"),
f6bcfd97
BP
5123 date.Format(_T("%d-%m-%Y")).c_str(),
5124 date.GetWeekDayName(date.GetWeekDay()).c_str());
5125
5126 date += wxDateSpan::Day();
5127 }
5128
456ae26d 5129 wxPuts(_T(""));
f6bcfd97
BP
5130}
5131
df05cdc5
VZ
5132static void TestTimeSpanFormat()
5133{
456ae26d 5134 wxPuts(_T("\n*** wxTimeSpan tests ***"));
df05cdc5 5135
456ae26d 5136 static const wxChar *formats[] =
df05cdc5
VZ
5137 {
5138 _T("(default) %H:%M:%S"),
5139 _T("%E weeks and %D days"),
5140 _T("%l milliseconds"),
5141 _T("(with ms) %H:%M:%S:%l"),
5142 _T("100%% of minutes is %M"), // test "%%"
5143 _T("%D days and %H hours"),
a8625337 5144 _T("or also %S seconds"),
df05cdc5
VZ
5145 };
5146
5147 wxTimeSpan ts1(1, 2, 3, 4),
5148 ts2(111, 222, 333);
5149 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
5150 {
456ae26d 5151 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
df05cdc5
VZ
5152 ts1.Format(formats[n]).c_str(),
5153 ts2.Format(formats[n]).c_str());
5154 }
5155
456ae26d 5156 wxPuts(_T(""));
df05cdc5
VZ
5157}
5158
68ee7c47
VZ
5159#if 0
5160
97e0ceea
VZ
5161// test compatibility with the old wxDate/wxTime classes
5162static void TestTimeCompatibility()
5163{
456ae26d 5164 wxPuts(_T("\n*** wxDateTime compatibility test ***"));
97e0ceea 5165
456ae26d
VZ
5166 wxPrintf(_T("wxDate for JDN 0: %s\n"), wxDate(0l).FormatDate().c_str());
5167 wxPrintf(_T("wxDate for MJD 0: %s\n"), wxDate(2400000).FormatDate().c_str());
97e0ceea
VZ
5168
5169 double jdnNow = wxDateTime::Now().GetJDN();
5170 long jdnMidnight = (long)(jdnNow - 0.5);
456ae26d 5171 wxPrintf(_T("wxDate for today: %s\n"), wxDate(jdnMidnight).FormatDate().c_str());
97e0ceea
VZ
5172
5173 jdnMidnight = wxDate().Set().GetJulianDate();
456ae26d 5174 wxPrintf(_T("wxDateTime for today: %s\n"),
97e0ceea
VZ
5175 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
5176
5177 int flags = wxEUROPEAN;//wxFULL;
5178 wxDate date;
5179 date.Set();
456ae26d 5180 wxPrintf(_T("Today is %s\n"), date.FormatDate(flags).c_str());
97e0ceea
VZ
5181 for ( int n = 0; n < 7; n++ )
5182 {
456ae26d 5183 wxPrintf(_T("Previous %s is %s\n"),
97e0ceea
VZ
5184 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
5185 date.Previous(n + 1).FormatDate(flags).c_str());
5186 }
5187}
5188
68ee7c47
VZ
5189#endif // 0
5190
d31b7b68 5191#endif // TEST_DATETIME
b76b015e 5192
39937656
VZ
5193// ----------------------------------------------------------------------------
5194// wxTextInput/OutputStream
5195// ----------------------------------------------------------------------------
5196
5197#ifdef TEST_TEXTSTREAM
5198
5199#include "wx/txtstrm.h"
5200#include "wx/wfstream.h"
5201
5202static void TestTextInputStream()
5203{
5204 wxPuts(_T("\n*** wxTextInputStream test ***"));
5205
5206 wxFileInputStream fsIn(_T("testdata.fc"));
5207 if ( !fsIn.Ok() )
5208 {
5209 wxPuts(_T("ERROR: couldn't open file."));
5210 }
5211 else
5212 {
5213 wxTextInputStream tis(fsIn);
5214
5215 size_t line = 1;
5216 for ( ;; )
5217 {
5218 const wxString s = tis.ReadLine();
5219
5220 // line could be non empty if the last line of the file isn't
5221 // terminated with EOL
5222 if ( fsIn.Eof() && s.empty() )
5223 break;
5224
5225 wxPrintf(_T("Line %d: %s\n"), line++, s.c_str());
5226 }
5227 }
5228}
5229
5230#endif // TEST_TEXTSTREAM
5231
e87271f3
VZ
5232// ----------------------------------------------------------------------------
5233// threads
5234// ----------------------------------------------------------------------------
5235
5236#ifdef TEST_THREADS
5237
e84010cf 5238#include "wx/thread.h"
37667812 5239
bbfa0322
VZ
5240static size_t gs_counter = (size_t)-1;
5241static wxCriticalSection gs_critsect;
c112e100 5242static wxSemaphore gs_cond;
bbfa0322 5243
b568d04f 5244class MyJoinableThread : public wxThread
bbfa0322
VZ
5245{
5246public:
b568d04f
VZ
5247 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
5248 { m_n = n; Create(); }
bbfa0322
VZ
5249
5250 // thread execution starts here
b568d04f 5251 virtual ExitCode Entry();
bbfa0322 5252
b568d04f
VZ
5253private:
5254 size_t m_n;
bbfa0322
VZ
5255};
5256
b568d04f 5257wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 5258{
b568d04f
VZ
5259 unsigned long res = 1;
5260 for ( size_t n = 1; n < m_n; n++ )
5261 {
5262 res *= n;
5263
5264 // it's a loooong calculation :-)
5265 Sleep(100);
5266 }
bbfa0322 5267
b568d04f 5268 return (ExitCode)res;
bbfa0322
VZ
5269}
5270
b568d04f
VZ
5271class MyDetachedThread : public wxThread
5272{
5273public:
456ae26d 5274 MyDetachedThread(size_t n, wxChar ch)
fcc3d7cb
VZ
5275 {
5276 m_n = n;
5277 m_ch = ch;
cab8f76e 5278 m_cancelled = false;
fcc3d7cb
VZ
5279
5280 Create();
5281 }
b568d04f
VZ
5282
5283 // thread execution starts here
5284 virtual ExitCode Entry();
5285
5286 // and stops here
5287 virtual void OnExit();
5288
5289private:
9fc3ad34 5290 size_t m_n; // number of characters to write
456ae26d 5291 wxChar m_ch; // character to write
fcc3d7cb 5292
cab8f76e 5293 bool m_cancelled; // false if we exit normally
b568d04f
VZ
5294};
5295
5296wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
5297{
5298 {
5299 wxCriticalSectionLocker lock(gs_critsect);
5300 if ( gs_counter == (size_t)-1 )
5301 gs_counter = 1;
5302 else
5303 gs_counter++;
5304 }
5305
9fc3ad34 5306 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
5307 {
5308 if ( TestDestroy() )
fcc3d7cb 5309 {
cab8f76e 5310 m_cancelled = true;
fcc3d7cb 5311
bbfa0322 5312 break;
fcc3d7cb 5313 }
bbfa0322
VZ
5314
5315 putchar(m_ch);
5316 fflush(stdout);
5317
5318 wxThread::Sleep(100);
5319 }
5320
b568d04f 5321 return 0;
bbfa0322
VZ
5322}
5323
b568d04f 5324void MyDetachedThread::OnExit()
bbfa0322 5325{
456ae26d 5326 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
9fc3ad34 5327
bbfa0322 5328 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 5329 if ( !--gs_counter && !m_cancelled )
c112e100 5330 gs_cond.Post();
bbfa0322
VZ
5331}
5332
2f2f3e2a 5333static void TestDetachedThreads()
9fc3ad34 5334{
456ae26d 5335 wxPuts(_T("\n*** Testing detached threads ***"));
9fc3ad34
VZ
5336
5337 static const size_t nThreads = 3;
5338 MyDetachedThread *threads[nThreads];
5339 size_t n;
5340 for ( n = 0; n < nThreads; n++ )
5341 {
5342 threads[n] = new MyDetachedThread(10, 'A' + n);
5343 }
5344
5345 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
5346 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
5347
5348 for ( n = 0; n < nThreads; n++ )
5349 {
5350 threads[n]->Run();
5351 }
5352
5353 // wait until all threads terminate
5354 gs_cond.Wait();
5355
456ae26d 5356 wxPuts(_T(""));
9fc3ad34
VZ
5357}
5358
2f2f3e2a 5359static void TestJoinableThreads()
9fc3ad34 5360{
456ae26d 5361 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
9fc3ad34
VZ
5362
5363 // calc 10! in the background
5364 MyJoinableThread thread(10);
5365 thread.Run();
5366
456ae26d 5367 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
9fc3ad34
VZ
5368 (unsigned long)thread.Wait());
5369}
5370
2f2f3e2a 5371static void TestThreadSuspend()
9fc3ad34 5372{
456ae26d 5373 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
2f02cb89
VZ
5374
5375 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
5376
5377 thread->Run();
5378
5379 // this is for this demo only, in a real life program we'd use another
5380 // condition variable which would be signaled from wxThread::Entry() to
5381 // tell us that the thread really started running - but here just wait a
5382 // bit and hope that it will be enough (the problem is, of course, that
5383 // the thread might still not run when we call Pause() which will result
5384 // in an error)
5385 wxThread::Sleep(300);
5386
5387 for ( size_t n = 0; n < 3; n++ )
5388 {
5389 thread->Pause();
5390
456ae26d 5391 wxPuts(_T("\nThread suspended"));
9fc3ad34
VZ
5392 if ( n > 0 )
5393 {
5394 // don't sleep but resume immediately the first time
5395 wxThread::Sleep(300);
5396 }
456ae26d 5397 wxPuts(_T("Going to resume the thread"));
9fc3ad34
VZ
5398
5399 thread->Resume();
5400 }
5401
456ae26d 5402 wxPuts(_T("Waiting until it terminates now"));
4c460b34 5403
9fc3ad34
VZ
5404 // wait until the thread terminates
5405 gs_cond.Wait();
5406
456ae26d 5407 wxPuts(_T(""));
9fc3ad34
VZ
5408}
5409
2f2f3e2a 5410static void TestThreadDelete()
2f02cb89
VZ
5411{
5412 // As above, using Sleep() is only for testing here - we must use some
5413 // synchronisation object instead to ensure that the thread is still
5414 // running when we delete it - deleting a detached thread which already
5415 // terminated will lead to a crash!
5416
456ae26d 5417 wxPuts(_T("\n*** Testing thread delete function ***"));
2f02cb89 5418
4c460b34
VZ
5419 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
5420
5421 thread0->Delete();
5422
456ae26d 5423 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
4c460b34 5424
2f02cb89
VZ
5425 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
5426
5427 thread1->Run();
5428
5429 wxThread::Sleep(300);
5430
5431 thread1->Delete();
5432
456ae26d 5433 wxPuts(_T("\nDeleted a running thread."));
2f02cb89
VZ
5434
5435 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
5436
5437 thread2->Run();
5438
5439 wxThread::Sleep(300);
5440
5441 thread2->Pause();
5442
5443 thread2->Delete();
5444
456ae26d 5445 wxPuts(_T("\nDeleted a sleeping thread."));
2f02cb89 5446
4c460b34
VZ
5447 MyJoinableThread thread3(20);
5448 thread3.Run();
2f02cb89 5449
4c460b34 5450 thread3.Delete();
2f02cb89 5451
456ae26d 5452 wxPuts(_T("\nDeleted a joinable thread."));
2f02cb89 5453
4c460b34
VZ
5454 MyJoinableThread thread4(2);
5455 thread4.Run();
2f02cb89
VZ
5456
5457 wxThread::Sleep(300);
5458
4c460b34 5459 thread4.Delete();
2f02cb89 5460
456ae26d 5461 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
2f02cb89 5462
456ae26d 5463 wxPuts(_T(""));
2f02cb89
VZ
5464}
5465
2f2f3e2a
VZ
5466class MyWaitingThread : public wxThread
5467{
5468public:
c112e100 5469 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
2f2f3e2a 5470 {
c112e100 5471 m_mutex = mutex;
2f2f3e2a
VZ
5472 m_condition = condition;
5473
5474 Create();
5475 }
5476
5477 virtual ExitCode Entry()
5478 {
456ae26d 5479 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
2f2f3e2a
VZ
5480 fflush(stdout);
5481
c112e100 5482 gs_cond.Post();
2f2f3e2a 5483
456ae26d 5484 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
2f2f3e2a
VZ
5485 fflush(stdout);
5486
c112e100 5487 m_mutex->Lock();
2f2f3e2a 5488 m_condition->Wait();
c112e100 5489 m_mutex->Unlock();
2f2f3e2a 5490
456ae26d 5491 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
2f2f3e2a
VZ
5492 fflush(stdout);
5493
5494 return 0;
5495 }
5496
5497private:
c112e100 5498 wxMutex *m_mutex;
2f2f3e2a
VZ
5499 wxCondition *m_condition;
5500};
5501
5502static void TestThreadConditions()
5503{
c112e100
VZ
5504 wxMutex mutex;
5505 wxCondition condition(mutex);
2f2f3e2a 5506
8d5eff60
VZ
5507 // otherwise its difficult to understand which log messages pertain to
5508 // which condition
456ae26d 5509 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
c112e100 5510 // condition.GetId(), gs_cond.GetId());
8d5eff60 5511
2f2f3e2a 5512 // create and launch threads
60ce696e 5513 MyWaitingThread *threads[10];
2f2f3e2a
VZ
5514
5515 size_t n;
5516 for ( n = 0; n < WXSIZEOF(threads); n++ )
5517 {
c112e100 5518 threads[n] = new MyWaitingThread( &mutex, &condition );
2f2f3e2a
VZ
5519 }
5520
5521 for ( n = 0; n < WXSIZEOF(threads); n++ )
5522 {
5523 threads[n]->Run();
5524 }
5525
5526 // wait until all threads run
456ae26d 5527 wxPuts(_T("Main thread is waiting for the other threads to start"));
2f2f3e2a
VZ
5528 fflush(stdout);
5529
5530 size_t nRunning = 0;
5531 while ( nRunning < WXSIZEOF(threads) )
5532 {
5533 gs_cond.Wait();
5534
2f2f3e2a 5535 nRunning++;
8d5eff60 5536
456ae26d 5537 wxPrintf(_T("Main thread: %u already running\n"), nRunning);
8d5eff60 5538 fflush(stdout);
2f2f3e2a
VZ
5539 }
5540
456ae26d 5541 wxPuts(_T("Main thread: all threads started up."));
2f2f3e2a
VZ
5542 fflush(stdout);
5543
8d5eff60
VZ
5544 wxThread::Sleep(500);
5545
60ce696e 5546#if 1
8d5eff60 5547 // now wake one of them up
456ae26d 5548 wxPrintf(_T("Main thread: about to signal the condition.\n"));
2f2f3e2a
VZ
5549 fflush(stdout);
5550 condition.Signal();
8d5eff60 5551#endif
2f2f3e2a 5552
60ce696e
VZ
5553 wxThread::Sleep(200);
5554
8d5eff60 5555 // wake all the (remaining) threads up, so that they can exit
456ae26d 5556 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
2f2f3e2a
VZ
5557 fflush(stdout);
5558 condition.Broadcast();
5559
8d5eff60
VZ
5560 // give them time to terminate (dirty!)
5561 wxThread::Sleep(500);
2f2f3e2a
VZ
5562}
5563
c112e100
VZ
5564#include "wx/utils.h"
5565
5566class MyExecThread : public wxThread
5567{
5568public:
5569 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
5570 m_command(command)
5571 {
5572 Create();
5573 }
5574
5575 virtual ExitCode Entry()
5576 {
5577 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
5578 }
5579
5580private:
5581 wxString m_command;
5582};
5583
5584static void TestThreadExec()
5585{
5586 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
5587
5588 MyExecThread thread(_T("true"));
5589 thread.Run();
5590
5591 wxPrintf(_T("Main program exit code: %ld.\n"),
5592 wxExecute(_T("false"), wxEXEC_SYNC));
5593
5594 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
5595}
5596
5597// semaphore tests
5598#include "wx/datetime.h"
5599
5600class MySemaphoreThread : public wxThread
5601{
5602public:
5603 MySemaphoreThread(int i, wxSemaphore *sem)
5604 : wxThread(wxTHREAD_JOINABLE),
5605 m_sem(sem),
5606 m_i(i)
5607 {
5608 Create();
5609 }
5610
5611 virtual ExitCode Entry()
5612 {
f06ef5f4
VZ
5613 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
5614 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5615
5616 m_sem->Wait();
5617
f06ef5f4
VZ
5618 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
5619 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5620
5621 Sleep(1000);
5622
f06ef5f4
VZ
5623 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
5624 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5625
5626 m_sem->Post();
5627
5628 return 0;
5629 }
5630
5631private:
5632 wxSemaphore *m_sem;
5633 int m_i;
5634};
5635
5636WX_DEFINE_ARRAY(wxThread *, ArrayThreads);
5637
5638static void TestSemaphore()
5639{
5640 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5641
5642 static const int SEM_LIMIT = 3;
5643
5644 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
5645 ArrayThreads threads;
5646
5647 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
5648 {
5649 threads.Add(new MySemaphoreThread(i, &sem));
5650 threads.Last()->Run();
5651 }
5652
5653 for ( size_t n = 0; n < threads.GetCount(); n++ )
5654 {
5655 threads[n]->Wait();
5656 delete threads[n];
5657 }
5658}
5659
e87271f3
VZ
5660#endif // TEST_THREADS
5661
5662// ----------------------------------------------------------------------------
5663// arrays
5664// ----------------------------------------------------------------------------
5665
5666#ifdef TEST_ARRAYS
5667
1a931653 5668#include "wx/dynarray.h"
e87271f3 5669
3dc01741
VZ
5670typedef unsigned short ushort;
5671
1a931653
VZ
5672#define DefineCompare(name, T) \
5673 \
5674int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
5675{ \
5676 return first - second; \
5677} \
5678 \
5679int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
5680{ \
5681 return *first - *second; \
5682} \
5683 \
5684int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
5685{ \
5686 return *second - *first; \
5687} \
5688
3dc01741 5689DefineCompare(UShort, ushort);
1a931653
VZ
5690DefineCompare(Int, int);
5691
5692// test compilation of all macros
3dc01741
VZ
5693WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
5694WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
5695WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
5696WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
e87271f3 5697
1a931653
VZ
5698WX_DECLARE_OBJARRAY(Bar, ArrayBars);
5699#include "wx/arrimpl.cpp"
5700WX_DEFINE_OBJARRAY(ArrayBars);
5701
456ae26d 5702static void PrintArray(const wxChar* name, const wxArrayString& array)
d6c9c1b7 5703{
456ae26d 5704 wxPrintf(_T("Dump of the array '%s'\n"), name);
d6c9c1b7
VZ
5705
5706 size_t nCount = array.GetCount();
5707 for ( size_t n = 0; n < nCount; n++ )
5708 {
456ae26d 5709 wxPrintf(_T("\t%s[%u] = '%s'\n"), name, n, array[n].c_str());
d6c9c1b7
VZ
5710 }
5711}
5712
5713int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
5714 const wxString& second)
f6bcfd97
BP
5715{
5716 return first.length() - second.length();
5717}
5718
1a931653
VZ
5719#define TestArrayOf(name) \
5720 \
456ae26d 5721static void PrintArray(const wxChar* name, const wxSortedArray##name & array) \
1a931653 5722{ \
456ae26d 5723 wxPrintf(_T("Dump of the array '%s'\n"), name); \
1a931653
VZ
5724 \
5725 size_t nCount = array.GetCount(); \
5726 for ( size_t n = 0; n < nCount; n++ ) \
5727 { \
456ae26d 5728 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
1a931653
VZ
5729 } \
5730} \
5731 \
456ae26d 5732static void PrintArray(const wxChar* name, const wxArray##name & array) \
1a931653 5733{ \
456ae26d 5734 wxPrintf(_T("Dump of the array '%s'\n"), name); \
1a931653
VZ
5735 \
5736 size_t nCount = array.GetCount(); \
5737 for ( size_t n = 0; n < nCount; n++ ) \
5738 { \
456ae26d 5739 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
1a931653
VZ
5740 } \
5741} \
5742 \
5743static void TestArrayOf ## name ## s() \
5744{ \
456ae26d 5745 wxPrintf(_T("*** Testing wxArray%s ***\n"), #name); \
1a931653
VZ
5746 \
5747 wxArray##name a; \
5748 a.Add(1); \
f74a90b3
SN
5749 a.Add(17,2); \
5750 a.Add(5,3); \
5751 a.Add(3,4); \
1a931653 5752 \
456ae26d
VZ
5753 wxPuts(_T("Initially:")); \
5754 PrintArray(_T("a"), a); \
1a931653 5755 \
456ae26d 5756 wxPuts(_T("After sort:")); \
1a931653 5757 a.Sort(name ## Compare); \
456ae26d 5758 PrintArray(_T("a"), a); \
1a931653 5759 \
456ae26d 5760 wxPuts(_T("After reverse sort:")); \
1a931653 5761 a.Sort(name ## RevCompare); \
456ae26d 5762 PrintArray(_T("a"), a); \
1a931653
VZ
5763 \
5764 wxSortedArray##name b; \
5765 b.Add(1); \
5766 b.Add(17); \
5767 b.Add(5); \
5768 b.Add(3); \
5769 \
456ae26d
VZ
5770 wxPuts(_T("Sorted array initially:")); \
5771 PrintArray(_T("b"), b); \
d6c9c1b7
VZ
5772}
5773
3dc01741 5774TestArrayOf(UShort);
1a931653 5775TestArrayOf(Int);
f6bcfd97
BP
5776
5777static void TestArrayOfObjects()
5778{
456ae26d 5779 wxPuts(_T("*** Testing wxObjArray ***\n"));
f6bcfd97
BP
5780
5781 {
5782 ArrayBars bars;
f74a90b3 5783 Bar bar("second bar (two copies!)");
f6bcfd97 5784
456ae26d 5785 wxPrintf(_T("Initially: %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5786 bars.GetCount(), Bar::GetNumber());
5787
5788 bars.Add(new Bar("first bar"));
f74a90b3 5789 bars.Add(bar,2);
f6bcfd97 5790
456ae26d 5791 wxPrintf(_T("Now: %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5792 bars.GetCount(), Bar::GetNumber());
5793
456ae26d 5794 bars.RemoveAt(1, bars.GetCount() - 1);
f74a90b3 5795
456ae26d
VZ
5796 wxPrintf(_T("After removing all but first element: %u objects in the ")
5797 _T("array, %u objects total.\n"),
f74a90b3
SN
5798 bars.GetCount(), Bar::GetNumber());
5799
f6bcfd97
BP
5800 bars.Empty();
5801
456ae26d 5802 wxPrintf(_T("After Empty(): %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5803 bars.GetCount(), Bar::GetNumber());
5804 }
5805
456ae26d 5806 wxPrintf(_T("Finally: no more objects in the array, %u objects total.\n"),
f6bcfd97
BP
5807 Bar::GetNumber());
5808}
5809
e87271f3
VZ
5810#endif // TEST_ARRAYS
5811
9fc3ad34
VZ
5812// ----------------------------------------------------------------------------
5813// strings
5814// ----------------------------------------------------------------------------
5815
5816#ifdef TEST_STRINGS
5817
5818#include "wx/timer.h"
bbf8fc53 5819#include "wx/tokenzr.h"
9fc3ad34 5820
7c968cee
VZ
5821static void TestStringConstruction()
5822{
456ae26d 5823 wxPuts(_T("*** Testing wxString constructores ***"));
7c968cee
VZ
5824
5825 #define TEST_CTOR(args, res) \
5826 { \
5827 wxString s args ; \
456ae26d 5828 wxPrintf(_T("wxString%s = %s "), #args, s.c_str()); \
7c968cee
VZ
5829 if ( s == res ) \
5830 { \
456ae26d 5831 wxPuts(_T("(ok)")); \
7c968cee
VZ
5832 } \
5833 else \
5834 { \
456ae26d 5835 wxPrintf(_T("(ERROR: should be %s)\n"), res); \
7c968cee
VZ
5836 } \
5837 }
5838
5839 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5840 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5841 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5842 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5843
5844 static const wxChar *s = _T("?really!");
5845 const wxChar *start = wxStrchr(s, _T('r'));
5846 const wxChar *end = wxStrchr(s, _T('!'));
5847 TEST_CTOR((start, end), _T("really"));
5848
456ae26d 5849 wxPuts(_T(""));
7c968cee
VZ
5850}
5851
299fcbfe 5852static void TestString()
9fc3ad34
VZ
5853{
5854 wxStopWatch sw;
5855
5856 wxString a, b, c;
5857
5858 a.reserve (128);
5859 b.reserve (128);
5860 c.reserve (128);
5861
5862 for (int i = 0; i < 1000000; ++i)
5863 {
5864 a = "Hello";
5865 b = " world";
5866 c = "! How'ya doin'?";
5867 a += b;
5868 a += c;
5869 c = "Hello world! What's up?";
5870 if (c != a)
5871 c = "Doh!";
5872 }
5873
456ae26d 5874 wxPrintf(_T("TestString elapsed time: %ld\n"), sw.Time());
9fc3ad34
VZ
5875}
5876
299fcbfe 5877static void TestPChar()
9fc3ad34
VZ
5878{
5879 wxStopWatch sw;
5880
456ae26d
VZ
5881 wxChar a [128];
5882 wxChar b [128];
5883 wxChar c [128];
9fc3ad34
VZ
5884
5885 for (int i = 0; i < 1000000; ++i)
5886 {
456ae26d
VZ
5887 wxStrcpy (a, _T("Hello"));
5888 wxStrcpy (b, _T(" world"));
5889 wxStrcpy (c, _T("! How'ya doin'?"));
5890 wxStrcat (a, b);
5891 wxStrcat (a, c);
5892 wxStrcpy (c, _T("Hello world! What's up?"));
5893 if (wxStrcmp (c, a) == 0)
5894 wxStrcpy (c, _T("Doh!"));
9fc3ad34
VZ
5895 }
5896
456ae26d 5897 wxPrintf(_T("TestPChar elapsed time: %ld\n"), sw.Time());
9fc3ad34
VZ
5898}
5899
299fcbfe
VZ
5900static void TestStringSub()
5901{
5902 wxString s("Hello, world!");
5903
456ae26d 5904 wxPuts(_T("*** Testing wxString substring extraction ***"));
299fcbfe 5905
456ae26d
VZ
5906 wxPrintf(_T("String = '%s'\n"), s.c_str());
5907 wxPrintf(_T("Left(5) = '%s'\n"), s.Left(5).c_str());
5908 wxPrintf(_T("Right(6) = '%s'\n"), s.Right(6).c_str());
5909 wxPrintf(_T("Mid(3, 5) = '%s'\n"), s(3, 5).c_str());
5910 wxPrintf(_T("Mid(3) = '%s'\n"), s.Mid(3).c_str());
5911 wxPrintf(_T("substr(3, 5) = '%s'\n"), s.substr(3, 5).c_str());
5912 wxPrintf(_T("substr(3) = '%s'\n"), s.substr(3).c_str());
299fcbfe 5913
f6bcfd97
BP
5914 static const wxChar *prefixes[] =
5915 {
5916 _T("Hello"),
5917 _T("Hello, "),
5918 _T("Hello, world!"),
5919 _T("Hello, world!!!"),
5920 _T(""),
5921 _T("Goodbye"),
5922 _T("Hi"),
5923 };
5924
5925 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5926 {
5927 wxString prefix = prefixes[n], rest;
5928 bool rc = s.StartsWith(prefix, &rest);
cab8f76e 5929 wxPrintf(_T("StartsWith('%s') = %s"), prefix.c_str(), rc ? _T("true") : _T("false"));
f6bcfd97
BP
5930 if ( rc )
5931 {
456ae26d 5932 wxPrintf(_T(" (the rest is '%s')\n"), rest.c_str());
f6bcfd97
BP
5933 }
5934 else
5935 {
5936 putchar('\n');
5937 }
5938 }
5939
456ae26d 5940 wxPuts(_T(""));
299fcbfe
VZ
5941}
5942
f0f951fa
VZ
5943static void TestStringFormat()
5944{
456ae26d 5945 wxPuts(_T("*** Testing wxString formatting ***"));
f0f951fa
VZ
5946
5947 wxString s;
456ae26d 5948 s.Printf(_T("%03d"), 18);
f0f951fa 5949
456ae26d
VZ
5950 wxPrintf(_T("Number 18: %s\n"), wxString::Format(_T("%03d"), 18).c_str());
5951 wxPrintf(_T("Number 18: %s\n"), s.c_str());
f0f951fa 5952
456ae26d 5953 wxPuts(_T(""));
f0f951fa
VZ
5954}
5955
d71fa6fb
VZ
5956// returns "not found" for npos, value for all others
5957static wxString PosToString(size_t res)
5958{
5959 wxString s = res == wxString::npos ? wxString(_T("not found"))
5960 : wxString::Format(_T("%u"), res);
5961 return s;
5962}
5963
5964static void TestStringFind()
5965{
456ae26d 5966 wxPuts(_T("*** Testing wxString find() functions ***"));
d71fa6fb
VZ
5967
5968 static const wxChar *strToFind = _T("ell");
5969 static const struct StringFindTest
5970 {
5971 const wxChar *str;
5972 size_t start,
5973 result; // of searching "ell" in str
5974 } findTestData[] =
5975 {
5976 { _T("Well, hello world"), 0, 1 },
5977 { _T("Well, hello world"), 6, 7 },
5978 { _T("Well, hello world"), 9, wxString::npos },
5979 };
5980
5981 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5982 {
5983 const StringFindTest& ft = findTestData[n];
5984 size_t res = wxString(ft.str).find(strToFind, ft.start);
5985
456ae26d 5986 wxPrintf(_T("Index of '%s' in '%s' starting from %u is %s "),
d71fa6fb
VZ
5987 strToFind, ft.str, ft.start, PosToString(res).c_str());
5988
5989 size_t resTrue = ft.result;
5990 if ( res == resTrue )
5991 {
456ae26d 5992 wxPuts(_T("(ok)"));
d71fa6fb
VZ
5993 }
5994 else
5995 {
456ae26d 5996 wxPrintf(_T("(ERROR: should be %s)\n"),
d71fa6fb
VZ
5997 PosToString(resTrue).c_str());
5998 }
5999 }
6000
456ae26d 6001 wxPuts(_T(""));
d71fa6fb
VZ
6002}
6003
bbf8fc53
VZ
6004static void TestStringTokenizer()
6005{
456ae26d 6006 wxPuts(_T("*** Testing wxStringTokenizer ***"));
bbf8fc53 6007
7c968cee
VZ
6008 static const wxChar *modeNames[] =
6009 {
6010 _T("default"),
6011 _T("return empty"),
6012 _T("return all empty"),
6013 _T("with delims"),
6014 _T("like strtok"),
6015 };
6016
bbf8fc53
VZ
6017 static const struct StringTokenizerTest
6018 {
7c968cee
VZ
6019 const wxChar *str; // string to tokenize
6020 const wxChar *delims; // delimiters to use
6021 size_t count; // count of token
6022 wxStringTokenizerMode mode; // how should we tokenize it
6023 } tokenizerTestData[] =
6024 {
6025 { _T(""), _T(" "), 0 },
6026 { _T("Hello, world"), _T(" "), 2 },
6027 { _T("Hello, world "), _T(" "), 2 },
6028 { _T("Hello, world"), _T(","), 2 },
6029 { _T("Hello, world!"), _T(",!"), 2 },
6030 { _T("Hello,, world!"), _T(",!"), 3 },
6031 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
6032 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
6033 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
6034 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
6035 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
6036 { _T("01/02/99"), _T("/-"), 3 },
6037 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
bbf8fc53
VZ
6038 };
6039
6040 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
6041 {
6042 const StringTokenizerTest& tt = tokenizerTestData[n];
7c968cee 6043 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
bbf8fc53
VZ
6044
6045 size_t count = tkz.CountTokens();
456ae26d 6046 wxPrintf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
7c968cee 6047 MakePrintable(tt.str).c_str(),
bbf8fc53 6048 count,
7c968cee
VZ
6049 MakePrintable(tt.delims).c_str(),
6050 modeNames[tkz.GetMode()]);
bbf8fc53
VZ
6051 if ( count == tt.count )
6052 {
456ae26d 6053 wxPuts(_T("(ok)"));
bbf8fc53
VZ
6054 }
6055 else
6056 {
456ae26d 6057 wxPrintf(_T("(ERROR: should be %u)\n"), tt.count);
bbf8fc53
VZ
6058
6059 continue;
6060 }
6061
7c968cee 6062 // if we emulate strtok(), check that we do it correctly
f6bcfd97 6063 wxChar *buf, *s = NULL, *last;
7c968cee
VZ
6064
6065 if ( tkz.GetMode() == wxTOKEN_STRTOK )
6066 {
6067 buf = new wxChar[wxStrlen(tt.str) + 1];
6068 wxStrcpy(buf, tt.str);
6069
6070 s = wxStrtok(buf, tt.delims, &last);
6071 }
6072 else
6073 {
6074 buf = NULL;
6075 }
6076
bbf8fc53
VZ
6077 // now show the tokens themselves
6078 size_t count2 = 0;
6079 while ( tkz.HasMoreTokens() )
6080 {
7c968cee
VZ
6081 wxString token = tkz.GetNextToken();
6082
456ae26d 6083 wxPrintf(_T("\ttoken %u: '%s'"),
bbf8fc53 6084 ++count2,
7c968cee
VZ
6085 MakePrintable(token).c_str());
6086
6087 if ( buf )
6088 {
6089 if ( token == s )
6090 {
456ae26d 6091 wxPuts(_T(" (ok)"));
7c968cee
VZ
6092 }
6093 else
6094 {
456ae26d 6095 wxPrintf(_T(" (ERROR: should be %s)\n"), s);
7c968cee
VZ
6096 }
6097
6098 s = wxStrtok(NULL, tt.delims, &last);
6099 }
6100 else
6101 {
6102 // nothing to compare with
456ae26d 6103 wxPuts(_T(""));
7c968cee 6104 }
bbf8fc53
VZ
6105 }
6106
6107 if ( count2 != count )
6108 {
456ae26d 6109 wxPuts(_T("\tERROR: token count mismatch"));
bbf8fc53 6110 }
7c968cee
VZ
6111
6112 delete [] buf;
bbf8fc53
VZ
6113 }
6114
456ae26d 6115 wxPuts(_T(""));
bbf8fc53
VZ
6116}
6117
f6bcfd97
BP
6118static void TestStringReplace()
6119{
456ae26d 6120 wxPuts(_T("*** Testing wxString::replace ***"));
f6bcfd97
BP
6121
6122 static const struct StringReplaceTestData
6123 {
6124 const wxChar *original; // original test string
6125 size_t start, len; // the part to replace
6126 const wxChar *replacement; // the replacement string
6127 const wxChar *result; // and the expected result
6128 } stringReplaceTestData[] =
6129 {
6130 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
6131 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
6132 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
6133 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
6134 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
6135 };
6136
6137 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
6138 {
6139 const StringReplaceTestData data = stringReplaceTestData[n];
6140
6141 wxString original = data.original;
6142 original.replace(data.start, data.len, data.replacement);
6143
6144 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
6145 data.original, data.start, data.len, data.replacement,
6146 original.c_str());
6147
6148 if ( original == data.result )
6149 {
456ae26d 6150 wxPuts(_T("(ok)"));
f6bcfd97
BP
6151 }
6152 else
6153 {
6154 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
6155 }
6156 }
6157
456ae26d 6158 wxPuts(_T(""));
f6bcfd97
BP
6159}
6160
9a4232dc
VZ
6161static void TestStringMatch()
6162{
6163 wxPuts(_T("*** Testing wxString::Matches() ***"));
6164
6165 static const struct StringMatchTestData
6166 {
6167 const wxChar *text;
6168 const wxChar *wildcard;
6169 bool matches;
6170 } stringMatchTestData[] =
6171 {
6172 { _T("foobar"), _T("foo*"), 1 },
6173 { _T("foobar"), _T("*oo*"), 1 },
6174 { _T("foobar"), _T("*bar"), 1 },
6175 { _T("foobar"), _T("??????"), 1 },
6176 { _T("foobar"), _T("f??b*"), 1 },
6177 { _T("foobar"), _T("f?b*"), 0 },
6178 { _T("foobar"), _T("*goo*"), 0 },
6179 { _T("foobar"), _T("*foo"), 0 },
6180 { _T("foobarfoo"), _T("*foo"), 1 },
6181 { _T(""), _T("*"), 1 },
6182 { _T(""), _T("?"), 0 },
6183 };
6184
6185 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
6186 {
6187 const StringMatchTestData& data = stringMatchTestData[n];
6188 bool matches = wxString(data.text).Matches(data.wildcard);
6189 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
6190 data.wildcard,
6191 matches ? _T("matches") : _T("doesn't match"),
6192 data.text,
6193 matches == data.matches ? _T("ok") : _T("ERROR"));
6194 }
6195
6196 wxPuts(_T(""));
6197}
6198
9fc3ad34
VZ
6199#endif // TEST_STRINGS
6200
e87271f3
VZ
6201// ----------------------------------------------------------------------------
6202// entry point
6203// ----------------------------------------------------------------------------
6204
daa2c7d9
VZ
6205#ifdef TEST_SNGLINST
6206 #include "wx/snglinst.h"
6207#endif // TEST_SNGLINST
6208
bbfa0322 6209int main(int argc, char **argv)
37667812 6210{
9cb47ea2
VZ
6211 wxApp::CheckBuildOptions(wxBuildOptions());
6212
58b24a56
VZ
6213 wxInitializer initializer;
6214 if ( !initializer )
37667812
VZ
6215 {
6216 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
6217
6218 return -1;
6219 }
6220
6221#ifdef TEST_SNGLINST
b5299791
VZ
6222 wxSingleInstanceChecker checker;
6223 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 6224 {
b5299791
VZ
6225 if ( checker.IsAnotherRunning() )
6226 {
6227 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 6228
b5299791
VZ
6229 return 1;
6230 }
37667812 6231
b5299791
VZ
6232 // wait some time to give time to launch another instance
6233 wxPrintf(_T("Press \"Enter\" to continue..."));
6234 wxFgetc(stdin);
6235 }
6236 else // failed to create
6237 {
6238 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
6239 }
58b24a56
VZ
6240#endif // TEST_SNGLINST
6241
551fe3a6
VZ
6242#ifdef TEST_CHARSET
6243 TestCharset();
6244#endif // TEST_CHARSET
0de868d9 6245
d34bce84 6246#ifdef TEST_CMDLINE
31f6de22
VZ
6247 TestCmdLineConvert();
6248
6249#if wxUSE_CMDLINE_PARSER
d34bce84
VZ
6250 static const wxCmdLineEntryDesc cmdLineDesc[] =
6251 {
456ae26d 6252 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
31a06b07 6253 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
456ae26d
VZ
6254 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
6255 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },
d34bce84 6256
456ae26d
VZ
6257 { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },
6258 { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },
6259 { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),
31a06b07 6260 wxCMD_LINE_VAL_NUMBER },
456ae26d 6261 { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),
31a06b07 6262 wxCMD_LINE_VAL_DATE },
d34bce84 6263
456ae26d 6264 { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),
d34bce84
VZ
6265 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
6266
6267 { wxCMD_LINE_NONE }
6268 };
6269
456ae26d
VZ
6270#if wxUSE_UNICODE
6271 wxChar **wargv = new wxChar *[argc + 1];
6272
6273 {
6274 for ( int n = 0; n < argc; n++ )
6275 {
6276 wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
6277 wargv[n] = wxStrdup(warg);
6278 }
6279
6280 wargv[n] = NULL;
6281 }
6282
6283 #define argv wargv
6284#endif // wxUSE_UNICODE
6285
d34bce84
VZ
6286 wxCmdLineParser parser(cmdLineDesc, argc, argv);
6287
456ae26d
VZ
6288#if wxUSE_UNICODE
6289 {
6290 for ( int n = 0; n < argc; n++ )
6291 free(wargv[n]);
6292
6293 delete [] wargv;
6294 }
6295#endif // wxUSE_UNICODE
6296
6297 parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
f6bcfd97
BP
6298 wxCMD_LINE_VAL_STRING,
6299 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
6300
d34bce84
VZ
6301 switch ( parser.Parse() )
6302 {
6303 case -1:
456ae26d 6304 wxLogMessage(_T("Help was given, terminating."));
d34bce84
VZ
6305 break;
6306
6307 case 0:
6308 ShowCmdLine(parser);
6309 break;
6310
6311 default:
456ae26d 6312 wxLogMessage(_T("Syntax error detected, aborting."));
d34bce84
VZ
6313 break;
6314 }
31f6de22
VZ
6315#endif // wxUSE_CMDLINE_PARSER
6316
d34bce84
VZ
6317#endif // TEST_CMDLINE
6318
9fc3ad34 6319#ifdef TEST_STRINGS
daa2c7d9 6320 if ( TEST_ALL )
299fcbfe
VZ
6321 {
6322 TestPChar();
6323 TestString();
f6bcfd97 6324 TestStringSub();
7c968cee 6325 TestStringConstruction();
d71fa6fb 6326 TestStringFormat();
bbf8fc53 6327 TestStringFind();
7c968cee 6328 TestStringTokenizer();
f6bcfd97 6329 TestStringReplace();
ee6e1b1d 6330 }
daa2c7d9
VZ
6331 else
6332 {
6333 TestStringMatch();
6334 }
9fc3ad34
VZ
6335#endif // TEST_STRINGS
6336
e87271f3 6337#ifdef TEST_ARRAYS
daa2c7d9 6338 if ( TEST_ALL )
d6c9c1b7 6339 {
daa2c7d9 6340 wxArrayString a1;
456ae26d
VZ
6341 a1.Add(_T("tiger"));
6342 a1.Add(_T("cat"));
6343 a1.Add(_T("lion"), 3);
6344 a1.Add(_T("dog"));
6345 a1.Add(_T("human"));
6346 a1.Add(_T("ape"));
e87271f3 6347
456ae26d 6348 wxPuts(_T("*** Initially:"));
e87271f3 6349
456ae26d 6350 PrintArray(_T("a1"), a1);
e87271f3 6351
daa2c7d9 6352 wxArrayString a2(a1);
456ae26d 6353 PrintArray(_T("a2"), a2);
e87271f3 6354
daa2c7d9 6355 wxSortedArrayString a3(a1);
456ae26d 6356 PrintArray(_T("a3"), a3);
e87271f3 6357
456ae26d 6358 wxPuts(_T("*** After deleting three strings from a1"));
f74a90b3 6359 a1.Remove(2,3);
e87271f3 6360
456ae26d
VZ
6361 PrintArray(_T("a1"), a1);
6362 PrintArray(_T("a2"), a2);
6363 PrintArray(_T("a3"), a3);
e87271f3 6364
456ae26d 6365 wxPuts(_T("*** After reassigning a1 to a2 and a3"));
daa2c7d9 6366 a3 = a2 = a1;
456ae26d
VZ
6367 PrintArray(_T("a2"), a2);
6368 PrintArray(_T("a3"), a3);
f6bcfd97 6369
456ae26d 6370 wxPuts(_T("*** After sorting a1"));
daa2c7d9 6371 a1.Sort();
456ae26d 6372 PrintArray(_T("a1"), a1);
f6bcfd97 6373
456ae26d 6374 wxPuts(_T("*** After sorting a1 in reverse order"));
cab8f76e 6375 a1.Sort(true);
456ae26d 6376 PrintArray(_T("a1"), a1);
f6bcfd97 6377
456ae26d 6378 wxPuts(_T("*** After sorting a1 by the string length"));
daa2c7d9 6379 a1.Sort(StringLenCompare);
456ae26d 6380 PrintArray(_T("a1"), a1);
f6bcfd97 6381
daa2c7d9 6382 TestArrayOfObjects();
3dc01741 6383 TestArrayOfUShorts();
daa2c7d9 6384 }
1a931653
VZ
6385
6386 TestArrayOfInts();
e87271f3
VZ
6387#endif // TEST_ARRAYS
6388
1944c6bd 6389#ifdef TEST_DIR
daa2c7d9
VZ
6390 if ( TEST_ALL )
6391 {
99a5af7f 6392 TestDirExists();
2f0c19d0 6393 TestDirEnum();
daa2c7d9 6394 }
2f0c19d0 6395 TestDirTraverse();
1944c6bd
VZ
6396#endif // TEST_DIR
6397
f6bcfd97
BP
6398#ifdef TEST_DLLLOADER
6399 TestDllLoad();
6400#endif // TEST_DLLLOADER
6401
8fd0d89b
VZ
6402#ifdef TEST_ENVIRON
6403 TestEnvironment();
6404#endif // TEST_ENVIRON
6405
d93c719a
VZ
6406#ifdef TEST_EXECUTE
6407 TestExecute();
6408#endif // TEST_EXECUTE
6409
ee6e1b1d
VZ
6410#ifdef TEST_FILECONF
6411 TestFileConfRead();
6412#endif // TEST_FILECONF
6413
f6bcfd97
BP
6414#ifdef TEST_LIST
6415 TestListCtor();
6416#endif // TEST_LIST
6417
ec37df57
VZ
6418#ifdef TEST_LOCALE
6419 TestDefaultLang();
6420#endif // TEST_LOCALE
6421
378b05f7 6422#ifdef TEST_LOG
cab8f76e
VZ
6423 wxPuts(_T("*** Testing wxLog ***"));
6424
378b05f7
VZ
6425 wxString s;
6426 for ( size_t n = 0; n < 8000; n++ )
6427 {
456ae26d 6428 s << (wxChar)(_T('A') + (n % 26));
378b05f7
VZ
6429 }
6430
cab8f76e
VZ
6431 wxLogWarning(_T("The length of the string is %lu"),
6432 (unsigned long)s.length());
6433
378b05f7 6434 wxString msg;
456ae26d 6435 msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
378b05f7
VZ
6436
6437 // this one shouldn't be truncated
456ae26d 6438 wxPrintf(msg);
378b05f7
VZ
6439
6440 // but this one will because log functions use fixed size buffer
b568d04f
VZ
6441 // (note that it doesn't need '\n' at the end neither - will be added
6442 // by wxLog anyhow)
456ae26d 6443 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
378b05f7
VZ
6444#endif // TEST_LOG
6445
f6bcfd97 6446#ifdef TEST_FILE
daa2c7d9 6447 if ( TEST_ALL )
a339970a 6448 {
3ca6a5f0 6449 TestFileRead();
a339970a 6450 TestTextFileRead();
daa2c7d9 6451 TestFileCopy();
a339970a 6452 }
f6bcfd97
BP
6453#endif // TEST_FILE
6454
844f90fb 6455#ifdef TEST_FILENAME
6307da56 6456 if ( 0 )
81f25632
VZ
6457 {
6458 wxFileName fn;
456ae26d
VZ
6459 fn.Assign(_T("c:\\foo"), _T("bar.baz"));
6460 fn.Assign(_T("/u/os9-port/Viewer/tvision/WEI2HZ-3B3-14_05-04-00MSC1.asc"));
81f25632
VZ
6461
6462 DumpFileName(fn);
6463 }
6464
6307da56 6465 TestFileNameConstruction();
a5b7374f 6466 if ( TEST_ALL )
9e8d8607 6467 {
daa2c7d9
VZ
6468 TestFileNameConstruction();
6469 TestFileNameMakeRelative();
e7266247 6470 TestFileNameMakeAbsolute();
daa2c7d9
VZ
6471 TestFileNameSplit();
6472 TestFileNameTemp();
9e8d8607
VZ
6473 TestFileNameCwd();
6474 TestFileNameComparison();
6475 TestFileNameOperations();
6476 }
844f90fb
VZ
6477#endif // TEST_FILENAME
6478
d56e2b97
VZ
6479#ifdef TEST_FILETIME
6480 TestFileGetTimes();
9cb47ea2 6481 if ( 0 )
d56e2b97
VZ
6482 TestFileSetTimes();
6483#endif // TEST_FILETIME
6484
07a56e45
VZ
6485#ifdef TEST_FTP
6486 wxLog::AddTraceMask(FTP_TRACE_MASK);
6487 if ( TestFtpConnect() )
6488 {
daa2c7d9 6489 if ( TEST_ALL )
07a56e45
VZ
6490 {
6491 TestFtpList();
6492 TestFtpDownload();
6493 TestFtpMisc();
daa2c7d9 6494 TestFtpFileSize();
07a56e45
VZ
6495 TestFtpUpload();
6496 }
daa2c7d9
VZ
6497
6498 if ( TEST_INTERACTIVE )
6499 TestFtpInteractive();
07a56e45
VZ
6500 }
6501 //else: connecting to the FTP server failed
6502
6503 if ( 0 )
6504 TestFtpWuFtpd();
6505#endif // TEST_FTP
6506
b76b015e 6507#ifdef TEST_LONGLONG
2a310492
VZ
6508 // seed pseudo random generator
6509 srand((unsigned)time(NULL));
6510
b76b015e 6511 if ( 0 )
2a310492 6512 {
b76b015e 6513 TestSpeed();
2a310492 6514 }
daa2c7d9
VZ
6515
6516 if ( TEST_ALL )
2a310492 6517 {
f6bcfd97 6518 TestMultiplication();
b76b015e 6519 TestDivision();
2a310492
VZ
6520 TestAddition();
6521 TestLongLongConversion();
6522 TestBitOperations();
3a994742 6523 TestLongLongComparison();
2b5f62a0
VZ
6524 TestLongLongToString();
6525 TestLongLongPrintf();
2a310492 6526 }
b76b015e
VZ
6527#endif // TEST_LONGLONG
6528
2c8e4738
VZ
6529#ifdef TEST_HASH
6530 TestHash();
6531#endif // TEST_HASH
6532
0508ba2a
MB
6533#ifdef TEST_HASHMAP
6534 TestHashMap();
6535#endif // TEST_HASHMAP
6536
696e1ea0 6537#ifdef TEST_MIME
f6bcfd97 6538 wxLog::AddTraceMask(_T("mime"));
8d5eff60 6539 if ( TEST_ALL )
c7ce8392 6540 {
f6bcfd97 6541 TestMimeEnum();
c7ce8392 6542 TestMimeOverride();
f06ef5f4 6543 TestMimeAssociate();
c7ce8392 6544 }
f06ef5f4 6545 TestMimeFilename();
696e1ea0
VZ
6546#endif // TEST_MIME
6547
89e60357 6548#ifdef TEST_INFO_FUNCTIONS
daa2c7d9 6549 if ( TEST_ALL )
3a994742
VZ
6550 {
6551 TestOsInfo();
6552 TestUserInfo();
19f45995
VZ
6553
6554 if ( TEST_INTERACTIVE )
6555 TestDiskInfo();
3a994742 6556 }
89e60357
VZ
6557#endif // TEST_INFO_FUNCTIONS
6558
39189b9d
VZ
6559#ifdef TEST_PATHLIST
6560 TestPathList();
6561#endif // TEST_PATHLIST
6562
8d5eff60
VZ
6563#ifdef TEST_ODBC
6564 TestDbOpen();
6565#endif // TEST_ODBC
6566
7aeebdcd
VZ
6567#ifdef TEST_PRINTF
6568 TestPrintf();
6569#endif // TEST_PRINTF
6570
7ba4fbeb
VZ
6571#ifdef TEST_REGCONF
6572 TestRegConfWrite();
6573#endif // TEST_REGCONF
6574
07a56e45
VZ
6575#ifdef TEST_REGEX
6576 // TODO: write a real test using src/regex/tests file
daa2c7d9 6577 if ( TEST_ALL )
07a56e45
VZ
6578 {
6579 TestRegExCompile();
6580 TestRegExMatch();
6581 TestRegExSubmatch();
daa2c7d9
VZ
6582 TestRegExReplacement();
6583
6584 if ( TEST_INTERACTIVE )
6585 TestRegExInteractive();
07a56e45 6586 }
07a56e45
VZ
6587#endif // TEST_REGEX
6588
6dfec4b8 6589#ifdef TEST_REGISTRY
daa2c7d9 6590 TestRegistryRead();
6ba63600 6591 TestRegistryAssociation();
6dfec4b8
VZ
6592#endif // TEST_REGISTRY
6593
2c8e4738 6594#ifdef TEST_SOCKETS
daa2c7d9
VZ
6595 TestSocketServer();
6596 TestSocketClient();
2c8e4738
VZ
6597#endif // TEST_SOCKETS
6598
83141d3a 6599#ifdef TEST_STREAMS
99a5af7f
VZ
6600 if ( TEST_ALL )
6601 {
6602 TestFileStream();
6603 }
6604 TestMemoryStream();
83141d3a
VZ
6605#endif // TEST_STREAMS
6606
39937656
VZ
6607#ifdef TEST_TEXTSTREAM
6608 TestTextInputStream();
6609#endif // TEST_TEXTSTREAM
6610
8d5eff60
VZ
6611#ifdef TEST_THREADS
6612 int nCPUs = wxThread::GetCPUCount();
456ae26d 6613 wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
8d5eff60
VZ
6614 if ( nCPUs != -1 )
6615 wxThread::SetConcurrency(nCPUs);
6616
7aeebdcd 6617 TestDetachedThreads();
8d5eff60
VZ
6618 if ( TEST_ALL )
6619 {
8d5eff60
VZ
6620 TestJoinableThreads();
6621 TestThreadSuspend();
6622 TestThreadDelete();
c112e100
VZ
6623 TestThreadConditions();
6624 TestThreadExec();
7aeebdcd 6625 TestSemaphore();
8d5eff60 6626 }
8d5eff60
VZ
6627#endif // TEST_THREADS
6628
d31b7b68
VZ
6629#ifdef TEST_TIMER
6630 TestStopWatch();
6631#endif // TEST_TIMER
6632
6633#ifdef TEST_DATETIME
daa2c7d9 6634 if ( TEST_ALL )
299fcbfe 6635 {
9d9b7755
VZ
6636 TestTimeSet();
6637 TestTimeStatic();
6638 TestTimeRange();
6639 TestTimeZones();
6640 TestTimeTicks();
6641 TestTimeJDN();
6642 TestTimeDST();
6643 TestTimeWDays();
6644 TestTimeWNumber();
6645 TestTimeParse();
9d9b7755 6646 TestTimeArithmetics();
f6bcfd97
BP
6647 TestTimeHolidays();
6648 TestTimeFormat();
daa2c7d9 6649 TestTimeSpanFormat();
3ca6a5f0 6650 TestTimeMS();
f6bcfd97
BP
6651
6652 TestTimeZoneBug();
41acf5c0 6653 }
2b5f62a0
VZ
6654
6655 TestTimeWNumber();
daa2c7d9
VZ
6656
6657 if ( TEST_INTERACTIVE )
b92fd37c 6658 TestDateTimeInteractive();
d31b7b68 6659#endif // TEST_DATETIME
b76b015e 6660
551fe3a6 6661#ifdef TEST_USLEEP
456ae26d 6662 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
551fe3a6
VZ
6663 wxUsleep(3000);
6664#endif // TEST_USLEEP
6665
f6bcfd97 6666#ifdef TEST_VCARD
f6bcfd97
BP
6667 TestVCardRead();
6668 TestVCardWrite();
6669#endif // TEST_VCARD
6670
0e2c5534
VZ
6671#ifdef TEST_VOLUME
6672 TestFSVolume();
6673#endif // TEST_VOLUME
6674
e7d41190
VZ
6675#ifdef TEST_UNICODE
6676 TestUnicodeToFromAscii();
6677#endif // TEST_UNICODE
6678
f6bcfd97
BP
6679#ifdef TEST_WCHAR
6680 TestUtf8();
ac511156 6681 TestEncodingConverter();
f6bcfd97
BP
6682#endif // TEST_WCHAR
6683
6684#ifdef TEST_ZIP
daa2c7d9 6685 TestZipStreamRead();
2ca8b884 6686 TestZipFileSystem();
f6bcfd97
BP
6687#endif // TEST_ZIP
6688
3ca6a5f0 6689#ifdef TEST_ZLIB
3ca6a5f0
BP
6690 TestZlibStreamWrite();
6691 TestZlibStreamRead();
6692#endif // TEST_ZLIB
6693
37667812
VZ
6694 return 0;
6695}
f6bcfd97 6696