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