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