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