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