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