]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
wxConvGdk is not used anymore
[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
c66cca2a 98 #define TEST_LOG
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
c66cca2a
VZ
2988// ----------------------------------------------------------------------------
2989// scope guard
2990// ----------------------------------------------------------------------------
2991
2992#include "wx/scopeguard.h"
2993
2994static void function0() { puts("function0()"); }
2995static void function1(int n) { printf("function1(%d)\n", n); }
2996static void function2(double x, char c) { printf("function2(%g, %c)\n", x, c); }
2997
2998struct Object
2999{
3000 void method0() { printf("method0()\n"); }
3001 void method1(int n) { printf("method1(%d)\n", n); }
3002 void method2(double x, char c) { printf("method2(%g, %c)\n", x, c); }
3003};
3004
3005static void TestScopeGuard()
3006{
3007 ON_BLOCK_EXIT0(function0);
3008 ON_BLOCK_EXIT1(function1, 17);
3009 ON_BLOCK_EXIT2(function2, 3.14, 'p');
3010
3011 Object obj;
3012 ON_BLOCK_EXIT_OBJ0(obj, Object::method0);
3013 ON_BLOCK_EXIT_OBJ1(obj, Object::method1, 7);
3014 ON_BLOCK_EXIT_OBJ2(obj, Object::method2, 2.71, 'e');
3015
3016 wxScopeGuard dismissed = wxMakeGuard(function0);
3017 dismissed.Dismiss();
3018}
3019
2c8e4738
VZ
3020// ----------------------------------------------------------------------------
3021// sockets
3022// ----------------------------------------------------------------------------
3023
3024#ifdef TEST_SOCKETS
3025
e84010cf
GD
3026#include "wx/socket.h"
3027#include "wx/protocol/protocol.h"
3028#include "wx/protocol/http.h"
8e907a13
VZ
3029
3030static void TestSocketServer()
3031{
456ae26d 3032 wxPuts(_T("*** Testing wxSocketServer ***\n"));
8e907a13 3033
ccdb23df
VZ
3034 static const int PORT = 3000;
3035
8e907a13 3036 wxIPV4address addr;
ccdb23df 3037 addr.Service(PORT);
8e907a13
VZ
3038
3039 wxSocketServer *server = new wxSocketServer(addr);
3040 if ( !server->Ok() )
3041 {
456ae26d 3042 wxPuts(_T("ERROR: failed to bind"));
ccdb23df
VZ
3043
3044 return;
8e907a13 3045 }
8dfea369 3046
cab8f76e
VZ
3047 bool quit = false;
3048 while ( !quit )
8dfea369 3049 {
456ae26d 3050 wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT);
8dfea369
VZ
3051
3052 wxSocketBase *socket = server->Accept();
3053 if ( !socket )
3054 {
456ae26d 3055 wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
8dfea369
VZ
3056 break;
3057 }
3058
456ae26d 3059 wxPuts(_T("Server: got a client."));
8dfea369 3060
ccdb23df
VZ
3061 server->SetTimeout(60); // 1 min
3062
cab8f76e
VZ
3063 bool close = false;
3064 while ( !close && socket->IsConnected() )
8dfea369 3065 {
ccdb23df 3066 wxString s;
456ae26d 3067 wxChar ch = _T('\0');
ccdb23df 3068 for ( ;; )
8dfea369 3069 {
ccdb23df
VZ
3070 if ( socket->Read(&ch, sizeof(ch)).Error() )
3071 {
3072 // don't log error if the client just close the connection
3073 if ( socket->IsConnected() )
3074 {
456ae26d 3075 wxPuts(_T("ERROR: in wxSocket::Read."));
ccdb23df 3076 }
8dfea369 3077
ccdb23df
VZ
3078 break;
3079 }
8dfea369 3080
ccdb23df
VZ
3081 if ( ch == '\r' )
3082 continue;
8dfea369 3083
ccdb23df
VZ
3084 if ( ch == '\n' )
3085 break;
8dfea369 3086
ccdb23df
VZ
3087 s += ch;
3088 }
8dfea369 3089
ccdb23df
VZ
3090 if ( ch != '\n' )
3091 {
3092 break;
3093 }
8dfea369 3094
456ae26d 3095 wxPrintf(_T("Server: got '%s'.\n"), s.c_str());
cab8f76e 3096 if ( s == _T("close") )
ccdb23df 3097 {
cab8f76e 3098 wxPuts(_T("Closing connection"));
8dfea369 3099
cab8f76e 3100 close = true;
ccdb23df 3101 }
cab8f76e
VZ
3102 else if ( s == _T("quit") )
3103 {
3104 close =
3105 quit = true;
ccdb23df 3106
cab8f76e
VZ
3107 wxPuts(_T("Shutting down the server"));
3108 }
3109 else // not a special command
3110 {
3111 socket->Write(s.MakeUpper().c_str(), s.length());
3112 socket->Write("\r\n", 2);
3113 wxPrintf(_T("Server: wrote '%s'.\n"), s.c_str());
3114 }
8dfea369
VZ
3115 }
3116
cab8f76e
VZ
3117 if ( !close )
3118 {
3119 wxPuts(_T("Server: lost a client unexpectedly."));
3120 }
8dfea369 3121
ccdb23df 3122 socket->Destroy();
8dfea369 3123 }
9fc3cba7 3124
ccdb23df
VZ
3125 // same as "delete server" but is consistent with GUI programs
3126 server->Destroy();
8e907a13 3127}
2c8e4738
VZ
3128
3129static void TestSocketClient()
3130{
456ae26d 3131 wxPuts(_T("*** Testing wxSocketClient ***\n"));
2c8e4738 3132
456ae26d 3133 static const wxChar *hostname = _T("www.wxwindows.org");
8e907a13
VZ
3134
3135 wxIPV4address addr;
3136 addr.Hostname(hostname);
3137 addr.Service(80);
3138
456ae26d 3139 wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname);
2c8e4738
VZ
3140
3141 wxSocketClient client;
8e907a13 3142 if ( !client.Connect(addr) )
2c8e4738 3143 {
456ae26d 3144 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2c8e4738
VZ
3145 }
3146 else
3147 {
456ae26d 3148 wxPrintf(_T("--- Connected to %s:%u...\n"),
8e907a13
VZ
3149 addr.Hostname().c_str(), addr.Service());
3150
456ae26d 3151 wxChar buf[8192];
2c8e4738 3152
8e907a13
VZ
3153 // could use simply "GET" here I suppose
3154 wxString cmdGet =
456ae26d 3155 wxString::Format(_T("GET http://%s/\r\n"), hostname);
8e907a13 3156 client.Write(cmdGet, cmdGet.length());
456ae26d 3157 wxPrintf(_T("--- Sent command '%s' to the server\n"),
8e907a13 3158 MakePrintable(cmdGet).c_str());
2c8e4738 3159 client.Read(buf, WXSIZEOF(buf));
456ae26d 3160 wxPrintf(_T("--- Server replied:\n%s"), buf);
8e907a13
VZ
3161 }
3162}
3163
2e907fab
VZ
3164#endif // TEST_SOCKETS
3165
b92fd37c
VZ
3166// ----------------------------------------------------------------------------
3167// FTP
3168// ----------------------------------------------------------------------------
3169
2e907fab
VZ
3170#ifdef TEST_FTP
3171
e84010cf 3172#include "wx/protocol/ftp.h"
2e907fab 3173
b92fd37c
VZ
3174static wxFTP ftp;
3175
3176#define FTP_ANONYMOUS
3177
3178#ifdef FTP_ANONYMOUS
456ae26d
VZ
3179 static const wxChar *directory = _T("/pub");
3180 static const wxChar *filename = _T("welcome.msg");
b92fd37c 3181#else
456ae26d
VZ
3182 static const wxChar *directory = _T("/etc");
3183 static const wxChar *filename = _T("issue");
b92fd37c
VZ
3184#endif
3185
3186static bool TestFtpConnect()
8e907a13 3187{
456ae26d 3188 wxPuts(_T("*** Testing FTP connect ***"));
8e907a13 3189
b92fd37c 3190#ifdef FTP_ANONYMOUS
456ae26d 3191 static const wxChar *hostname = _T("ftp.wxwindows.org");
b92fd37c 3192
456ae26d 3193 wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname);
b92fd37c 3194#else // !FTP_ANONYMOUS
456ae26d 3195 static const wxChar *hostname = "localhost";
b92fd37c 3196
456ae26d
VZ
3197 wxChar user[256];
3198 wxFgets(user, WXSIZEOF(user), stdin);
3199 user[wxStrlen(user) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3200 ftp.SetUser(user);
3201
456ae26d
VZ
3202 wxChar password[256];
3203 wxPrintf(_T("Password for %s: "), password);
3204 wxFgets(password, WXSIZEOF(password), stdin);
3205 password[wxStrlen(password) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3206 ftp.SetPassword(password);
3207
456ae26d 3208 wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname, user);
b92fd37c
VZ
3209#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
3210
3211 if ( !ftp.Connect(hostname) )
3212 {
456ae26d 3213 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b92fd37c 3214
cab8f76e 3215 return false;
b92fd37c
VZ
3216 }
3217 else
3218 {
456ae26d 3219 wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
b92fd37c
VZ
3220 hostname, ftp.Pwd().c_str());
3221 }
3222
cab8f76e 3223 return true;
b92fd37c 3224}
b1229561 3225
b92fd37c
VZ
3226// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
3227static void TestFtpWuFtpd()
3228{
3229 wxFTP ftp;
456ae26d 3230 static const wxChar *hostname = _T("ftp.eudora.com");
b1229561
VZ
3231 if ( !ftp.Connect(hostname) )
3232 {
456ae26d 3233 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b1229561
VZ
3234 }
3235 else
3236 {
456ae26d 3237 static const wxChar *filename = _T("eudora/pubs/draft-gellens-submit-09.txt");
b1229561
VZ
3238 wxInputStream *in = ftp.GetInputStream(filename);
3239 if ( !in )
3240 {
456ae26d 3241 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b1229561
VZ
3242 }
3243 else
3244 {
4c51b688 3245 size_t size = in->GetSize();
456ae26d 3246 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b1229561 3247
456ae26d 3248 wxChar *data = new wxChar[size];
b1229561
VZ
3249 if ( !in->Read(data, size) )
3250 {
456ae26d 3251 wxPuts(_T("ERROR: read error"));
b1229561
VZ
3252 }
3253 else
3254 {
456ae26d 3255 wxPrintf(_T("Successfully retrieved the file.\n"));
b1229561
VZ
3256 }
3257
3258 delete [] data;
3259 delete in;
3260 }
3261 }
b92fd37c 3262}
b1229561 3263
b92fd37c
VZ
3264static void TestFtpList()
3265{
456ae26d 3266 wxPuts(_T("*** Testing wxFTP file listing ***\n"));
8e907a13 3267
b92fd37c
VZ
3268 // test CWD
3269 if ( !ftp.ChDir(directory) )
3270 {
456ae26d 3271 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c 3272 }
2e907fab 3273
456ae26d 3274 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2e907fab 3275
b92fd37c
VZ
3276 // test NLIST and LIST
3277 wxArrayString files;
3278 if ( !ftp.GetFilesList(files) )
8e907a13 3279 {
456ae26d 3280 wxPuts(_T("ERROR: failed to get NLIST of files"));
8e907a13
VZ
3281 }
3282 else
3283 {
456ae26d 3284 wxPrintf(_T("Brief list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3285 size_t count = files.GetCount();
3286 for ( size_t n = 0; n < count; n++ )
8e907a13 3287 {
456ae26d 3288 wxPrintf(_T("\t%s\n"), files[n].c_str());
8e907a13 3289 }
456ae26d 3290 wxPuts(_T("End of the file list"));
b92fd37c 3291 }
8e907a13 3292
b92fd37c
VZ
3293 if ( !ftp.GetDirList(files) )
3294 {
456ae26d 3295 wxPuts(_T("ERROR: failed to get LIST of files"));
b92fd37c
VZ
3296 }
3297 else
3298 {
456ae26d 3299 wxPrintf(_T("Detailed list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3300 size_t count = files.GetCount();
3301 for ( size_t n = 0; n < count; n++ )
8e907a13 3302 {
456ae26d 3303 wxPrintf(_T("\t%s\n"), files[n].c_str());
2e907fab 3304 }
456ae26d 3305 wxPuts(_T("End of the file list"));
b92fd37c
VZ
3306 }
3307
3308 if ( !ftp.ChDir(_T("..")) )
3309 {
456ae26d 3310 wxPuts(_T("ERROR: failed to cd to .."));
b92fd37c 3311 }
2e907fab 3312
456ae26d 3313 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3314}
3315
3316static void TestFtpDownload()
3317{
456ae26d 3318 wxPuts(_T("*** Testing wxFTP download ***\n"));
b92fd37c
VZ
3319
3320 // test RETR
3321 wxInputStream *in = ftp.GetInputStream(filename);
3322 if ( !in )
3323 {
456ae26d 3324 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b92fd37c
VZ
3325 }
3326 else
3327 {
4c51b688 3328 size_t size = in->GetSize();
456ae26d 3329 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b92fd37c
VZ
3330 fflush(stdout);
3331
456ae26d 3332 wxChar *data = new wxChar[size];
b92fd37c 3333 if ( !in->Read(data, size) )
2e907fab 3334 {
456ae26d 3335 wxPuts(_T("ERROR: read error"));
2e907fab
VZ
3336 }
3337 else
3338 {
456ae26d 3339 wxPrintf(_T("\nContents of %s:\n%s\n"), filename, data);
8e907a13
VZ
3340 }
3341
b92fd37c
VZ
3342 delete [] data;
3343 delete in;
3344 }
3345}
8e907a13 3346
b92fd37c
VZ
3347static void TestFtpFileSize()
3348{
456ae26d 3349 wxPuts(_T("*** Testing FTP SIZE command ***"));
b92fd37c
VZ
3350
3351 if ( !ftp.ChDir(directory) )
3352 {
456ae26d 3353 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c
VZ
3354 }
3355
456ae26d 3356 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3357
3358 if ( ftp.FileExists(filename) )
3359 {
3360 int size = ftp.GetFileSize(filename);
3361 if ( size == -1 )
456ae26d 3362 wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename);
8e907a13 3363 else
456ae26d 3364 wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename, size);
b92fd37c
VZ
3365 }
3366 else
3367 {
456ae26d 3368 wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename);
b92fd37c
VZ
3369 }
3370}
3371
3372static void TestFtpMisc()
3373{
456ae26d 3374 wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
b92fd37c
VZ
3375
3376 if ( ftp.SendCommand("STAT") != '2' )
3377 {
456ae26d 3378 wxPuts(_T("ERROR: STAT failed"));
b92fd37c
VZ
3379 }
3380 else
3381 {
456ae26d 3382 wxPrintf(_T("STAT returned:\n\n%s\n"), ftp.GetLastResult().c_str());
b92fd37c
VZ
3383 }
3384
3385 if ( ftp.SendCommand("HELP SITE") != '2' )
3386 {
456ae26d 3387 wxPuts(_T("ERROR: HELP SITE failed"));
b92fd37c
VZ
3388 }
3389 else
3390 {
456ae26d 3391 wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
b92fd37c
VZ
3392 ftp.GetLastResult().c_str());
3393 }
3394}
3395
3396static void TestFtpInteractive()
3397{
456ae26d 3398 wxPuts(_T("\n*** Interactive wxFTP test ***"));
b92fd37c 3399
456ae26d 3400 wxChar buf[128];
b92fd37c
VZ
3401
3402 for ( ;; )
3403 {
456ae26d
VZ
3404 wxPrintf(_T("Enter FTP command: "));
3405 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
b92fd37c
VZ
3406 break;
3407
3408 // kill the last '\n'
456ae26d 3409 buf[wxStrlen(buf) - 1] = 0;
b92fd37c
VZ
3410
3411 // special handling of LIST and NLST as they require data connection
3412 wxString start(buf, 4);
3413 start.MakeUpper();
3414 if ( start == "LIST" || start == "NLST" )
8e907a13 3415 {
b92fd37c 3416 wxString wildcard;
456ae26d 3417 if ( wxStrlen(buf) > 4 )
b92fd37c 3418 wildcard = buf + 5;
8e907a13 3419
b92fd37c
VZ
3420 wxArrayString files;
3421 if ( !ftp.GetList(files, wildcard, start == "LIST") )
8e907a13 3422 {
456ae26d 3423 wxPrintf(_T("ERROR: failed to get %s of files\n"), start.c_str());
8e907a13
VZ
3424 }
3425 else
3426 {
456ae26d 3427 wxPrintf(_T("--- %s of '%s' under '%s':\n"),
b92fd37c
VZ
3428 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
3429 size_t count = files.GetCount();
3430 for ( size_t n = 0; n < count; n++ )
3431 {
456ae26d 3432 wxPrintf(_T("\t%s\n"), files[n].c_str());
b92fd37c 3433 }
456ae26d 3434 wxPuts(_T("--- End of the file list"));
8e907a13 3435 }
2e907fab 3436 }
b92fd37c 3437 else // !list
2e907fab 3438 {
456ae26d
VZ
3439 wxChar ch = ftp.SendCommand(buf);
3440 wxPrintf(_T("Command %s"), ch ? _T("succeeded") : _T("failed"));
b92fd37c
VZ
3441 if ( ch )
3442 {
456ae26d 3443 wxPrintf(_T(" (return code %c)"), ch);
b92fd37c 3444 }
2e907fab 3445
456ae26d 3446 wxPrintf(_T(", server reply:\n%s\n\n"), ftp.GetLastResult().c_str());
2e907fab 3447 }
2c8e4738 3448 }
b92fd37c 3449
456ae26d 3450 wxPuts(_T("\n*** done ***"));
2c8e4738
VZ
3451}
3452
b92fd37c 3453static void TestFtpUpload()
f6bcfd97 3454{
456ae26d 3455 wxPuts(_T("*** Testing wxFTP uploading ***\n"));
f6bcfd97 3456
b92fd37c 3457 // upload a file
456ae26d
VZ
3458 static const wxChar *file1 = _T("test1");
3459 static const wxChar *file2 = _T("test2");
b92fd37c
VZ
3460 wxOutputStream *out = ftp.GetOutputStream(file1);
3461 if ( out )
3462 {
456ae26d 3463 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3464 out->Write("First hello", 11);
3465 delete out;
3466 }
f6bcfd97 3467
b92fd37c
VZ
3468 // send a command to check the remote file
3469 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
f6bcfd97 3470 {
456ae26d 3471 wxPrintf(_T("ERROR: STAT %s failed\n"), file1);
f6bcfd97
BP
3472 }
3473 else
3474 {
456ae26d 3475 wxPrintf(_T("STAT %s returned:\n\n%s\n"),
b92fd37c
VZ
3476 file1, ftp.GetLastResult().c_str());
3477 }
2e907fab 3478
b92fd37c
VZ
3479 out = ftp.GetOutputStream(file2);
3480 if ( out )
3481 {
456ae26d 3482 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3483 out->Write("Second hello", 12);
3484 delete out;
f6bcfd97
BP
3485 }
3486}
3487
2e907fab 3488#endif // TEST_FTP
2c8e4738 3489
83141d3a
VZ
3490// ----------------------------------------------------------------------------
3491// streams
3492// ----------------------------------------------------------------------------
3493
3494#ifdef TEST_STREAMS
3495
e84010cf
GD
3496#include "wx/wfstream.h"
3497#include "wx/mstream.h"
83141d3a 3498
24f25c8a
VZ
3499static void TestFileStream()
3500{
456ae26d 3501 wxPuts(_T("*** Testing wxFileInputStream ***"));
24f25c8a
VZ
3502
3503 static const wxChar *filename = _T("testdata.fs");
3504 {
3505 wxFileOutputStream fsOut(filename);
3506 fsOut.Write("foo", 3);
3507 }
3508
3509 wxFileInputStream fsIn(filename);
456ae26d 3510 wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
24f25c8a
VZ
3511 while ( !fsIn.Eof() )
3512 {
3513 putchar(fsIn.GetC());
3514 }
3515
3516 if ( !wxRemoveFile(filename) )
3517 {
456ae26d 3518 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename);
24f25c8a
VZ
3519 }
3520
456ae26d 3521 wxPuts(_T("\n*** wxFileInputStream test done ***"));
24f25c8a
VZ
3522}
3523
83141d3a
VZ
3524static void TestMemoryStream()
3525{
99a5af7f
VZ
3526 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
3527
3528 wxMemoryOutputStream memOutStream;
3529 wxPrintf(_T("Initially out stream offset: %lu\n"),
3530 (unsigned long)memOutStream.TellO());
3531
3532 for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
3533 {
3534 memOutStream.PutC(*p);
3535 }
3536
3537 wxPrintf(_T("Final out stream offset: %lu\n"),
3538 (unsigned long)memOutStream.TellO());
3539
3540 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
83141d3a
VZ
3541
3542 wxChar buf[1024];
99a5af7f 3543 size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
83141d3a 3544
99a5af7f
VZ
3545 wxMemoryInputStream memInpStream(buf, len);
3546 wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
83141d3a
VZ
3547 while ( !memInpStream.Eof() )
3548 {
3549 putchar(memInpStream.GetC());
3550 }
3551
456ae26d 3552 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
83141d3a
VZ
3553}
3554
3555#endif // TEST_STREAMS
3556
d31b7b68
VZ
3557// ----------------------------------------------------------------------------
3558// timers
3559// ----------------------------------------------------------------------------
3560
3561#ifdef TEST_TIMER
3562
e84010cf
GD
3563#include "wx/timer.h"
3564#include "wx/utils.h"
d31b7b68
VZ
3565
3566static void TestStopWatch()
3567{
456ae26d 3568 wxPuts(_T("*** Testing wxStopWatch ***\n"));
d31b7b68
VZ
3569
3570 wxStopWatch sw;
677eff07 3571 sw.Pause();
456ae26d 3572 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
677eff07
VZ
3573 fflush(stdout);
3574 wxSleep(2);
456ae26d 3575 wxPrintf(_T("\t%ldms\n"), sw.Time());
677eff07 3576
456ae26d 3577 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
677eff07
VZ
3578 fflush(stdout);
3579 sw.Resume();
d31b7b68 3580 wxSleep(3);
456ae26d 3581 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3582
3583 sw.Pause();
456ae26d 3584 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
677eff07 3585 fflush(stdout);
d31b7b68 3586 wxSleep(2);
456ae26d 3587 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3588
3589 sw.Resume();
456ae26d 3590 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
677eff07
VZ
3591 fflush(stdout);
3592 wxSleep(2);
456ae26d 3593 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
87798c00
VZ
3594
3595 wxStopWatch sw2;
456ae26d 3596 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
87798c00
VZ
3597 for ( size_t n = 0; n < 70; n++ )
3598 {
3599 sw2.Start();
89e6463c
GRG
3600
3601 for ( size_t m = 0; m < 100000; m++ )
87798c00 3602 {
89e6463c
GRG
3603 if ( sw.Time() < 0 || sw2.Time() < 0 )
3604 {
456ae26d 3605 wxPuts(_T("\ntime is negative - ERROR!"));
89e6463c 3606 }
87798c00
VZ
3607 }
3608
3609 putchar('.');
677eff07 3610 fflush(stdout);
87798c00
VZ
3611 }
3612
456ae26d 3613 wxPuts(_T(", ok."));
d31b7b68
VZ
3614}
3615
3616#endif // TEST_TIMER
3617
f6bcfd97
BP
3618// ----------------------------------------------------------------------------
3619// vCard support
3620// ----------------------------------------------------------------------------
3621
3622#ifdef TEST_VCARD
3623
e84010cf 3624#include "wx/vcard.h"
f6bcfd97
BP
3625
3626static void DumpVObject(size_t level, const wxVCardObject& vcard)
3627{
3628 void *cookie;
3629 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3630 while ( vcObj )
3631 {
456ae26d 3632 wxPrintf(_T("%s%s"),
f6bcfd97
BP
3633 wxString(_T('\t'), level).c_str(),
3634 vcObj->GetName().c_str());
3635
3636 wxString value;
3637 switch ( vcObj->GetType() )
3638 {
3639 case wxVCardObject::String:
3640 case wxVCardObject::UString:
3641 {
3642 wxString val;
3643 vcObj->GetValue(&val);
3644 value << _T('"') << val << _T('"');
3645 }
3646 break;
3647
3648 case wxVCardObject::Int:
3649 {
3650 unsigned int i;
3651 vcObj->GetValue(&i);
3652 value.Printf(_T("%u"), i);
3653 }
3654 break;
3655
3656 case wxVCardObject::Long:
3657 {
3658 unsigned long l;
3659 vcObj->GetValue(&l);
3660 value.Printf(_T("%lu"), l);
3661 }
3662 break;
3663
3664 case wxVCardObject::None:
3665 break;
3666
3667 case wxVCardObject::Object:
3668 value = _T("<node>");
3669 break;
3670
3671 default:
3672 value = _T("<unknown value type>");
3673 }
3674
3675 if ( !!value )
456ae26d 3676 wxPrintf(_T(" = %s"), value.c_str());
f6bcfd97
BP
3677 putchar('\n');
3678
3679 DumpVObject(level + 1, *vcObj);
3680
3681 delete vcObj;
3682 vcObj = vcard.GetNextProp(&cookie);
3683 }
3684}
3685
3686static void DumpVCardAddresses(const wxVCard& vcard)
3687{
456ae26d 3688 wxPuts(_T("\nShowing all addresses from vCard:\n"));
f6bcfd97
BP
3689
3690 size_t nAdr = 0;
3691 void *cookie;
3692 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3693 while ( addr )
3694 {
3695 wxString flagsStr;
3696 int flags = addr->GetFlags();
3697 if ( flags & wxVCardAddress::Domestic )
3698 {
3699 flagsStr << _T("domestic ");
3700 }
3701 if ( flags & wxVCardAddress::Intl )
3702 {
3703 flagsStr << _T("international ");
3704 }
3705 if ( flags & wxVCardAddress::Postal )
3706 {
3707 flagsStr << _T("postal ");
3708 }
3709 if ( flags & wxVCardAddress::Parcel )
3710 {
3711 flagsStr << _T("parcel ");
3712 }
3713 if ( flags & wxVCardAddress::Home )
3714 {
3715 flagsStr << _T("home ");
3716 }
3717 if ( flags & wxVCardAddress::Work )
3718 {
3719 flagsStr << _T("work ");
3720 }
3721
456ae26d 3722 wxPrintf(_T("Address %u:\n")
f6bcfd97
BP
3723 "\tflags = %s\n"
3724 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3725 ++nAdr,
3726 flagsStr.c_str(),
3727 addr->GetPostOffice().c_str(),
3728 addr->GetExtAddress().c_str(),
3729 addr->GetStreet().c_str(),
3730 addr->GetLocality().c_str(),
3731 addr->GetRegion().c_str(),
3732 addr->GetPostalCode().c_str(),
3733 addr->GetCountry().c_str()
3734 );
3735
3736 delete addr;
3737 addr = vcard.GetNextAddress(&cookie);
3738 }
3739}
3740
3741static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3742{
456ae26d 3743 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
f6bcfd97
BP
3744
3745 size_t nPhone = 0;
3746 void *cookie;
3747 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3748 while ( phone )
3749 {
3750 wxString flagsStr;
3751 int flags = phone->GetFlags();
3752 if ( flags & wxVCardPhoneNumber::Voice )
3753 {
3754 flagsStr << _T("voice ");
3755 }
3756 if ( flags & wxVCardPhoneNumber::Fax )
3757 {
3758 flagsStr << _T("fax ");
3759 }
3760 if ( flags & wxVCardPhoneNumber::Cellular )
3761 {
3762 flagsStr << _T("cellular ");
3763 }
3764 if ( flags & wxVCardPhoneNumber::Modem )
3765 {
3766 flagsStr << _T("modem ");
3767 }
3768 if ( flags & wxVCardPhoneNumber::Home )
3769 {
3770 flagsStr << _T("home ");
3771 }
3772 if ( flags & wxVCardPhoneNumber::Work )
3773 {
3774 flagsStr << _T("work ");
3775 }
3776
456ae26d 3777 wxPrintf(_T("Phone number %u:\n")
f6bcfd97
BP
3778 "\tflags = %s\n"
3779 "\tvalue = %s\n",
3780 ++nPhone,
3781 flagsStr.c_str(),
3782 phone->GetNumber().c_str()
3783 );
3784
3785 delete phone;
3786 phone = vcard.GetNextPhoneNumber(&cookie);
3787 }
3788}
3789
3790static void TestVCardRead()
3791{
456ae26d 3792 wxPuts(_T("*** Testing wxVCard reading ***\n"));
f6bcfd97
BP
3793
3794 wxVCard vcard(_T("vcard.vcf"));
3795 if ( !vcard.IsOk() )
3796 {
456ae26d 3797 wxPuts(_T("ERROR: couldn't load vCard."));
f6bcfd97
BP
3798 }
3799 else
3800 {
3801 // read individual vCard properties
3802 wxVCardObject *vcObj = vcard.GetProperty("FN");
3803 wxString value;
3804 if ( vcObj )
3805 {
3806 vcObj->GetValue(&value);
3807 delete vcObj;
3808 }
3809 else
3810 {
3811 value = _T("<none>");
3812 }
3813
456ae26d 3814 wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
f6bcfd97
BP
3815
3816
3817 if ( !vcard.GetFullName(&value) )
3818 {
3819 value = _T("<none>");
3820 }
3821
456ae26d 3822 wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
f6bcfd97
BP
3823
3824 // now show how to deal with multiply occuring properties
3825 DumpVCardAddresses(vcard);
3826 DumpVCardPhoneNumbers(vcard);
3827
3828 // and finally show all
456ae26d 3829 wxPuts(_T("\nNow dumping the entire vCard:\n")
f6bcfd97
BP
3830 "-----------------------------\n");
3831
3832 DumpVObject(0, vcard);
3833 }
3834}
3835
3836static void TestVCardWrite()
3837{
456ae26d 3838 wxPuts(_T("*** Testing wxVCard writing ***\n"));
f6bcfd97
BP
3839
3840 wxVCard vcard;
3841 if ( !vcard.IsOk() )
3842 {
456ae26d 3843 wxPuts(_T("ERROR: couldn't create vCard."));
f6bcfd97
BP
3844 }
3845 else
3846 {
3847 // set some fields
3848 vcard.SetName("Zeitlin", "Vadim");
3849 vcard.SetFullName("Vadim Zeitlin");
3850 vcard.SetOrganization("wxWindows", "R&D");
3851
3852 // just dump the vCard back
456ae26d
VZ
3853 wxPuts(_T("Entire vCard follows:\n"));
3854 wxPuts(vcard.Write());
f6bcfd97
BP
3855 }
3856}
3857
3858#endif // TEST_VCARD
3859
0e2c5534
VZ
3860// ----------------------------------------------------------------------------
3861// wxVolume tests
3862// ----------------------------------------------------------------------------
3863
ba6ea19e 3864#if !defined(__WIN32__) || !wxUSE_FSVOLUME
0e2c5534
VZ
3865 #undef TEST_VOLUME
3866#endif
3867
3868#ifdef TEST_VOLUME
3869
3870#include "wx/volume.h"
3871
3872static const wxChar *volumeKinds[] =
3873{
3874 _T("floppy"),
3875 _T("hard disk"),
3876 _T("CD-ROM"),
3877 _T("DVD-ROM"),
3878 _T("network volume"),
3879 _T("other volume"),
3880};
3881
3882static void TestFSVolume()
3883{
3884 wxPuts(_T("*** Testing wxFSVolume class ***"));
3885
3886 wxArrayString volumes = wxFSVolume::GetVolumes();
3887 size_t count = volumes.GetCount();
3888
3889 if ( !count )
3890 {
3891 wxPuts(_T("ERROR: no mounted volumes?"));
3892 return;
3893 }
3894
3895 wxPrintf(_T("%u mounted volumes found:\n"), count);
3896
3897 for ( size_t n = 0; n < count; n++ )
3898 {
3899 wxFSVolume vol(volumes[n]);
3900 if ( !vol.IsOk() )
3901 {
3902 wxPuts(_T("ERROR: couldn't create volume"));
3903 continue;
3904 }
3905
3906 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3907 n + 1,
3908 vol.GetDisplayName().c_str(),
3909 vol.GetName().c_str(),
3910 volumeKinds[vol.GetKind()],
3911 vol.IsWritable() ? _T("rw") : _T("ro"),
3912 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3913 : _T("fixed"));
3914 }
3915}
3916
3917#endif // TEST_VOLUME
3918
f6bcfd97 3919// ----------------------------------------------------------------------------
e7d41190 3920// wide char and Unicode support
f6bcfd97
BP
3921// ----------------------------------------------------------------------------
3922
e7d41190
VZ
3923#ifdef TEST_UNICODE
3924
3925static void TestUnicodeToFromAscii()
3926{
3927 wxPuts(_T("Testing wxString::To/FromAscii()\n"));
3928
3929 static const char *msg = "Hello, world!";
3930 wxString s = wxString::FromAscii(msg);
3931
3932 wxPrintf(_T("Message in Unicode: %s\n"), s.c_str());
7aeebdcd 3933 printf("Message in ASCII: %s\n", (const char *)s.ToAscii());
e7d41190
VZ
3934
3935 wxPutchar(_T('\n'));
3936}
3937
3938#endif // TEST_UNICODE
3939
f6bcfd97
BP
3940#ifdef TEST_WCHAR
3941
e84010cf
GD
3942#include "wx/strconv.h"
3943#include "wx/fontenc.h"
3944#include "wx/encconv.h"
3945#include "wx/buffer.h"
f6bcfd97 3946
2b5f62a0 3947static const unsigned char utf8koi8r[] =
ac511156
VZ
3948{
3949 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3950 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3951 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3952 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3953 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3954 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3955 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3956};
3957
2b5f62a0
VZ
3958static const unsigned char utf8iso8859_1[] =
3959{
3960 0x53, 0x79, 0x73, 0x74, 0xc3, 0xa8, 0x6d, 0x65, 0x73, 0x20, 0x49, 0x6e,
3961 0x74, 0xc3, 0xa9, 0x67, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x65,
3962 0x6e, 0x20, 0x4d, 0xc3, 0xa9, 0x63, 0x61, 0x6e, 0x69, 0x71, 0x75, 0x65,
3963 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x71, 0x75, 0x65, 0x20, 0x65,
3964 0x74, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x71, 0x75, 0x65, 0
3965};
3966
3967static const unsigned char utf8Invalid[] =
3968{
3969 0x3c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3e, 0x32, 0x30, 0x30,
3970 0x32, 0xe5, 0xb9, 0xb4, 0x30, 0x39, 0xe6, 0x9c, 0x88, 0x32, 0x35, 0xe6,
3971 0x97, 0xa5, 0x20, 0x30, 0x37, 0xe6, 0x99, 0x82, 0x33, 0x39, 0xe5, 0x88,
3972 0x86, 0x35, 0x37, 0xe7, 0xa7, 0x92, 0x3c, 0x2f, 0x64, 0x69, 0x73, 0x70,
3973 0x6c, 0x61, 0x79, 0
3974};
3975
3976static const struct Utf8Data
3977{
3978 const unsigned char *text;
3979 size_t len;
3980 const wxChar *charset;
3981 wxFontEncoding encoding;
3982} utf8data[] =
3983{
3984 { utf8Invalid, WXSIZEOF(utf8Invalid), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3985 { utf8koi8r, WXSIZEOF(utf8koi8r), _T("koi8-r"), wxFONTENCODING_KOI8 },
3986 { utf8iso8859_1, WXSIZEOF(utf8iso8859_1), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3987};
456ae26d 3988
f6bcfd97
BP
3989static void TestUtf8()
3990{
456ae26d 3991 wxPuts(_T("*** Testing UTF8 support ***\n"));
f6bcfd97 3992
24f25c8a
VZ
3993 char buf[1024];
3994 wchar_t wbuf[1024];
2b5f62a0
VZ
3995
3996 for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
24f25c8a 3997 {
2b5f62a0
VZ
3998 const Utf8Data& u8d = utf8data[n];
3999 if ( wxConvUTF8.MB2WC(wbuf, (const char *)u8d.text,
4000 WXSIZEOF(wbuf)) == (size_t)-1 )
24f25c8a 4001 {
2b5f62a0 4002 wxPuts(_T("ERROR: UTF-8 decoding failed."));
24f25c8a
VZ
4003 }
4004 else
ac511156 4005 {
2b5f62a0
VZ
4006 wxCSConv conv(u8d.charset);
4007 if ( conv.WC2MB(buf, wbuf, WXSIZEOF(buf)) == (size_t)-1 )
4008 {
4009 wxPrintf(_T("ERROR: conversion to %s failed.\n"), u8d.charset);
4010 }
4011 else
4012 {
4013 wxPrintf(_T("String in %s: %s\n"), u8d.charset, buf);
4014 }
ac511156 4015 }
ac511156 4016
2b5f62a0
VZ
4017 wxString s(wxConvUTF8.cMB2WC((const char *)u8d.text), *wxConvCurrent);
4018 if ( s.empty() )
4019 s = _T("<< conversion failed >>");
4020 wxPrintf(_T("String in current cset: %s\n"), s.c_str());
4021
ac511156
VZ
4022 }
4023
456ae26d 4024 wxPuts(_T(""));
ac511156 4025}
f6bcfd97 4026
ac511156
VZ
4027static void TestEncodingConverter()
4028{
4029 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
4030
4031 // using wxEncodingConverter should give the same result as above
4032 char buf[1024];
4033 wchar_t wbuf[1024];
2b5f62a0
VZ
4034 if ( wxConvUTF8.MB2WC(wbuf, (const char *)utf8koi8r,
4035 WXSIZEOF(utf8koi8r)) == (size_t)-1 )
ac511156 4036 {
456ae26d 4037 wxPuts(_T("ERROR: UTF-8 decoding failed."));
ac511156
VZ
4038 }
4039 else
4040 {
4041 wxEncodingConverter ec;
4042 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
4043 ec.Convert(wbuf, buf);
2b5f62a0 4044 wxPrintf(_T("The same KOI8-R string using wxEC: %s\n"), buf);
24f25c8a 4045 }
ac511156 4046
456ae26d 4047 wxPuts(_T(""));
f6bcfd97
BP
4048}
4049
4050#endif // TEST_WCHAR
4051
4052// ----------------------------------------------------------------------------
4053// ZIP stream
4054// ----------------------------------------------------------------------------
4055
4056#ifdef TEST_ZIP
4057
2ca8b884
VZ
4058#include "wx/filesys.h"
4059#include "wx/fs_zip.h"
f6bcfd97
BP
4060#include "wx/zipstrm.h"
4061
2ca8b884
VZ
4062static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
4063
f6bcfd97
BP
4064static void TestZipStreamRead()
4065{
456ae26d 4066 wxPuts(_T("*** Testing ZIP reading ***\n"));
f6bcfd97 4067
2ca8b884
VZ
4068 static const wxChar *filename = _T("foo");
4069 wxZipInputStream istr(TESTFILE_ZIP, filename);
456ae26d 4070 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
f6bcfd97 4071
456ae26d 4072 wxPrintf(_T("Dumping the file '%s':\n"), filename);
f6bcfd97
BP
4073 while ( !istr.Eof() )
4074 {
4075 putchar(istr.GetC());
4076 fflush(stdout);
4077 }
4078
456ae26d 4079 wxPuts(_T("\n----- done ------"));
f6bcfd97
BP
4080}
4081
2ca8b884
VZ
4082static void DumpZipDirectory(wxFileSystem& fs,
4083 const wxString& dir,
4084 const wxString& indent)
4085{
4086 wxString prefix = wxString::Format(_T("%s#zip:%s"),
4087 TESTFILE_ZIP, dir.c_str());
4088 wxString wildcard = prefix + _T("/*");
4089
4090 wxString dirname = fs.FindFirst(wildcard, wxDIR);
4091 while ( !dirname.empty() )
4092 {
4093 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
4094 {
4095 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4096
4097 break;
4098 }
4099
4100 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
4101
4102 DumpZipDirectory(fs, dirname,
4103 indent + wxString(_T(' '), 4));
4104
4105 dirname = fs.FindNext();
4106 }
4107
4108 wxString filename = fs.FindFirst(wildcard, wxFILE);
4109 while ( !filename.empty() )
4110 {
4111 if ( !filename.StartsWith(prefix, &filename) )
4112 {
4113 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4114
4115 break;
4116 }
4117
4118 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
4119
4120 filename = fs.FindNext();
4121 }
4122}
4123
4124static void TestZipFileSystem()
4125{
456ae26d 4126 wxPuts(_T("*** Testing ZIP file system ***\n"));
2ca8b884
VZ
4127
4128 wxFileSystem::AddHandler(new wxZipFSHandler);
4129 wxFileSystem fs;
4130 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
4131
4132 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
4133}
4134
f6bcfd97
BP
4135#endif // TEST_ZIP
4136
3ca6a5f0
BP
4137// ----------------------------------------------------------------------------
4138// ZLIB stream
4139// ----------------------------------------------------------------------------
4140
4141#ifdef TEST_ZLIB
4142
e84010cf
GD
4143#include "wx/zstream.h"
4144#include "wx/wfstream.h"
3ca6a5f0
BP
4145
4146static const wxChar *FILENAME_GZ = _T("test.gz");
456ae26d 4147static const wxChar *TEST_DATA = _T("hello and hello and hello and hello and hello");
3ca6a5f0
BP
4148
4149static void TestZlibStreamWrite()
4150{
456ae26d 4151 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4152
4153 wxFileOutputStream fileOutStream(FILENAME_GZ);
2104ba31 4154 wxZlibOutputStream ostr(fileOutStream);
456ae26d
VZ
4155 wxPrintf(_T("Compressing the test string... "));
4156 ostr.Write(TEST_DATA, wxStrlen(TEST_DATA) + 1);
3ca6a5f0
BP
4157 if ( !ostr )
4158 {
456ae26d 4159 wxPuts(_T("(ERROR: failed)"));
3ca6a5f0
BP
4160 }
4161 else
4162 {
456ae26d 4163 wxPuts(_T("(ok)"));
3ca6a5f0
BP
4164 }
4165
456ae26d 4166 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4167}
4168
4169static void TestZlibStreamRead()
4170{
456ae26d 4171 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4172
4173 wxFileInputStream fileInStream(FILENAME_GZ);
4174 wxZlibInputStream istr(fileInStream);
456ae26d 4175 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3ca6a5f0 4176
456ae26d 4177 wxPuts(_T("Dumping the file:"));
3ca6a5f0
BP
4178 while ( !istr.Eof() )
4179 {
4180 putchar(istr.GetC());
4181 fflush(stdout);
4182 }
4183
456ae26d 4184 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4185}
4186
4187#endif // TEST_ZLIB
4188
b76b015e
VZ
4189// ----------------------------------------------------------------------------
4190// date time
4191// ----------------------------------------------------------------------------
4192
d31b7b68 4193#ifdef TEST_DATETIME
b76b015e 4194
551fe3a6
VZ
4195#include <math.h>
4196
e84010cf 4197#include "wx/datetime.h"
b76b015e 4198
299fcbfe
VZ
4199// the test data
4200struct Date
4201{
4202 wxDateTime::wxDateTime_t day;
4203 wxDateTime::Month month;
4204 int year;
4205 wxDateTime::wxDateTime_t hour, min, sec;
4206 double jdn;
211c2250 4207 wxDateTime::WeekDay wday;
299fcbfe
VZ
4208 time_t gmticks, ticks;
4209
4210 void Init(const wxDateTime::Tm& tm)
4211 {
4212 day = tm.mday;
4213 month = tm.mon;
4214 year = tm.year;
4215 hour = tm.hour;
4216 min = tm.min;
4217 sec = tm.sec;
4218 jdn = 0.0;
4219 gmticks = ticks = -1;
4220 }
4221
4222 wxDateTime DT() const
4223 { return wxDateTime(day, month, year, hour, min, sec); }
4224
239446b4
VZ
4225 bool SameDay(const wxDateTime::Tm& tm) const
4226 {
4227 return day == tm.mday && month == tm.mon && year == tm.year;
4228 }
4229
299fcbfe
VZ
4230 wxString Format() const
4231 {
4232 wxString s;
456ae26d 4233 s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"),
299fcbfe
VZ
4234 hour, min, sec,
4235 wxDateTime::GetMonthName(month).c_str(),
4236 day,
4237 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4238 year > 0 ? _T("AD") : _T("BC"));
299fcbfe
VZ
4239 return s;
4240 }
239446b4
VZ
4241
4242 wxString FormatDate() const
4243 {
4244 wxString s;
456ae26d 4245 s.Printf(_T("%02d-%s-%4d%s"),
239446b4 4246 day,
f0f951fa 4247 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
239446b4 4248 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4249 year > 0 ? _T("AD") : _T("BC"));
239446b4
VZ
4250 return s;
4251 }
299fcbfe
VZ
4252};
4253
4254static const Date testDates[] =
4255{
211c2250 4256 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
e7d41190
VZ
4257 { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 },
4258 { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 },
4259 { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 },
4260 { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 },
211c2250
VZ
4261 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
4262 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
4263 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
4264 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
4265 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
4266 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
4267 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
4268 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
4269 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
239446b4
VZ
4270 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
4271 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
4272 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
4273 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
211c2250 4274 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
299fcbfe
VZ
4275};
4276
2f02cb89
VZ
4277// this test miscellaneous static wxDateTime functions
4278static void TestTimeStatic()
4279{
456ae26d 4280 wxPuts(_T("\n*** wxDateTime static methods test ***"));
2f02cb89
VZ
4281
4282 // some info about the current date
4283 int year = wxDateTime::GetCurrentYear();
456ae26d 4284 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
2f02cb89
VZ
4285 year,
4286 wxDateTime::IsLeapYear(year) ? "" : "not ",
4287 wxDateTime::GetNumberOfDays(year));
4288
4289 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
456ae26d 4290 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
f0f951fa 4291 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2f02cb89
VZ
4292 wxDateTime::GetMonthName(month).c_str(),
4293 wxDateTime::GetNumberOfDays(month));
4294
4295 // leap year logic
fcc3d7cb
VZ
4296 static const size_t nYears = 5;
4297 static const size_t years[2][nYears] =
2f02cb89
VZ
4298 {
4299 // first line: the years to test
4300 { 1990, 1976, 2000, 2030, 1984, },
4301
cab8f76e
VZ
4302 // second line: true if leap, false otherwise
4303 { false, true, true, false, true }
2f02cb89
VZ
4304 };
4305
4306 for ( size_t n = 0; n < nYears; n++ )
4307 {
4308 int year = years[0][n];
239446b4
VZ
4309 bool should = years[1][n] != 0,
4310 is = wxDateTime::IsLeapYear(year);
2f02cb89 4311
456ae26d 4312 wxPrintf(_T("Year %d is %sa leap year (%s)\n"),
2f02cb89 4313 year,
239446b4
VZ
4314 is ? "" : "not ",
4315 should == is ? "ok" : "ERROR");
2f02cb89
VZ
4316
4317 wxASSERT( should == wxDateTime::IsLeapYear(year) );
4318 }
4319}
4320
4321// test constructing wxDateTime objects
4322static void TestTimeSet()
4323{
456ae26d 4324 wxPuts(_T("\n*** wxDateTime construction test ***"));
2f02cb89 4325
299fcbfe
VZ
4326 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4327 {
4328 const Date& d1 = testDates[n];
4329 wxDateTime dt = d1.DT();
4330
4331 Date d2;
4332 d2.Init(dt.GetTm());
4333
4334 wxString s1 = d1.Format(),
4335 s2 = d2.Format();
4336
456ae26d
VZ
4337 wxPrintf(_T("Date: %s == %s (%s)\n"),
4338 s1.c_str(), s2.c_str(),
4339 s1 == s2 ? _T("ok") : _T("ERROR"));
299fcbfe 4340 }
2f02cb89
VZ
4341}
4342
fcc3d7cb
VZ
4343// test time zones stuff
4344static void TestTimeZones()
4345{
456ae26d 4346 wxPuts(_T("\n*** wxDateTime timezone test ***"));
fcc3d7cb
VZ
4347
4348 wxDateTime now = wxDateTime::Now();
4349
456ae26d
VZ
4350 wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
4351 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
4352 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
4353 wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
4354 wxPrintf(_T(" Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
4355 wxPrintf(_T(" New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
9d9b7755
VZ
4356
4357 wxDateTime::Tm tm = now.GetTm();
4358 if ( wxDateTime(tm) != now )
4359 {
456ae26d
VZ
4360 wxPrintf(_T("ERROR: got %s instead of %s\n"),
4361 wxDateTime(tm).Format().c_str(), now.Format().c_str());
9d9b7755 4362 }
fcc3d7cb
VZ
4363}
4364
e6ec579c
VZ
4365// test some minimal support for the dates outside the standard range
4366static void TestTimeRange()
4367{
456ae26d 4368 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
e6ec579c 4369
456ae26d 4370 static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
211c2250 4371
456ae26d
VZ
4372 wxPrintf(_T("Unix epoch:\t%s\n"),
4373 wxDateTime(2440587.5).Format(fmt).c_str());
4374 wxPrintf(_T("Feb 29, 0: \t%s\n"),
4375 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
4376 wxPrintf(_T("JDN 0: \t%s\n"),
4377 wxDateTime(0.0).Format(fmt).c_str());
4378 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
4379 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
4380 wxPrintf(_T("May 29, 2099:\t%s\n"),
4381 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
e6ec579c
VZ
4382}
4383
299fcbfe 4384static void TestTimeTicks()
e6ec579c 4385{
456ae26d 4386 wxPuts(_T("\n*** wxDateTime ticks test ***"));
e6ec579c 4387
299fcbfe 4388 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1ef54dcf 4389 {
299fcbfe
VZ
4390 const Date& d = testDates[n];
4391 if ( d.ticks == -1 )
4392 continue;
1ef54dcf 4393
299fcbfe
VZ
4394 wxDateTime dt = d.DT();
4395 long ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4396 wxPrintf(_T("Ticks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4397 if ( ticks == d.ticks )
4398 {
456ae26d 4399 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4400 }
4401 else
4402 {
456ae26d
VZ
4403 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4404 (long)d.ticks, (long)(ticks - d.ticks));
299fcbfe
VZ
4405 }
4406
4407 dt = d.DT().ToTimezone(wxDateTime::GMT0);
4408 ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4409 wxPrintf(_T("GMtks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4410 if ( ticks == d.gmticks )
4411 {
456ae26d 4412 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4413 }
4414 else
4415 {
456ae26d
VZ
4416 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4417 (long)d.gmticks, (long)(ticks - d.gmticks));
299fcbfe
VZ
4418 }
4419 }
4420
456ae26d 4421 wxPuts(_T(""));
299fcbfe
VZ
4422}
4423
4424// test conversions to JDN &c
4425static void TestTimeJDN()
4426{
456ae26d 4427 wxPuts(_T("\n*** wxDateTime to JDN test ***"));
1ef54dcf
VZ
4428
4429 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4430 {
4431 const Date& d = testDates[n];
299fcbfe 4432 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1ef54dcf
VZ
4433 double jdn = dt.GetJulianDayNumber();
4434
456ae26d 4435 wxPrintf(_T("JDN of %s is:\t% 15.6f"), d.Format().c_str(), jdn);
1ef54dcf
VZ
4436 if ( jdn == d.jdn )
4437 {
456ae26d 4438 wxPuts(_T(" (ok)"));
1ef54dcf
VZ
4439 }
4440 else
4441 {
456ae26d
VZ
4442 wxPrintf(_T(" (ERROR: should be %f, delta = %f)\n"),
4443 d.jdn, jdn - d.jdn);
1ef54dcf
VZ
4444 }
4445 }
e6ec579c
VZ
4446}
4447
211c2250
VZ
4448// test week days computation
4449static void TestTimeWDays()
4450{
456ae26d 4451 wxPuts(_T("\n*** wxDateTime weekday test ***"));
211c2250 4452
239446b4
VZ
4453 // test GetWeekDay()
4454 size_t n;
4455 for ( n = 0; n < WXSIZEOF(testDates); n++ )
211c2250
VZ
4456 {
4457 const Date& d = testDates[n];
4458 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
4459
4460 wxDateTime::WeekDay wday = dt.GetWeekDay();
456ae26d
VZ
4461 wxPrintf(_T("%s is: %s"),
4462 d.Format().c_str(),
4463 wxDateTime::GetWeekDayName(wday).c_str());
211c2250
VZ
4464 if ( wday == d.wday )
4465 {
456ae26d 4466 wxPuts(_T(" (ok)"));
211c2250
VZ
4467 }
4468 else
4469 {
456ae26d
VZ
4470 wxPrintf(_T(" (ERROR: should be %s)\n"),
4471 wxDateTime::GetWeekDayName(d.wday).c_str());
239446b4
VZ
4472 }
4473 }
4474
456ae26d 4475 wxPuts(_T(""));
239446b4
VZ
4476
4477 // test SetToWeekDay()
4478 struct WeekDateTestData
4479 {
4480 Date date; // the real date (precomputed)
4481 int nWeek; // its week index in the month
4482 wxDateTime::WeekDay wday; // the weekday
4483 wxDateTime::Month month; // the month
4484 int year; // and the year
4485
4486 wxString Format() const
4487 {
4488 wxString s, which;
4489 switch ( nWeek < -1 ? -nWeek : nWeek )
4490 {
456ae26d
VZ
4491 case 1: which = _T("first"); break;
4492 case 2: which = _T("second"); break;
4493 case 3: which = _T("third"); break;
4494 case 4: which = _T("fourth"); break;
4495 case 5: which = _T("fifth"); break;
239446b4 4496
456ae26d 4497 case -1: which = _T("last"); break;
239446b4
VZ
4498 }
4499
4500 if ( nWeek < -1 )
4501 {
456ae26d 4502 which += _T(" from end");
239446b4
VZ
4503 }
4504
456ae26d 4505 s.Printf(_T("The %s %s of %s in %d"),
239446b4
VZ
4506 which.c_str(),
4507 wxDateTime::GetWeekDayName(wday).c_str(),
4508 wxDateTime::GetMonthName(month).c_str(),
4509 year);
4510
4511 return s;
4512 }
4513 };
4514
4515 // the array data was generated by the following python program
4516 /*
4517from DateTime import *
4518from whrandom import *
4519from string import *
4520
4521monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4522wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4523
4524week = DateTimeDelta(7)
4525
4526for n in range(20):
4527 year = randint(1900, 2100)
4528 month = randint(1, 12)
4529 day = randint(1, 28)
4530 dt = DateTime(year, month, day)
4531 wday = dt.day_of_week
4532
4533 countFromEnd = choice([-1, 1])
4534 weekNum = 0;
4535
4536 while dt.month is month:
4537 dt = dt - countFromEnd * week
4538 weekNum = weekNum + countFromEnd
4539
4540 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
97e0ceea 4541
239446b4
VZ
4542 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
4543 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
97e0ceea 4544 */
239446b4
VZ
4545
4546 static const WeekDateTestData weekDatesTestData[] =
4547 {
4548 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
4549 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
4550 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
4551 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
4552 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
4553 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
4554 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
4555 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
4556 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
4557 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
4558 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
4559 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
4560 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
4561 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
4562 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
4563 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
4564 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
4565 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
4566 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
4567 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
4568 };
4569
456ae26d 4570 static const wxChar *fmt = _T("%d-%b-%Y");
239446b4
VZ
4571
4572 wxDateTime dt;
4573 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
4574 {
4575 const WeekDateTestData& wd = weekDatesTestData[n];
4576
4577 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
4578
456ae26d 4579 wxPrintf(_T("%s is %s"), wd.Format().c_str(), dt.Format(fmt).c_str());
239446b4
VZ
4580
4581 const Date& d = wd.date;
4582 if ( d.SameDay(dt.GetTm()) )
4583 {
456ae26d 4584 wxPuts(_T(" (ok)"));
239446b4
VZ
4585 }
4586 else
4587 {
4588 dt.Set(d.day, d.month, d.year);
4589
456ae26d 4590 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.Format(fmt).c_str());
211c2250
VZ
4591 }
4592 }
4593}
4594
239446b4
VZ
4595// test the computation of (ISO) week numbers
4596static void TestTimeWNumber()
4597{
456ae26d 4598 wxPuts(_T("\n*** wxDateTime week number test ***"));
239446b4
VZ
4599
4600 struct WeekNumberTestData
4601 {
4602 Date date; // the date
9d9b7755
VZ
4603 wxDateTime::wxDateTime_t week; // the week number in the year
4604 wxDateTime::wxDateTime_t wmon; // the week number in the month
4605 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
239446b4
VZ
4606 wxDateTime::wxDateTime_t dnum; // day number in the year
4607 };
4608
4609 // data generated with the following python script:
4610 /*
4611from DateTime import *
4612from whrandom import *
4613from string import *
4614
4615monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4616wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4617
9d9b7755
VZ
4618def GetMonthWeek(dt):
4619 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4620 if weekNumMonth < 0:
4621 weekNumMonth = weekNumMonth + 53
4622 return weekNumMonth
7c968cee 4623
9d9b7755
VZ
4624def GetLastSundayBefore(dt):
4625 if dt.iso_week[2] == 7:
4626 return dt
4627 else:
4628 return dt - DateTimeDelta(dt.iso_week[2])
4629
239446b4
VZ
4630for n in range(20):
4631 year = randint(1900, 2100)
4632 month = randint(1, 12)
4633 day = randint(1, 28)
4634 dt = DateTime(year, month, day)
4635 dayNum = dt.day_of_year
4636 weekNum = dt.iso_week[1]
9d9b7755
VZ
4637 weekNumMonth = GetMonthWeek(dt)
4638
4639 weekNumMonth2 = 0
4640 dtSunday = GetLastSundayBefore(dt)
4641
4642 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4643 weekNumMonth2 = weekNumMonth2 + 1
4644 dtSunday = dtSunday - DateTimeDelta(7)
4645
4646 data = { 'day': rjust(`day`, 2), \
4647 'month': monthNames[month - 1], \
4648 'year': year, \
4649 'weekNum': rjust(`weekNum`, 2), \
4650 'weekNumMonth': weekNumMonth, \
4651 'weekNumMonth2': weekNumMonth2, \
4652 'dayNum': rjust(`dayNum`, 3) }
4653
4654 print " { { %(day)s, "\
4655 "wxDateTime::%(month)s, "\
4656 "%(year)d }, "\
4657 "%(weekNum)s, "\
4658 "%(weekNumMonth)s, "\
4659 "%(weekNumMonth2)s, "\
239446b4 4660 "%(dayNum)s }," % data
9d9b7755 4661
239446b4
VZ
4662 */
4663 static const WeekNumberTestData weekNumberTestDates[] =
4664 {
9d9b7755
VZ
4665 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
4666 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
4667 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
4668 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
4669 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
4670 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
4671 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
4672 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
4673 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
4674 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
4675 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
4676 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
4677 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
4678 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
4679 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
4680 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
4681 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
4682 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
4683 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
4684 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
239446b4
VZ
4685 };
4686
4687 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
4688 {
4689 const WeekNumberTestData& wn = weekNumberTestDates[n];
4690 const Date& d = wn.date;
4691
4692 wxDateTime dt = d.DT();
4693
9d9b7755
VZ
4694 wxDateTime::wxDateTime_t
4695 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
4696 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
4697 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4698 dnum = dt.GetDayOfYear();
239446b4 4699
456ae26d 4700 wxPrintf(_T("%s: the day number is %d"), d.FormatDate().c_str(), dnum);
239446b4
VZ
4701 if ( dnum == wn.dnum )
4702 {
456ae26d 4703 wxPrintf(_T(" (ok)"));
239446b4
VZ
4704 }
4705 else
4706 {
456ae26d 4707 wxPrintf(_T(" (ERROR: should be %d)"), wn.dnum);
239446b4
VZ
4708 }
4709
2b5f62a0
VZ
4710 wxPrintf(_T(", week in month = %d"), wmon);
4711 if ( wmon != wn.wmon )
9d9b7755 4712 {
456ae26d 4713 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon);
9d9b7755
VZ
4714 }
4715
456ae26d 4716 wxPrintf(_T(" or %d"), wmon2);
9d9b7755
VZ
4717 if ( wmon2 == wn.wmon2 )
4718 {
456ae26d 4719 wxPrintf(_T(" (ok)"));
9d9b7755
VZ
4720 }
4721 else
4722 {
456ae26d 4723 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon2);
9d9b7755
VZ
4724 }
4725
2b5f62a0
VZ
4726 wxPrintf(_T(", week in year = %d"), week);
4727 if ( week != wn.week )
239446b4 4728 {
2b5f62a0 4729 wxPrintf(_T(" (ERROR: should be %d)"), wn.week);
239446b4 4730 }
2b5f62a0
VZ
4731
4732 wxPutchar(_T('\n'));
4733
4734 wxDateTime dt2(1, wxDateTime::Jan, d.year);
4735 dt2.SetToTheWeek(wn.week, dt.GetWeekDay());
4736 if ( dt2 != dt )
239446b4 4737 {
2b5f62a0
VZ
4738 Date d2;
4739 d2.Init(dt2.GetTm());
4740 wxPrintf(_T("ERROR: SetToTheWeek() returned %s\n"),
4741 d2.FormatDate().c_str());
239446b4
VZ
4742 }
4743 }
4744}
4745
4746// test DST calculations
4747static void TestTimeDST()
4748{
456ae26d 4749 wxPuts(_T("\n*** wxDateTime DST test ***"));
239446b4 4750
456ae26d
VZ
4751 wxPrintf(_T("DST is%s in effect now.\n\n"),
4752 wxDateTime::Now().IsDST() ? _T("") : _T(" not"));
239446b4
VZ
4753
4754 // taken from http://www.energy.ca.gov/daylightsaving.html
4755 static const Date datesDST[2][2004 - 1900 + 1] =
4756 {
4757 {
4758 { 1, wxDateTime::Apr, 1990 },
4759 { 7, wxDateTime::Apr, 1991 },
4760 { 5, wxDateTime::Apr, 1992 },
4761 { 4, wxDateTime::Apr, 1993 },
4762 { 3, wxDateTime::Apr, 1994 },
4763 { 2, wxDateTime::Apr, 1995 },
4764 { 7, wxDateTime::Apr, 1996 },
4765 { 6, wxDateTime::Apr, 1997 },
4766 { 5, wxDateTime::Apr, 1998 },
4767 { 4, wxDateTime::Apr, 1999 },
4768 { 2, wxDateTime::Apr, 2000 },
4769 { 1, wxDateTime::Apr, 2001 },
4770 { 7, wxDateTime::Apr, 2002 },
4771 { 6, wxDateTime::Apr, 2003 },
4772 { 4, wxDateTime::Apr, 2004 },
4773 },
4774 {
4775 { 28, wxDateTime::Oct, 1990 },
4776 { 27, wxDateTime::Oct, 1991 },
4777 { 25, wxDateTime::Oct, 1992 },
4778 { 31, wxDateTime::Oct, 1993 },
4779 { 30, wxDateTime::Oct, 1994 },
4780 { 29, wxDateTime::Oct, 1995 },
4781 { 27, wxDateTime::Oct, 1996 },
4782 { 26, wxDateTime::Oct, 1997 },
4783 { 25, wxDateTime::Oct, 1998 },
4784 { 31, wxDateTime::Oct, 1999 },
4785 { 29, wxDateTime::Oct, 2000 },
4786 { 28, wxDateTime::Oct, 2001 },
4787 { 27, wxDateTime::Oct, 2002 },
4788 { 26, wxDateTime::Oct, 2003 },
4789 { 31, wxDateTime::Oct, 2004 },
4790 }
4791 };
4792
4793 int year;
4794 for ( year = 1990; year < 2005; year++ )
4795 {
4796 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4797 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4798
456ae26d
VZ
4799 wxPrintf(_T("DST period in the US for year %d: from %s to %s"),
4800 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
239446b4
VZ
4801
4802 size_t n = year - 1990;
4803 const Date& dBegin = datesDST[0][n];
4804 const Date& dEnd = datesDST[1][n];
97e0ceea 4805
239446b4
VZ
4806 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4807 {
456ae26d 4808 wxPuts(_T(" (ok)"));
239446b4
VZ
4809 }
4810 else
4811 {
456ae26d
VZ
4812 wxPrintf(_T(" (ERROR: should be %s %d to %s %d)\n"),
4813 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4814 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
239446b4
VZ
4815 }
4816 }
4817
456ae26d 4818 wxPuts(_T(""));
239446b4
VZ
4819
4820 for ( year = 1990; year < 2005; year++ )
4821 {
456ae26d
VZ
4822 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
4823 year,
4824 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4825 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
239446b4
VZ
4826 }
4827}
4828
68ee7c47
VZ
4829// test wxDateTime -> text conversion
4830static void TestTimeFormat()
4831{
456ae26d 4832 wxPuts(_T("\n*** wxDateTime formatting test ***"));
68ee7c47 4833
b38e2f7d
VZ
4834 // some information may be lost during conversion, so store what kind
4835 // of info should we recover after a round trip
4836 enum CompareKind
68ee7c47 4837 {
b38e2f7d
VZ
4838 CompareNone, // don't try comparing
4839 CompareBoth, // dates and times should be identical
4840 CompareDate, // dates only
4841 CompareTime // time only
4842 };
4843
4844 static const struct
4845 {
4846 CompareKind compareKind;
456ae26d 4847 const wxChar *format;
b38e2f7d
VZ
4848 } formatTestFormats[] =
4849 {
456ae26d
VZ
4850 { CompareBoth, _T("---> %c") },
4851 { CompareDate, _T("Date is %A, %d of %B, in year %Y") },
4852 { CompareBoth, _T("Date is %x, time is %X") },
4853 { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") },
4854 { CompareNone, _T("The day of year: %j, the week of year: %W") },
ee3ef281 4855 { CompareDate, _T("ISO date without separators: %Y%m%d") },
68ee7c47
VZ
4856 };
4857
4858 static const Date formatTestDates[] =
4859 {
68ee7c47
VZ
4860 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4861 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
b38e2f7d
VZ
4862#if 0
4863 // this test can't work for other centuries because it uses two digit
4864 // years in formats, so don't even try it
68ee7c47
VZ
4865 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4866 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4867 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
b38e2f7d 4868#endif
68ee7c47
VZ
4869 };
4870
4871 // an extra test (as it doesn't depend on date, don't do it in the loop)
456ae26d 4872 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
68ee7c47 4873
b38e2f7d 4874 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
68ee7c47 4875 {
456ae26d 4876 wxPuts(_T(""));
68ee7c47 4877
b38e2f7d 4878 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
68ee7c47
VZ
4879 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4880 {
b38e2f7d 4881 wxString s = dt.Format(formatTestFormats[n].format);
456ae26d 4882 wxPrintf(_T("%s"), s.c_str());
f0f951fa 4883
b38e2f7d
VZ
4884 // what can we recover?
4885 int kind = formatTestFormats[n].compareKind;
4886
f0f951fa
VZ
4887 // convert back
4888 wxDateTime dt2;
b38e2f7d 4889 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
f0f951fa
VZ
4890 if ( !result )
4891 {
b38e2f7d
VZ
4892 // converion failed - should it have?
4893 if ( kind == CompareNone )
456ae26d 4894 wxPuts(_T(" (ok)"));
b38e2f7d 4895 else
456ae26d 4896 wxPuts(_T(" (ERROR: conversion back failed)"));
f0f951fa
VZ
4897 }
4898 else if ( *result )
4899 {
4900 // should have parsed the entire string
456ae26d 4901 wxPuts(_T(" (ERROR: conversion back stopped too soon)"));
f0f951fa 4902 }
f0f951fa
VZ
4903 else
4904 {
cab8f76e 4905 bool equal = false; // suppress compilaer warning
b38e2f7d
VZ
4906 switch ( kind )
4907 {
4908 case CompareBoth:
4909 equal = dt2 == dt;
4910 break;
4911
4912 case CompareDate:
4913 equal = dt.IsSameDate(dt2);
4914 break;
4915
4916 case CompareTime:
4917 equal = dt.IsSameTime(dt2);
4918 break;
4919 }
4920
4921 if ( !equal )
4922 {
456ae26d 4923 wxPrintf(_T(" (ERROR: got back '%s' instead of '%s')\n"),
b38e2f7d
VZ
4924 dt2.Format().c_str(), dt.Format().c_str());
4925 }
4926 else
4927 {
456ae26d 4928 wxPuts(_T(" (ok)"));
b38e2f7d 4929 }
f0f951fa 4930 }
68ee7c47
VZ
4931 }
4932 }
4933}
4934
97e0ceea
VZ
4935// test text -> wxDateTime conversion
4936static void TestTimeParse()
4937{
456ae26d 4938 wxPuts(_T("\n*** wxDateTime parse test ***"));
97e0ceea
VZ
4939
4940 struct ParseTestData
4941 {
456ae26d 4942 const wxChar *format;
97e0ceea
VZ
4943 Date date;
4944 bool good;
4945 };
4946
4947 static const ParseTestData parseTestDates[] =
4948 {
cab8f76e
VZ
4949 { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, true },
4950 { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, true },
97e0ceea
VZ
4951 };
4952
4953 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4954 {
456ae26d 4955 const wxChar *format = parseTestDates[n].format;
97e0ceea 4956
456ae26d 4957 wxPrintf(_T("%s => "), format);
97e0ceea
VZ
4958
4959 wxDateTime dt;
4960 if ( dt.ParseRfc822Date(format) )
4961 {
456ae26d 4962 wxPrintf(_T("%s "), dt.Format().c_str());
97e0ceea
VZ
4963
4964 if ( parseTestDates[n].good )
4965 {
4966 wxDateTime dtReal = parseTestDates[n].date.DT();
4967 if ( dt == dtReal )
4968 {
456ae26d 4969 wxPuts(_T("(ok)"));
97e0ceea
VZ
4970 }
4971 else
4972 {
456ae26d 4973 wxPrintf(_T("(ERROR: should be %s)\n"), dtReal.Format().c_str());
97e0ceea
VZ
4974 }
4975 }
4976 else
4977 {
456ae26d 4978 wxPuts(_T("(ERROR: bad format)"));
97e0ceea
VZ
4979 }
4980 }
4981 else
4982 {
456ae26d 4983 wxPrintf(_T("bad format (%s)\n"),
97e0ceea
VZ
4984 parseTestDates[n].good ? "ERROR" : "ok");
4985 }
4986 }
4987}
4988
b92fd37c 4989static void TestDateTimeInteractive()
9d9b7755 4990{
456ae26d 4991 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
9d9b7755 4992
456ae26d 4993 wxChar buf[128];
9d9b7755
VZ
4994
4995 for ( ;; )
4996 {
456ae26d
VZ
4997 wxPrintf(_T("Enter a date: "));
4998 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
9d9b7755
VZ
4999 break;
5000
f6bcfd97 5001 // kill the last '\n'
456ae26d 5002 buf[wxStrlen(buf) - 1] = 0;
f6bcfd97 5003
9d9b7755 5004 wxDateTime dt;
456ae26d 5005 const wxChar *p = dt.ParseDate(buf);
f6bcfd97 5006 if ( !p )
9d9b7755 5007 {
456ae26d 5008 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
9d9b7755
VZ
5009
5010 continue;
5011 }
f6bcfd97
BP
5012 else if ( *p )
5013 {
456ae26d 5014 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
f6bcfd97 5015 }
9d9b7755 5016
456ae26d
VZ
5017 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
5018 dt.Format(_T("%b %d, %Y")).c_str(),
5019 dt.GetDayOfYear(),
5020 dt.GetWeekOfMonth(wxDateTime::Monday_First),
5021 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
5022 dt.GetWeekOfYear(wxDateTime::Monday_First));
9d9b7755
VZ
5023 }
5024
456ae26d 5025 wxPuts(_T("\n*** done ***"));
9d9b7755
VZ
5026}
5027
f6bcfd97
BP
5028static void TestTimeMS()
5029{
456ae26d 5030 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
f6bcfd97
BP
5031
5032 wxDateTime dt1 = wxDateTime::Now(),
5033 dt2 = wxDateTime::UNow();
5034
456ae26d
VZ
5035 wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
5036 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
5037 wxPrintf(_T("Dummy loop: "));
3ca6a5f0
BP
5038 for ( int i = 0; i < 6000; i++ )
5039 {
5040 //for ( int j = 0; j < 10; j++ )
5041 {
5042 wxString s;
456ae26d 5043 s.Printf(_T("%g"), sqrt(i));
3ca6a5f0
BP
5044 }
5045
5046 if ( !(i % 100) )
5047 putchar('.');
5048 }
456ae26d 5049 wxPuts(_T(", done"));
3ca6a5f0
BP
5050
5051 dt1 = dt2;
5052 dt2 = wxDateTime::UNow();
456ae26d 5053 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3ca6a5f0 5054
456ae26d 5055 wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
f6bcfd97 5056
456ae26d 5057 wxPuts(_T("\n*** done ***"));
f6bcfd97
BP
5058}
5059
9d9b7755
VZ
5060static void TestTimeArithmetics()
5061{
456ae26d 5062 wxPuts(_T("\n*** testing arithmetic operations on wxDateTime ***"));
9d9b7755 5063
f6bcfd97 5064 static const struct ArithmData
9d9b7755 5065 {
456ae26d 5066 ArithmData(const wxDateSpan& sp, const wxChar *nam)
f6bcfd97
BP
5067 : span(sp), name(nam) { }
5068
9d9b7755 5069 wxDateSpan span;
456ae26d 5070 const wxChar *name;
7c968cee 5071 } testArithmData[] =
9d9b7755 5072 {
456ae26d
VZ
5073 ArithmData(wxDateSpan::Day(), _T("day")),
5074 ArithmData(wxDateSpan::Week(), _T("week")),
5075 ArithmData(wxDateSpan::Month(), _T("month")),
5076 ArithmData(wxDateSpan::Year(), _T("year")),
5077 ArithmData(wxDateSpan(1, 2, 3, 4), _T("year, 2 months, 3 weeks, 4 days")),
9d9b7755 5078 };
7c968cee 5079
9d9b7755
VZ
5080 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
5081
5082 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
5083 {
5084 wxDateSpan span = testArithmData[n].span;
5085 dt1 = dt + span;
5086 dt2 = dt - span;
5087
456ae26d
VZ
5088 const wxChar *name = testArithmData[n].name;
5089 wxPrintf(_T("%s + %s = %s, %s - %s = %s\n"),
9d9b7755
VZ
5090 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
5091 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
5092
456ae26d 5093 wxPrintf(_T("Going back: %s"), (dt1 - span).FormatISODate().c_str());
9d9b7755
VZ
5094 if ( dt1 - span == dt )
5095 {
456ae26d 5096 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5097 }
5098 else
5099 {
456ae26d 5100 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5101 }
5102
456ae26d 5103 wxPrintf(_T("Going forward: %s"), (dt2 + span).FormatISODate().c_str());
9d9b7755
VZ
5104 if ( dt2 + span == dt )
5105 {
456ae26d 5106 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5107 }
5108 else
5109 {
456ae26d 5110 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5111 }
5112
456ae26d 5113 wxPrintf(_T("Double increment: %s"), (dt2 + 2*span).FormatISODate().c_str());
9d9b7755
VZ
5114 if ( dt2 + 2*span == dt1 )
5115 {
456ae26d 5116 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5117 }
5118 else
5119 {
456ae26d 5120 wxPrintf(_T(" (ERROR: should be %s)\n"), dt2.FormatISODate().c_str());
9d9b7755
VZ
5121 }
5122
456ae26d 5123 wxPuts(_T(""));
9d9b7755
VZ
5124 }
5125}
5126
0de868d9
VZ
5127static void TestTimeHolidays()
5128{
456ae26d 5129 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
0de868d9
VZ
5130
5131 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
5132 wxDateTime dtStart(1, tm.mon, tm.year),
5133 dtEnd = dtStart.GetLastMonthDay();
5134
5135 wxDateTimeArray hol;
5136 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
5137
456ae26d 5138 const wxChar *format = _T("%d-%b-%Y (%a)");
0de868d9 5139
456ae26d 5140 wxPrintf(_T("All holidays between %s and %s:\n"),
0de868d9
VZ
5141 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
5142
5143 size_t count = hol.GetCount();
5144 for ( size_t n = 0; n < count; n++ )
5145 {
456ae26d 5146 wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
0de868d9
VZ
5147 }
5148
456ae26d 5149 wxPuts(_T(""));
0de868d9
VZ
5150}
5151
f6bcfd97
BP
5152static void TestTimeZoneBug()
5153{
456ae26d 5154 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
f6bcfd97
BP
5155
5156 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
5157 for ( int i = 0; i < 31; i++ )
5158 {
456ae26d 5159 wxPrintf(_T("Date %s: week day %s.\n"),
f6bcfd97
BP
5160 date.Format(_T("%d-%m-%Y")).c_str(),
5161 date.GetWeekDayName(date.GetWeekDay()).c_str());
5162
5163 date += wxDateSpan::Day();
5164 }
5165
456ae26d 5166 wxPuts(_T(""));
f6bcfd97
BP
5167}
5168
df05cdc5
VZ
5169static void TestTimeSpanFormat()
5170{
456ae26d 5171 wxPuts(_T("\n*** wxTimeSpan tests ***"));
df05cdc5 5172
456ae26d 5173 static const wxChar *formats[] =
df05cdc5
VZ
5174 {
5175 _T("(default) %H:%M:%S"),
5176 _T("%E weeks and %D days"),
5177 _T("%l milliseconds"),
5178 _T("(with ms) %H:%M:%S:%l"),
5179 _T("100%% of minutes is %M"), // test "%%"
5180 _T("%D days and %H hours"),
a8625337 5181 _T("or also %S seconds"),
df05cdc5
VZ
5182 };
5183
5184 wxTimeSpan ts1(1, 2, 3, 4),
5185 ts2(111, 222, 333);
5186 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
5187 {
456ae26d 5188 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
df05cdc5
VZ
5189 ts1.Format(formats[n]).c_str(),
5190 ts2.Format(formats[n]).c_str());
5191 }
5192
456ae26d 5193 wxPuts(_T(""));
df05cdc5
VZ
5194}
5195
d31b7b68 5196#endif // TEST_DATETIME
b76b015e 5197
39937656
VZ
5198// ----------------------------------------------------------------------------
5199// wxTextInput/OutputStream
5200// ----------------------------------------------------------------------------
5201
5202#ifdef TEST_TEXTSTREAM
5203
5204#include "wx/txtstrm.h"
5205#include "wx/wfstream.h"
5206
5207static void TestTextInputStream()
5208{
5209 wxPuts(_T("\n*** wxTextInputStream test ***"));
5210
5211 wxFileInputStream fsIn(_T("testdata.fc"));
5212 if ( !fsIn.Ok() )
5213 {
5214 wxPuts(_T("ERROR: couldn't open file."));
5215 }
5216 else
5217 {
5218 wxTextInputStream tis(fsIn);
5219
5220 size_t line = 1;
5221 for ( ;; )
5222 {
5223 const wxString s = tis.ReadLine();
5224
5225 // line could be non empty if the last line of the file isn't
5226 // terminated with EOL
5227 if ( fsIn.Eof() && s.empty() )
5228 break;
5229
5230 wxPrintf(_T("Line %d: %s\n"), line++, s.c_str());
5231 }
5232 }
5233}
5234
5235#endif // TEST_TEXTSTREAM
5236
e87271f3
VZ
5237// ----------------------------------------------------------------------------
5238// threads
5239// ----------------------------------------------------------------------------
5240
5241#ifdef TEST_THREADS
5242
e84010cf 5243#include "wx/thread.h"
37667812 5244
bbfa0322
VZ
5245static size_t gs_counter = (size_t)-1;
5246static wxCriticalSection gs_critsect;
c112e100 5247static wxSemaphore gs_cond;
bbfa0322 5248
b568d04f 5249class MyJoinableThread : public wxThread
bbfa0322
VZ
5250{
5251public:
b568d04f
VZ
5252 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
5253 { m_n = n; Create(); }
bbfa0322
VZ
5254
5255 // thread execution starts here
b568d04f 5256 virtual ExitCode Entry();
bbfa0322 5257
b568d04f
VZ
5258private:
5259 size_t m_n;
bbfa0322
VZ
5260};
5261
b568d04f 5262wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 5263{
b568d04f
VZ
5264 unsigned long res = 1;
5265 for ( size_t n = 1; n < m_n; n++ )
5266 {
5267 res *= n;
5268
5269 // it's a loooong calculation :-)
5270 Sleep(100);
5271 }
bbfa0322 5272
b568d04f 5273 return (ExitCode)res;
bbfa0322
VZ
5274}
5275
b568d04f
VZ
5276class MyDetachedThread : public wxThread
5277{
5278public:
456ae26d 5279 MyDetachedThread(size_t n, wxChar ch)
fcc3d7cb
VZ
5280 {
5281 m_n = n;
5282 m_ch = ch;
cab8f76e 5283 m_cancelled = false;
fcc3d7cb
VZ
5284
5285 Create();
5286 }
b568d04f
VZ
5287
5288 // thread execution starts here
5289 virtual ExitCode Entry();
5290
5291 // and stops here
5292 virtual void OnExit();
5293
5294private:
9fc3ad34 5295 size_t m_n; // number of characters to write
456ae26d 5296 wxChar m_ch; // character to write
fcc3d7cb 5297
cab8f76e 5298 bool m_cancelled; // false if we exit normally
b568d04f
VZ
5299};
5300
5301wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
5302{
5303 {
5304 wxCriticalSectionLocker lock(gs_critsect);
5305 if ( gs_counter == (size_t)-1 )
5306 gs_counter = 1;
5307 else
5308 gs_counter++;
5309 }
5310
9fc3ad34 5311 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
5312 {
5313 if ( TestDestroy() )
fcc3d7cb 5314 {
cab8f76e 5315 m_cancelled = true;
fcc3d7cb 5316
bbfa0322 5317 break;
fcc3d7cb 5318 }
bbfa0322
VZ
5319
5320 putchar(m_ch);
5321 fflush(stdout);
5322
5323 wxThread::Sleep(100);
5324 }
5325
b568d04f 5326 return 0;
bbfa0322
VZ
5327}
5328
b568d04f 5329void MyDetachedThread::OnExit()
bbfa0322 5330{
456ae26d 5331 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
9fc3ad34 5332
bbfa0322 5333 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 5334 if ( !--gs_counter && !m_cancelled )
c112e100 5335 gs_cond.Post();
bbfa0322
VZ
5336}
5337
2f2f3e2a 5338static void TestDetachedThreads()
9fc3ad34 5339{
456ae26d 5340 wxPuts(_T("\n*** Testing detached threads ***"));
9fc3ad34
VZ
5341
5342 static const size_t nThreads = 3;
5343 MyDetachedThread *threads[nThreads];
5344 size_t n;
5345 for ( n = 0; n < nThreads; n++ )
5346 {
5347 threads[n] = new MyDetachedThread(10, 'A' + n);
5348 }
5349
5350 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
5351 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
5352
5353 for ( n = 0; n < nThreads; n++ )
5354 {
5355 threads[n]->Run();
5356 }
5357
5358 // wait until all threads terminate
5359 gs_cond.Wait();
5360
456ae26d 5361 wxPuts(_T(""));
9fc3ad34
VZ
5362}
5363
2f2f3e2a 5364static void TestJoinableThreads()
9fc3ad34 5365{
456ae26d 5366 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
9fc3ad34
VZ
5367
5368 // calc 10! in the background
5369 MyJoinableThread thread(10);
5370 thread.Run();
5371
456ae26d 5372 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
9fc3ad34
VZ
5373 (unsigned long)thread.Wait());
5374}
5375
2f2f3e2a 5376static void TestThreadSuspend()
9fc3ad34 5377{
456ae26d 5378 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
2f02cb89
VZ
5379
5380 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
5381
5382 thread->Run();
5383
5384 // this is for this demo only, in a real life program we'd use another
5385 // condition variable which would be signaled from wxThread::Entry() to
5386 // tell us that the thread really started running - but here just wait a
5387 // bit and hope that it will be enough (the problem is, of course, that
5388 // the thread might still not run when we call Pause() which will result
5389 // in an error)
5390 wxThread::Sleep(300);
5391
5392 for ( size_t n = 0; n < 3; n++ )
5393 {
5394 thread->Pause();
5395
456ae26d 5396 wxPuts(_T("\nThread suspended"));
9fc3ad34
VZ
5397 if ( n > 0 )
5398 {
5399 // don't sleep but resume immediately the first time
5400 wxThread::Sleep(300);
5401 }
456ae26d 5402 wxPuts(_T("Going to resume the thread"));
9fc3ad34
VZ
5403
5404 thread->Resume();
5405 }
5406
456ae26d 5407 wxPuts(_T("Waiting until it terminates now"));
4c460b34 5408
9fc3ad34
VZ
5409 // wait until the thread terminates
5410 gs_cond.Wait();
5411
456ae26d 5412 wxPuts(_T(""));
9fc3ad34
VZ
5413}
5414
2f2f3e2a 5415static void TestThreadDelete()
2f02cb89
VZ
5416{
5417 // As above, using Sleep() is only for testing here - we must use some
5418 // synchronisation object instead to ensure that the thread is still
5419 // running when we delete it - deleting a detached thread which already
5420 // terminated will lead to a crash!
5421
456ae26d 5422 wxPuts(_T("\n*** Testing thread delete function ***"));
2f02cb89 5423
4c460b34
VZ
5424 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
5425
5426 thread0->Delete();
5427
456ae26d 5428 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
4c460b34 5429
2f02cb89
VZ
5430 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
5431
5432 thread1->Run();
5433
5434 wxThread::Sleep(300);
5435
5436 thread1->Delete();
5437
456ae26d 5438 wxPuts(_T("\nDeleted a running thread."));
2f02cb89
VZ
5439
5440 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
5441
5442 thread2->Run();
5443
5444 wxThread::Sleep(300);
5445
5446 thread2->Pause();
5447
5448 thread2->Delete();
5449
456ae26d 5450 wxPuts(_T("\nDeleted a sleeping thread."));
2f02cb89 5451
4c460b34
VZ
5452 MyJoinableThread thread3(20);
5453 thread3.Run();
2f02cb89 5454
4c460b34 5455 thread3.Delete();
2f02cb89 5456
456ae26d 5457 wxPuts(_T("\nDeleted a joinable thread."));
2f02cb89 5458
4c460b34
VZ
5459 MyJoinableThread thread4(2);
5460 thread4.Run();
2f02cb89
VZ
5461
5462 wxThread::Sleep(300);
5463
4c460b34 5464 thread4.Delete();
2f02cb89 5465
456ae26d 5466 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
2f02cb89 5467
456ae26d 5468 wxPuts(_T(""));
2f02cb89
VZ
5469}
5470
2f2f3e2a
VZ
5471class MyWaitingThread : public wxThread
5472{
5473public:
c112e100 5474 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
2f2f3e2a 5475 {
c112e100 5476 m_mutex = mutex;
2f2f3e2a
VZ
5477 m_condition = condition;
5478
5479 Create();
5480 }
5481
5482 virtual ExitCode Entry()
5483 {
456ae26d 5484 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
2f2f3e2a
VZ
5485 fflush(stdout);
5486
c112e100 5487 gs_cond.Post();
2f2f3e2a 5488
456ae26d 5489 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
2f2f3e2a
VZ
5490 fflush(stdout);
5491
c112e100 5492 m_mutex->Lock();
2f2f3e2a 5493 m_condition->Wait();
c112e100 5494 m_mutex->Unlock();
2f2f3e2a 5495
456ae26d 5496 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
2f2f3e2a
VZ
5497 fflush(stdout);
5498
5499 return 0;
5500 }
5501
5502private:
c112e100 5503 wxMutex *m_mutex;
2f2f3e2a
VZ
5504 wxCondition *m_condition;
5505};
5506
5507static void TestThreadConditions()
5508{
c112e100
VZ
5509 wxMutex mutex;
5510 wxCondition condition(mutex);
2f2f3e2a 5511
8d5eff60
VZ
5512 // otherwise its difficult to understand which log messages pertain to
5513 // which condition
456ae26d 5514 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
c112e100 5515 // condition.GetId(), gs_cond.GetId());
8d5eff60 5516
2f2f3e2a 5517 // create and launch threads
60ce696e 5518 MyWaitingThread *threads[10];
2f2f3e2a
VZ
5519
5520 size_t n;
5521 for ( n = 0; n < WXSIZEOF(threads); n++ )
5522 {
c112e100 5523 threads[n] = new MyWaitingThread( &mutex, &condition );
2f2f3e2a
VZ
5524 }
5525
5526 for ( n = 0; n < WXSIZEOF(threads); n++ )
5527 {
5528 threads[n]->Run();
5529 }
5530
5531 // wait until all threads run
456ae26d 5532 wxPuts(_T("Main thread is waiting for the other threads to start"));
2f2f3e2a
VZ
5533 fflush(stdout);
5534
5535 size_t nRunning = 0;
5536 while ( nRunning < WXSIZEOF(threads) )
5537 {
5538 gs_cond.Wait();
5539
2f2f3e2a 5540 nRunning++;
8d5eff60 5541
456ae26d 5542 wxPrintf(_T("Main thread: %u already running\n"), nRunning);
8d5eff60 5543 fflush(stdout);
2f2f3e2a
VZ
5544 }
5545
456ae26d 5546 wxPuts(_T("Main thread: all threads started up."));
2f2f3e2a
VZ
5547 fflush(stdout);
5548
8d5eff60
VZ
5549 wxThread::Sleep(500);
5550
60ce696e 5551#if 1
8d5eff60 5552 // now wake one of them up
456ae26d 5553 wxPrintf(_T("Main thread: about to signal the condition.\n"));
2f2f3e2a
VZ
5554 fflush(stdout);
5555 condition.Signal();
8d5eff60 5556#endif
2f2f3e2a 5557
60ce696e
VZ
5558 wxThread::Sleep(200);
5559
8d5eff60 5560 // wake all the (remaining) threads up, so that they can exit
456ae26d 5561 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
2f2f3e2a
VZ
5562 fflush(stdout);
5563 condition.Broadcast();
5564
8d5eff60
VZ
5565 // give them time to terminate (dirty!)
5566 wxThread::Sleep(500);
2f2f3e2a
VZ
5567}
5568
c112e100
VZ
5569#include "wx/utils.h"
5570
5571class MyExecThread : public wxThread
5572{
5573public:
5574 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
5575 m_command(command)
5576 {
5577 Create();
5578 }
5579
5580 virtual ExitCode Entry()
5581 {
5582 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
5583 }
5584
5585private:
5586 wxString m_command;
5587};
5588
5589static void TestThreadExec()
5590{
5591 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
5592
5593 MyExecThread thread(_T("true"));
5594 thread.Run();
5595
5596 wxPrintf(_T("Main program exit code: %ld.\n"),
5597 wxExecute(_T("false"), wxEXEC_SYNC));
5598
5599 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
5600}
5601
5602// semaphore tests
5603#include "wx/datetime.h"
5604
5605class MySemaphoreThread : public wxThread
5606{
5607public:
5608 MySemaphoreThread(int i, wxSemaphore *sem)
5609 : wxThread(wxTHREAD_JOINABLE),
5610 m_sem(sem),
5611 m_i(i)
5612 {
5613 Create();
5614 }
5615
5616 virtual ExitCode Entry()
5617 {
f06ef5f4
VZ
5618 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
5619 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5620
5621 m_sem->Wait();
5622
f06ef5f4
VZ
5623 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
5624 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5625
5626 Sleep(1000);
5627
f06ef5f4
VZ
5628 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
5629 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5630
5631 m_sem->Post();
5632
5633 return 0;
5634 }
5635
5636private:
5637 wxSemaphore *m_sem;
5638 int m_i;
5639};
5640
5641WX_DEFINE_ARRAY(wxThread *, ArrayThreads);
5642
5643static void TestSemaphore()
5644{
5645 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5646
5647 static const int SEM_LIMIT = 3;
5648
5649 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
5650 ArrayThreads threads;
5651
5652 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
5653 {
5654 threads.Add(new MySemaphoreThread(i, &sem));
5655 threads.Last()->Run();
5656 }
5657
5658 for ( size_t n = 0; n < threads.GetCount(); n++ )
5659 {
5660 threads[n]->Wait();
5661 delete threads[n];
5662 }
5663}
5664
e87271f3
VZ
5665#endif // TEST_THREADS
5666
5667// ----------------------------------------------------------------------------
5668// arrays
5669// ----------------------------------------------------------------------------
5670
5671#ifdef TEST_ARRAYS
5672
1a931653 5673#include "wx/dynarray.h"
e87271f3 5674
3dc01741
VZ
5675typedef unsigned short ushort;
5676
1a931653
VZ
5677#define DefineCompare(name, T) \
5678 \
5679int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
5680{ \
5681 return first - second; \
5682} \
5683 \
5684int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
5685{ \
5686 return *first - *second; \
5687} \
5688 \
5689int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
5690{ \
5691 return *second - *first; \
5692} \
5693
3dc01741 5694DefineCompare(UShort, ushort);
1a931653
VZ
5695DefineCompare(Int, int);
5696
5697// test compilation of all macros
3dc01741
VZ
5698WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
5699WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
5700WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
5701WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
e87271f3 5702
1a931653
VZ
5703WX_DECLARE_OBJARRAY(Bar, ArrayBars);
5704#include "wx/arrimpl.cpp"
5705WX_DEFINE_OBJARRAY(ArrayBars);
5706
456ae26d 5707static void PrintArray(const wxChar* name, const wxArrayString& array)
d6c9c1b7 5708{
456ae26d 5709 wxPrintf(_T("Dump of the array '%s'\n"), name);
d6c9c1b7
VZ
5710
5711 size_t nCount = array.GetCount();
5712 for ( size_t n = 0; n < nCount; n++ )
5713 {
456ae26d 5714 wxPrintf(_T("\t%s[%u] = '%s'\n"), name, n, array[n].c_str());
d6c9c1b7
VZ
5715 }
5716}
5717
5718int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
5719 const wxString& second)
f6bcfd97
BP
5720{
5721 return first.length() - second.length();
5722}
5723
1a931653
VZ
5724#define TestArrayOf(name) \
5725 \
456ae26d 5726static void PrintArray(const wxChar* name, const wxSortedArray##name & array) \
1a931653 5727{ \
456ae26d 5728 wxPrintf(_T("Dump of the array '%s'\n"), name); \
1a931653
VZ
5729 \
5730 size_t nCount = array.GetCount(); \
5731 for ( size_t n = 0; n < nCount; n++ ) \
5732 { \
456ae26d 5733 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
1a931653
VZ
5734 } \
5735} \
5736 \
456ae26d 5737static void PrintArray(const wxChar* name, const wxArray##name & array) \
1a931653 5738{ \
456ae26d 5739 wxPrintf(_T("Dump of the array '%s'\n"), name); \
1a931653
VZ
5740 \
5741 size_t nCount = array.GetCount(); \
5742 for ( size_t n = 0; n < nCount; n++ ) \
5743 { \
456ae26d 5744 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
1a931653
VZ
5745 } \
5746} \
5747 \
5748static void TestArrayOf ## name ## s() \
5749{ \
456ae26d 5750 wxPrintf(_T("*** Testing wxArray%s ***\n"), #name); \
1a931653
VZ
5751 \
5752 wxArray##name a; \
5753 a.Add(1); \
f74a90b3
SN
5754 a.Add(17,2); \
5755 a.Add(5,3); \
5756 a.Add(3,4); \
1a931653 5757 \
456ae26d
VZ
5758 wxPuts(_T("Initially:")); \
5759 PrintArray(_T("a"), a); \
1a931653 5760 \
456ae26d 5761 wxPuts(_T("After sort:")); \
1a931653 5762 a.Sort(name ## Compare); \
456ae26d 5763 PrintArray(_T("a"), a); \
1a931653 5764 \
456ae26d 5765 wxPuts(_T("After reverse sort:")); \
1a931653 5766 a.Sort(name ## RevCompare); \
456ae26d 5767 PrintArray(_T("a"), a); \
1a931653
VZ
5768 \
5769 wxSortedArray##name b; \
5770 b.Add(1); \
5771 b.Add(17); \
5772 b.Add(5); \
5773 b.Add(3); \
5774 \
456ae26d
VZ
5775 wxPuts(_T("Sorted array initially:")); \
5776 PrintArray(_T("b"), b); \
d6c9c1b7
VZ
5777}
5778
3dc01741 5779TestArrayOf(UShort);
1a931653 5780TestArrayOf(Int);
f6bcfd97
BP
5781
5782static void TestArrayOfObjects()
5783{
456ae26d 5784 wxPuts(_T("*** Testing wxObjArray ***\n"));
f6bcfd97
BP
5785
5786 {
5787 ArrayBars bars;
f74a90b3 5788 Bar bar("second bar (two copies!)");
f6bcfd97 5789
456ae26d 5790 wxPrintf(_T("Initially: %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5791 bars.GetCount(), Bar::GetNumber());
5792
5793 bars.Add(new Bar("first bar"));
f74a90b3 5794 bars.Add(bar,2);
f6bcfd97 5795
456ae26d 5796 wxPrintf(_T("Now: %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5797 bars.GetCount(), Bar::GetNumber());
5798
456ae26d 5799 bars.RemoveAt(1, bars.GetCount() - 1);
f74a90b3 5800
456ae26d
VZ
5801 wxPrintf(_T("After removing all but first element: %u objects in the ")
5802 _T("array, %u objects total.\n"),
f74a90b3
SN
5803 bars.GetCount(), Bar::GetNumber());
5804
f6bcfd97
BP
5805 bars.Empty();
5806
456ae26d 5807 wxPrintf(_T("After Empty(): %u objects in the array, %u objects total.\n"),
f6bcfd97
BP
5808 bars.GetCount(), Bar::GetNumber());
5809 }
5810
456ae26d 5811 wxPrintf(_T("Finally: no more objects in the array, %u objects total.\n"),
f6bcfd97
BP
5812 Bar::GetNumber());
5813}
5814
e87271f3
VZ
5815#endif // TEST_ARRAYS
5816
9fc3ad34
VZ
5817// ----------------------------------------------------------------------------
5818// strings
5819// ----------------------------------------------------------------------------
5820
5821#ifdef TEST_STRINGS
5822
5823#include "wx/timer.h"
bbf8fc53 5824#include "wx/tokenzr.h"
9fc3ad34 5825
7c968cee
VZ
5826static void TestStringConstruction()
5827{
456ae26d 5828 wxPuts(_T("*** Testing wxString constructores ***"));
7c968cee
VZ
5829
5830 #define TEST_CTOR(args, res) \
5831 { \
5832 wxString s args ; \
456ae26d 5833 wxPrintf(_T("wxString%s = %s "), #args, s.c_str()); \
7c968cee
VZ
5834 if ( s == res ) \
5835 { \
456ae26d 5836 wxPuts(_T("(ok)")); \
7c968cee
VZ
5837 } \
5838 else \
5839 { \
456ae26d 5840 wxPrintf(_T("(ERROR: should be %s)\n"), res); \
7c968cee
VZ
5841 } \
5842 }
5843
5844 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5845 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5846 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5847 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5848
5849 static const wxChar *s = _T("?really!");
5850 const wxChar *start = wxStrchr(s, _T('r'));
5851 const wxChar *end = wxStrchr(s, _T('!'));
5852 TEST_CTOR((start, end), _T("really"));
5853
456ae26d 5854 wxPuts(_T(""));
7c968cee
VZ
5855}
5856
299fcbfe 5857static void TestString()
9fc3ad34
VZ
5858{
5859 wxStopWatch sw;
5860
5861 wxString a, b, c;
5862
5863 a.reserve (128);
5864 b.reserve (128);
5865 c.reserve (128);
5866
5867 for (int i = 0; i < 1000000; ++i)
5868 {
5869 a = "Hello";
5870 b = " world";
5871 c = "! How'ya doin'?";
5872 a += b;
5873 a += c;
5874 c = "Hello world! What's up?";
5875 if (c != a)
5876 c = "Doh!";
5877 }
5878
456ae26d 5879 wxPrintf(_T("TestString elapsed time: %ld\n"), sw.Time());
9fc3ad34
VZ
5880}
5881
299fcbfe 5882static void TestPChar()
9fc3ad34
VZ
5883{
5884 wxStopWatch sw;
5885
456ae26d
VZ
5886 wxChar a [128];
5887 wxChar b [128];
5888 wxChar c [128];
9fc3ad34
VZ
5889
5890 for (int i = 0; i < 1000000; ++i)
5891 {
456ae26d
VZ
5892 wxStrcpy (a, _T("Hello"));
5893 wxStrcpy (b, _T(" world"));
5894 wxStrcpy (c, _T("! How'ya doin'?"));
5895 wxStrcat (a, b);
5896 wxStrcat (a, c);
5897 wxStrcpy (c, _T("Hello world! What's up?"));
5898 if (wxStrcmp (c, a) == 0)
5899 wxStrcpy (c, _T("Doh!"));
9fc3ad34
VZ
5900 }
5901
456ae26d 5902 wxPrintf(_T("TestPChar elapsed time: %ld\n"), sw.Time());
9fc3ad34
VZ
5903}
5904
299fcbfe
VZ
5905static void TestStringSub()
5906{
5907 wxString s("Hello, world!");
5908
456ae26d 5909 wxPuts(_T("*** Testing wxString substring extraction ***"));
299fcbfe 5910
456ae26d
VZ
5911 wxPrintf(_T("String = '%s'\n"), s.c_str());
5912 wxPrintf(_T("Left(5) = '%s'\n"), s.Left(5).c_str());
5913 wxPrintf(_T("Right(6) = '%s'\n"), s.Right(6).c_str());
5914 wxPrintf(_T("Mid(3, 5) = '%s'\n"), s(3, 5).c_str());
5915 wxPrintf(_T("Mid(3) = '%s'\n"), s.Mid(3).c_str());
5916 wxPrintf(_T("substr(3, 5) = '%s'\n"), s.substr(3, 5).c_str());
5917 wxPrintf(_T("substr(3) = '%s'\n"), s.substr(3).c_str());
299fcbfe 5918
f6bcfd97
BP
5919 static const wxChar *prefixes[] =
5920 {
5921 _T("Hello"),
5922 _T("Hello, "),
5923 _T("Hello, world!"),
5924 _T("Hello, world!!!"),
5925 _T(""),
5926 _T("Goodbye"),
5927 _T("Hi"),
5928 };
5929
5930 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5931 {
5932 wxString prefix = prefixes[n], rest;
5933 bool rc = s.StartsWith(prefix, &rest);
cab8f76e 5934 wxPrintf(_T("StartsWith('%s') = %s"), prefix.c_str(), rc ? _T("true") : _T("false"));
f6bcfd97
BP
5935 if ( rc )
5936 {
456ae26d 5937 wxPrintf(_T(" (the rest is '%s')\n"), rest.c_str());
f6bcfd97
BP
5938 }
5939 else
5940 {
5941 putchar('\n');
5942 }
5943 }
5944
456ae26d 5945 wxPuts(_T(""));
299fcbfe
VZ
5946}
5947
f0f951fa
VZ
5948static void TestStringFormat()
5949{
456ae26d 5950 wxPuts(_T("*** Testing wxString formatting ***"));
f0f951fa
VZ
5951
5952 wxString s;
456ae26d 5953 s.Printf(_T("%03d"), 18);
f0f951fa 5954
456ae26d
VZ
5955 wxPrintf(_T("Number 18: %s\n"), wxString::Format(_T("%03d"), 18).c_str());
5956 wxPrintf(_T("Number 18: %s\n"), s.c_str());
f0f951fa 5957
456ae26d 5958 wxPuts(_T(""));
f0f951fa
VZ
5959}
5960
d71fa6fb
VZ
5961// returns "not found" for npos, value for all others
5962static wxString PosToString(size_t res)
5963{
5964 wxString s = res == wxString::npos ? wxString(_T("not found"))
5965 : wxString::Format(_T("%u"), res);
5966 return s;
5967}
5968
5969static void TestStringFind()
5970{
456ae26d 5971 wxPuts(_T("*** Testing wxString find() functions ***"));
d71fa6fb
VZ
5972
5973 static const wxChar *strToFind = _T("ell");
5974 static const struct StringFindTest
5975 {
5976 const wxChar *str;
5977 size_t start,
5978 result; // of searching "ell" in str
5979 } findTestData[] =
5980 {
5981 { _T("Well, hello world"), 0, 1 },
5982 { _T("Well, hello world"), 6, 7 },
5983 { _T("Well, hello world"), 9, wxString::npos },
5984 };
5985
5986 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5987 {
5988 const StringFindTest& ft = findTestData[n];
5989 size_t res = wxString(ft.str).find(strToFind, ft.start);
5990
456ae26d 5991 wxPrintf(_T("Index of '%s' in '%s' starting from %u is %s "),
d71fa6fb
VZ
5992 strToFind, ft.str, ft.start, PosToString(res).c_str());
5993
5994 size_t resTrue = ft.result;
5995 if ( res == resTrue )
5996 {
456ae26d 5997 wxPuts(_T("(ok)"));
d71fa6fb
VZ
5998 }
5999 else
6000 {
456ae26d 6001 wxPrintf(_T("(ERROR: should be %s)\n"),
d71fa6fb
VZ
6002 PosToString(resTrue).c_str());
6003 }
6004 }
6005
456ae26d 6006 wxPuts(_T(""));
d71fa6fb
VZ
6007}
6008
bbf8fc53
VZ
6009static void TestStringTokenizer()
6010{
456ae26d 6011 wxPuts(_T("*** Testing wxStringTokenizer ***"));
bbf8fc53 6012
7c968cee
VZ
6013 static const wxChar *modeNames[] =
6014 {
6015 _T("default"),
6016 _T("return empty"),
6017 _T("return all empty"),
6018 _T("with delims"),
6019 _T("like strtok"),
6020 };
6021
bbf8fc53
VZ
6022 static const struct StringTokenizerTest
6023 {
7c968cee
VZ
6024 const wxChar *str; // string to tokenize
6025 const wxChar *delims; // delimiters to use
6026 size_t count; // count of token
6027 wxStringTokenizerMode mode; // how should we tokenize it
6028 } tokenizerTestData[] =
6029 {
6030 { _T(""), _T(" "), 0 },
6031 { _T("Hello, world"), _T(" "), 2 },
6032 { _T("Hello, world "), _T(" "), 2 },
6033 { _T("Hello, world"), _T(","), 2 },
6034 { _T("Hello, world!"), _T(",!"), 2 },
6035 { _T("Hello,, world!"), _T(",!"), 3 },
6036 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
6037 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
6038 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
6039 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
6040 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
6041 { _T("01/02/99"), _T("/-"), 3 },
6042 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
bbf8fc53
VZ
6043 };
6044
6045 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
6046 {
6047 const StringTokenizerTest& tt = tokenizerTestData[n];
7c968cee 6048 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
bbf8fc53
VZ
6049
6050 size_t count = tkz.CountTokens();
456ae26d 6051 wxPrintf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
7c968cee 6052 MakePrintable(tt.str).c_str(),
bbf8fc53 6053 count,
7c968cee
VZ
6054 MakePrintable(tt.delims).c_str(),
6055 modeNames[tkz.GetMode()]);
bbf8fc53
VZ
6056 if ( count == tt.count )
6057 {
456ae26d 6058 wxPuts(_T("(ok)"));
bbf8fc53
VZ
6059 }
6060 else
6061 {
456ae26d 6062 wxPrintf(_T("(ERROR: should be %u)\n"), tt.count);
bbf8fc53
VZ
6063
6064 continue;
6065 }
6066
7c968cee 6067 // if we emulate strtok(), check that we do it correctly
f6bcfd97 6068 wxChar *buf, *s = NULL, *last;
7c968cee
VZ
6069
6070 if ( tkz.GetMode() == wxTOKEN_STRTOK )
6071 {
6072 buf = new wxChar[wxStrlen(tt.str) + 1];
6073 wxStrcpy(buf, tt.str);
6074
6075 s = wxStrtok(buf, tt.delims, &last);
6076 }
6077 else
6078 {
6079 buf = NULL;
6080 }
6081
bbf8fc53
VZ
6082 // now show the tokens themselves
6083 size_t count2 = 0;
6084 while ( tkz.HasMoreTokens() )
6085 {
7c968cee
VZ
6086 wxString token = tkz.GetNextToken();
6087
456ae26d 6088 wxPrintf(_T("\ttoken %u: '%s'"),
bbf8fc53 6089 ++count2,
7c968cee
VZ
6090 MakePrintable(token).c_str());
6091
6092 if ( buf )
6093 {
6094 if ( token == s )
6095 {
456ae26d 6096 wxPuts(_T(" (ok)"));
7c968cee
VZ
6097 }
6098 else
6099 {
456ae26d 6100 wxPrintf(_T(" (ERROR: should be %s)\n"), s);
7c968cee
VZ
6101 }
6102
6103 s = wxStrtok(NULL, tt.delims, &last);
6104 }
6105 else
6106 {
6107 // nothing to compare with
456ae26d 6108 wxPuts(_T(""));
7c968cee 6109 }
bbf8fc53
VZ
6110 }
6111
6112 if ( count2 != count )
6113 {
456ae26d 6114 wxPuts(_T("\tERROR: token count mismatch"));
bbf8fc53 6115 }
7c968cee
VZ
6116
6117 delete [] buf;
bbf8fc53
VZ
6118 }
6119
456ae26d 6120 wxPuts(_T(""));
bbf8fc53
VZ
6121}
6122
f6bcfd97
BP
6123static void TestStringReplace()
6124{
456ae26d 6125 wxPuts(_T("*** Testing wxString::replace ***"));
f6bcfd97
BP
6126
6127 static const struct StringReplaceTestData
6128 {
6129 const wxChar *original; // original test string
6130 size_t start, len; // the part to replace
6131 const wxChar *replacement; // the replacement string
6132 const wxChar *result; // and the expected result
6133 } stringReplaceTestData[] =
6134 {
6135 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
6136 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
6137 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
6138 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
6139 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
6140 };
6141
6142 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
6143 {
6144 const StringReplaceTestData data = stringReplaceTestData[n];
6145
6146 wxString original = data.original;
6147 original.replace(data.start, data.len, data.replacement);
6148
6149 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
6150 data.original, data.start, data.len, data.replacement,
6151 original.c_str());
6152
6153 if ( original == data.result )
6154 {
456ae26d 6155 wxPuts(_T("(ok)"));
f6bcfd97
BP
6156 }
6157 else
6158 {
6159 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
6160 }
6161 }
6162
456ae26d 6163 wxPuts(_T(""));
f6bcfd97
BP
6164}
6165
9a4232dc
VZ
6166static void TestStringMatch()
6167{
6168 wxPuts(_T("*** Testing wxString::Matches() ***"));
6169
6170 static const struct StringMatchTestData
6171 {
6172 const wxChar *text;
6173 const wxChar *wildcard;
6174 bool matches;
6175 } stringMatchTestData[] =
6176 {
6177 { _T("foobar"), _T("foo*"), 1 },
6178 { _T("foobar"), _T("*oo*"), 1 },
6179 { _T("foobar"), _T("*bar"), 1 },
6180 { _T("foobar"), _T("??????"), 1 },
6181 { _T("foobar"), _T("f??b*"), 1 },
6182 { _T("foobar"), _T("f?b*"), 0 },
6183 { _T("foobar"), _T("*goo*"), 0 },
6184 { _T("foobar"), _T("*foo"), 0 },
6185 { _T("foobarfoo"), _T("*foo"), 1 },
6186 { _T(""), _T("*"), 1 },
6187 { _T(""), _T("?"), 0 },
6188 };
6189
6190 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
6191 {
6192 const StringMatchTestData& data = stringMatchTestData[n];
6193 bool matches = wxString(data.text).Matches(data.wildcard);
6194 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
6195 data.wildcard,
6196 matches ? _T("matches") : _T("doesn't match"),
6197 data.text,
6198 matches == data.matches ? _T("ok") : _T("ERROR"));
6199 }
6200
6201 wxPuts(_T(""));
6202}
6203
9fc3ad34
VZ
6204#endif // TEST_STRINGS
6205
e87271f3
VZ
6206// ----------------------------------------------------------------------------
6207// entry point
6208// ----------------------------------------------------------------------------
6209
daa2c7d9
VZ
6210#ifdef TEST_SNGLINST
6211 #include "wx/snglinst.h"
6212#endif // TEST_SNGLINST
6213
bbfa0322 6214int main(int argc, char **argv)
37667812 6215{
9cb47ea2
VZ
6216 wxApp::CheckBuildOptions(wxBuildOptions());
6217
58b24a56
VZ
6218 wxInitializer initializer;
6219 if ( !initializer )
37667812
VZ
6220 {
6221 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
6222
6223 return -1;
6224 }
6225
6226#ifdef TEST_SNGLINST
b5299791
VZ
6227 wxSingleInstanceChecker checker;
6228 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 6229 {
b5299791
VZ
6230 if ( checker.IsAnotherRunning() )
6231 {
6232 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 6233
b5299791
VZ
6234 return 1;
6235 }
37667812 6236
b5299791
VZ
6237 // wait some time to give time to launch another instance
6238 wxPrintf(_T("Press \"Enter\" to continue..."));
6239 wxFgetc(stdin);
6240 }
6241 else // failed to create
6242 {
6243 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
6244 }
58b24a56
VZ
6245#endif // TEST_SNGLINST
6246
551fe3a6
VZ
6247#ifdef TEST_CHARSET
6248 TestCharset();
6249#endif // TEST_CHARSET
0de868d9 6250
d34bce84 6251#ifdef TEST_CMDLINE
31f6de22
VZ
6252 TestCmdLineConvert();
6253
6254#if wxUSE_CMDLINE_PARSER
d34bce84
VZ
6255 static const wxCmdLineEntryDesc cmdLineDesc[] =
6256 {
456ae26d 6257 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
31a06b07 6258 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
456ae26d
VZ
6259 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
6260 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },
d34bce84 6261
456ae26d
VZ
6262 { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },
6263 { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },
6264 { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),
31a06b07 6265 wxCMD_LINE_VAL_NUMBER },
456ae26d 6266 { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),
31a06b07 6267 wxCMD_LINE_VAL_DATE },
d34bce84 6268
456ae26d 6269 { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),
d34bce84
VZ
6270 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
6271
6272 { wxCMD_LINE_NONE }
6273 };
6274
456ae26d
VZ
6275#if wxUSE_UNICODE
6276 wxChar **wargv = new wxChar *[argc + 1];
6277
6278 {
6279 for ( int n = 0; n < argc; n++ )
6280 {
6281 wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
6282 wargv[n] = wxStrdup(warg);
6283 }
6284
6285 wargv[n] = NULL;
6286 }
6287
6288 #define argv wargv
6289#endif // wxUSE_UNICODE
6290
d34bce84
VZ
6291 wxCmdLineParser parser(cmdLineDesc, argc, argv);
6292
456ae26d
VZ
6293#if wxUSE_UNICODE
6294 {
6295 for ( int n = 0; n < argc; n++ )
6296 free(wargv[n]);
6297
6298 delete [] wargv;
6299 }
6300#endif // wxUSE_UNICODE
6301
6302 parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
f6bcfd97
BP
6303 wxCMD_LINE_VAL_STRING,
6304 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
6305
d34bce84
VZ
6306 switch ( parser.Parse() )
6307 {
6308 case -1:
456ae26d 6309 wxLogMessage(_T("Help was given, terminating."));
d34bce84
VZ
6310 break;
6311
6312 case 0:
6313 ShowCmdLine(parser);
6314 break;
6315
6316 default:
456ae26d 6317 wxLogMessage(_T("Syntax error detected, aborting."));
d34bce84
VZ
6318 break;
6319 }
31f6de22
VZ
6320#endif // wxUSE_CMDLINE_PARSER
6321
d34bce84
VZ
6322#endif // TEST_CMDLINE
6323
9fc3ad34 6324#ifdef TEST_STRINGS
daa2c7d9 6325 if ( TEST_ALL )
299fcbfe
VZ
6326 {
6327 TestPChar();
6328 TestString();
f6bcfd97 6329 TestStringSub();
7c968cee 6330 TestStringConstruction();
d71fa6fb 6331 TestStringFormat();
bbf8fc53 6332 TestStringFind();
7c968cee 6333 TestStringTokenizer();
f6bcfd97 6334 TestStringReplace();
ee6e1b1d 6335 }
daa2c7d9
VZ
6336 else
6337 {
6338 TestStringMatch();
6339 }
9fc3ad34
VZ
6340#endif // TEST_STRINGS
6341
e87271f3 6342#ifdef TEST_ARRAYS
daa2c7d9 6343 if ( TEST_ALL )
d6c9c1b7 6344 {
daa2c7d9 6345 wxArrayString a1;
456ae26d
VZ
6346 a1.Add(_T("tiger"));
6347 a1.Add(_T("cat"));
6348 a1.Add(_T("lion"), 3);
6349 a1.Add(_T("dog"));
6350 a1.Add(_T("human"));
6351 a1.Add(_T("ape"));
e87271f3 6352
456ae26d 6353 wxPuts(_T("*** Initially:"));
e87271f3 6354
456ae26d 6355 PrintArray(_T("a1"), a1);
e87271f3 6356
daa2c7d9 6357 wxArrayString a2(a1);
456ae26d 6358 PrintArray(_T("a2"), a2);
e87271f3 6359
daa2c7d9 6360 wxSortedArrayString a3(a1);
456ae26d 6361 PrintArray(_T("a3"), a3);
e87271f3 6362
456ae26d 6363 wxPuts(_T("*** After deleting three strings from a1"));
f74a90b3 6364 a1.Remove(2,3);
e87271f3 6365
456ae26d
VZ
6366 PrintArray(_T("a1"), a1);
6367 PrintArray(_T("a2"), a2);
6368 PrintArray(_T("a3"), a3);
e87271f3 6369
456ae26d 6370 wxPuts(_T("*** After reassigning a1 to a2 and a3"));
daa2c7d9 6371 a3 = a2 = a1;
456ae26d
VZ
6372 PrintArray(_T("a2"), a2);
6373 PrintArray(_T("a3"), a3);
f6bcfd97 6374
456ae26d 6375 wxPuts(_T("*** After sorting a1"));
daa2c7d9 6376 a1.Sort();
456ae26d 6377 PrintArray(_T("a1"), a1);
f6bcfd97 6378
456ae26d 6379 wxPuts(_T("*** After sorting a1 in reverse order"));
cab8f76e 6380 a1.Sort(true);
456ae26d 6381 PrintArray(_T("a1"), a1);
f6bcfd97 6382
456ae26d 6383 wxPuts(_T("*** After sorting a1 by the string length"));
daa2c7d9 6384 a1.Sort(StringLenCompare);
456ae26d 6385 PrintArray(_T("a1"), a1);
f6bcfd97 6386
daa2c7d9 6387 TestArrayOfObjects();
3dc01741 6388 TestArrayOfUShorts();
daa2c7d9 6389 }
1a931653
VZ
6390
6391 TestArrayOfInts();
e87271f3
VZ
6392#endif // TEST_ARRAYS
6393
1944c6bd 6394#ifdef TEST_DIR
daa2c7d9
VZ
6395 if ( TEST_ALL )
6396 {
99a5af7f 6397 TestDirExists();
2f0c19d0 6398 TestDirEnum();
daa2c7d9 6399 }
2f0c19d0 6400 TestDirTraverse();
1944c6bd
VZ
6401#endif // TEST_DIR
6402
f6bcfd97
BP
6403#ifdef TEST_DLLLOADER
6404 TestDllLoad();
6405#endif // TEST_DLLLOADER
6406
8fd0d89b
VZ
6407#ifdef TEST_ENVIRON
6408 TestEnvironment();
6409#endif // TEST_ENVIRON
6410
d93c719a
VZ
6411#ifdef TEST_EXECUTE
6412 TestExecute();
6413#endif // TEST_EXECUTE
6414
ee6e1b1d
VZ
6415#ifdef TEST_FILECONF
6416 TestFileConfRead();
6417#endif // TEST_FILECONF
6418
f6bcfd97
BP
6419#ifdef TEST_LIST
6420 TestListCtor();
6421#endif // TEST_LIST
6422
ec37df57
VZ
6423#ifdef TEST_LOCALE
6424 TestDefaultLang();
6425#endif // TEST_LOCALE
6426
378b05f7 6427#ifdef TEST_LOG
cab8f76e
VZ
6428 wxPuts(_T("*** Testing wxLog ***"));
6429
378b05f7
VZ
6430 wxString s;
6431 for ( size_t n = 0; n < 8000; n++ )
6432 {
456ae26d 6433 s << (wxChar)(_T('A') + (n % 26));
378b05f7
VZ
6434 }
6435
cab8f76e
VZ
6436 wxLogWarning(_T("The length of the string is %lu"),
6437 (unsigned long)s.length());
6438
378b05f7 6439 wxString msg;
456ae26d 6440 msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
378b05f7
VZ
6441
6442 // this one shouldn't be truncated
456ae26d 6443 wxPrintf(msg);
378b05f7
VZ
6444
6445 // but this one will because log functions use fixed size buffer
b568d04f
VZ
6446 // (note that it doesn't need '\n' at the end neither - will be added
6447 // by wxLog anyhow)
456ae26d 6448 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
378b05f7
VZ
6449#endif // TEST_LOG
6450
f6bcfd97 6451#ifdef TEST_FILE
daa2c7d9 6452 if ( TEST_ALL )
a339970a 6453 {
3ca6a5f0 6454 TestFileRead();
a339970a 6455 TestTextFileRead();
daa2c7d9 6456 TestFileCopy();
a339970a 6457 }
f6bcfd97
BP
6458#endif // TEST_FILE
6459
844f90fb 6460#ifdef TEST_FILENAME
6307da56 6461 if ( 0 )
81f25632
VZ
6462 {
6463 wxFileName fn;
456ae26d
VZ
6464 fn.Assign(_T("c:\\foo"), _T("bar.baz"));
6465 fn.Assign(_T("/u/os9-port/Viewer/tvision/WEI2HZ-3B3-14_05-04-00MSC1.asc"));
81f25632
VZ
6466
6467 DumpFileName(fn);
6468 }
6469
6307da56 6470 TestFileNameConstruction();
a5b7374f 6471 if ( TEST_ALL )
9e8d8607 6472 {
daa2c7d9
VZ
6473 TestFileNameConstruction();
6474 TestFileNameMakeRelative();
e7266247 6475 TestFileNameMakeAbsolute();
daa2c7d9
VZ
6476 TestFileNameSplit();
6477 TestFileNameTemp();
9e8d8607
VZ
6478 TestFileNameCwd();
6479 TestFileNameComparison();
6480 TestFileNameOperations();
6481 }
844f90fb
VZ
6482#endif // TEST_FILENAME
6483
d56e2b97
VZ
6484#ifdef TEST_FILETIME
6485 TestFileGetTimes();
9cb47ea2 6486 if ( 0 )
d56e2b97
VZ
6487 TestFileSetTimes();
6488#endif // TEST_FILETIME
6489
07a56e45
VZ
6490#ifdef TEST_FTP
6491 wxLog::AddTraceMask(FTP_TRACE_MASK);
6492 if ( TestFtpConnect() )
6493 {
daa2c7d9 6494 if ( TEST_ALL )
07a56e45
VZ
6495 {
6496 TestFtpList();
6497 TestFtpDownload();
6498 TestFtpMisc();
daa2c7d9 6499 TestFtpFileSize();
07a56e45
VZ
6500 TestFtpUpload();
6501 }
daa2c7d9
VZ
6502
6503 if ( TEST_INTERACTIVE )
6504 TestFtpInteractive();
07a56e45
VZ
6505 }
6506 //else: connecting to the FTP server failed
6507
6508 if ( 0 )
6509 TestFtpWuFtpd();
6510#endif // TEST_FTP
6511
b76b015e 6512#ifdef TEST_LONGLONG
2a310492
VZ
6513 // seed pseudo random generator
6514 srand((unsigned)time(NULL));
6515
b76b015e 6516 if ( 0 )
2a310492 6517 {
b76b015e 6518 TestSpeed();
2a310492 6519 }
daa2c7d9
VZ
6520
6521 if ( TEST_ALL )
2a310492 6522 {
f6bcfd97 6523 TestMultiplication();
b76b015e 6524 TestDivision();
2a310492
VZ
6525 TestAddition();
6526 TestLongLongConversion();
6527 TestBitOperations();
3a994742 6528 TestLongLongComparison();
2b5f62a0
VZ
6529 TestLongLongToString();
6530 TestLongLongPrintf();
2a310492 6531 }
b76b015e
VZ
6532#endif // TEST_LONGLONG
6533
2c8e4738
VZ
6534#ifdef TEST_HASH
6535 TestHash();
6536#endif // TEST_HASH
6537
0508ba2a
MB
6538#ifdef TEST_HASHMAP
6539 TestHashMap();
6540#endif // TEST_HASHMAP
6541
696e1ea0 6542#ifdef TEST_MIME
f6bcfd97 6543 wxLog::AddTraceMask(_T("mime"));
8d5eff60 6544 if ( TEST_ALL )
c7ce8392 6545 {
f6bcfd97 6546 TestMimeEnum();
c7ce8392 6547 TestMimeOverride();
f06ef5f4 6548 TestMimeAssociate();
c7ce8392 6549 }
f06ef5f4 6550 TestMimeFilename();
696e1ea0
VZ
6551#endif // TEST_MIME
6552
89e60357 6553#ifdef TEST_INFO_FUNCTIONS
daa2c7d9 6554 if ( TEST_ALL )
3a994742
VZ
6555 {
6556 TestOsInfo();
6557 TestUserInfo();
19f45995
VZ
6558
6559 if ( TEST_INTERACTIVE )
6560 TestDiskInfo();
3a994742 6561 }
89e60357
VZ
6562#endif // TEST_INFO_FUNCTIONS
6563
39189b9d
VZ
6564#ifdef TEST_PATHLIST
6565 TestPathList();
6566#endif // TEST_PATHLIST
6567
8d5eff60
VZ
6568#ifdef TEST_ODBC
6569 TestDbOpen();
6570#endif // TEST_ODBC
6571
7aeebdcd
VZ
6572#ifdef TEST_PRINTF
6573 TestPrintf();
6574#endif // TEST_PRINTF
6575
7ba4fbeb
VZ
6576#ifdef TEST_REGCONF
6577 TestRegConfWrite();
6578#endif // TEST_REGCONF
6579
07a56e45
VZ
6580#ifdef TEST_REGEX
6581 // TODO: write a real test using src/regex/tests file
daa2c7d9 6582 if ( TEST_ALL )
07a56e45
VZ
6583 {
6584 TestRegExCompile();
6585 TestRegExMatch();
6586 TestRegExSubmatch();
daa2c7d9
VZ
6587 TestRegExReplacement();
6588
6589 if ( TEST_INTERACTIVE )
6590 TestRegExInteractive();
07a56e45 6591 }
07a56e45
VZ
6592#endif // TEST_REGEX
6593
6dfec4b8 6594#ifdef TEST_REGISTRY
daa2c7d9 6595 TestRegistryRead();
6ba63600 6596 TestRegistryAssociation();
6dfec4b8
VZ
6597#endif // TEST_REGISTRY
6598
2c8e4738 6599#ifdef TEST_SOCKETS
daa2c7d9
VZ
6600 TestSocketServer();
6601 TestSocketClient();
2c8e4738
VZ
6602#endif // TEST_SOCKETS
6603
83141d3a 6604#ifdef TEST_STREAMS
99a5af7f
VZ
6605 if ( TEST_ALL )
6606 {
6607 TestFileStream();
6608 }
6609 TestMemoryStream();
83141d3a
VZ
6610#endif // TEST_STREAMS
6611
39937656
VZ
6612#ifdef TEST_TEXTSTREAM
6613 TestTextInputStream();
6614#endif // TEST_TEXTSTREAM
6615
8d5eff60
VZ
6616#ifdef TEST_THREADS
6617 int nCPUs = wxThread::GetCPUCount();
456ae26d 6618 wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
8d5eff60
VZ
6619 if ( nCPUs != -1 )
6620 wxThread::SetConcurrency(nCPUs);
6621
7aeebdcd 6622 TestDetachedThreads();
8d5eff60
VZ
6623 if ( TEST_ALL )
6624 {
8d5eff60
VZ
6625 TestJoinableThreads();
6626 TestThreadSuspend();
6627 TestThreadDelete();
c112e100
VZ
6628 TestThreadConditions();
6629 TestThreadExec();
7aeebdcd 6630 TestSemaphore();
8d5eff60 6631 }
8d5eff60
VZ
6632#endif // TEST_THREADS
6633
d31b7b68
VZ
6634#ifdef TEST_TIMER
6635 TestStopWatch();
6636#endif // TEST_TIMER
6637
6638#ifdef TEST_DATETIME
daa2c7d9 6639 if ( TEST_ALL )
299fcbfe 6640 {
9d9b7755
VZ
6641 TestTimeSet();
6642 TestTimeStatic();
6643 TestTimeRange();
6644 TestTimeZones();
6645 TestTimeTicks();
6646 TestTimeJDN();
6647 TestTimeDST();
6648 TestTimeWDays();
6649 TestTimeWNumber();
6650 TestTimeParse();
9d9b7755 6651 TestTimeArithmetics();
f6bcfd97
BP
6652 TestTimeHolidays();
6653 TestTimeFormat();
daa2c7d9 6654 TestTimeSpanFormat();
3ca6a5f0 6655 TestTimeMS();
f6bcfd97
BP
6656
6657 TestTimeZoneBug();
41acf5c0 6658 }
2b5f62a0
VZ
6659
6660 TestTimeWNumber();
daa2c7d9
VZ
6661
6662 if ( TEST_INTERACTIVE )
b92fd37c 6663 TestDateTimeInteractive();
d31b7b68 6664#endif // TEST_DATETIME
b76b015e 6665
551fe3a6 6666#ifdef TEST_USLEEP
456ae26d 6667 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
551fe3a6
VZ
6668 wxUsleep(3000);
6669#endif // TEST_USLEEP
6670
f6bcfd97 6671#ifdef TEST_VCARD
f6bcfd97
BP
6672 TestVCardRead();
6673 TestVCardWrite();
6674#endif // TEST_VCARD
6675
0e2c5534
VZ
6676#ifdef TEST_VOLUME
6677 TestFSVolume();
6678#endif // TEST_VOLUME
6679
e7d41190
VZ
6680#ifdef TEST_UNICODE
6681 TestUnicodeToFromAscii();
6682#endif // TEST_UNICODE
6683
f6bcfd97
BP
6684#ifdef TEST_WCHAR
6685 TestUtf8();
ac511156 6686 TestEncodingConverter();
f6bcfd97
BP
6687#endif // TEST_WCHAR
6688
6689#ifdef TEST_ZIP
daa2c7d9 6690 TestZipStreamRead();
2ca8b884 6691 TestZipFileSystem();
f6bcfd97
BP
6692#endif // TEST_ZIP
6693
3ca6a5f0 6694#ifdef TEST_ZLIB
3ca6a5f0
BP
6695 TestZlibStreamWrite();
6696 TestZlibStreamRead();
6697#endif // TEST_ZLIB
6698
37667812
VZ
6699 return 0;
6700}
f6bcfd97 6701