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