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