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