]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
added network-to-host noops
[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 2289
07a56e45
VZ
2290static void TestRegExInteractive()
2291{
2292 wxPuts(_T("*** Testing RE interactively ***"));
2293
2294 for ( ;; )
2295 {
456ae26d
VZ
2296 wxChar pattern[128];
2297 wxPrintf(_T("\nEnter a pattern: "));
2298 if ( !wxFgets(pattern, WXSIZEOF(pattern), stdin) )
07a56e45
VZ
2299 break;
2300
2301 // kill the last '\n'
456ae26d 2302 pattern[wxStrlen(pattern) - 1] = 0;
07a56e45
VZ
2303
2304 wxRegEx re;
2305 if ( !re.Compile(pattern) )
2306 {
2307 continue;
2308 }
2309
456ae26d 2310 wxChar text[128];
07a56e45
VZ
2311 for ( ;; )
2312 {
456ae26d
VZ
2313 wxPrintf(_T("Enter text to match: "));
2314 if ( !wxFgets(text, WXSIZEOF(text), stdin) )
07a56e45
VZ
2315 break;
2316
2317 // kill the last '\n'
456ae26d 2318 text[wxStrlen(text) - 1] = 0;
07a56e45
VZ
2319
2320 if ( !re.Matches(text) )
2321 {
456ae26d 2322 wxPrintf(_T("No match.\n"));
07a56e45
VZ
2323 }
2324 else
2325 {
456ae26d 2326 wxPrintf(_T("Pattern matches at '%s'\n"), re.GetMatch(text).c_str());
07a56e45
VZ
2327
2328 size_t start, len;
2329 for ( size_t n = 1; ; n++ )
2330 {
2331 if ( !re.GetMatch(&start, &len, n) )
2332 {
2333 break;
2334 }
2335
456ae26d
VZ
2336 wxPrintf(_T("Subexpr %u matched '%s'\n"),
2337 n, wxString(text + start, len).c_str());
07a56e45
VZ
2338 }
2339 }
2340 }
2341 }
2342}
2343
2344#endif // TEST_REGEX
2345
8d5eff60
VZ
2346// ----------------------------------------------------------------------------
2347// database
2348// ----------------------------------------------------------------------------
2349
ba6ea19e
VZ
2350#if !wxUSE_ODBC
2351 #undef TEST_ODBC
2352#endif
2353
8d5eff60
VZ
2354#ifdef TEST_ODBC
2355
2356#include <wx/db.h>
2357
2358static void TestDbOpen()
2359{
2360 HENV henv;
2361 wxDb db(henv);
2362}
2363
2364#endif // TEST_ODBC
2365
7aeebdcd
VZ
2366// ----------------------------------------------------------------------------
2367// printf() tests
2368// ----------------------------------------------------------------------------
2369
2370/*
2371 NB: this stuff was taken from the glibc test suite and modified to build
2372 in wxWindows: if I read the copyright below properly, this shouldn't
2373 be a problem
2374 */
2375
2376#ifdef TEST_PRINTF
2377
2378#ifdef wxTEST_PRINTF
2379 // use our functions from wxchar.cpp
2380 #undef wxPrintf
2381 #undef wxSprintf
2382
2383 // NB: do _not_ use ATTRIBUTE_PRINTF here, we have some invalid formats
2384 // in the tests below
2385 int wxPrintf( const wxChar *format, ... );
2386 int wxSprintf( wxChar *str, const wxChar *format, ... );
2387#endif
2388
f1389d46
VZ
2389#include "wx/longlong.h"
2390
7aeebdcd
VZ
2391#include <float.h>
2392
2393static void rfg1 (void);
2394static void rfg2 (void);
2395
2396
2397static void
2398fmtchk (const wxChar *fmt)
2399{
2400 (void) wxPrintf(_T("%s:\t`"), fmt);
2401 (void) wxPrintf(fmt, 0x12);
2402 (void) wxPrintf(_T("'\n"));
2403}
2404
2405static void
2406fmtst1chk (const wxChar *fmt)
2407{
2408 (void) wxPrintf(_T("%s:\t`"), fmt);
2409 (void) wxPrintf(fmt, 4, 0x12);
2410 (void) wxPrintf(_T("'\n"));
2411}
2412
2413static void
2414fmtst2chk (const wxChar *fmt)
2415{
2416 (void) wxPrintf(_T("%s:\t`"), fmt);
2417 (void) wxPrintf(fmt, 4, 4, 0x12);
2418 (void) wxPrintf(_T("'\n"));
2419}
2420
2421/* This page is covered by the following copyright: */
2422
2423/* (C) Copyright C E Chew
2424 *
2425 * Feel free to copy, use and distribute this software provided:
2426 *
2427 * 1. you do not pretend that you wrote it
2428 * 2. you leave this copyright notice intact.
2429 */
2430
2431/*
2432 * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
2433 */
2434
2435#define DEC -123
2436#define INT 255
2437#define UNS (~0)
2438
2439/* Formatted Output Test
2440 *
2441 * This exercises the output formatting code.
2442 */
2443
e9d2bb6f
DS
2444wxChar *PointerNull = NULL;
2445
7aeebdcd
VZ
2446static void
2447fp_test (void)
2448{
2449 int i, j, k, l;
2450 wxChar buf[7];
2451 wxChar *prefix = buf;
2452 wxChar tp[20];
2453
2454 wxPuts(_T("\nFormatted output test"));
2455 wxPrintf(_T("prefix 6d 6o 6x 6X 6u\n"));
2456 wxStrcpy(prefix, _T("%"));
2457 for (i = 0; i < 2; i++) {
2458 for (j = 0; j < 2; j++) {
2459 for (k = 0; k < 2; k++) {
2460 for (l = 0; l < 2; l++) {
2461 wxStrcpy(prefix, _T("%"));
2462 if (i == 0) wxStrcat(prefix, _T("-"));
2463 if (j == 0) wxStrcat(prefix, _T("+"));
2464 if (k == 0) wxStrcat(prefix, _T("#"));
2465 if (l == 0) wxStrcat(prefix, _T("0"));
2466 wxPrintf(_T("%5s |"), prefix);
2467 wxStrcpy(tp, prefix);
2468 wxStrcat(tp, _T("6d |"));
2469 wxPrintf(tp, DEC);
2470 wxStrcpy(tp, prefix);
2471 wxStrcat(tp, _T("6o |"));
2472 wxPrintf(tp, INT);
2473 wxStrcpy(tp, prefix);
2474 wxStrcat(tp, _T("6x |"));
2475 wxPrintf(tp, INT);
2476 wxStrcpy(tp, prefix);
2477 wxStrcat(tp, _T("6X |"));
2478 wxPrintf(tp, INT);
2479 wxStrcpy(tp, prefix);
2480 wxStrcat(tp, _T("6u |"));
2481 wxPrintf(tp, UNS);
2482 wxPrintf(_T("\n"));
2483 }
2484 }
2485 }
2486 }
e9d2bb6f
DS
2487 wxPrintf(_T("%10s\n"), PointerNull);
2488 wxPrintf(_T("%-10s\n"), PointerNull);
7aeebdcd
VZ
2489}
2490
2491static void TestPrintf()
2492{
2493 static wxChar shortstr[] = _T("Hi, Z.");
f1389d46
VZ
2494 static wxChar longstr[] = _T("Good morning, Doctor Chandra. This is Hal. \
2495I am ready for my first lesson today.");
7aeebdcd 2496 int result = 0;
e9d2bb6f 2497 wxString test_format;
7aeebdcd
VZ
2498
2499 fmtchk(_T("%.4x"));
2500 fmtchk(_T("%04x"));
2501 fmtchk(_T("%4.4x"));
2502 fmtchk(_T("%04.4x"));
2503 fmtchk(_T("%4.3x"));
2504 fmtchk(_T("%04.3x"));
2505
2506 fmtst1chk(_T("%.*x"));
2507 fmtst1chk(_T("%0*x"));
2508 fmtst2chk(_T("%*.*x"));
2509 fmtst2chk(_T("%0*.*x"));
2510
e9d2bb6f
DS
2511 wxString bad_format = _T("bad format:\t\"%b\"\n");
2512 wxPrintf(bad_format.c_str());
7aeebdcd
VZ
2513 wxPrintf(_T("nil pointer (padded):\t\"%10p\"\n"), (void *) NULL);
2514
2515 wxPrintf(_T("decimal negative:\t\"%d\"\n"), -2345);
2516 wxPrintf(_T("octal negative:\t\"%o\"\n"), -2345);
2517 wxPrintf(_T("hex negative:\t\"%x\"\n"), -2345);
2518 wxPrintf(_T("long decimal number:\t\"%ld\"\n"), -123456L);
2519 wxPrintf(_T("long octal negative:\t\"%lo\"\n"), -2345L);
2520 wxPrintf(_T("long unsigned decimal number:\t\"%lu\"\n"), -123456L);
2521 wxPrintf(_T("zero-padded LDN:\t\"%010ld\"\n"), -123456L);
e9d2bb6f
DS
2522 test_format = _T("left-adjusted ZLDN:\t\"%-010ld\"\n");
2523 wxPrintf(test_format.c_str(), -123456);
7aeebdcd
VZ
2524 wxPrintf(_T("space-padded LDN:\t\"%10ld\"\n"), -123456L);
2525 wxPrintf(_T("left-adjusted SLDN:\t\"%-10ld\"\n"), -123456L);
2526
e9d2bb6f
DS
2527 test_format = _T("zero-padded string:\t\"%010s\"\n");
2528 wxPrintf(test_format.c_str(), shortstr);
2529 test_format = _T("left-adjusted Z string:\t\"%-010s\"\n");
2530 wxPrintf(test_format.c_str(), shortstr);
7aeebdcd
VZ
2531 wxPrintf(_T("space-padded string:\t\"%10s\"\n"), shortstr);
2532 wxPrintf(_T("left-adjusted S string:\t\"%-10s\"\n"), shortstr);
e9d2bb6f 2533 wxPrintf(_T("null string:\t\"%s\"\n"), PointerNull);
7aeebdcd
VZ
2534 wxPrintf(_T("limited string:\t\"%.22s\"\n"), longstr);
2535
2536 wxPrintf(_T("e-style >= 1:\t\"%e\"\n"), 12.34);
2537 wxPrintf(_T("e-style >= .1:\t\"%e\"\n"), 0.1234);
2538 wxPrintf(_T("e-style < .1:\t\"%e\"\n"), 0.001234);
2539 wxPrintf(_T("e-style big:\t\"%.60e\"\n"), 1e20);
2540 wxPrintf(_T("e-style == .1:\t\"%e\"\n"), 0.1);
2541 wxPrintf(_T("f-style >= 1:\t\"%f\"\n"), 12.34);
2542 wxPrintf(_T("f-style >= .1:\t\"%f\"\n"), 0.1234);
2543 wxPrintf(_T("f-style < .1:\t\"%f\"\n"), 0.001234);
2544 wxPrintf(_T("g-style >= 1:\t\"%g\"\n"), 12.34);
2545 wxPrintf(_T("g-style >= .1:\t\"%g\"\n"), 0.1234);
2546 wxPrintf(_T("g-style < .1:\t\"%g\"\n"), 0.001234);
2547 wxPrintf(_T("g-style big:\t\"%.60g\"\n"), 1e20);
2548
2549 wxPrintf (_T(" %6.5f\n"), .099999999860301614);
2550 wxPrintf (_T(" %6.5f\n"), .1);
2551 wxPrintf (_T("x%5.4fx\n"), .5);
2552
2553 wxPrintf (_T("%#03x\n"), 1);
2554
2555 //wxPrintf (_T("something really insane: %.10000f\n"), 1.0);
2556
2557 {
2558 double d = FLT_MIN;
2559 int niter = 17;
2560
2561 while (niter-- != 0)
2562 wxPrintf (_T("%.17e\n"), d / 2);
2563 fflush (stdout);
2564 }
2565
e9d2bb6f
DS
2566#ifndef __WATCOMC__
2567 // Open Watcom cause compiler error here
2568 // Error! E173: col(24) floating-point constant too small to represent
7aeebdcd 2569 wxPrintf (_T("%15.5e\n"), 4.9406564584124654e-324);
e9d2bb6f 2570#endif
7aeebdcd
VZ
2571
2572#define FORMAT _T("|%12.4f|%12.4e|%12.4g|\n")
2573 wxPrintf (FORMAT, 0.0, 0.0, 0.0);
2574 wxPrintf (FORMAT, 1.0, 1.0, 1.0);
2575 wxPrintf (FORMAT, -1.0, -1.0, -1.0);
2576 wxPrintf (FORMAT, 100.0, 100.0, 100.0);
2577 wxPrintf (FORMAT, 1000.0, 1000.0, 1000.0);
2578 wxPrintf (FORMAT, 10000.0, 10000.0, 10000.0);
2579 wxPrintf (FORMAT, 12345.0, 12345.0, 12345.0);
2580 wxPrintf (FORMAT, 100000.0, 100000.0, 100000.0);
2581 wxPrintf (FORMAT, 123456.0, 123456.0, 123456.0);
2582#undef FORMAT
2583
2584 {
2585 wxChar buf[20];
2586 int rc = wxSnprintf (buf, WXSIZEOF(buf), _T("%30s"), _T("foo"));
2587
2588 wxPrintf(_T("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n"),
2589 rc, WXSIZEOF(buf), buf);
2590#if 0
2591 wxChar buf2[512];
2592 wxPrintf ("snprintf (\"%%.999999u\", 10)\n",
2593 wxSnprintf(buf2, WXSIZEOFbuf2), "%.999999u", 10));
2594#endif
2595 }
2596
2597 fp_test ();
2598
2599 wxPrintf (_T("%e should be 1.234568e+06\n"), 1234567.8);
2600 wxPrintf (_T("%f should be 1234567.800000\n"), 1234567.8);
2601 wxPrintf (_T("%g should be 1.23457e+06\n"), 1234567.8);
2602 wxPrintf (_T("%g should be 123.456\n"), 123.456);
2603 wxPrintf (_T("%g should be 1e+06\n"), 1000000.0);
2604 wxPrintf (_T("%g should be 10\n"), 10.0);
2605 wxPrintf (_T("%g should be 0.02\n"), 0.02);
2606
2607 {
2608 double x=1.0;
2609 wxPrintf(_T("%.17f\n"),(1.0/x/10.0+1.0)*x-x);
2610 }
2611
2612 {
2613 wxChar buf[200];
2614
2615 wxSprintf(buf,_T("%*s%*s%*s"),-1,_T("one"),-20,_T("two"),-30,_T("three"));
2616
2617 result |= wxStrcmp (buf,
2618 _T("onetwo three "));
2619
2620 wxPuts (result != 0 ? _T("Test failed!") : _T("Test ok."));
2621 }
2622
f1389d46 2623#ifdef wxLongLong_t
7aeebdcd 2624 {
f1389d46 2625 wxChar buf[200];
7aeebdcd 2626
2b5f62a0 2627 wxSprintf(buf, _T("%07") wxLongLongFmtSpec _T("o"), wxLL(040000000000));
f2cb8a17
JS
2628 #if 0
2629 // for some reason below line fails under Borland
f1389d46 2630 wxPrintf (_T("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s"), buf);
f2cb8a17 2631 #endif
7aeebdcd 2632
f1389d46 2633 if (wxStrcmp (buf, _T("40000000000")) != 0)
7aeebdcd 2634 {
f1389d46
VZ
2635 result = 1;
2636 wxPuts (_T("\tFAILED"));
7aeebdcd 2637 }
e9d2bb6f
DS
2638 wxUnusedVar(result);
2639 wxPuts (wxEmptyString);
7aeebdcd 2640 }
f1389d46 2641#endif // wxLongLong_t
7aeebdcd
VZ
2642
2643 wxPrintf (_T("printf (\"%%hhu\", %u) = %hhu\n"), UCHAR_MAX + 2, UCHAR_MAX + 2);
2644 wxPrintf (_T("printf (\"%%hu\", %u) = %hu\n"), USHRT_MAX + 2, USHRT_MAX + 2);
2645
2646 wxPuts (_T("--- Should be no further output. ---"));
2647 rfg1 ();
2648 rfg2 ();
2649
2650#if 0
2651 {
2652 wxChar bytes[7];
2653 wxChar buf[20];
2654
2655 memset (bytes, '\xff', sizeof bytes);
2656 wxSprintf (buf, _T("foo%hhn\n"), &bytes[3]);
2657 if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
2658 || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
2659 {
2660 wxPuts (_T("%hhn overwrite more bytes"));
2661 result = 1;
2662 }
2663 if (bytes[3] != 3)
2664 {
2665 wxPuts (_T("%hhn wrote incorrect value"));
2666 result = 1;
2667 }
2668 }
2669#endif
2670}
2671
2672static void
2673rfg1 (void)
2674{
2675 wxChar buf[100];
2676
2677 wxSprintf (buf, _T("%5.s"), _T("xyz"));
2678 if (wxStrcmp (buf, _T(" ")) != 0)
2679 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" "));
2680 wxSprintf (buf, _T("%5.f"), 33.3);
2681 if (wxStrcmp (buf, _T(" 33")) != 0)
2682 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 33"));
2683 wxSprintf (buf, _T("%8.e"), 33.3e7);
2684 if (wxStrcmp (buf, _T(" 3e+08")) != 0)
2685 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3e+08"));
2686 wxSprintf (buf, _T("%8.E"), 33.3e7);
2687 if (wxStrcmp (buf, _T(" 3E+08")) != 0)
2688 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3E+08"));
2689 wxSprintf (buf, _T("%.g"), 33.3);
2690 if (wxStrcmp (buf, _T("3e+01")) != 0)
2691 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3e+01"));
2692 wxSprintf (buf, _T("%.G"), 33.3);
2693 if (wxStrcmp (buf, _T("3E+01")) != 0)
2694 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3E+01"));
2695}
2696
2697static void
2698rfg2 (void)
2699{
2700 int prec;
2701 wxChar buf[100];
e9d2bb6f 2702 wxString test_format;
7aeebdcd
VZ
2703
2704 prec = 0;
2705 wxSprintf (buf, _T("%.*g"), prec, 3.3);
2706 if (wxStrcmp (buf, _T("3")) != 0)
2707 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2708 prec = 0;
2709 wxSprintf (buf, _T("%.*G"), prec, 3.3);
2710 if (wxStrcmp (buf, _T("3")) != 0)
2711 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2712 prec = 0;
2713 wxSprintf (buf, _T("%7.*G"), prec, 3.33);
2714 if (wxStrcmp (buf, _T(" 3")) != 0)
2715 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3"));
2716 prec = 3;
e9d2bb6f
DS
2717 test_format = _T("%04.*o");
2718 wxSprintf (buf, test_format.c_str(), prec, 33);
7aeebdcd
VZ
2719 if (wxStrcmp (buf, _T(" 041")) != 0)
2720 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 041"));
2721 prec = 7;
e9d2bb6f
DS
2722 test_format = _T("%09.*u");
2723 wxSprintf (buf, test_format.c_str(), prec, 33);
7aeebdcd
VZ
2724 if (wxStrcmp (buf, _T(" 0000033")) != 0)
2725 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 0000033"));
2726 prec = 3;
e9d2bb6f
DS
2727 test_format = _T("%04.*x");
2728 wxSprintf (buf, test_format.c_str(), prec, 33);
7aeebdcd
VZ
2729 if (wxStrcmp (buf, _T(" 021")) != 0)
2730 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2731 prec = 3;
e9d2bb6f
DS
2732 test_format = _T("%04.*X");
2733 wxSprintf (buf, test_format.c_str(), prec, 33);
7aeebdcd
VZ
2734 if (wxStrcmp (buf, _T(" 021")) != 0)
2735 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2736}
2737
2738#endif // TEST_PRINTF
2739
6dfec4b8 2740// ----------------------------------------------------------------------------
7ba4fbeb 2741// registry and related stuff
6dfec4b8
VZ
2742// ----------------------------------------------------------------------------
2743
2744// this is for MSW only
2745#ifndef __WXMSW__
7ba4fbeb 2746 #undef TEST_REGCONF
6dfec4b8
VZ
2747 #undef TEST_REGISTRY
2748#endif
2749
7ba4fbeb
VZ
2750#ifdef TEST_REGCONF
2751
e84010cf
GD
2752#include "wx/confbase.h"
2753#include "wx/msw/regconf.h"
7ba4fbeb 2754
e9d2bb6f 2755#if 0
7ba4fbeb
VZ
2756static void TestRegConfWrite()
2757{
e9d2bb6f
DS
2758 wxConfig *config = new wxConfig(_T("myapp"));
2759 config->SetPath(_T("/group1"));
2760 config->Write(_T("entry1"), _T("foo"));
2761 config->SetPath(_T("/group2"));
2762 config->Write(_T("entry1"), _T("bar"));
0aa29b6b 2763}
e9d2bb6f 2764#endif
0aa29b6b
VZ
2765
2766static void TestRegConfRead()
2767{
e9d2bb6f 2768 wxConfig *config = new wxConfig(_T("myapp"));
0aa29b6b
VZ
2769
2770 wxString str;
2771 long dummy;
e9d2bb6f
DS
2772 config->SetPath(_T("/"));
2773 wxPuts(_T("Enumerating / subgroups:"));
0aa29b6b
VZ
2774 bool bCont = config->GetFirstGroup(str, dummy);
2775 while(bCont)
2776 {
e9d2bb6f 2777 wxPuts(str);
0aa29b6b
VZ
2778 bCont = config->GetNextGroup(str, dummy);
2779 }
7ba4fbeb
VZ
2780}
2781
2782#endif // TEST_REGCONF
2783
6dfec4b8
VZ
2784#ifdef TEST_REGISTRY
2785
e84010cf 2786#include "wx/msw/registry.h"
6dfec4b8
VZ
2787
2788// I chose this one because I liked its name, but it probably only exists under
2789// NT
2790static const wxChar *TESTKEY =
2791 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2792
2793static void TestRegistryRead()
2794{
456ae26d 2795 wxPuts(_T("*** testing registry reading ***"));
6dfec4b8
VZ
2796
2797 wxRegKey key(TESTKEY);
456ae26d 2798 wxPrintf(_T("The test key name is '%s'.\n"), key.GetName().c_str());
6dfec4b8
VZ
2799 if ( !key.Open() )
2800 {
456ae26d 2801 wxPuts(_T("ERROR: test key can't be opened, aborting test."));
6dfec4b8
VZ
2802
2803 return;
2804 }
2805
2806 size_t nSubKeys, nValues;
2807 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2808 {
456ae26d 2809 wxPrintf(_T("It has %u subkeys and %u values.\n"), nSubKeys, nValues);
6dfec4b8
VZ
2810 }
2811
456ae26d 2812 wxPrintf(_T("Enumerating values:\n"));
6dfec4b8
VZ
2813
2814 long dummy;
2815 wxString value;
2816 bool cont = key.GetFirstValue(value, dummy);
2817 while ( cont )
2818 {
456ae26d 2819 wxPrintf(_T("Value '%s': type "), value.c_str());
6dfec4b8
VZ
2820 switch ( key.GetValueType(value) )
2821 {
456ae26d
VZ
2822 case wxRegKey::Type_None: wxPrintf(_T("ERROR (none)")); break;
2823 case wxRegKey::Type_String: wxPrintf(_T("SZ")); break;
2824 case wxRegKey::Type_Expand_String: wxPrintf(_T("EXPAND_SZ")); break;
2825 case wxRegKey::Type_Binary: wxPrintf(_T("BINARY")); break;
2826 case wxRegKey::Type_Dword: wxPrintf(_T("DWORD")); break;
2827 case wxRegKey::Type_Multi_String: wxPrintf(_T("MULTI_SZ")); break;
2828 default: wxPrintf(_T("other (unknown)")); break;
6dfec4b8
VZ
2829 }
2830
456ae26d 2831 wxPrintf(_T(", value = "));
6dfec4b8
VZ
2832 if ( key.IsNumericValue(value) )
2833 {
2834 long val;
2835 key.QueryValue(value, &val);
456ae26d 2836 wxPrintf(_T("%ld"), val);
6dfec4b8
VZ
2837 }
2838 else // string
2839 {
2840 wxString val;
2841 key.QueryValue(value, val);
456ae26d 2842 wxPrintf(_T("'%s'"), val.c_str());
6dfec4b8
VZ
2843
2844 key.QueryRawValue(value, val);
456ae26d 2845 wxPrintf(_T(" (raw value '%s')"), val.c_str());
6dfec4b8
VZ
2846 }
2847
e9d2bb6f 2848 wxPutchar('\n');
6dfec4b8
VZ
2849
2850 cont = key.GetNextValue(value, dummy);
2851 }
2852}
2853
6ba63600
VZ
2854static void TestRegistryAssociation()
2855{
2856 /*
2857 The second call to deleteself genertaes an error message, with a
2858 messagebox saying .flo is crucial to system operation, while the .ddf
2859 call also fails, but with no error message
2860 */
2861
2862 wxRegKey key;
2863
f2cb8a17 2864 key.SetName(_T("HKEY_CLASSES_ROOT\\.ddf") );
6ba63600 2865 key.Create();
f2cb8a17
JS
2866 key = _T("ddxf_auto_file") ;
2867 key.SetName(_T("HKEY_CLASSES_ROOT\\.flo") );
6ba63600 2868 key.Create();
f2cb8a17
JS
2869 key = _T("ddxf_auto_file") ;
2870 key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"));
6ba63600 2871 key.Create();
f2cb8a17
JS
2872 key = _T("program,0") ;
2873 key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"));
6ba63600 2874 key.Create();
f2cb8a17 2875 key = _T("program \"%1\"") ;
6ba63600 2876
f2cb8a17 2877 key.SetName(_T("HKEY_CLASSES_ROOT\\.ddf") );
6ba63600 2878 key.DeleteSelf();
f2cb8a17 2879 key.SetName(_T("HKEY_CLASSES_ROOT\\.flo") );
6ba63600 2880 key.DeleteSelf();
f2cb8a17 2881 key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"));
6ba63600 2882 key.DeleteSelf();
f2cb8a17 2883 key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"));
6ba63600
VZ
2884 key.DeleteSelf();
2885}
2886
6dfec4b8
VZ
2887#endif // TEST_REGISTRY
2888
c66cca2a
VZ
2889// ----------------------------------------------------------------------------
2890// scope guard
2891// ----------------------------------------------------------------------------
2892
df5168c4
MB
2893#ifdef TEST_SCOPEGUARD
2894
c66cca2a
VZ
2895#include "wx/scopeguard.h"
2896
2897static void function0() { puts("function0()"); }
2898static void function1(int n) { printf("function1(%d)\n", n); }
2899static void function2(double x, char c) { printf("function2(%g, %c)\n", x, c); }
2900
2901struct Object
2902{
2903 void method0() { printf("method0()\n"); }
2904 void method1(int n) { printf("method1(%d)\n", n); }
2905 void method2(double x, char c) { printf("method2(%g, %c)\n", x, c); }
2906};
2907
2908static void TestScopeGuard()
2909{
24c8053b
RN
2910 wxON_BLOCK_EXIT0(function0);
2911 wxON_BLOCK_EXIT1(function1, 17);
2912 wxON_BLOCK_EXIT2(function2, 3.14, 'p');
c66cca2a
VZ
2913
2914 Object obj;
24c8053b
RN
2915 wxON_BLOCK_EXIT_OBJ0(obj, &Object::method0);
2916 wxON_BLOCK_EXIT_OBJ1(obj, &Object::method1, 7);
2917 wxON_BLOCK_EXIT_OBJ2(obj, &Object::method2, 2.71, 'e');
c66cca2a
VZ
2918
2919 wxScopeGuard dismissed = wxMakeGuard(function0);
2920 dismissed.Dismiss();
2921}
2922
df5168c4
MB
2923#endif
2924
2c8e4738
VZ
2925// ----------------------------------------------------------------------------
2926// sockets
2927// ----------------------------------------------------------------------------
2928
2929#ifdef TEST_SOCKETS
2930
e84010cf
GD
2931#include "wx/socket.h"
2932#include "wx/protocol/protocol.h"
2933#include "wx/protocol/http.h"
8e907a13
VZ
2934
2935static void TestSocketServer()
2936{
456ae26d 2937 wxPuts(_T("*** Testing wxSocketServer ***\n"));
8e907a13 2938
ccdb23df
VZ
2939 static const int PORT = 3000;
2940
8e907a13 2941 wxIPV4address addr;
ccdb23df 2942 addr.Service(PORT);
8e907a13
VZ
2943
2944 wxSocketServer *server = new wxSocketServer(addr);
2945 if ( !server->Ok() )
2946 {
456ae26d 2947 wxPuts(_T("ERROR: failed to bind"));
ccdb23df
VZ
2948
2949 return;
8e907a13 2950 }
8dfea369 2951
cab8f76e
VZ
2952 bool quit = false;
2953 while ( !quit )
8dfea369 2954 {
456ae26d 2955 wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT);
8dfea369
VZ
2956
2957 wxSocketBase *socket = server->Accept();
2958 if ( !socket )
2959 {
456ae26d 2960 wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
8dfea369
VZ
2961 break;
2962 }
2963
456ae26d 2964 wxPuts(_T("Server: got a client."));
8dfea369 2965
ccdb23df
VZ
2966 server->SetTimeout(60); // 1 min
2967
cab8f76e
VZ
2968 bool close = false;
2969 while ( !close && socket->IsConnected() )
8dfea369 2970 {
ccdb23df 2971 wxString s;
456ae26d 2972 wxChar ch = _T('\0');
ccdb23df 2973 for ( ;; )
8dfea369 2974 {
ccdb23df
VZ
2975 if ( socket->Read(&ch, sizeof(ch)).Error() )
2976 {
2977 // don't log error if the client just close the connection
2978 if ( socket->IsConnected() )
2979 {
456ae26d 2980 wxPuts(_T("ERROR: in wxSocket::Read."));
ccdb23df 2981 }
8dfea369 2982
ccdb23df
VZ
2983 break;
2984 }
8dfea369 2985
ccdb23df
VZ
2986 if ( ch == '\r' )
2987 continue;
8dfea369 2988
ccdb23df
VZ
2989 if ( ch == '\n' )
2990 break;
8dfea369 2991
ccdb23df
VZ
2992 s += ch;
2993 }
8dfea369 2994
ccdb23df
VZ
2995 if ( ch != '\n' )
2996 {
2997 break;
2998 }
8dfea369 2999
456ae26d 3000 wxPrintf(_T("Server: got '%s'.\n"), s.c_str());
cab8f76e 3001 if ( s == _T("close") )
ccdb23df 3002 {
cab8f76e 3003 wxPuts(_T("Closing connection"));
8dfea369 3004
cab8f76e 3005 close = true;
ccdb23df 3006 }
cab8f76e
VZ
3007 else if ( s == _T("quit") )
3008 {
3009 close =
3010 quit = true;
ccdb23df 3011
cab8f76e
VZ
3012 wxPuts(_T("Shutting down the server"));
3013 }
3014 else // not a special command
3015 {
3016 socket->Write(s.MakeUpper().c_str(), s.length());
3017 socket->Write("\r\n", 2);
3018 wxPrintf(_T("Server: wrote '%s'.\n"), s.c_str());
3019 }
8dfea369
VZ
3020 }
3021
cab8f76e
VZ
3022 if ( !close )
3023 {
3024 wxPuts(_T("Server: lost a client unexpectedly."));
3025 }
8dfea369 3026
ccdb23df 3027 socket->Destroy();
8dfea369 3028 }
9fc3cba7 3029
ccdb23df
VZ
3030 // same as "delete server" but is consistent with GUI programs
3031 server->Destroy();
8e907a13 3032}
2c8e4738
VZ
3033
3034static void TestSocketClient()
3035{
456ae26d 3036 wxPuts(_T("*** Testing wxSocketClient ***\n"));
2c8e4738 3037
456ae26d 3038 static const wxChar *hostname = _T("www.wxwindows.org");
8e907a13
VZ
3039
3040 wxIPV4address addr;
3041 addr.Hostname(hostname);
3042 addr.Service(80);
3043
456ae26d 3044 wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname);
2c8e4738
VZ
3045
3046 wxSocketClient client;
8e907a13 3047 if ( !client.Connect(addr) )
2c8e4738 3048 {
456ae26d 3049 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2c8e4738
VZ
3050 }
3051 else
3052 {
456ae26d 3053 wxPrintf(_T("--- Connected to %s:%u...\n"),
8e907a13
VZ
3054 addr.Hostname().c_str(), addr.Service());
3055
456ae26d 3056 wxChar buf[8192];
2c8e4738 3057
8e907a13
VZ
3058 // could use simply "GET" here I suppose
3059 wxString cmdGet =
456ae26d 3060 wxString::Format(_T("GET http://%s/\r\n"), hostname);
8e907a13 3061 client.Write(cmdGet, cmdGet.length());
456ae26d 3062 wxPrintf(_T("--- Sent command '%s' to the server\n"),
8e907a13 3063 MakePrintable(cmdGet).c_str());
2c8e4738 3064 client.Read(buf, WXSIZEOF(buf));
456ae26d 3065 wxPrintf(_T("--- Server replied:\n%s"), buf);
8e907a13
VZ
3066 }
3067}
3068
2e907fab
VZ
3069#endif // TEST_SOCKETS
3070
b92fd37c
VZ
3071// ----------------------------------------------------------------------------
3072// FTP
3073// ----------------------------------------------------------------------------
3074
2e907fab
VZ
3075#ifdef TEST_FTP
3076
e84010cf 3077#include "wx/protocol/ftp.h"
2e907fab 3078
b92fd37c
VZ
3079static wxFTP ftp;
3080
3081#define FTP_ANONYMOUS
3082
3083#ifdef FTP_ANONYMOUS
456ae26d
VZ
3084 static const wxChar *directory = _T("/pub");
3085 static const wxChar *filename = _T("welcome.msg");
b92fd37c 3086#else
456ae26d
VZ
3087 static const wxChar *directory = _T("/etc");
3088 static const wxChar *filename = _T("issue");
b92fd37c
VZ
3089#endif
3090
3091static bool TestFtpConnect()
8e907a13 3092{
456ae26d 3093 wxPuts(_T("*** Testing FTP connect ***"));
8e907a13 3094
b92fd37c 3095#ifdef FTP_ANONYMOUS
456ae26d 3096 static const wxChar *hostname = _T("ftp.wxwindows.org");
b92fd37c 3097
456ae26d 3098 wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname);
b92fd37c 3099#else // !FTP_ANONYMOUS
456ae26d 3100 static const wxChar *hostname = "localhost";
b92fd37c 3101
456ae26d
VZ
3102 wxChar user[256];
3103 wxFgets(user, WXSIZEOF(user), stdin);
3104 user[wxStrlen(user) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3105 ftp.SetUser(user);
3106
456ae26d
VZ
3107 wxChar password[256];
3108 wxPrintf(_T("Password for %s: "), password);
3109 wxFgets(password, WXSIZEOF(password), stdin);
3110 password[wxStrlen(password) - 1] = '\0'; // chop off '\n'
b92fd37c
VZ
3111 ftp.SetPassword(password);
3112
456ae26d 3113 wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname, user);
b92fd37c
VZ
3114#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
3115
3116 if ( !ftp.Connect(hostname) )
3117 {
456ae26d 3118 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b92fd37c 3119
cab8f76e 3120 return false;
b92fd37c
VZ
3121 }
3122 else
3123 {
456ae26d 3124 wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
b92fd37c
VZ
3125 hostname, ftp.Pwd().c_str());
3126 }
3127
cab8f76e 3128 return true;
b92fd37c 3129}
b1229561 3130
b92fd37c
VZ
3131// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
3132static void TestFtpWuFtpd()
3133{
3134 wxFTP ftp;
456ae26d 3135 static const wxChar *hostname = _T("ftp.eudora.com");
b1229561
VZ
3136 if ( !ftp.Connect(hostname) )
3137 {
456ae26d 3138 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
b1229561
VZ
3139 }
3140 else
3141 {
456ae26d 3142 static const wxChar *filename = _T("eudora/pubs/draft-gellens-submit-09.txt");
b1229561
VZ
3143 wxInputStream *in = ftp.GetInputStream(filename);
3144 if ( !in )
3145 {
456ae26d 3146 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b1229561
VZ
3147 }
3148 else
3149 {
4c51b688 3150 size_t size = in->GetSize();
456ae26d 3151 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b1229561 3152
456ae26d 3153 wxChar *data = new wxChar[size];
b1229561
VZ
3154 if ( !in->Read(data, size) )
3155 {
456ae26d 3156 wxPuts(_T("ERROR: read error"));
b1229561
VZ
3157 }
3158 else
3159 {
456ae26d 3160 wxPrintf(_T("Successfully retrieved the file.\n"));
b1229561
VZ
3161 }
3162
3163 delete [] data;
3164 delete in;
3165 }
3166 }
b92fd37c 3167}
b1229561 3168
b92fd37c
VZ
3169static void TestFtpList()
3170{
456ae26d 3171 wxPuts(_T("*** Testing wxFTP file listing ***\n"));
8e907a13 3172
b92fd37c
VZ
3173 // test CWD
3174 if ( !ftp.ChDir(directory) )
3175 {
456ae26d 3176 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c 3177 }
2e907fab 3178
456ae26d 3179 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2e907fab 3180
b92fd37c
VZ
3181 // test NLIST and LIST
3182 wxArrayString files;
3183 if ( !ftp.GetFilesList(files) )
8e907a13 3184 {
456ae26d 3185 wxPuts(_T("ERROR: failed to get NLIST of files"));
8e907a13
VZ
3186 }
3187 else
3188 {
456ae26d 3189 wxPrintf(_T("Brief list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3190 size_t count = files.GetCount();
3191 for ( size_t n = 0; n < count; n++ )
8e907a13 3192 {
456ae26d 3193 wxPrintf(_T("\t%s\n"), files[n].c_str());
8e907a13 3194 }
456ae26d 3195 wxPuts(_T("End of the file list"));
b92fd37c 3196 }
8e907a13 3197
b92fd37c
VZ
3198 if ( !ftp.GetDirList(files) )
3199 {
456ae26d 3200 wxPuts(_T("ERROR: failed to get LIST of files"));
b92fd37c
VZ
3201 }
3202 else
3203 {
456ae26d 3204 wxPrintf(_T("Detailed list of files under '%s':\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3205 size_t count = files.GetCount();
3206 for ( size_t n = 0; n < count; n++ )
8e907a13 3207 {
456ae26d 3208 wxPrintf(_T("\t%s\n"), files[n].c_str());
2e907fab 3209 }
456ae26d 3210 wxPuts(_T("End of the file list"));
b92fd37c
VZ
3211 }
3212
3213 if ( !ftp.ChDir(_T("..")) )
3214 {
456ae26d 3215 wxPuts(_T("ERROR: failed to cd to .."));
b92fd37c 3216 }
2e907fab 3217
456ae26d 3218 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3219}
3220
3221static void TestFtpDownload()
3222{
456ae26d 3223 wxPuts(_T("*** Testing wxFTP download ***\n"));
b92fd37c
VZ
3224
3225 // test RETR
3226 wxInputStream *in = ftp.GetInputStream(filename);
3227 if ( !in )
3228 {
456ae26d 3229 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
b92fd37c
VZ
3230 }
3231 else
3232 {
4c51b688 3233 size_t size = in->GetSize();
456ae26d 3234 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
b92fd37c
VZ
3235 fflush(stdout);
3236
456ae26d 3237 wxChar *data = new wxChar[size];
b92fd37c 3238 if ( !in->Read(data, size) )
2e907fab 3239 {
456ae26d 3240 wxPuts(_T("ERROR: read error"));
2e907fab
VZ
3241 }
3242 else
3243 {
456ae26d 3244 wxPrintf(_T("\nContents of %s:\n%s\n"), filename, data);
8e907a13
VZ
3245 }
3246
b92fd37c
VZ
3247 delete [] data;
3248 delete in;
3249 }
3250}
8e907a13 3251
b92fd37c
VZ
3252static void TestFtpFileSize()
3253{
456ae26d 3254 wxPuts(_T("*** Testing FTP SIZE command ***"));
b92fd37c
VZ
3255
3256 if ( !ftp.ChDir(directory) )
3257 {
456ae26d 3258 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
b92fd37c
VZ
3259 }
3260
456ae26d 3261 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
b92fd37c
VZ
3262
3263 if ( ftp.FileExists(filename) )
3264 {
3265 int size = ftp.GetFileSize(filename);
3266 if ( size == -1 )
456ae26d 3267 wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename);
8e907a13 3268 else
456ae26d 3269 wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename, size);
b92fd37c
VZ
3270 }
3271 else
3272 {
456ae26d 3273 wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename);
b92fd37c
VZ
3274 }
3275}
3276
3277static void TestFtpMisc()
3278{
456ae26d 3279 wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
b92fd37c 3280
f2cb8a17 3281 if ( ftp.SendCommand(_T("STAT")) != '2' )
b92fd37c 3282 {
456ae26d 3283 wxPuts(_T("ERROR: STAT failed"));
b92fd37c
VZ
3284 }
3285 else
3286 {
456ae26d 3287 wxPrintf(_T("STAT returned:\n\n%s\n"), ftp.GetLastResult().c_str());
b92fd37c
VZ
3288 }
3289
f2cb8a17 3290 if ( ftp.SendCommand(_T("HELP SITE")) != '2' )
b92fd37c 3291 {
456ae26d 3292 wxPuts(_T("ERROR: HELP SITE failed"));
b92fd37c
VZ
3293 }
3294 else
3295 {
456ae26d 3296 wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
b92fd37c
VZ
3297 ftp.GetLastResult().c_str());
3298 }
3299}
3300
3301static void TestFtpInteractive()
3302{
456ae26d 3303 wxPuts(_T("\n*** Interactive wxFTP test ***"));
b92fd37c 3304
456ae26d 3305 wxChar buf[128];
b92fd37c
VZ
3306
3307 for ( ;; )
3308 {
456ae26d
VZ
3309 wxPrintf(_T("Enter FTP command: "));
3310 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
b92fd37c
VZ
3311 break;
3312
3313 // kill the last '\n'
456ae26d 3314 buf[wxStrlen(buf) - 1] = 0;
b92fd37c
VZ
3315
3316 // special handling of LIST and NLST as they require data connection
3317 wxString start(buf, 4);
3318 start.MakeUpper();
f2cb8a17 3319 if ( start == _T("LIST") || start == _T("NLST") )
8e907a13 3320 {
b92fd37c 3321 wxString wildcard;
456ae26d 3322 if ( wxStrlen(buf) > 4 )
b92fd37c 3323 wildcard = buf + 5;
8e907a13 3324
b92fd37c 3325 wxArrayString files;
f2cb8a17 3326 if ( !ftp.GetList(files, wildcard, start == _T("LIST")) )
8e907a13 3327 {
456ae26d 3328 wxPrintf(_T("ERROR: failed to get %s of files\n"), start.c_str());
8e907a13
VZ
3329 }
3330 else
3331 {
456ae26d 3332 wxPrintf(_T("--- %s of '%s' under '%s':\n"),
b92fd37c
VZ
3333 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
3334 size_t count = files.GetCount();
3335 for ( size_t n = 0; n < count; n++ )
3336 {
456ae26d 3337 wxPrintf(_T("\t%s\n"), files[n].c_str());
b92fd37c 3338 }
456ae26d 3339 wxPuts(_T("--- End of the file list"));
8e907a13 3340 }
2e907fab 3341 }
b92fd37c 3342 else // !list
2e907fab 3343 {
456ae26d
VZ
3344 wxChar ch = ftp.SendCommand(buf);
3345 wxPrintf(_T("Command %s"), ch ? _T("succeeded") : _T("failed"));
b92fd37c
VZ
3346 if ( ch )
3347 {
456ae26d 3348 wxPrintf(_T(" (return code %c)"), ch);
b92fd37c 3349 }
2e907fab 3350
456ae26d 3351 wxPrintf(_T(", server reply:\n%s\n\n"), ftp.GetLastResult().c_str());
2e907fab 3352 }
2c8e4738 3353 }
b92fd37c 3354
456ae26d 3355 wxPuts(_T("\n*** done ***"));
2c8e4738
VZ
3356}
3357
b92fd37c 3358static void TestFtpUpload()
f6bcfd97 3359{
456ae26d 3360 wxPuts(_T("*** Testing wxFTP uploading ***\n"));
f6bcfd97 3361
b92fd37c 3362 // upload a file
456ae26d
VZ
3363 static const wxChar *file1 = _T("test1");
3364 static const wxChar *file2 = _T("test2");
b92fd37c
VZ
3365 wxOutputStream *out = ftp.GetOutputStream(file1);
3366 if ( out )
3367 {
456ae26d 3368 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3369 out->Write("First hello", 11);
3370 delete out;
3371 }
f6bcfd97 3372
b92fd37c 3373 // send a command to check the remote file
f2cb8a17 3374 if ( ftp.SendCommand(wxString(_T("STAT ")) + file1) != '2' )
f6bcfd97 3375 {
456ae26d 3376 wxPrintf(_T("ERROR: STAT %s failed\n"), file1);
f6bcfd97
BP
3377 }
3378 else
3379 {
456ae26d 3380 wxPrintf(_T("STAT %s returned:\n\n%s\n"),
b92fd37c
VZ
3381 file1, ftp.GetLastResult().c_str());
3382 }
2e907fab 3383
b92fd37c
VZ
3384 out = ftp.GetOutputStream(file2);
3385 if ( out )
3386 {
456ae26d 3387 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
b92fd37c
VZ
3388 out->Write("Second hello", 12);
3389 delete out;
f6bcfd97
BP
3390 }
3391}
3392
2e907fab 3393#endif // TEST_FTP
2c8e4738 3394
83141d3a
VZ
3395// ----------------------------------------------------------------------------
3396// streams
3397// ----------------------------------------------------------------------------
3398
3399#ifdef TEST_STREAMS
3400
e84010cf
GD
3401#include "wx/wfstream.h"
3402#include "wx/mstream.h"
83141d3a 3403
24f25c8a
VZ
3404static void TestFileStream()
3405{
456ae26d 3406 wxPuts(_T("*** Testing wxFileInputStream ***"));
24f25c8a 3407
e9d2bb6f 3408 static const wxString filename = _T("testdata.fs");
24f25c8a
VZ
3409 {
3410 wxFileOutputStream fsOut(filename);
3411 fsOut.Write("foo", 3);
3412 }
3413
3414 wxFileInputStream fsIn(filename);
456ae26d 3415 wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
24f25c8a
VZ
3416 while ( !fsIn.Eof() )
3417 {
e9d2bb6f 3418 wxPutchar(fsIn.GetC());
24f25c8a
VZ
3419 }
3420
3421 if ( !wxRemoveFile(filename) )
3422 {
e9d2bb6f 3423 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename.c_str());
24f25c8a
VZ
3424 }
3425
456ae26d 3426 wxPuts(_T("\n*** wxFileInputStream test done ***"));
24f25c8a
VZ
3427}
3428
83141d3a
VZ
3429static void TestMemoryStream()
3430{
99a5af7f
VZ
3431 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
3432
3433 wxMemoryOutputStream memOutStream;
3434 wxPrintf(_T("Initially out stream offset: %lu\n"),
3435 (unsigned long)memOutStream.TellO());
3436
3437 for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
3438 {
3439 memOutStream.PutC(*p);
3440 }
3441
3442 wxPrintf(_T("Final out stream offset: %lu\n"),
3443 (unsigned long)memOutStream.TellO());
3444
3445 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
83141d3a
VZ
3446
3447 wxChar buf[1024];
99a5af7f 3448 size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
83141d3a 3449
99a5af7f
VZ
3450 wxMemoryInputStream memInpStream(buf, len);
3451 wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
83141d3a
VZ
3452 while ( !memInpStream.Eof() )
3453 {
e9d2bb6f 3454 wxPutchar(memInpStream.GetC());
83141d3a
VZ
3455 }
3456
456ae26d 3457 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
83141d3a
VZ
3458}
3459
3460#endif // TEST_STREAMS
3461
d31b7b68
VZ
3462// ----------------------------------------------------------------------------
3463// timers
3464// ----------------------------------------------------------------------------
3465
3466#ifdef TEST_TIMER
3467
e84010cf
GD
3468#include "wx/timer.h"
3469#include "wx/utils.h"
d31b7b68
VZ
3470
3471static void TestStopWatch()
3472{
456ae26d 3473 wxPuts(_T("*** Testing wxStopWatch ***\n"));
d31b7b68
VZ
3474
3475 wxStopWatch sw;
677eff07 3476 sw.Pause();
456ae26d 3477 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
677eff07
VZ
3478 fflush(stdout);
3479 wxSleep(2);
456ae26d 3480 wxPrintf(_T("\t%ldms\n"), sw.Time());
677eff07 3481
456ae26d 3482 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
677eff07
VZ
3483 fflush(stdout);
3484 sw.Resume();
d31b7b68 3485 wxSleep(3);
456ae26d 3486 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3487
3488 sw.Pause();
456ae26d 3489 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
677eff07 3490 fflush(stdout);
d31b7b68 3491 wxSleep(2);
456ae26d 3492 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
d31b7b68
VZ
3493
3494 sw.Resume();
456ae26d 3495 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
677eff07
VZ
3496 fflush(stdout);
3497 wxSleep(2);
456ae26d 3498 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
87798c00
VZ
3499
3500 wxStopWatch sw2;
456ae26d 3501 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
87798c00
VZ
3502 for ( size_t n = 0; n < 70; n++ )
3503 {
3504 sw2.Start();
89e6463c
GRG
3505
3506 for ( size_t m = 0; m < 100000; m++ )
87798c00 3507 {
89e6463c
GRG
3508 if ( sw.Time() < 0 || sw2.Time() < 0 )
3509 {
456ae26d 3510 wxPuts(_T("\ntime is negative - ERROR!"));
89e6463c 3511 }
87798c00
VZ
3512 }
3513
e9d2bb6f 3514 wxPutchar('.');
677eff07 3515 fflush(stdout);
87798c00
VZ
3516 }
3517
456ae26d 3518 wxPuts(_T(", ok."));
d31b7b68
VZ
3519}
3520
3521#endif // TEST_TIMER
3522
f6bcfd97
BP
3523// ----------------------------------------------------------------------------
3524// vCard support
3525// ----------------------------------------------------------------------------
3526
3527#ifdef TEST_VCARD
3528
e84010cf 3529#include "wx/vcard.h"
f6bcfd97
BP
3530
3531static void DumpVObject(size_t level, const wxVCardObject& vcard)
3532{
3533 void *cookie;
3534 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3535 while ( vcObj )
3536 {
456ae26d 3537 wxPrintf(_T("%s%s"),
f6bcfd97
BP
3538 wxString(_T('\t'), level).c_str(),
3539 vcObj->GetName().c_str());
3540
3541 wxString value;
3542 switch ( vcObj->GetType() )
3543 {
3544 case wxVCardObject::String:
3545 case wxVCardObject::UString:
3546 {
3547 wxString val;
3548 vcObj->GetValue(&val);
3549 value << _T('"') << val << _T('"');
3550 }
3551 break;
3552
3553 case wxVCardObject::Int:
3554 {
3555 unsigned int i;
3556 vcObj->GetValue(&i);
3557 value.Printf(_T("%u"), i);
3558 }
3559 break;
3560
3561 case wxVCardObject::Long:
3562 {
3563 unsigned long l;
3564 vcObj->GetValue(&l);
3565 value.Printf(_T("%lu"), l);
3566 }
3567 break;
3568
3569 case wxVCardObject::None:
3570 break;
3571
3572 case wxVCardObject::Object:
3573 value = _T("<node>");
3574 break;
3575
3576 default:
3577 value = _T("<unknown value type>");
3578 }
3579
3580 if ( !!value )
456ae26d 3581 wxPrintf(_T(" = %s"), value.c_str());
e9d2bb6f 3582 wxPutchar('\n');
f6bcfd97
BP
3583
3584 DumpVObject(level + 1, *vcObj);
3585
3586 delete vcObj;
3587 vcObj = vcard.GetNextProp(&cookie);
3588 }
3589}
3590
3591static void DumpVCardAddresses(const wxVCard& vcard)
3592{
456ae26d 3593 wxPuts(_T("\nShowing all addresses from vCard:\n"));
f6bcfd97
BP
3594
3595 size_t nAdr = 0;
3596 void *cookie;
3597 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3598 while ( addr )
3599 {
3600 wxString flagsStr;
3601 int flags = addr->GetFlags();
3602 if ( flags & wxVCardAddress::Domestic )
3603 {
3604 flagsStr << _T("domestic ");
3605 }
3606 if ( flags & wxVCardAddress::Intl )
3607 {
3608 flagsStr << _T("international ");
3609 }
3610 if ( flags & wxVCardAddress::Postal )
3611 {
3612 flagsStr << _T("postal ");
3613 }
3614 if ( flags & wxVCardAddress::Parcel )
3615 {
3616 flagsStr << _T("parcel ");
3617 }
3618 if ( flags & wxVCardAddress::Home )
3619 {
3620 flagsStr << _T("home ");
3621 }
3622 if ( flags & wxVCardAddress::Work )
3623 {
3624 flagsStr << _T("work ");
3625 }
3626
456ae26d 3627 wxPrintf(_T("Address %u:\n")
f6bcfd97
BP
3628 "\tflags = %s\n"
3629 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3630 ++nAdr,
3631 flagsStr.c_str(),
3632 addr->GetPostOffice().c_str(),
3633 addr->GetExtAddress().c_str(),
3634 addr->GetStreet().c_str(),
3635 addr->GetLocality().c_str(),
3636 addr->GetRegion().c_str(),
3637 addr->GetPostalCode().c_str(),
3638 addr->GetCountry().c_str()
3639 );
3640
3641 delete addr;
3642 addr = vcard.GetNextAddress(&cookie);
3643 }
3644}
3645
3646static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3647{
456ae26d 3648 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
f6bcfd97
BP
3649
3650 size_t nPhone = 0;
3651 void *cookie;
3652 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3653 while ( phone )
3654 {
3655 wxString flagsStr;
3656 int flags = phone->GetFlags();
3657 if ( flags & wxVCardPhoneNumber::Voice )
3658 {
3659 flagsStr << _T("voice ");
3660 }
3661 if ( flags & wxVCardPhoneNumber::Fax )
3662 {
3663 flagsStr << _T("fax ");
3664 }
3665 if ( flags & wxVCardPhoneNumber::Cellular )
3666 {
3667 flagsStr << _T("cellular ");
3668 }
3669 if ( flags & wxVCardPhoneNumber::Modem )
3670 {
3671 flagsStr << _T("modem ");
3672 }
3673 if ( flags & wxVCardPhoneNumber::Home )
3674 {
3675 flagsStr << _T("home ");
3676 }
3677 if ( flags & wxVCardPhoneNumber::Work )
3678 {
3679 flagsStr << _T("work ");
3680 }
3681
456ae26d 3682 wxPrintf(_T("Phone number %u:\n")
f6bcfd97
BP
3683 "\tflags = %s\n"
3684 "\tvalue = %s\n",
3685 ++nPhone,
3686 flagsStr.c_str(),
3687 phone->GetNumber().c_str()
3688 );
3689
3690 delete phone;
3691 phone = vcard.GetNextPhoneNumber(&cookie);
3692 }
3693}
3694
3695static void TestVCardRead()
3696{
456ae26d 3697 wxPuts(_T("*** Testing wxVCard reading ***\n"));
f6bcfd97
BP
3698
3699 wxVCard vcard(_T("vcard.vcf"));
3700 if ( !vcard.IsOk() )
3701 {
456ae26d 3702 wxPuts(_T("ERROR: couldn't load vCard."));
f6bcfd97
BP
3703 }
3704 else
3705 {
3706 // read individual vCard properties
3707 wxVCardObject *vcObj = vcard.GetProperty("FN");
3708 wxString value;
3709 if ( vcObj )
3710 {
3711 vcObj->GetValue(&value);
3712 delete vcObj;
3713 }
3714 else
3715 {
3716 value = _T("<none>");
3717 }
3718
456ae26d 3719 wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
f6bcfd97
BP
3720
3721
3722 if ( !vcard.GetFullName(&value) )
3723 {
3724 value = _T("<none>");
3725 }
3726
456ae26d 3727 wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
f6bcfd97
BP
3728
3729 // now show how to deal with multiply occuring properties
3730 DumpVCardAddresses(vcard);
3731 DumpVCardPhoneNumbers(vcard);
3732
3733 // and finally show all
456ae26d 3734 wxPuts(_T("\nNow dumping the entire vCard:\n")
f6bcfd97
BP
3735 "-----------------------------\n");
3736
3737 DumpVObject(0, vcard);
3738 }
3739}
3740
3741static void TestVCardWrite()
3742{
456ae26d 3743 wxPuts(_T("*** Testing wxVCard writing ***\n"));
f6bcfd97
BP
3744
3745 wxVCard vcard;
3746 if ( !vcard.IsOk() )
3747 {
456ae26d 3748 wxPuts(_T("ERROR: couldn't create vCard."));
f6bcfd97
BP
3749 }
3750 else
3751 {
3752 // set some fields
3753 vcard.SetName("Zeitlin", "Vadim");
3754 vcard.SetFullName("Vadim Zeitlin");
3755 vcard.SetOrganization("wxWindows", "R&D");
3756
3757 // just dump the vCard back
456ae26d
VZ
3758 wxPuts(_T("Entire vCard follows:\n"));
3759 wxPuts(vcard.Write());
f6bcfd97
BP
3760 }
3761}
3762
3763#endif // TEST_VCARD
3764
0e2c5534
VZ
3765// ----------------------------------------------------------------------------
3766// wxVolume tests
3767// ----------------------------------------------------------------------------
3768
ba6ea19e 3769#if !defined(__WIN32__) || !wxUSE_FSVOLUME
0e2c5534
VZ
3770 #undef TEST_VOLUME
3771#endif
3772
3773#ifdef TEST_VOLUME
3774
3775#include "wx/volume.h"
3776
3777static const wxChar *volumeKinds[] =
3778{
3779 _T("floppy"),
3780 _T("hard disk"),
3781 _T("CD-ROM"),
3782 _T("DVD-ROM"),
3783 _T("network volume"),
3784 _T("other volume"),
3785};
3786
3787static void TestFSVolume()
3788{
3789 wxPuts(_T("*** Testing wxFSVolume class ***"));
3790
3791 wxArrayString volumes = wxFSVolume::GetVolumes();
3792 size_t count = volumes.GetCount();
3793
3794 if ( !count )
3795 {
3796 wxPuts(_T("ERROR: no mounted volumes?"));
3797 return;
3798 }
3799
3800 wxPrintf(_T("%u mounted volumes found:\n"), count);
3801
3802 for ( size_t n = 0; n < count; n++ )
3803 {
3804 wxFSVolume vol(volumes[n]);
3805 if ( !vol.IsOk() )
3806 {
3807 wxPuts(_T("ERROR: couldn't create volume"));
3808 continue;
3809 }
3810
3811 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3812 n + 1,
3813 vol.GetDisplayName().c_str(),
3814 vol.GetName().c_str(),
3815 volumeKinds[vol.GetKind()],
3816 vol.IsWritable() ? _T("rw") : _T("ro"),
3817 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3818 : _T("fixed"));
3819 }
3820}
3821
3822#endif // TEST_VOLUME
3823
f6bcfd97 3824// ----------------------------------------------------------------------------
e7d41190 3825// wide char and Unicode support
f6bcfd97
BP
3826// ----------------------------------------------------------------------------
3827
e7d41190
VZ
3828#ifdef TEST_UNICODE
3829
3830static void TestUnicodeToFromAscii()
3831{
3832 wxPuts(_T("Testing wxString::To/FromAscii()\n"));
3833
3834 static const char *msg = "Hello, world!";
3835 wxString s = wxString::FromAscii(msg);
3836
3837 wxPrintf(_T("Message in Unicode: %s\n"), s.c_str());
7aeebdcd 3838 printf("Message in ASCII: %s\n", (const char *)s.ToAscii());
e7d41190
VZ
3839
3840 wxPutchar(_T('\n'));
3841}
3842
5bc1deeb
VZ
3843#include "wx/textfile.h"
3844
3845static void TestUnicodeTextFileRead()
3846{
3847 wxPuts(_T("Testing wxTextFile in Unicode build\n"));
3848
3849 wxTextFile file;
3850 if ( file.Open(_T("testdata.fc"), wxConvLocal) )
e9d2bb6f 3851 {
5bc1deeb 3852 const size_t count = file.GetLineCount();
e9d2bb6f
DS
3853 for ( size_t n = 0; n < count; n++ )
3854 {
5bc1deeb
VZ
3855 const wxString& s = file[n];
3856
3857 wxPrintf(_T("Line %u: \"%s\" (len %u, last char = '%c')\n"),
3858 (unsigned)n, s.c_str(), (unsigned)s.length(), s.Last());
e9d2bb6f
DS
3859 }
3860 }
5bc1deeb
VZ
3861}
3862
e7d41190
VZ
3863#endif // TEST_UNICODE
3864
f6bcfd97
BP
3865#ifdef TEST_WCHAR
3866
e84010cf
GD
3867#include "wx/strconv.h"
3868#include "wx/fontenc.h"
3869#include "wx/encconv.h"
3870#include "wx/buffer.h"
f6bcfd97 3871
2b5f62a0 3872static const unsigned char utf8koi8r[] =
ac511156
VZ
3873{
3874 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3875 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3876 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3877 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3878 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3879 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3880 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3881};
3882
2b5f62a0
VZ
3883static const unsigned char utf8iso8859_1[] =
3884{
3885 0x53, 0x79, 0x73, 0x74, 0xc3, 0xa8, 0x6d, 0x65, 0x73, 0x20, 0x49, 0x6e,
3886 0x74, 0xc3, 0xa9, 0x67, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x65,
3887 0x6e, 0x20, 0x4d, 0xc3, 0xa9, 0x63, 0x61, 0x6e, 0x69, 0x71, 0x75, 0x65,
3888 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x71, 0x75, 0x65, 0x20, 0x65,
3889 0x74, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x71, 0x75, 0x65, 0
3890};
3891
3892static const unsigned char utf8Invalid[] =
3893{
3894 0x3c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3e, 0x32, 0x30, 0x30,
3895 0x32, 0xe5, 0xb9, 0xb4, 0x30, 0x39, 0xe6, 0x9c, 0x88, 0x32, 0x35, 0xe6,
3896 0x97, 0xa5, 0x20, 0x30, 0x37, 0xe6, 0x99, 0x82, 0x33, 0x39, 0xe5, 0x88,
3897 0x86, 0x35, 0x37, 0xe7, 0xa7, 0x92, 0x3c, 0x2f, 0x64, 0x69, 0x73, 0x70,
3898 0x6c, 0x61, 0x79, 0
3899};
3900
3901static const struct Utf8Data
3902{
3903 const unsigned char *text;
3904 size_t len;
3905 const wxChar *charset;
3906 wxFontEncoding encoding;
3907} utf8data[] =
3908{
3909 { utf8Invalid, WXSIZEOF(utf8Invalid), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3910 { utf8koi8r, WXSIZEOF(utf8koi8r), _T("koi8-r"), wxFONTENCODING_KOI8 },
3911 { utf8iso8859_1, WXSIZEOF(utf8iso8859_1), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3912};
456ae26d 3913
f6bcfd97
BP
3914static void TestUtf8()
3915{
456ae26d 3916 wxPuts(_T("*** Testing UTF8 support ***\n"));
f6bcfd97 3917
24f25c8a
VZ
3918 char buf[1024];
3919 wchar_t wbuf[1024];
2b5f62a0
VZ
3920
3921 for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
24f25c8a 3922 {
2b5f62a0
VZ
3923 const Utf8Data& u8d = utf8data[n];
3924 if ( wxConvUTF8.MB2WC(wbuf, (const char *)u8d.text,
3925 WXSIZEOF(wbuf)) == (size_t)-1 )
24f25c8a 3926 {
2b5f62a0 3927 wxPuts(_T("ERROR: UTF-8 decoding failed."));
24f25c8a
VZ
3928 }
3929 else
ac511156 3930 {
2b5f62a0
VZ
3931 wxCSConv conv(u8d.charset);
3932 if ( conv.WC2MB(buf, wbuf, WXSIZEOF(buf)) == (size_t)-1 )
3933 {
3934 wxPrintf(_T("ERROR: conversion to %s failed.\n"), u8d.charset);
3935 }
3936 else
3937 {
3938 wxPrintf(_T("String in %s: %s\n"), u8d.charset, buf);
3939 }
ac511156 3940 }
ac511156 3941
5bc1deeb 3942 wxString s(wxConvUTF8.cMB2WC((const char *)u8d.text));
2b5f62a0
VZ
3943 if ( s.empty() )
3944 s = _T("<< conversion failed >>");
3945 wxPrintf(_T("String in current cset: %s\n"), s.c_str());
3946
ac511156
VZ
3947 }
3948
e9d2bb6f 3949 wxPuts(wxEmptyString);
ac511156 3950}
f6bcfd97 3951
ac511156
VZ
3952static void TestEncodingConverter()
3953{
3954 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3955
3956 // using wxEncodingConverter should give the same result as above
3957 char buf[1024];
3958 wchar_t wbuf[1024];
2b5f62a0
VZ
3959 if ( wxConvUTF8.MB2WC(wbuf, (const char *)utf8koi8r,
3960 WXSIZEOF(utf8koi8r)) == (size_t)-1 )
ac511156 3961 {
456ae26d 3962 wxPuts(_T("ERROR: UTF-8 decoding failed."));
ac511156
VZ
3963 }
3964 else
3965 {
3966 wxEncodingConverter ec;
3967 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3968 ec.Convert(wbuf, buf);
2b5f62a0 3969 wxPrintf(_T("The same KOI8-R string using wxEC: %s\n"), buf);
24f25c8a 3970 }
ac511156 3971
e9d2bb6f 3972 wxPuts(wxEmptyString);
f6bcfd97
BP
3973}
3974
3975#endif // TEST_WCHAR
3976
3977// ----------------------------------------------------------------------------
3978// ZIP stream
3979// ----------------------------------------------------------------------------
3980
3981#ifdef TEST_ZIP
3982
2ca8b884
VZ
3983#include "wx/filesys.h"
3984#include "wx/fs_zip.h"
f6bcfd97
BP
3985#include "wx/zipstrm.h"
3986
2ca8b884
VZ
3987static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3988
f6bcfd97
BP
3989static void TestZipStreamRead()
3990{
456ae26d 3991 wxPuts(_T("*** Testing ZIP reading ***\n"));
f6bcfd97 3992
e9d2bb6f 3993 static const wxString filename = _T("foo");
2ca8b884 3994 wxZipInputStream istr(TESTFILE_ZIP, filename);
456ae26d 3995 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
f6bcfd97 3996
e9d2bb6f 3997 wxPrintf(_T("Dumping the file '%s':\n"), filename.c_str());
f6bcfd97
BP
3998 while ( !istr.Eof() )
3999 {
e9d2bb6f 4000 wxPutchar(istr.GetC());
f6bcfd97
BP
4001 fflush(stdout);
4002 }
4003
456ae26d 4004 wxPuts(_T("\n----- done ------"));
f6bcfd97
BP
4005}
4006
2ca8b884
VZ
4007static void DumpZipDirectory(wxFileSystem& fs,
4008 const wxString& dir,
4009 const wxString& indent)
4010{
4011 wxString prefix = wxString::Format(_T("%s#zip:%s"),
4012 TESTFILE_ZIP, dir.c_str());
4013 wxString wildcard = prefix + _T("/*");
4014
4015 wxString dirname = fs.FindFirst(wildcard, wxDIR);
4016 while ( !dirname.empty() )
4017 {
4018 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
4019 {
4020 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4021
4022 break;
4023 }
4024
4025 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
4026
4027 DumpZipDirectory(fs, dirname,
4028 indent + wxString(_T(' '), 4));
4029
4030 dirname = fs.FindNext();
4031 }
4032
4033 wxString filename = fs.FindFirst(wildcard, wxFILE);
4034 while ( !filename.empty() )
4035 {
4036 if ( !filename.StartsWith(prefix, &filename) )
4037 {
4038 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
4039
4040 break;
4041 }
4042
4043 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
4044
4045 filename = fs.FindNext();
4046 }
4047}
4048
4049static void TestZipFileSystem()
4050{
456ae26d 4051 wxPuts(_T("*** Testing ZIP file system ***\n"));
2ca8b884
VZ
4052
4053 wxFileSystem::AddHandler(new wxZipFSHandler);
4054 wxFileSystem fs;
4055 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
4056
4057 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
4058}
4059
f6bcfd97
BP
4060#endif // TEST_ZIP
4061
3ca6a5f0
BP
4062// ----------------------------------------------------------------------------
4063// ZLIB stream
4064// ----------------------------------------------------------------------------
4065
4066#ifdef TEST_ZLIB
4067
e84010cf
GD
4068#include "wx/zstream.h"
4069#include "wx/wfstream.h"
3ca6a5f0 4070
e9d2bb6f 4071static const wxString FILENAME_GZ = _T("test.gz");
456ae26d 4072static const wxChar *TEST_DATA = _T("hello and hello and hello and hello and hello");
3ca6a5f0
BP
4073
4074static void TestZlibStreamWrite()
4075{
456ae26d 4076 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4077
4078 wxFileOutputStream fileOutStream(FILENAME_GZ);
2104ba31 4079 wxZlibOutputStream ostr(fileOutStream);
456ae26d
VZ
4080 wxPrintf(_T("Compressing the test string... "));
4081 ostr.Write(TEST_DATA, wxStrlen(TEST_DATA) + 1);
3ca6a5f0
BP
4082 if ( !ostr )
4083 {
456ae26d 4084 wxPuts(_T("(ERROR: failed)"));
3ca6a5f0
BP
4085 }
4086 else
4087 {
456ae26d 4088 wxPuts(_T("(ok)"));
3ca6a5f0
BP
4089 }
4090
456ae26d 4091 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4092}
4093
4094static void TestZlibStreamRead()
4095{
456ae26d 4096 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3ca6a5f0
BP
4097
4098 wxFileInputStream fileInStream(FILENAME_GZ);
4099 wxZlibInputStream istr(fileInStream);
456ae26d 4100 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3ca6a5f0 4101
456ae26d 4102 wxPuts(_T("Dumping the file:"));
3ca6a5f0
BP
4103 while ( !istr.Eof() )
4104 {
e9d2bb6f 4105 wxPutchar(istr.GetC());
3ca6a5f0
BP
4106 fflush(stdout);
4107 }
4108
456ae26d 4109 wxPuts(_T("\n----- done ------"));
3ca6a5f0
BP
4110}
4111
4112#endif // TEST_ZLIB
4113
19d821c5
JS
4114// ----------------------------------------------------------------------------
4115// Gzip streams
4116// ----------------------------------------------------------------------------
4117
4118#ifdef TEST_GZIP
4119
4120#include "wx/wfstream.h"
4121#include "wx/gzstream.h"
4122#include "wx/filename.h"
4123#include "wx/txtstrm.h"
4124
4125// Reads two input streams and verifies that they are the same (and non-emtpy)
4126//
4127void GzipVerify(wxInputStream &in1, wxInputStream &in2)
4128{
4129 if (!in1 || !in2) {
4130 wxPuts(_T(" Can't verify"));
4131 return;
4132 }
4133
4134 const int BUFSIZE = 8192;
4135 wxCharBuffer buf1(BUFSIZE);
4136 wxCharBuffer buf2(BUFSIZE);
4137 bool none = true;
e9d2bb6f
DS
4138
4139 for (;;)
4140 {
19d821c5
JS
4141 int n1 = in1.Read(buf1.data(), BUFSIZE).LastRead();
4142 int n2 = in2.Read(buf2.data(), BUFSIZE).LastRead();
4143
4144 if (n1 != n2 || (n1 && memcmp(buf1, buf2, n1) != 0) || (!n1 && none)) {
4145 wxPuts(_T(" Failure"));
4146 break;
4147 }
4148
4149 if (!n1) {
4150 wxPuts(_T(" Success"));
4151 break;
4152 }
4153
4154 none = false;
4155 }
4156
4157 while (in1.IsOk())
4158 in1.Read(buf1.data(), BUFSIZE);
4159 while (in2.IsOk())
4160 in2.Read(buf2.data(), BUFSIZE);
4161}
4162
4163// Write a gzip file and read it back.
4164//
4165void TestGzip()
4166{
4167 wxPuts(_T("*** Testing gzip streams ***\n"));
4168
4169 const wxString testname = _T("gziptest");
4170 const wxString gzipname = testname + _T(".gz");
4171
4172 // write some random test data to a testfile
4173 wxPuts(_T("Writing random test data to ") + testname + _T("..."));
4174 {
4175 wxFFileOutputStream outstream(testname);
4176 wxTextOutputStream textout(outstream);
4177
4178 for (int i = 0; i < 1000 && outstream.Ok(); i++)
4179 textout << rand() << rand() << rand() << rand() << endl;
4180
4181 wxPuts(_T(" Done"));
4182 }
4183
4184 wxFileName fn(testname);
4185 wxDateTime dt = fn.GetModificationTime();
4186 wxFFileInputStream instream(testname);
4187
4188 // try writing a gzip file
4189 wxPuts(_T("Writing ") + gzipname + _T(" using wxGzipOutputStream..."));
4190 {
4191 wxFFileOutputStream outstream(gzipname);
4192 wxGzipOutputStream gzip(outstream, testname, dt);
4193
4194 if (!gzip.Write(instream))
4195 wxPuts(_T(" Failure"));
4196 else
4197 wxPuts(_T(" Success"));
4198 }
4199
4200 // try reading the gzip file
4201 wxPuts(_T("Reading ") + gzipname + _T(" using wxGzipInputStream..."));
4202 {
4203 instream.SeekI(0);
4204 wxFFileInputStream instream2(gzipname);
4205 wxGzipInputStream gzip(instream2);
4206 GzipVerify(instream, gzip);
4207
4208 if (gzip.GetName() != fn.GetFullName())
4209 wxPuts(gzipname + _T(" contains incorrect filename: ")
4210 + gzip.GetName());
4211 if (dt.IsValid() && gzip.GetDateTime() != dt)
4212 wxPuts(gzipname + _T(" contains incorrect timestamp: ")
4213 + gzip.GetDateTime().Format());
4214 }
4215
4216#ifdef __UNIX__
4217 // then verify it using gzip program if it is in the path
4218 wxPuts(_T("Reading ") + gzipname + _T(" using gzip program..."));
4219 wxFFile file(popen((_T("gzip -d -c ") + gzipname).mb_str(), "r"));
4220 if (file.fp()) {
4221 wxFFileInputStream instream2(file);
4222 instream.SeekI(0);
4223 GzipVerify(instream, instream2);
4224 pclose(file.fp());
4225 file.Detach();
4226 }
4227
4228 // try reading a gzip created by gzip program
4229 wxPuts(_T("Reading output of gzip program using wxGzipInputStream..."));
4230 file.Attach(popen((_T("gzip -c ") + testname).mb_str(), "r"));
4231 if (file.fp()) {
4232 wxFFileInputStream instream2(file);
4233 wxGzipInputStream gzip(instream2);
4234 instream.SeekI(0);
4235 GzipVerify(instream, gzip);
4236 pclose(file.fp());
4237 file.Detach();
4238 }
4239#endif
4240
4241 wxPuts(_T("\n--- Done gzip streams ---"));
4242}
4243
4244#endif // TEST_GZIP
4245
b76b015e
VZ
4246// ----------------------------------------------------------------------------
4247// date time
4248// ----------------------------------------------------------------------------
4249
d31b7b68 4250#ifdef TEST_DATETIME
b76b015e 4251
551fe3a6
VZ
4252#include <math.h>
4253
e84010cf 4254#include "wx/datetime.h"
b76b015e 4255
299fcbfe
VZ
4256// the test data
4257struct Date
4258{
4259 wxDateTime::wxDateTime_t day;
4260 wxDateTime::Month month;
4261 int year;
4262 wxDateTime::wxDateTime_t hour, min, sec;
4263 double jdn;
211c2250 4264 wxDateTime::WeekDay wday;
299fcbfe
VZ
4265 time_t gmticks, ticks;
4266
4267 void Init(const wxDateTime::Tm& tm)
4268 {
4269 day = tm.mday;
4270 month = tm.mon;
4271 year = tm.year;
4272 hour = tm.hour;
4273 min = tm.min;
4274 sec = tm.sec;
4275 jdn = 0.0;
4276 gmticks = ticks = -1;
4277 }
4278
4279 wxDateTime DT() const
4280 { return wxDateTime(day, month, year, hour, min, sec); }
4281
239446b4
VZ
4282 bool SameDay(const wxDateTime::Tm& tm) const
4283 {
4284 return day == tm.mday && month == tm.mon && year == tm.year;
4285 }
4286
299fcbfe
VZ
4287 wxString Format() const
4288 {
4289 wxString s;
456ae26d 4290 s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"),
299fcbfe
VZ
4291 hour, min, sec,
4292 wxDateTime::GetMonthName(month).c_str(),
4293 day,
4294 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4295 year > 0 ? _T("AD") : _T("BC"));
299fcbfe
VZ
4296 return s;
4297 }
239446b4
VZ
4298
4299 wxString FormatDate() const
4300 {
4301 wxString s;
456ae26d 4302 s.Printf(_T("%02d-%s-%4d%s"),
239446b4 4303 day,
f0f951fa 4304 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
239446b4 4305 abs(wxDateTime::ConvertYearToBC(year)),
456ae26d 4306 year > 0 ? _T("AD") : _T("BC"));
239446b4
VZ
4307 return s;
4308 }
299fcbfe
VZ
4309};
4310
4311static const Date testDates[] =
4312{
211c2250 4313 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
e7d41190
VZ
4314 { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 },
4315 { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 },
4316 { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 },
4317 { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 },
211c2250
VZ
4318 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
4319 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
4320 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
4321 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
4322 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
4323 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
4324 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
4325 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
4326 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
239446b4
VZ
4327 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
4328 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
4329 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
4330 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
211c2250 4331 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
299fcbfe
VZ
4332};
4333
2f02cb89
VZ
4334// this test miscellaneous static wxDateTime functions
4335static void TestTimeStatic()
4336{
456ae26d 4337 wxPuts(_T("\n*** wxDateTime static methods test ***"));
2f02cb89
VZ
4338
4339 // some info about the current date
4340 int year = wxDateTime::GetCurrentYear();
456ae26d 4341 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
2f02cb89
VZ
4342 year,
4343 wxDateTime::IsLeapYear(year) ? "" : "not ",
4344 wxDateTime::GetNumberOfDays(year));
4345
4346 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
456ae26d 4347 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
f0f951fa 4348 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2f02cb89
VZ
4349 wxDateTime::GetMonthName(month).c_str(),
4350 wxDateTime::GetNumberOfDays(month));
4351
4352 // leap year logic
fcc3d7cb
VZ
4353 static const size_t nYears = 5;
4354 static const size_t years[2][nYears] =
2f02cb89
VZ
4355 {
4356 // first line: the years to test
4357 { 1990, 1976, 2000, 2030, 1984, },
4358
cab8f76e
VZ
4359 // second line: true if leap, false otherwise
4360 { false, true, true, false, true }
2f02cb89
VZ
4361 };
4362
4363 for ( size_t n = 0; n < nYears; n++ )
4364 {
4365 int year = years[0][n];
239446b4
VZ
4366 bool should = years[1][n] != 0,
4367 is = wxDateTime::IsLeapYear(year);
2f02cb89 4368
456ae26d 4369 wxPrintf(_T("Year %d is %sa leap year (%s)\n"),
2f02cb89 4370 year,
239446b4
VZ
4371 is ? "" : "not ",
4372 should == is ? "ok" : "ERROR");
2f02cb89
VZ
4373
4374 wxASSERT( should == wxDateTime::IsLeapYear(year) );
4375 }
4376}
4377
4378// test constructing wxDateTime objects
4379static void TestTimeSet()
4380{
456ae26d 4381 wxPuts(_T("\n*** wxDateTime construction test ***"));
2f02cb89 4382
299fcbfe
VZ
4383 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4384 {
4385 const Date& d1 = testDates[n];
4386 wxDateTime dt = d1.DT();
4387
4388 Date d2;
4389 d2.Init(dt.GetTm());
4390
4391 wxString s1 = d1.Format(),
4392 s2 = d2.Format();
4393
456ae26d
VZ
4394 wxPrintf(_T("Date: %s == %s (%s)\n"),
4395 s1.c_str(), s2.c_str(),
4396 s1 == s2 ? _T("ok") : _T("ERROR"));
299fcbfe 4397 }
2f02cb89
VZ
4398}
4399
fcc3d7cb
VZ
4400// test time zones stuff
4401static void TestTimeZones()
4402{
456ae26d 4403 wxPuts(_T("\n*** wxDateTime timezone test ***"));
fcc3d7cb
VZ
4404
4405 wxDateTime now = wxDateTime::Now();
4406
456ae26d
VZ
4407 wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
4408 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
4409 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
4410 wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
4411 wxPrintf(_T(" Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
4412 wxPrintf(_T(" New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
9d9b7755
VZ
4413
4414 wxDateTime::Tm tm = now.GetTm();
4415 if ( wxDateTime(tm) != now )
4416 {
456ae26d
VZ
4417 wxPrintf(_T("ERROR: got %s instead of %s\n"),
4418 wxDateTime(tm).Format().c_str(), now.Format().c_str());
9d9b7755 4419 }
fcc3d7cb
VZ
4420}
4421
e6ec579c
VZ
4422// test some minimal support for the dates outside the standard range
4423static void TestTimeRange()
4424{
456ae26d 4425 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
e6ec579c 4426
456ae26d 4427 static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
211c2250 4428
456ae26d
VZ
4429 wxPrintf(_T("Unix epoch:\t%s\n"),
4430 wxDateTime(2440587.5).Format(fmt).c_str());
4431 wxPrintf(_T("Feb 29, 0: \t%s\n"),
4432 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
4433 wxPrintf(_T("JDN 0: \t%s\n"),
4434 wxDateTime(0.0).Format(fmt).c_str());
4435 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
4436 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
4437 wxPrintf(_T("May 29, 2099:\t%s\n"),
4438 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
e6ec579c
VZ
4439}
4440
299fcbfe 4441static void TestTimeTicks()
e6ec579c 4442{
456ae26d 4443 wxPuts(_T("\n*** wxDateTime ticks test ***"));
e6ec579c 4444
299fcbfe 4445 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1ef54dcf 4446 {
299fcbfe
VZ
4447 const Date& d = testDates[n];
4448 if ( d.ticks == -1 )
4449 continue;
1ef54dcf 4450
299fcbfe
VZ
4451 wxDateTime dt = d.DT();
4452 long ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4453 wxPrintf(_T("Ticks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4454 if ( ticks == d.ticks )
4455 {
456ae26d 4456 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4457 }
4458 else
4459 {
456ae26d
VZ
4460 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4461 (long)d.ticks, (long)(ticks - d.ticks));
299fcbfe
VZ
4462 }
4463
4464 dt = d.DT().ToTimezone(wxDateTime::GMT0);
4465 ticks = (dt.GetValue() / 1000).ToLong();
456ae26d 4466 wxPrintf(_T("GMtks of %s:\t% 10ld"), d.Format().c_str(), ticks);
299fcbfe
VZ
4467 if ( ticks == d.gmticks )
4468 {
456ae26d 4469 wxPuts(_T(" (ok)"));
299fcbfe
VZ
4470 }
4471 else
4472 {
456ae26d
VZ
4473 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4474 (long)d.gmticks, (long)(ticks - d.gmticks));
299fcbfe
VZ
4475 }
4476 }
4477
e9d2bb6f 4478 wxPuts(wxEmptyString);
299fcbfe
VZ
4479}
4480
4481// test conversions to JDN &c
4482static void TestTimeJDN()
4483{
456ae26d 4484 wxPuts(_T("\n*** wxDateTime to JDN test ***"));
1ef54dcf
VZ
4485
4486 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4487 {
4488 const Date& d = testDates[n];
299fcbfe 4489 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1ef54dcf
VZ
4490 double jdn = dt.GetJulianDayNumber();
4491
456ae26d 4492 wxPrintf(_T("JDN of %s is:\t% 15.6f"), d.Format().c_str(), jdn);
1ef54dcf
VZ
4493 if ( jdn == d.jdn )
4494 {
456ae26d 4495 wxPuts(_T(" (ok)"));
1ef54dcf
VZ
4496 }
4497 else
4498 {
456ae26d
VZ
4499 wxPrintf(_T(" (ERROR: should be %f, delta = %f)\n"),
4500 d.jdn, jdn - d.jdn);
1ef54dcf
VZ
4501 }
4502 }
e6ec579c
VZ
4503}
4504
211c2250
VZ
4505// test week days computation
4506static void TestTimeWDays()
4507{
456ae26d 4508 wxPuts(_T("\n*** wxDateTime weekday test ***"));
211c2250 4509
239446b4
VZ
4510 // test GetWeekDay()
4511 size_t n;
4512 for ( n = 0; n < WXSIZEOF(testDates); n++ )
211c2250
VZ
4513 {
4514 const Date& d = testDates[n];
4515 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
4516
4517 wxDateTime::WeekDay wday = dt.GetWeekDay();
456ae26d
VZ
4518 wxPrintf(_T("%s is: %s"),
4519 d.Format().c_str(),
4520 wxDateTime::GetWeekDayName(wday).c_str());
211c2250
VZ
4521 if ( wday == d.wday )
4522 {
456ae26d 4523 wxPuts(_T(" (ok)"));
211c2250
VZ
4524 }
4525 else
4526 {
456ae26d
VZ
4527 wxPrintf(_T(" (ERROR: should be %s)\n"),
4528 wxDateTime::GetWeekDayName(d.wday).c_str());
239446b4
VZ
4529 }
4530 }
4531
e9d2bb6f 4532 wxPuts(wxEmptyString);
239446b4
VZ
4533
4534 // test SetToWeekDay()
4535 struct WeekDateTestData
4536 {
4537 Date date; // the real date (precomputed)
4538 int nWeek; // its week index in the month
4539 wxDateTime::WeekDay wday; // the weekday
4540 wxDateTime::Month month; // the month
4541 int year; // and the year
4542
4543 wxString Format() const
4544 {
4545 wxString s, which;
4546 switch ( nWeek < -1 ? -nWeek : nWeek )
4547 {
456ae26d
VZ
4548 case 1: which = _T("first"); break;
4549 case 2: which = _T("second"); break;
4550 case 3: which = _T("third"); break;
4551 case 4: which = _T("fourth"); break;
4552 case 5: which = _T("fifth"); break;
239446b4 4553
456ae26d 4554 case -1: which = _T("last"); break;
239446b4
VZ
4555 }
4556
4557 if ( nWeek < -1 )
4558 {
456ae26d 4559 which += _T(" from end");
239446b4
VZ
4560 }
4561
456ae26d 4562 s.Printf(_T("The %s %s of %s in %d"),
239446b4
VZ
4563 which.c_str(),
4564 wxDateTime::GetWeekDayName(wday).c_str(),
4565 wxDateTime::GetMonthName(month).c_str(),
4566 year);
4567
4568 return s;
4569 }
4570 };
4571
4572 // the array data was generated by the following python program
4573 /*
4574from DateTime import *
4575from whrandom import *
4576from string import *
4577
4578monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4579wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4580
4581week = DateTimeDelta(7)
4582
4583for n in range(20):
4584 year = randint(1900, 2100)
4585 month = randint(1, 12)
4586 day = randint(1, 28)
4587 dt = DateTime(year, month, day)
4588 wday = dt.day_of_week
4589
4590 countFromEnd = choice([-1, 1])
4591 weekNum = 0;
4592
4593 while dt.month is month:
4594 dt = dt - countFromEnd * week
4595 weekNum = weekNum + countFromEnd
4596
4597 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
97e0ceea 4598
239446b4
VZ
4599 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
4600 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
97e0ceea 4601 */
239446b4
VZ
4602
4603 static const WeekDateTestData weekDatesTestData[] =
4604 {
4605 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
4606 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
4607 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
4608 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
4609 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
4610 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
4611 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
4612 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
4613 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
4614 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
4615 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
4616 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
4617 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
4618 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
4619 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
4620 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
4621 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
4622 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
4623 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
4624 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
4625 };
4626
456ae26d 4627 static const wxChar *fmt = _T("%d-%b-%Y");
239446b4
VZ
4628
4629 wxDateTime dt;
4630 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
4631 {
4632 const WeekDateTestData& wd = weekDatesTestData[n];
4633
4634 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
4635
456ae26d 4636 wxPrintf(_T("%s is %s"), wd.Format().c_str(), dt.Format(fmt).c_str());
239446b4
VZ
4637
4638 const Date& d = wd.date;
4639 if ( d.SameDay(dt.GetTm()) )
4640 {
456ae26d 4641 wxPuts(_T(" (ok)"));
239446b4
VZ
4642 }
4643 else
4644 {
4645 dt.Set(d.day, d.month, d.year);
4646
456ae26d 4647 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.Format(fmt).c_str());
211c2250
VZ
4648 }
4649 }
4650}
4651
239446b4
VZ
4652// test the computation of (ISO) week numbers
4653static void TestTimeWNumber()
4654{
456ae26d 4655 wxPuts(_T("\n*** wxDateTime week number test ***"));
239446b4
VZ
4656
4657 struct WeekNumberTestData
4658 {
4659 Date date; // the date
9d9b7755
VZ
4660 wxDateTime::wxDateTime_t week; // the week number in the year
4661 wxDateTime::wxDateTime_t wmon; // the week number in the month
4662 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
239446b4
VZ
4663 wxDateTime::wxDateTime_t dnum; // day number in the year
4664 };
4665
4666 // data generated with the following python script:
4667 /*
4668from DateTime import *
4669from whrandom import *
4670from string import *
4671
4672monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4673wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4674
9d9b7755
VZ
4675def GetMonthWeek(dt):
4676 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4677 if weekNumMonth < 0:
4678 weekNumMonth = weekNumMonth + 53
4679 return weekNumMonth
7c968cee 4680
9d9b7755
VZ
4681def GetLastSundayBefore(dt):
4682 if dt.iso_week[2] == 7:
4683 return dt
4684 else:
4685 return dt - DateTimeDelta(dt.iso_week[2])
4686
239446b4
VZ
4687for n in range(20):
4688 year = randint(1900, 2100)
4689 month = randint(1, 12)
4690 day = randint(1, 28)
4691 dt = DateTime(year, month, day)
4692 dayNum = dt.day_of_year
4693 weekNum = dt.iso_week[1]
9d9b7755
VZ
4694 weekNumMonth = GetMonthWeek(dt)
4695
4696 weekNumMonth2 = 0
4697 dtSunday = GetLastSundayBefore(dt)
4698
4699 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4700 weekNumMonth2 = weekNumMonth2 + 1
4701 dtSunday = dtSunday - DateTimeDelta(7)
4702
4703 data = { 'day': rjust(`day`, 2), \
4704 'month': monthNames[month - 1], \
4705 'year': year, \
4706 'weekNum': rjust(`weekNum`, 2), \
4707 'weekNumMonth': weekNumMonth, \
4708 'weekNumMonth2': weekNumMonth2, \
4709 'dayNum': rjust(`dayNum`, 3) }
4710
4711 print " { { %(day)s, "\
4712 "wxDateTime::%(month)s, "\
4713 "%(year)d }, "\
4714 "%(weekNum)s, "\
4715 "%(weekNumMonth)s, "\
4716 "%(weekNumMonth2)s, "\
239446b4 4717 "%(dayNum)s }," % data
9d9b7755 4718
239446b4
VZ
4719 */
4720 static const WeekNumberTestData weekNumberTestDates[] =
4721 {
9d9b7755
VZ
4722 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
4723 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
4724 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
4725 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
4726 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
4727 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
4728 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
4729 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
4730 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
4731 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
4732 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
4733 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
4734 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
4735 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
4736 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
4737 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
4738 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
4739 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
4740 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
4741 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
239446b4
VZ
4742 };
4743
4744 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
4745 {
4746 const WeekNumberTestData& wn = weekNumberTestDates[n];
4747 const Date& d = wn.date;
4748
4749 wxDateTime dt = d.DT();
4750
9d9b7755
VZ
4751 wxDateTime::wxDateTime_t
4752 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
4753 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
4754 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4755 dnum = dt.GetDayOfYear();
239446b4 4756
456ae26d 4757 wxPrintf(_T("%s: the day number is %d"), d.FormatDate().c_str(), dnum);
239446b4
VZ
4758 if ( dnum == wn.dnum )
4759 {
456ae26d 4760 wxPrintf(_T(" (ok)"));
239446b4
VZ
4761 }
4762 else
4763 {
456ae26d 4764 wxPrintf(_T(" (ERROR: should be %d)"), wn.dnum);
239446b4
VZ
4765 }
4766
2b5f62a0
VZ
4767 wxPrintf(_T(", week in month = %d"), wmon);
4768 if ( wmon != wn.wmon )
9d9b7755 4769 {
456ae26d 4770 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon);
9d9b7755
VZ
4771 }
4772
456ae26d 4773 wxPrintf(_T(" or %d"), wmon2);
9d9b7755
VZ
4774 if ( wmon2 == wn.wmon2 )
4775 {
456ae26d 4776 wxPrintf(_T(" (ok)"));
9d9b7755
VZ
4777 }
4778 else
4779 {
456ae26d 4780 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon2);
9d9b7755
VZ
4781 }
4782
2b5f62a0
VZ
4783 wxPrintf(_T(", week in year = %d"), week);
4784 if ( week != wn.week )
239446b4 4785 {
2b5f62a0 4786 wxPrintf(_T(" (ERROR: should be %d)"), wn.week);
239446b4 4787 }
2b5f62a0
VZ
4788
4789 wxPutchar(_T('\n'));
4790
4791 wxDateTime dt2(1, wxDateTime::Jan, d.year);
4792 dt2.SetToTheWeek(wn.week, dt.GetWeekDay());
4793 if ( dt2 != dt )
239446b4 4794 {
2b5f62a0
VZ
4795 Date d2;
4796 d2.Init(dt2.GetTm());
4797 wxPrintf(_T("ERROR: SetToTheWeek() returned %s\n"),
4798 d2.FormatDate().c_str());
239446b4
VZ
4799 }
4800 }
4801}
4802
4803// test DST calculations
4804static void TestTimeDST()
4805{
456ae26d 4806 wxPuts(_T("\n*** wxDateTime DST test ***"));
239446b4 4807
456ae26d 4808 wxPrintf(_T("DST is%s in effect now.\n\n"),
e9d2bb6f 4809 wxDateTime::Now().IsDST() ? wxEmptyString : _T(" not"));
239446b4
VZ
4810
4811 // taken from http://www.energy.ca.gov/daylightsaving.html
4812 static const Date datesDST[2][2004 - 1900 + 1] =
4813 {
4814 {
4815 { 1, wxDateTime::Apr, 1990 },
4816 { 7, wxDateTime::Apr, 1991 },
4817 { 5, wxDateTime::Apr, 1992 },
4818 { 4, wxDateTime::Apr, 1993 },
4819 { 3, wxDateTime::Apr, 1994 },
4820 { 2, wxDateTime::Apr, 1995 },
4821 { 7, wxDateTime::Apr, 1996 },
4822 { 6, wxDateTime::Apr, 1997 },
4823 { 5, wxDateTime::Apr, 1998 },
4824 { 4, wxDateTime::Apr, 1999 },
4825 { 2, wxDateTime::Apr, 2000 },
4826 { 1, wxDateTime::Apr, 2001 },
4827 { 7, wxDateTime::Apr, 2002 },
4828 { 6, wxDateTime::Apr, 2003 },
4829 { 4, wxDateTime::Apr, 2004 },
4830 },
4831 {
4832 { 28, wxDateTime::Oct, 1990 },
4833 { 27, wxDateTime::Oct, 1991 },
4834 { 25, wxDateTime::Oct, 1992 },
4835 { 31, wxDateTime::Oct, 1993 },
4836 { 30, wxDateTime::Oct, 1994 },
4837 { 29, wxDateTime::Oct, 1995 },
4838 { 27, wxDateTime::Oct, 1996 },
4839 { 26, wxDateTime::Oct, 1997 },
4840 { 25, wxDateTime::Oct, 1998 },
4841 { 31, wxDateTime::Oct, 1999 },
4842 { 29, wxDateTime::Oct, 2000 },
4843 { 28, wxDateTime::Oct, 2001 },
4844 { 27, wxDateTime::Oct, 2002 },
4845 { 26, wxDateTime::Oct, 2003 },
4846 { 31, wxDateTime::Oct, 2004 },
4847 }
4848 };
4849
4850 int year;
4851 for ( year = 1990; year < 2005; year++ )
4852 {
4853 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4854 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4855
456ae26d
VZ
4856 wxPrintf(_T("DST period in the US for year %d: from %s to %s"),
4857 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
239446b4
VZ
4858
4859 size_t n = year - 1990;
4860 const Date& dBegin = datesDST[0][n];
4861 const Date& dEnd = datesDST[1][n];
97e0ceea 4862
239446b4
VZ
4863 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4864 {
456ae26d 4865 wxPuts(_T(" (ok)"));
239446b4
VZ
4866 }
4867 else
4868 {
456ae26d
VZ
4869 wxPrintf(_T(" (ERROR: should be %s %d to %s %d)\n"),
4870 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4871 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
239446b4
VZ
4872 }
4873 }
4874
e9d2bb6f 4875 wxPuts(wxEmptyString);
239446b4
VZ
4876
4877 for ( year = 1990; year < 2005; year++ )
4878 {
456ae26d
VZ
4879 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
4880 year,
4881 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4882 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
239446b4
VZ
4883 }
4884}
4885
68ee7c47
VZ
4886// test wxDateTime -> text conversion
4887static void TestTimeFormat()
4888{
456ae26d 4889 wxPuts(_T("\n*** wxDateTime formatting test ***"));
68ee7c47 4890
b38e2f7d
VZ
4891 // some information may be lost during conversion, so store what kind
4892 // of info should we recover after a round trip
4893 enum CompareKind
68ee7c47 4894 {
b38e2f7d
VZ
4895 CompareNone, // don't try comparing
4896 CompareBoth, // dates and times should be identical
4897 CompareDate, // dates only
4898 CompareTime // time only
4899 };
4900
4901 static const struct
4902 {
4903 CompareKind compareKind;
456ae26d 4904 const wxChar *format;
b38e2f7d
VZ
4905 } formatTestFormats[] =
4906 {
456ae26d
VZ
4907 { CompareBoth, _T("---> %c") },
4908 { CompareDate, _T("Date is %A, %d of %B, in year %Y") },
4909 { CompareBoth, _T("Date is %x, time is %X") },
4910 { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") },
4911 { CompareNone, _T("The day of year: %j, the week of year: %W") },
ee3ef281 4912 { CompareDate, _T("ISO date without separators: %Y%m%d") },
68ee7c47
VZ
4913 };
4914
4915 static const Date formatTestDates[] =
4916 {
68ee7c47
VZ
4917 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4918 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
b38e2f7d
VZ
4919#if 0
4920 // this test can't work for other centuries because it uses two digit
4921 // years in formats, so don't even try it
68ee7c47
VZ
4922 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4923 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4924 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
b38e2f7d 4925#endif
68ee7c47
VZ
4926 };
4927
4928 // an extra test (as it doesn't depend on date, don't do it in the loop)
456ae26d 4929 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
68ee7c47 4930
b38e2f7d 4931 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
68ee7c47 4932 {
e9d2bb6f 4933 wxPuts(wxEmptyString);
68ee7c47 4934
b38e2f7d 4935 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
68ee7c47
VZ
4936 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4937 {
b38e2f7d 4938 wxString s = dt.Format(formatTestFormats[n].format);
456ae26d 4939 wxPrintf(_T("%s"), s.c_str());
f0f951fa 4940
b38e2f7d
VZ
4941 // what can we recover?
4942 int kind = formatTestFormats[n].compareKind;
4943
f0f951fa
VZ
4944 // convert back
4945 wxDateTime dt2;
b38e2f7d 4946 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
f0f951fa
VZ
4947 if ( !result )
4948 {
b38e2f7d
VZ
4949 // converion failed - should it have?
4950 if ( kind == CompareNone )
456ae26d 4951 wxPuts(_T(" (ok)"));
b38e2f7d 4952 else
456ae26d 4953 wxPuts(_T(" (ERROR: conversion back failed)"));
f0f951fa
VZ
4954 }
4955 else if ( *result )
4956 {
4957 // should have parsed the entire string
456ae26d 4958 wxPuts(_T(" (ERROR: conversion back stopped too soon)"));
f0f951fa 4959 }
f0f951fa
VZ
4960 else
4961 {
cab8f76e 4962 bool equal = false; // suppress compilaer warning
b38e2f7d
VZ
4963 switch ( kind )
4964 {
4965 case CompareBoth:
4966 equal = dt2 == dt;
4967 break;
4968
4969 case CompareDate:
4970 equal = dt.IsSameDate(dt2);
4971 break;
4972
4973 case CompareTime:
4974 equal = dt.IsSameTime(dt2);
4975 break;
4976 }
4977
4978 if ( !equal )
4979 {
456ae26d 4980 wxPrintf(_T(" (ERROR: got back '%s' instead of '%s')\n"),
b38e2f7d
VZ
4981 dt2.Format().c_str(), dt.Format().c_str());
4982 }
4983 else
4984 {
456ae26d 4985 wxPuts(_T(" (ok)"));
b38e2f7d 4986 }
f0f951fa 4987 }
68ee7c47
VZ
4988 }
4989 }
4990}
4991
97e0ceea
VZ
4992// test text -> wxDateTime conversion
4993static void TestTimeParse()
4994{
456ae26d 4995 wxPuts(_T("\n*** wxDateTime parse test ***"));
97e0ceea
VZ
4996
4997 struct ParseTestData
4998 {
456ae26d 4999 const wxChar *format;
97e0ceea
VZ
5000 Date date;
5001 bool good;
5002 };
5003
5004 static const ParseTestData parseTestDates[] =
5005 {
cab8f76e
VZ
5006 { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, true },
5007 { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, true },
97e0ceea
VZ
5008 };
5009
5010 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
5011 {
456ae26d 5012 const wxChar *format = parseTestDates[n].format;
97e0ceea 5013
456ae26d 5014 wxPrintf(_T("%s => "), format);
97e0ceea
VZ
5015
5016 wxDateTime dt;
5017 if ( dt.ParseRfc822Date(format) )
5018 {
456ae26d 5019 wxPrintf(_T("%s "), dt.Format().c_str());
97e0ceea
VZ
5020
5021 if ( parseTestDates[n].good )
5022 {
5023 wxDateTime dtReal = parseTestDates[n].date.DT();
5024 if ( dt == dtReal )
5025 {
456ae26d 5026 wxPuts(_T("(ok)"));
97e0ceea
VZ
5027 }
5028 else
5029 {
456ae26d 5030 wxPrintf(_T("(ERROR: should be %s)\n"), dtReal.Format().c_str());
97e0ceea
VZ
5031 }
5032 }
5033 else
5034 {
456ae26d 5035 wxPuts(_T("(ERROR: bad format)"));
97e0ceea
VZ
5036 }
5037 }
5038 else
5039 {
456ae26d 5040 wxPrintf(_T("bad format (%s)\n"),
97e0ceea
VZ
5041 parseTestDates[n].good ? "ERROR" : "ok");
5042 }
5043 }
5044}
5045
b92fd37c 5046static void TestDateTimeInteractive()
9d9b7755 5047{
456ae26d 5048 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
9d9b7755 5049
456ae26d 5050 wxChar buf[128];
9d9b7755
VZ
5051
5052 for ( ;; )
5053 {
456ae26d
VZ
5054 wxPrintf(_T("Enter a date: "));
5055 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
9d9b7755
VZ
5056 break;
5057
f6bcfd97 5058 // kill the last '\n'
456ae26d 5059 buf[wxStrlen(buf) - 1] = 0;
f6bcfd97 5060
9d9b7755 5061 wxDateTime dt;
456ae26d 5062 const wxChar *p = dt.ParseDate(buf);
f6bcfd97 5063 if ( !p )
9d9b7755 5064 {
456ae26d 5065 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
9d9b7755
VZ
5066
5067 continue;
5068 }
f6bcfd97
BP
5069 else if ( *p )
5070 {
456ae26d 5071 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
f6bcfd97 5072 }
9d9b7755 5073
456ae26d
VZ
5074 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
5075 dt.Format(_T("%b %d, %Y")).c_str(),
5076 dt.GetDayOfYear(),
5077 dt.GetWeekOfMonth(wxDateTime::Monday_First),
5078 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
5079 dt.GetWeekOfYear(wxDateTime::Monday_First));
9d9b7755
VZ
5080 }
5081
456ae26d 5082 wxPuts(_T("\n*** done ***"));
9d9b7755
VZ
5083}
5084
f6bcfd97
BP
5085static void TestTimeMS()
5086{
456ae26d 5087 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
f6bcfd97
BP
5088
5089 wxDateTime dt1 = wxDateTime::Now(),
5090 dt2 = wxDateTime::UNow();
5091
456ae26d
VZ
5092 wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
5093 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
5094 wxPrintf(_T("Dummy loop: "));
3ca6a5f0
BP
5095 for ( int i = 0; i < 6000; i++ )
5096 {
5097 //for ( int j = 0; j < 10; j++ )
5098 {
5099 wxString s;
456ae26d 5100 s.Printf(_T("%g"), sqrt(i));
3ca6a5f0
BP
5101 }
5102
5103 if ( !(i % 100) )
e9d2bb6f 5104 wxPutchar('.');
3ca6a5f0 5105 }
456ae26d 5106 wxPuts(_T(", done"));
3ca6a5f0
BP
5107
5108 dt1 = dt2;
5109 dt2 = wxDateTime::UNow();
456ae26d 5110 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3ca6a5f0 5111
456ae26d 5112 wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
f6bcfd97 5113
456ae26d 5114 wxPuts(_T("\n*** done ***"));
f6bcfd97
BP
5115}
5116
9d9b7755
VZ
5117static void TestTimeArithmetics()
5118{
456ae26d 5119 wxPuts(_T("\n*** testing arithmetic operations on wxDateTime ***"));
9d9b7755 5120
f6bcfd97 5121 static const struct ArithmData
9d9b7755 5122 {
456ae26d 5123 ArithmData(const wxDateSpan& sp, const wxChar *nam)
f6bcfd97
BP
5124 : span(sp), name(nam) { }
5125
9d9b7755 5126 wxDateSpan span;
456ae26d 5127 const wxChar *name;
7c968cee 5128 } testArithmData[] =
9d9b7755 5129 {
456ae26d
VZ
5130 ArithmData(wxDateSpan::Day(), _T("day")),
5131 ArithmData(wxDateSpan::Week(), _T("week")),
5132 ArithmData(wxDateSpan::Month(), _T("month")),
5133 ArithmData(wxDateSpan::Year(), _T("year")),
5134 ArithmData(wxDateSpan(1, 2, 3, 4), _T("year, 2 months, 3 weeks, 4 days")),
9d9b7755 5135 };
7c968cee 5136
9d9b7755
VZ
5137 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
5138
5139 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
5140 {
5141 wxDateSpan span = testArithmData[n].span;
5142 dt1 = dt + span;
5143 dt2 = dt - span;
5144
456ae26d
VZ
5145 const wxChar *name = testArithmData[n].name;
5146 wxPrintf(_T("%s + %s = %s, %s - %s = %s\n"),
9d9b7755
VZ
5147 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
5148 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
5149
456ae26d 5150 wxPrintf(_T("Going back: %s"), (dt1 - span).FormatISODate().c_str());
9d9b7755
VZ
5151 if ( dt1 - span == dt )
5152 {
456ae26d 5153 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5154 }
5155 else
5156 {
456ae26d 5157 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5158 }
5159
456ae26d 5160 wxPrintf(_T("Going forward: %s"), (dt2 + span).FormatISODate().c_str());
9d9b7755
VZ
5161 if ( dt2 + span == dt )
5162 {
456ae26d 5163 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5164 }
5165 else
5166 {
456ae26d 5167 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
9d9b7755
VZ
5168 }
5169
456ae26d 5170 wxPrintf(_T("Double increment: %s"), (dt2 + 2*span).FormatISODate().c_str());
9d9b7755
VZ
5171 if ( dt2 + 2*span == dt1 )
5172 {
456ae26d 5173 wxPuts(_T(" (ok)"));
9d9b7755
VZ
5174 }
5175 else
5176 {
456ae26d 5177 wxPrintf(_T(" (ERROR: should be %s)\n"), dt2.FormatISODate().c_str());
9d9b7755
VZ
5178 }
5179
e9d2bb6f 5180 wxPuts(wxEmptyString);
9d9b7755
VZ
5181 }
5182}
5183
0de868d9
VZ
5184static void TestTimeHolidays()
5185{
456ae26d 5186 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
0de868d9
VZ
5187
5188 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
5189 wxDateTime dtStart(1, tm.mon, tm.year),
5190 dtEnd = dtStart.GetLastMonthDay();
5191
5192 wxDateTimeArray hol;
5193 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
5194
456ae26d 5195 const wxChar *format = _T("%d-%b-%Y (%a)");
0de868d9 5196
456ae26d 5197 wxPrintf(_T("All holidays between %s and %s:\n"),
0de868d9
VZ
5198 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
5199
5200 size_t count = hol.GetCount();
5201 for ( size_t n = 0; n < count; n++ )
5202 {
456ae26d 5203 wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
0de868d9
VZ
5204 }
5205
e9d2bb6f 5206 wxPuts(wxEmptyString);
0de868d9
VZ
5207}
5208
f6bcfd97
BP
5209static void TestTimeZoneBug()
5210{
456ae26d 5211 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
f6bcfd97
BP
5212
5213 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
5214 for ( int i = 0; i < 31; i++ )
5215 {
456ae26d 5216 wxPrintf(_T("Date %s: week day %s.\n"),
f6bcfd97
BP
5217 date.Format(_T("%d-%m-%Y")).c_str(),
5218 date.GetWeekDayName(date.GetWeekDay()).c_str());
5219
5220 date += wxDateSpan::Day();
5221 }
5222
e9d2bb6f 5223 wxPuts(wxEmptyString);
f6bcfd97
BP
5224}
5225
df05cdc5
VZ
5226static void TestTimeSpanFormat()
5227{
456ae26d 5228 wxPuts(_T("\n*** wxTimeSpan tests ***"));
df05cdc5 5229
456ae26d 5230 static const wxChar *formats[] =
df05cdc5
VZ
5231 {
5232 _T("(default) %H:%M:%S"),
5233 _T("%E weeks and %D days"),
5234 _T("%l milliseconds"),
5235 _T("(with ms) %H:%M:%S:%l"),
5236 _T("100%% of minutes is %M"), // test "%%"
5237 _T("%D days and %H hours"),
a8625337 5238 _T("or also %S seconds"),
df05cdc5
VZ
5239 };
5240
5241 wxTimeSpan ts1(1, 2, 3, 4),
5242 ts2(111, 222, 333);
5243 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
5244 {
456ae26d 5245 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
df05cdc5
VZ
5246 ts1.Format(formats[n]).c_str(),
5247 ts2.Format(formats[n]).c_str());
5248 }
5249
e9d2bb6f 5250 wxPuts(wxEmptyString);
df05cdc5
VZ
5251}
5252
d31b7b68 5253#endif // TEST_DATETIME
b76b015e 5254
39937656
VZ
5255// ----------------------------------------------------------------------------
5256// wxTextInput/OutputStream
5257// ----------------------------------------------------------------------------
5258
5259#ifdef TEST_TEXTSTREAM
5260
5261#include "wx/txtstrm.h"
5262#include "wx/wfstream.h"
5263
5264static void TestTextInputStream()
5265{
5266 wxPuts(_T("\n*** wxTextInputStream test ***"));
5267
e9d2bb6f
DS
5268 wxString filename = _T("testdata.fc");
5269 wxFileInputStream fsIn(filename);
39937656
VZ
5270 if ( !fsIn.Ok() )
5271 {
5272 wxPuts(_T("ERROR: couldn't open file."));
5273 }
5274 else
5275 {
5276 wxTextInputStream tis(fsIn);
5277
5278 size_t line = 1;
5279 for ( ;; )
5280 {
5281 const wxString s = tis.ReadLine();
5282
5283 // line could be non empty if the last line of the file isn't
5284 // terminated with EOL
5285 if ( fsIn.Eof() && s.empty() )
5286 break;
5287
5288 wxPrintf(_T("Line %d: %s\n"), line++, s.c_str());
5289 }
5290 }
5291}
5292
5293#endif // TEST_TEXTSTREAM
5294
e87271f3
VZ
5295// ----------------------------------------------------------------------------
5296// threads
5297// ----------------------------------------------------------------------------
5298
5299#ifdef TEST_THREADS
5300
e84010cf 5301#include "wx/thread.h"
37667812 5302
bbfa0322
VZ
5303static size_t gs_counter = (size_t)-1;
5304static wxCriticalSection gs_critsect;
c112e100 5305static wxSemaphore gs_cond;
bbfa0322 5306
b568d04f 5307class MyJoinableThread : public wxThread
bbfa0322
VZ
5308{
5309public:
b568d04f
VZ
5310 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
5311 { m_n = n; Create(); }
bbfa0322
VZ
5312
5313 // thread execution starts here
b568d04f 5314 virtual ExitCode Entry();
bbfa0322 5315
b568d04f
VZ
5316private:
5317 size_t m_n;
bbfa0322
VZ
5318};
5319
b568d04f 5320wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 5321{
b568d04f
VZ
5322 unsigned long res = 1;
5323 for ( size_t n = 1; n < m_n; n++ )
5324 {
5325 res *= n;
5326
5327 // it's a loooong calculation :-)
5328 Sleep(100);
5329 }
bbfa0322 5330
b568d04f 5331 return (ExitCode)res;
bbfa0322
VZ
5332}
5333
b568d04f
VZ
5334class MyDetachedThread : public wxThread
5335{
5336public:
456ae26d 5337 MyDetachedThread(size_t n, wxChar ch)
fcc3d7cb
VZ
5338 {
5339 m_n = n;
5340 m_ch = ch;
cab8f76e 5341 m_cancelled = false;
fcc3d7cb
VZ
5342
5343 Create();
5344 }
b568d04f
VZ
5345
5346 // thread execution starts here
5347 virtual ExitCode Entry();
5348
5349 // and stops here
5350 virtual void OnExit();
5351
5352private:
9fc3ad34 5353 size_t m_n; // number of characters to write
456ae26d 5354 wxChar m_ch; // character to write
fcc3d7cb 5355
cab8f76e 5356 bool m_cancelled; // false if we exit normally
b568d04f
VZ
5357};
5358
5359wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
5360{
5361 {
5362 wxCriticalSectionLocker lock(gs_critsect);
5363 if ( gs_counter == (size_t)-1 )
5364 gs_counter = 1;
5365 else
5366 gs_counter++;
5367 }
5368
9fc3ad34 5369 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
5370 {
5371 if ( TestDestroy() )
fcc3d7cb 5372 {
cab8f76e 5373 m_cancelled = true;
fcc3d7cb 5374
bbfa0322 5375 break;
fcc3d7cb 5376 }
bbfa0322 5377
e9d2bb6f 5378 wxPutchar(m_ch);
bbfa0322
VZ
5379 fflush(stdout);
5380
5381 wxThread::Sleep(100);
5382 }
5383
b568d04f 5384 return 0;
bbfa0322
VZ
5385}
5386
b568d04f 5387void MyDetachedThread::OnExit()
bbfa0322 5388{
456ae26d 5389 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
9fc3ad34 5390
bbfa0322 5391 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 5392 if ( !--gs_counter && !m_cancelled )
c112e100 5393 gs_cond.Post();
bbfa0322
VZ
5394}
5395
2f2f3e2a 5396static void TestDetachedThreads()
9fc3ad34 5397{
456ae26d 5398 wxPuts(_T("\n*** Testing detached threads ***"));
9fc3ad34
VZ
5399
5400 static const size_t nThreads = 3;
5401 MyDetachedThread *threads[nThreads];
5402 size_t n;
5403 for ( n = 0; n < nThreads; n++ )
5404 {
5405 threads[n] = new MyDetachedThread(10, 'A' + n);
5406 }
5407
5408 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
5409 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
5410
5411 for ( n = 0; n < nThreads; n++ )
5412 {
5413 threads[n]->Run();
5414 }
5415
5416 // wait until all threads terminate
5417 gs_cond.Wait();
5418
e9d2bb6f 5419 wxPuts(wxEmptyString);
9fc3ad34
VZ
5420}
5421
2f2f3e2a 5422static void TestJoinableThreads()
9fc3ad34 5423{
456ae26d 5424 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
9fc3ad34
VZ
5425
5426 // calc 10! in the background
5427 MyJoinableThread thread(10);
5428 thread.Run();
5429
456ae26d 5430 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
5bc1deeb 5431 (unsigned long)thread.Wait());
9fc3ad34
VZ
5432}
5433
2f2f3e2a 5434static void TestThreadSuspend()
9fc3ad34 5435{
456ae26d 5436 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
2f02cb89
VZ
5437
5438 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
5439
5440 thread->Run();
5441
5442 // this is for this demo only, in a real life program we'd use another
5443 // condition variable which would be signaled from wxThread::Entry() to
5444 // tell us that the thread really started running - but here just wait a
5445 // bit and hope that it will be enough (the problem is, of course, that
5446 // the thread might still not run when we call Pause() which will result
5447 // in an error)
5448 wxThread::Sleep(300);
5449
5450 for ( size_t n = 0; n < 3; n++ )
5451 {
5452 thread->Pause();
5453
456ae26d 5454 wxPuts(_T("\nThread suspended"));
9fc3ad34
VZ
5455 if ( n > 0 )
5456 {
5457 // don't sleep but resume immediately the first time
5458 wxThread::Sleep(300);
5459 }
456ae26d 5460 wxPuts(_T("Going to resume the thread"));
9fc3ad34
VZ
5461
5462 thread->Resume();
5463 }
5464
456ae26d 5465 wxPuts(_T("Waiting until it terminates now"));
4c460b34 5466
9fc3ad34
VZ
5467 // wait until the thread terminates
5468 gs_cond.Wait();
5469
e9d2bb6f 5470 wxPuts(wxEmptyString);
9fc3ad34
VZ
5471}
5472
2f2f3e2a 5473static void TestThreadDelete()
2f02cb89
VZ
5474{
5475 // As above, using Sleep() is only for testing here - we must use some
5476 // synchronisation object instead to ensure that the thread is still
5477 // running when we delete it - deleting a detached thread which already
5478 // terminated will lead to a crash!
5479
456ae26d 5480 wxPuts(_T("\n*** Testing thread delete function ***"));
2f02cb89 5481
4c460b34
VZ
5482 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
5483
5484 thread0->Delete();
5485
456ae26d 5486 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
4c460b34 5487
2f02cb89
VZ
5488 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
5489
5490 thread1->Run();
5491
5492 wxThread::Sleep(300);
5493
5494 thread1->Delete();
5495
456ae26d 5496 wxPuts(_T("\nDeleted a running thread."));
2f02cb89
VZ
5497
5498 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
5499
5500 thread2->Run();
5501
5502 wxThread::Sleep(300);
5503
5504 thread2->Pause();
5505
5506 thread2->Delete();
5507
456ae26d 5508 wxPuts(_T("\nDeleted a sleeping thread."));
2f02cb89 5509
4c460b34
VZ
5510 MyJoinableThread thread3(20);
5511 thread3.Run();
2f02cb89 5512
4c460b34 5513 thread3.Delete();
2f02cb89 5514
456ae26d 5515 wxPuts(_T("\nDeleted a joinable thread."));
2f02cb89 5516
4c460b34
VZ
5517 MyJoinableThread thread4(2);
5518 thread4.Run();
2f02cb89
VZ
5519
5520 wxThread::Sleep(300);
5521
4c460b34 5522 thread4.Delete();
2f02cb89 5523
456ae26d 5524 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
2f02cb89 5525
e9d2bb6f 5526 wxPuts(wxEmptyString);
2f02cb89
VZ
5527}
5528
2f2f3e2a
VZ
5529class MyWaitingThread : public wxThread
5530{
5531public:
c112e100 5532 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
2f2f3e2a 5533 {
c112e100 5534 m_mutex = mutex;
2f2f3e2a
VZ
5535 m_condition = condition;
5536
5537 Create();
5538 }
5539
5540 virtual ExitCode Entry()
5541 {
456ae26d 5542 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
2f2f3e2a
VZ
5543 fflush(stdout);
5544
c112e100 5545 gs_cond.Post();
2f2f3e2a 5546
456ae26d 5547 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
2f2f3e2a
VZ
5548 fflush(stdout);
5549
c112e100 5550 m_mutex->Lock();
2f2f3e2a 5551 m_condition->Wait();
c112e100 5552 m_mutex->Unlock();
2f2f3e2a 5553
456ae26d 5554 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
2f2f3e2a
VZ
5555 fflush(stdout);
5556
5557 return 0;
5558 }
5559
5560private:
c112e100 5561 wxMutex *m_mutex;
2f2f3e2a
VZ
5562 wxCondition *m_condition;
5563};
5564
5565static void TestThreadConditions()
5566{
c112e100
VZ
5567 wxMutex mutex;
5568 wxCondition condition(mutex);
2f2f3e2a 5569
8d5eff60
VZ
5570 // otherwise its difficult to understand which log messages pertain to
5571 // which condition
456ae26d 5572 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
c112e100 5573 // condition.GetId(), gs_cond.GetId());
8d5eff60 5574
2f2f3e2a 5575 // create and launch threads
60ce696e 5576 MyWaitingThread *threads[10];
2f2f3e2a
VZ
5577
5578 size_t n;
5579 for ( n = 0; n < WXSIZEOF(threads); n++ )
5580 {
c112e100 5581 threads[n] = new MyWaitingThread( &mutex, &condition );
2f2f3e2a
VZ
5582 }
5583
5584 for ( n = 0; n < WXSIZEOF(threads); n++ )
5585 {
5586 threads[n]->Run();
5587 }
5588
5589 // wait until all threads run
456ae26d 5590 wxPuts(_T("Main thread is waiting for the other threads to start"));
2f2f3e2a
VZ
5591 fflush(stdout);
5592
5593 size_t nRunning = 0;
5594 while ( nRunning < WXSIZEOF(threads) )
5595 {
5596 gs_cond.Wait();
5597
2f2f3e2a 5598 nRunning++;
8d5eff60 5599
456ae26d 5600 wxPrintf(_T("Main thread: %u already running\n"), nRunning);
8d5eff60 5601 fflush(stdout);
2f2f3e2a
VZ
5602 }
5603
456ae26d 5604 wxPuts(_T("Main thread: all threads started up."));
2f2f3e2a
VZ
5605 fflush(stdout);
5606
8d5eff60
VZ
5607 wxThread::Sleep(500);
5608
60ce696e 5609#if 1
8d5eff60 5610 // now wake one of them up
456ae26d 5611 wxPrintf(_T("Main thread: about to signal the condition.\n"));
2f2f3e2a
VZ
5612 fflush(stdout);
5613 condition.Signal();
8d5eff60 5614#endif
2f2f3e2a 5615
60ce696e
VZ
5616 wxThread::Sleep(200);
5617
8d5eff60 5618 // wake all the (remaining) threads up, so that they can exit
456ae26d 5619 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
2f2f3e2a
VZ
5620 fflush(stdout);
5621 condition.Broadcast();
5622
8d5eff60
VZ
5623 // give them time to terminate (dirty!)
5624 wxThread::Sleep(500);
2f2f3e2a
VZ
5625}
5626
c112e100
VZ
5627#include "wx/utils.h"
5628
5629class MyExecThread : public wxThread
5630{
5631public:
5632 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
5633 m_command(command)
5634 {
5635 Create();
5636 }
5637
5638 virtual ExitCode Entry()
5639 {
5640 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
5641 }
5642
5643private:
5644 wxString m_command;
5645};
5646
5647static void TestThreadExec()
5648{
5649 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
5650
5651 MyExecThread thread(_T("true"));
5652 thread.Run();
5653
5654 wxPrintf(_T("Main program exit code: %ld.\n"),
5655 wxExecute(_T("false"), wxEXEC_SYNC));
5656
5657 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
5658}
5659
5660// semaphore tests
5661#include "wx/datetime.h"
5662
5663class MySemaphoreThread : public wxThread
5664{
5665public:
5666 MySemaphoreThread(int i, wxSemaphore *sem)
5667 : wxThread(wxTHREAD_JOINABLE),
5668 m_sem(sem),
5669 m_i(i)
5670 {
5671 Create();
5672 }
5673
5674 virtual ExitCode Entry()
5675 {
f06ef5f4
VZ
5676 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
5677 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5678
5679 m_sem->Wait();
5680
f06ef5f4
VZ
5681 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
5682 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5683
5684 Sleep(1000);
5685
f06ef5f4
VZ
5686 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
5687 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
c112e100
VZ
5688
5689 m_sem->Post();
5690
5691 return 0;
5692 }
5693
5694private:
5695 wxSemaphore *m_sem;
5696 int m_i;
5697};
5698
e9d2bb6f 5699WX_DEFINE_ARRAY_PTR(wxThread *, ArrayThreads);
c112e100
VZ
5700
5701static void TestSemaphore()
5702{
5703 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5704
5705 static const int SEM_LIMIT = 3;
5706
5707 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
5708 ArrayThreads threads;
5709
5710 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
5711 {
5712 threads.Add(new MySemaphoreThread(i, &sem));
5713 threads.Last()->Run();
5714 }
5715
5716 for ( size_t n = 0; n < threads.GetCount(); n++ )
5717 {
5718 threads[n]->Wait();
5719 delete threads[n];
5720 }
5721}
5722
e87271f3
VZ
5723#endif // TEST_THREADS
5724
e87271f3
VZ
5725// ----------------------------------------------------------------------------
5726// entry point
5727// ----------------------------------------------------------------------------
5728
daa2c7d9
VZ
5729#ifdef TEST_SNGLINST
5730 #include "wx/snglinst.h"
5731#endif // TEST_SNGLINST
5732
bbfa0322 5733int main(int argc, char **argv)
37667812 5734{
6f35ed60 5735 wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");
9cb47ea2 5736
58b24a56
VZ
5737 wxInitializer initializer;
5738 if ( !initializer )
37667812
VZ
5739 {
5740 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
5741
5742 return -1;
5743 }
5744
5745#ifdef TEST_SNGLINST
b5299791
VZ
5746 wxSingleInstanceChecker checker;
5747 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 5748 {
b5299791
VZ
5749 if ( checker.IsAnotherRunning() )
5750 {
5751 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 5752
b5299791
VZ
5753 return 1;
5754 }
37667812 5755
b5299791
VZ
5756 // wait some time to give time to launch another instance
5757 wxPrintf(_T("Press \"Enter\" to continue..."));
5758 wxFgetc(stdin);
5759 }
5760 else // failed to create
5761 {
5762 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
5763 }
58b24a56
VZ
5764#endif // TEST_SNGLINST
5765
551fe3a6
VZ
5766#ifdef TEST_CHARSET
5767 TestCharset();
5768#endif // TEST_CHARSET
0de868d9 5769
d34bce84 5770#ifdef TEST_CMDLINE
31f6de22
VZ
5771 TestCmdLineConvert();
5772
5773#if wxUSE_CMDLINE_PARSER
d34bce84
VZ
5774 static const wxCmdLineEntryDesc cmdLineDesc[] =
5775 {
456ae26d 5776 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
31a06b07 5777 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
456ae26d
VZ
5778 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
5779 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },
d34bce84 5780
456ae26d
VZ
5781 { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },
5782 { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },
5783 { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),
31a06b07 5784 wxCMD_LINE_VAL_NUMBER },
456ae26d 5785 { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),
31a06b07 5786 wxCMD_LINE_VAL_DATE },
d34bce84 5787
456ae26d 5788 { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),
d34bce84
VZ
5789 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
5790
5791 { wxCMD_LINE_NONE }
5792 };
5793
456ae26d
VZ
5794#if wxUSE_UNICODE
5795 wxChar **wargv = new wxChar *[argc + 1];
5796
5797 {
f2cb8a17
JS
5798 int n;
5799
5800 for (n = 0; n < argc; n++ )
456ae26d
VZ
5801 {
5802 wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
5803 wargv[n] = wxStrdup(warg);
5804 }
5805
5806 wargv[n] = NULL;
5807 }
5808
5809 #define argv wargv
5810#endif // wxUSE_UNICODE
5811
d34bce84
VZ
5812 wxCmdLineParser parser(cmdLineDesc, argc, argv);
5813
456ae26d
VZ
5814#if wxUSE_UNICODE
5815 {
5816 for ( int n = 0; n < argc; n++ )
5817 free(wargv[n]);
5818
5819 delete [] wargv;
5820 }
5821#endif // wxUSE_UNICODE
5822
5823 parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
f6bcfd97
BP
5824 wxCMD_LINE_VAL_STRING,
5825 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
5826
d34bce84
VZ
5827 switch ( parser.Parse() )
5828 {
5829 case -1:
456ae26d 5830 wxLogMessage(_T("Help was given, terminating."));
d34bce84
VZ
5831 break;
5832
5833 case 0:
5834 ShowCmdLine(parser);
5835 break;
5836
5837 default:
456ae26d 5838 wxLogMessage(_T("Syntax error detected, aborting."));
d34bce84
VZ
5839 break;
5840 }
31f6de22
VZ
5841#endif // wxUSE_CMDLINE_PARSER
5842
d34bce84
VZ
5843#endif // TEST_CMDLINE
5844
1944c6bd 5845#ifdef TEST_DIR
e9d2bb6f 5846 #if TEST_ALL
99a5af7f 5847 TestDirExists();
2f0c19d0 5848 TestDirEnum();
e9d2bb6f 5849 #endif
2f0c19d0 5850 TestDirTraverse();
1944c6bd
VZ
5851#endif // TEST_DIR
5852
f6bcfd97
BP
5853#ifdef TEST_DLLLOADER
5854 TestDllLoad();
5855#endif // TEST_DLLLOADER
5856
8fd0d89b
VZ
5857#ifdef TEST_ENVIRON
5858 TestEnvironment();
5859#endif // TEST_ENVIRON
5860
d93c719a
VZ
5861#ifdef TEST_EXECUTE
5862 TestExecute();
5863#endif // TEST_EXECUTE
5864
ee6e1b1d
VZ
5865#ifdef TEST_FILECONF
5866 TestFileConfRead();
5867#endif // TEST_FILECONF
5868
f6bcfd97
BP
5869#ifdef TEST_LIST
5870 TestListCtor();
df5168c4 5871 TestList();
f6bcfd97
BP
5872#endif // TEST_LIST
5873
ec37df57
VZ
5874#ifdef TEST_LOCALE
5875 TestDefaultLang();
5876#endif // TEST_LOCALE
5877
378b05f7 5878#ifdef TEST_LOG
cab8f76e
VZ
5879 wxPuts(_T("*** Testing wxLog ***"));
5880
378b05f7
VZ
5881 wxString s;
5882 for ( size_t n = 0; n < 8000; n++ )
5883 {
456ae26d 5884 s << (wxChar)(_T('A') + (n % 26));
378b05f7
VZ
5885 }
5886
cab8f76e
VZ
5887 wxLogWarning(_T("The length of the string is %lu"),
5888 (unsigned long)s.length());
5889
378b05f7 5890 wxString msg;
456ae26d 5891 msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
378b05f7
VZ
5892
5893 // this one shouldn't be truncated
456ae26d 5894 wxPrintf(msg);
378b05f7
VZ
5895
5896 // but this one will because log functions use fixed size buffer
b568d04f
VZ
5897 // (note that it doesn't need '\n' at the end neither - will be added
5898 // by wxLog anyhow)
456ae26d 5899 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
378b05f7
VZ
5900#endif // TEST_LOG
5901
f6bcfd97 5902#ifdef TEST_FILE
e9d2bb6f
DS
5903 TestFileRead();
5904 TestTextFileRead();
5905 TestFileCopy();
f6bcfd97
BP
5906#endif // TEST_FILE
5907
844f90fb 5908#ifdef TEST_FILENAME
e9d2bb6f
DS
5909 TestFileNameConstruction();
5910 TestFileNameMakeRelative();
5911 TestFileNameMakeAbsolute();
5912 TestFileNameSplit();
5913 TestFileNameTemp();
5914 TestFileNameCwd();
5915 TestFileNameDirManip();
5916 TestFileNameComparison();
5917 TestFileNameOperations();
844f90fb
VZ
5918#endif // TEST_FILENAME
5919
d56e2b97
VZ
5920#ifdef TEST_FILETIME
5921 TestFileGetTimes();
e9d2bb6f 5922 #if 0
d56e2b97 5923 TestFileSetTimes();
e9d2bb6f 5924 #endif
d56e2b97
VZ
5925#endif // TEST_FILETIME
5926
07a56e45
VZ
5927#ifdef TEST_FTP
5928 wxLog::AddTraceMask(FTP_TRACE_MASK);
5929 if ( TestFtpConnect() )
5930 {
e9d2bb6f 5931 #if TEST_ALL
07a56e45
VZ
5932 TestFtpList();
5933 TestFtpDownload();
5934 TestFtpMisc();
daa2c7d9 5935 TestFtpFileSize();
07a56e45 5936 TestFtpUpload();
e9d2bb6f 5937 #endif
daa2c7d9 5938
e9d2bb6f 5939 #if TEST_INTERACTIVE
daa2c7d9 5940 TestFtpInteractive();
e9d2bb6f 5941 #endif
07a56e45
VZ
5942 }
5943 //else: connecting to the FTP server failed
5944
e9d2bb6f 5945 #if 0
07a56e45 5946 TestFtpWuFtpd();
e9d2bb6f 5947 #endif
07a56e45
VZ
5948#endif // TEST_FTP
5949
2c8e4738
VZ
5950#ifdef TEST_HASH
5951 TestHash();
5952#endif // TEST_HASH
5953
0508ba2a
MB
5954#ifdef TEST_HASHMAP
5955 TestHashMap();
5956#endif // TEST_HASHMAP
5957
8142d704
MB
5958#ifdef TEST_HASHSET
5959 TestHashSet();
5960#endif // TEST_HASHSET
5961
696e1ea0 5962#ifdef TEST_MIME
f6bcfd97 5963 wxLog::AddTraceMask(_T("mime"));
e9d2bb6f 5964 #if TEST_ALL
f6bcfd97 5965 TestMimeEnum();
c7ce8392 5966 TestMimeOverride();
f06ef5f4 5967 TestMimeAssociate();
e9d2bb6f 5968 #endif
f06ef5f4 5969 TestMimeFilename();
696e1ea0
VZ
5970#endif // TEST_MIME
5971
89e60357 5972#ifdef TEST_INFO_FUNCTIONS
e9d2bb6f 5973 #if TEST_ALL
3a994742
VZ
5974 TestOsInfo();
5975 TestUserInfo();
19f45995 5976
e9d2bb6f 5977 #if TEST_INTERACTIVE
19f45995 5978 TestDiskInfo();
e9d2bb6f
DS
5979 #endif
5980 #endif
89e60357
VZ
5981#endif // TEST_INFO_FUNCTIONS
5982
39189b9d
VZ
5983#ifdef TEST_PATHLIST
5984 TestPathList();
5985#endif // TEST_PATHLIST
5986
8d5eff60
VZ
5987#ifdef TEST_ODBC
5988 TestDbOpen();
5989#endif // TEST_ODBC
5990
7aeebdcd
VZ
5991#ifdef TEST_PRINTF
5992 TestPrintf();
5993#endif // TEST_PRINTF
5994
7ba4fbeb 5995#ifdef TEST_REGCONF
e9d2bb6f
DS
5996 #if 0
5997 TestRegConfWrite();
5998 #endif
0aa29b6b 5999 TestRegConfRead();
7ba4fbeb
VZ
6000#endif // TEST_REGCONF
6001
bc10103e
VS
6002#if defined TEST_REGEX && TEST_INTERACTIVE
6003 TestRegExInteractive();
6004#endif // defined TEST_REGEX && TEST_INTERACTIVE
07a56e45 6005
6dfec4b8 6006#ifdef TEST_REGISTRY
daa2c7d9 6007 TestRegistryRead();
6ba63600 6008 TestRegistryAssociation();
6dfec4b8
VZ
6009#endif // TEST_REGISTRY
6010
2c8e4738 6011#ifdef TEST_SOCKETS
daa2c7d9
VZ
6012 TestSocketServer();
6013 TestSocketClient();
2c8e4738
VZ
6014#endif // TEST_SOCKETS
6015
83141d3a 6016#ifdef TEST_STREAMS
e9d2bb6f 6017 #if TEST_ALL
99a5af7f 6018 TestFileStream();
e9d2bb6f 6019 #endif
99a5af7f 6020 TestMemoryStream();
83141d3a
VZ
6021#endif // TEST_STREAMS
6022
39937656
VZ
6023#ifdef TEST_TEXTSTREAM
6024 TestTextInputStream();
6025#endif // TEST_TEXTSTREAM
6026
8d5eff60
VZ
6027#ifdef TEST_THREADS
6028 int nCPUs = wxThread::GetCPUCount();
456ae26d 6029 wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
8d5eff60
VZ
6030 if ( nCPUs != -1 )
6031 wxThread::SetConcurrency(nCPUs);
6032
5bc1deeb
VZ
6033 TestJoinableThreads();
6034
e9d2bb6f 6035 #if TEST_ALL
8d5eff60 6036 TestJoinableThreads();
5bc1deeb 6037 TestDetachedThreads();
8d5eff60
VZ
6038 TestThreadSuspend();
6039 TestThreadDelete();
c112e100
VZ
6040 TestThreadConditions();
6041 TestThreadExec();
7aeebdcd 6042 TestSemaphore();
e9d2bb6f 6043 #endif
8d5eff60
VZ
6044#endif // TEST_THREADS
6045
d31b7b68
VZ
6046#ifdef TEST_TIMER
6047 TestStopWatch();
6048#endif // TEST_TIMER
6049
6050#ifdef TEST_DATETIME
e9d2bb6f 6051 #if TEST_ALL
9d9b7755
VZ
6052 TestTimeSet();
6053 TestTimeStatic();
6054 TestTimeRange();
6055 TestTimeZones();
6056 TestTimeTicks();
6057 TestTimeJDN();
6058 TestTimeDST();
6059 TestTimeWDays();
6060 TestTimeWNumber();
6061 TestTimeParse();
9d9b7755 6062 TestTimeArithmetics();
f6bcfd97
BP
6063 TestTimeHolidays();
6064 TestTimeFormat();
daa2c7d9 6065 TestTimeSpanFormat();
3ca6a5f0 6066 TestTimeMS();
f6bcfd97
BP
6067
6068 TestTimeZoneBug();
e9d2bb6f 6069 #endif
2b5f62a0 6070
e9d2bb6f 6071 #if TEST_INTERACTIVE
b92fd37c 6072 TestDateTimeInteractive();
e9d2bb6f 6073 #endif
d31b7b68 6074#endif // TEST_DATETIME
b76b015e 6075
df5168c4
MB
6076#ifdef TEST_SCOPEGUARD
6077 TestScopeGuard();
6078#endif
6079
551fe3a6 6080#ifdef TEST_USLEEP
456ae26d 6081 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
551fe3a6
VZ
6082 wxUsleep(3000);
6083#endif // TEST_USLEEP
6084
f6bcfd97 6085#ifdef TEST_VCARD
f6bcfd97
BP
6086 TestVCardRead();
6087 TestVCardWrite();
6088#endif // TEST_VCARD
6089
0e2c5534
VZ
6090#ifdef TEST_VOLUME
6091 TestFSVolume();
6092#endif // TEST_VOLUME
6093
e7d41190 6094#ifdef TEST_UNICODE
5bc1deeb 6095 TestUnicodeTextFileRead();
e9d2bb6f 6096 #if TEST_ALL
5bc1deeb 6097 TestUnicodeToFromAscii();
e9d2bb6f 6098 #endif
e7d41190
VZ
6099#endif // TEST_UNICODE
6100
f6bcfd97
BP
6101#ifdef TEST_WCHAR
6102 TestUtf8();
ac511156 6103 TestEncodingConverter();
f6bcfd97
BP
6104#endif // TEST_WCHAR
6105
6106#ifdef TEST_ZIP
daa2c7d9 6107 TestZipStreamRead();
2ca8b884 6108 TestZipFileSystem();
f6bcfd97
BP
6109#endif // TEST_ZIP
6110
3ca6a5f0 6111#ifdef TEST_ZLIB
3ca6a5f0
BP
6112 TestZlibStreamWrite();
6113 TestZlibStreamRead();
6114#endif // TEST_ZLIB
6115
19d821c5
JS
6116#ifdef TEST_GZIP
6117 TestGzip();
6118#endif
6119
e9d2bb6f
DS
6120 wxUnusedVar(argc);
6121 wxUnusedVar(argv);
37667812
VZ
6122 return 0;
6123}
f6bcfd97 6124