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