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