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