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