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