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