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