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