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