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