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