]> git.saurik.com Git - wxWidgets.git/blame - samples/console/console.cpp
don't use wxApp::GetStdIcon
[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
19f45995 102 static const bool TEST_INTERACTIVE = TRUE;
daa2c7d9
VZ
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
df0dc216
VZ
1705 _T("XYZ File"), // description
1706 _T(".xyz"), // extensions
1707 NULL // end of extensions
a6c65e88
VZ
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
19f45995
VZ
1950 // get a random (but non null) long (not wxLongLong for now) to divide
1951 // it with
1952 long l;
1953 do
1954 {
1955 l = rand();
1956 }
1957 while ( !l );
1958
2ea24d9f
VZ
1959 q = ll / l;
1960 r = ll % l;
1961
2a310492
VZ
1962#if wxUSE_LONGLONG_NATIVE
1963 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1964
1965 wxLongLongNative p = m / l, s = m % l;
1966 wxASSERT_MSG( q == p && r == s, "division failure" );
1967#else // !wxUSE_LONGLONG_NATIVE
5e6a0e83 1968 // verify the result
2ea24d9f 1969 wxASSERT_MSG( ll == q*l + r, "division failure" );
2a310492 1970#endif // wxUSE_LONGLONG_NATIVE
2f02cb89 1971
5e6a0e83
VZ
1972 if ( !(nTested % 1000) )
1973 {
1974 putchar('.');
1975 fflush(stdout);
1976 }
1977
2f02cb89
VZ
1978 nTested++;
1979 }
1980
5e6a0e83 1981 puts(" done!");
2a310492 1982}
2f02cb89 1983
2a310492
VZ
1984static void TestAddition()
1985{
1986 puts("*** Testing wxLongLong addition ***\n");
1987
1988 wxLongLong a, b, c;
1989 size_t nTested = 0;
1990 for ( size_t n = 0; n < 100000; n++ )
1991 {
1992 a = RAND_LL();
1993 b = RAND_LL();
1994 c = a + b;
1995
1996#if wxUSE_LONGLONG_NATIVE
1997 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1998 wxLongLongNative(b.GetHi(), b.GetLo()),
7c968cee 1999 "addition failure" );
2a310492
VZ
2000#else // !wxUSE_LONGLONG_NATIVE
2001 wxASSERT_MSG( c - b == a, "addition failure" );
2002#endif // wxUSE_LONGLONG_NATIVE
2003
2004 if ( !(nTested % 1000) )
2005 {
2006 putchar('.');
2007 fflush(stdout);
2008 }
2009
2010 nTested++;
2011 }
2012
2013 puts(" done!");
b76b015e
VZ
2014}
2015
2a310492
VZ
2016static void TestBitOperations()
2017{
2018 puts("*** Testing wxLongLong bit operation ***\n");
2019
f6bcfd97 2020 wxLongLong ll;
2a310492
VZ
2021 size_t nTested = 0;
2022 for ( size_t n = 0; n < 100000; n++ )
2023 {
f6bcfd97 2024 ll = RAND_LL();
2a310492
VZ
2025
2026#if wxUSE_LONGLONG_NATIVE
2027 for ( size_t n = 0; n < 33; n++ )
2028 {
2a310492 2029 }
2a310492
VZ
2030#else // !wxUSE_LONGLONG_NATIVE
2031 puts("Can't do it without native long long type, test skipped.");
2032
2033 return;
2034#endif // wxUSE_LONGLONG_NATIVE
2035
2036 if ( !(nTested % 1000) )
2037 {
2038 putchar('.');
2039 fflush(stdout);
2040 }
2041
2042 nTested++;
2043 }
2044
2045 puts(" done!");
2046}
2047
f6bcfd97
BP
2048static void TestLongLongComparison()
2049{
2d3112ad 2050#if wxUSE_LONGLONG_WX
f6bcfd97
BP
2051 puts("*** Testing wxLongLong comparison ***\n");
2052
f6bcfd97
BP
2053 static const long ls[2] =
2054 {
2055 0x1234,
2056 -0x1234,
2057 };
2058
2059 wxLongLongWx lls[2];
2060 lls[0] = ls[0];
3a994742 2061 lls[1] = ls[1];
f6bcfd97
BP
2062
2063 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2064 {
2065 bool res;
2066
2067 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
2068 {
2069 res = lls[m] > testLongs[n];
2070 printf("0x%lx > 0x%lx is %s (%s)\n",
2071 ls[m], testLongs[n], res ? "true" : "false",
2072 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
2073
2074 res = lls[m] < testLongs[n];
2075 printf("0x%lx < 0x%lx is %s (%s)\n",
2076 ls[m], testLongs[n], res ? "true" : "false",
2077 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
2078
2079 res = lls[m] == testLongs[n];
2080 printf("0x%lx == 0x%lx is %s (%s)\n",
2081 ls[m], testLongs[n], res ? "true" : "false",
2082 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
2083 }
2084 }
2d3112ad 2085#endif // wxUSE_LONGLONG_WX
f6bcfd97
BP
2086}
2087
3a994742
VZ
2088static void TestLongLongPrint()
2089{
2090 wxPuts(_T("*** Testing wxLongLong printing ***\n"));
2091
2092 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2093 {
2094 wxLongLong ll = testLongs[n];
2095 wxPrintf(_T("%ld == %s\n"), testLongs[n], ll.ToString().c_str());
2096 }
2097
2098 wxLongLong ll(0x12345678, 0x87654321);
2099 wxPrintf(_T("0x1234567887654321 = %s\n"), ll.ToString().c_str());
2100
2101 ll.Negate();
2102 wxPrintf(_T("-0x1234567887654321 = %s\n"), ll.ToString().c_str());
2103}
2104
2a310492
VZ
2105#undef MAKE_LL
2106#undef RAND_LL
2107
b76b015e
VZ
2108#endif // TEST_LONGLONG
2109
39189b9d
VZ
2110// ----------------------------------------------------------------------------
2111// path list
2112// ----------------------------------------------------------------------------
2113
2114#ifdef TEST_PATHLIST
2115
2116static void TestPathList()
2117{
2118 puts("*** Testing wxPathList ***\n");
2119
2120 wxPathList pathlist;
2121 pathlist.AddEnvList("PATH");
2122 wxString path = pathlist.FindValidPath("ls");
2123 if ( path.empty() )
2124 {
2125 printf("ERROR: command not found in the path.\n");
2126 }
2127 else
2128 {
2129 printf("Command found in the path as '%s'.\n", path.c_str());
2130 }
2131}
2132
2133#endif // TEST_PATHLIST
2134
07a56e45
VZ
2135// ----------------------------------------------------------------------------
2136// regular expressions
2137// ----------------------------------------------------------------------------
2138
2139#ifdef TEST_REGEX
2140
e84010cf 2141#include "wx/regex.h"
07a56e45
VZ
2142
2143static void TestRegExCompile()
2144{
2145 wxPuts(_T("*** Testing RE compilation ***\n"));
2146
2147 static struct RegExCompTestData
2148 {
2149 const wxChar *pattern;
2150 bool correct;
2151 } regExCompTestData[] =
2152 {
2153 { _T("foo"), TRUE },
2154 { _T("foo("), FALSE },
2155 { _T("foo(bar"), FALSE },
2156 { _T("foo(bar)"), TRUE },
2157 { _T("foo["), FALSE },
2158 { _T("foo[bar"), FALSE },
2159 { _T("foo[bar]"), TRUE },
2160 { _T("foo{"), TRUE },
2161 { _T("foo{1"), FALSE },
2162 { _T("foo{bar"), TRUE },
2163 { _T("foo{1}"), TRUE },
2164 { _T("foo{1,2}"), TRUE },
2165 { _T("foo{bar}"), TRUE },
2166 { _T("foo*"), TRUE },
2167 { _T("foo**"), FALSE },
2168 { _T("foo+"), TRUE },
2169 { _T("foo++"), FALSE },
2170 { _T("foo?"), TRUE },
2171 { _T("foo??"), FALSE },
2172 { _T("foo?+"), FALSE },
2173 };
2174
2175 wxRegEx re;
2176 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
2177 {
2178 const RegExCompTestData& data = regExCompTestData[n];
2179 bool ok = re.Compile(data.pattern);
2180
2181 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
2182 data.pattern,
2183 ok ? _T("") : _T("not "),
2184 ok == data.correct ? _T("ok") : _T("ERROR"));
2185 }
2186}
2187
2188static void TestRegExMatch()
2189{
2190 wxPuts(_T("*** Testing RE matching ***\n"));
2191
2192 static struct RegExMatchTestData
2193 {
2194 const wxChar *pattern;
2195 const wxChar *text;
2196 bool correct;
2197 } regExMatchTestData[] =
2198 {
2199 { _T("foo"), _T("bar"), FALSE },
2200 { _T("foo"), _T("foobar"), TRUE },
2201 { _T("^foo"), _T("foobar"), TRUE },
2202 { _T("^foo"), _T("barfoo"), FALSE },
2203 { _T("bar$"), _T("barbar"), TRUE },
2204 { _T("bar$"), _T("barbar "), FALSE },
2205 };
2206
2207 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
2208 {
2209 const RegExMatchTestData& data = regExMatchTestData[n];
2210
2211 wxRegEx re(data.pattern);
2212 bool ok = re.Matches(data.text);
2213
2214 wxPrintf(_T("'%s' %s %s (%s)\n"),
2215 data.pattern,
2216 ok ? _T("matches") : _T("doesn't match"),
2217 data.text,
2218 ok == data.correct ? _T("ok") : _T("ERROR"));
2219 }
2220}
2221
2222static void TestRegExSubmatch()
2223{
2224 wxPuts(_T("*** Testing RE subexpressions ***\n"));
2225
2226 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
2227 if ( !re.IsValid() )
2228 {
2229 wxPuts(_T("ERROR: compilation failed."));
2230 return;
2231 }
2232
2233 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
2234
2235 if ( !re.Matches(text) )
2236 {
2237 wxPuts(_T("ERROR: match expected."));
2238 }
2239 else
2240 {
2241 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
2242
2243 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
2244 re.GetMatch(text, 3).c_str(),
2245 re.GetMatch(text, 2).c_str(),
2246 re.GetMatch(text, 4).c_str(),
2247 re.GetMatch(text, 1).c_str());
2248 }
2249}
2250
765624f7
VZ
2251static void TestRegExReplacement()
2252{
2253 wxPuts(_T("*** Testing RE replacement ***"));
2254
2255 static struct RegExReplTestData
2256 {
2257 const wxChar *text;
2258 const wxChar *repl;
2259 const wxChar *result;
2260 size_t count;
2261 } regExReplTestData[] =
2262 {
2263 { _T("foo123"), _T("bar"), _T("bar"), 1 },
2264 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
2265 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
2266 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
2267 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
2268 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
2269 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
2270 };
2271
2272 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
daa2c7d9 2273 wxRegEx re(pattern);
765624f7
VZ
2274
2275 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
2276
2277 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
2278 {
2279 const RegExReplTestData& data = regExReplTestData[n];
2280
2281 wxString text = data.text;
2282 size_t nRepl = re.Replace(&text, data.repl);
2283
2284 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
2285 data.text, data.repl,
2286 nRepl, nRepl == 1 ? _T("") : _T("es"),
2287 text.c_str());
2288 if ( text == data.result && nRepl == data.count )
2289 {
2290 wxPuts(_T("ok)"));
2291 }
2292 else
2293 {
2294 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
2295 data.count, data.result);
2296 }
2297 }
2298}
2299
07a56e45
VZ
2300static void TestRegExInteractive()
2301{
2302 wxPuts(_T("*** Testing RE interactively ***"));
2303
2304 for ( ;; )
2305 {
2306 char pattern[128];
2307 printf("\nEnter a pattern: ");
2308 if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
2309 break;
2310
2311 // kill the last '\n'
2312 pattern[strlen(pattern) - 1] = 0;
2313
2314 wxRegEx re;
2315 if ( !re.Compile(pattern) )
2316 {
2317 continue;
2318 }
2319
2320 char text[128];
2321 for ( ;; )
2322 {
2323 printf("Enter text to match: ");
2324 if ( !fgets(text, WXSIZEOF(text), stdin) )
2325 break;
2326
2327 // kill the last '\n'
2328 text[strlen(text) - 1] = 0;
2329
2330 if ( !re.Matches(text) )
2331 {
2332 printf("No match.\n");
2333 }
2334 else
2335 {
2336 printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
2337
2338 size_t start, len;
2339 for ( size_t n = 1; ; n++ )
2340 {
2341 if ( !re.GetMatch(&start, &len, n) )
2342 {
2343 break;
2344 }
2345
2346 printf("Subexpr %u matched '%s'\n",
2347 n, wxString(text + start, len).c_str());
2348 }
2349 }
2350 }
2351 }
2352}
2353
2354#endif // TEST_REGEX
2355
8d5eff60
VZ
2356// ----------------------------------------------------------------------------
2357// database
2358// ----------------------------------------------------------------------------
2359
2360#ifdef TEST_ODBC
2361
2362#include <wx/db.h>
2363
2364static void TestDbOpen()
2365{
2366 HENV henv;
2367 wxDb db(henv);
2368}
2369
2370#endif // TEST_ODBC
2371
6dfec4b8 2372// ----------------------------------------------------------------------------
7ba4fbeb 2373// registry and related stuff
6dfec4b8
VZ
2374// ----------------------------------------------------------------------------
2375
2376// this is for MSW only
2377#ifndef __WXMSW__
7ba4fbeb 2378 #undef TEST_REGCONF
6dfec4b8
VZ
2379 #undef TEST_REGISTRY
2380#endif
2381
7ba4fbeb
VZ
2382#ifdef TEST_REGCONF
2383
e84010cf
GD
2384#include "wx/confbase.h"
2385#include "wx/msw/regconf.h"
7ba4fbeb
VZ
2386
2387static void TestRegConfWrite()
2388{
2389 wxRegConfig regconf(_T("console"), _T("wxwindows"));
2390 regconf.Write(_T("Hello"), wxString(_T("world")));
2391}
2392
2393#endif // TEST_REGCONF
2394
6dfec4b8
VZ
2395#ifdef TEST_REGISTRY
2396
e84010cf 2397#include "wx/msw/registry.h"
6dfec4b8
VZ
2398
2399// I chose this one because I liked its name, but it probably only exists under
2400// NT
2401static const wxChar *TESTKEY =
2402 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2403
2404static void TestRegistryRead()
2405{
2406 puts("*** testing registry reading ***");
2407
2408 wxRegKey key(TESTKEY);
2409 printf("The test key name is '%s'.\n", key.GetName().c_str());
2410 if ( !key.Open() )
2411 {
2412 puts("ERROR: test key can't be opened, aborting test.");
2413
2414 return;
2415 }
2416
2417 size_t nSubKeys, nValues;
2418 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2419 {
2420 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
2421 }
2422
2423 printf("Enumerating values:\n");
2424
2425 long dummy;
2426 wxString value;
2427 bool cont = key.GetFirstValue(value, dummy);
2428 while ( cont )
2429 {
2430 printf("Value '%s': type ", value.c_str());
2431 switch ( key.GetValueType(value) )
2432 {
2433 case wxRegKey::Type_None: printf("ERROR (none)"); break;
2434 case wxRegKey::Type_String: printf("SZ"); break;
2435 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
2436 case wxRegKey::Type_Binary: printf("BINARY"); break;
2437 case wxRegKey::Type_Dword: printf("DWORD"); break;
2438 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
2439 default: printf("other (unknown)"); break;
2440 }
2441
2442 printf(", value = ");
2443 if ( key.IsNumericValue(value) )
2444 {
2445 long val;
2446 key.QueryValue(value, &val);
2447 printf("%ld", val);
2448 }
2449 else // string
2450 {
2451 wxString val;
2452 key.QueryValue(value, val);
2453 printf("'%s'", val.c_str());
2454
2455 key.QueryRawValue(value, val);
2456 printf(" (raw value '%s')", val.c_str());
2457 }
2458
2459 putchar('\n');
2460
2461 cont = key.GetNextValue(value, dummy);
2462 }
2463}
2464
6ba63600
VZ
2465static void TestRegistryAssociation()
2466{
2467 /*
2468 The second call to deleteself genertaes an error message, with a
2469 messagebox saying .flo is crucial to system operation, while the .ddf
2470 call also fails, but with no error message
2471 */
2472
2473 wxRegKey key;
2474
2475 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2476 key.Create();
2477 key = "ddxf_auto_file" ;
2478 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2479 key.Create();
2480 key = "ddxf_auto_file" ;
2481 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2482 key.Create();
2483 key = "program,0" ;
2484 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2485 key.Create();
2486 key = "program \"%1\"" ;
2487
2488 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2489 key.DeleteSelf();
2490 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2491 key.DeleteSelf();
2492 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2493 key.DeleteSelf();
2494 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2495 key.DeleteSelf();
2496}
2497
6dfec4b8
VZ
2498#endif // TEST_REGISTRY
2499
2c8e4738
VZ
2500// ----------------------------------------------------------------------------
2501// sockets
2502// ----------------------------------------------------------------------------
2503
2504#ifdef TEST_SOCKETS
2505
e84010cf
GD
2506#include "wx/socket.h"
2507#include "wx/protocol/protocol.h"
2508#include "wx/protocol/http.h"
8e907a13
VZ
2509
2510static void TestSocketServer()
2511{
2512 puts("*** Testing wxSocketServer ***\n");
2513
ccdb23df
VZ
2514 static const int PORT = 3000;
2515
8e907a13 2516 wxIPV4address addr;
ccdb23df 2517 addr.Service(PORT);
8e907a13
VZ
2518
2519 wxSocketServer *server = new wxSocketServer(addr);
2520 if ( !server->Ok() )
2521 {
2522 puts("ERROR: failed to bind");
ccdb23df
VZ
2523
2524 return;
8e907a13 2525 }
8dfea369
VZ
2526
2527 for ( ;; )
2528 {
ccdb23df 2529 printf("Server: waiting for connection on port %d...\n", PORT);
8dfea369
VZ
2530
2531 wxSocketBase *socket = server->Accept();
2532 if ( !socket )
2533 {
2534 puts("ERROR: wxSocketServer::Accept() failed.");
2535 break;
2536 }
2537
2538 puts("Server: got a client.");
2539
ccdb23df
VZ
2540 server->SetTimeout(60); // 1 min
2541
2542 while ( socket->IsConnected() )
8dfea369 2543 {
ccdb23df
VZ
2544 wxString s;
2545 char ch = '\0';
2546 for ( ;; )
8dfea369 2547 {
ccdb23df
VZ
2548 if ( socket->Read(&ch, sizeof(ch)).Error() )
2549 {
2550 // don't log error if the client just close the connection
2551 if ( socket->IsConnected() )
2552 {
2553 puts("ERROR: in wxSocket::Read.");
2554 }
8dfea369 2555
ccdb23df
VZ
2556 break;
2557 }
8dfea369 2558
ccdb23df
VZ
2559 if ( ch == '\r' )
2560 continue;
8dfea369 2561
ccdb23df
VZ
2562 if ( ch == '\n' )
2563 break;
8dfea369 2564
ccdb23df
VZ
2565 s += ch;
2566 }
8dfea369 2567
ccdb23df
VZ
2568 if ( ch != '\n' )
2569 {
2570 break;
2571 }
8dfea369 2572
ccdb23df
VZ
2573 printf("Server: got '%s'.\n", s.c_str());
2574 if ( s == _T("bye") )
2575 {
2576 delete socket;
8dfea369 2577
ccdb23df
VZ
2578 break;
2579 }
2580
2581 socket->Write(s.MakeUpper().c_str(), s.length());
2582 socket->Write("\r\n", 2);
2583 printf("Server: wrote '%s'.\n", s.c_str());
8dfea369
VZ
2584 }
2585
ccdb23df 2586 puts("Server: lost a client.");
8dfea369 2587
ccdb23df 2588 socket->Destroy();
8dfea369 2589 }
9fc3cba7 2590
ccdb23df
VZ
2591 // same as "delete server" but is consistent with GUI programs
2592 server->Destroy();
8e907a13 2593}
2c8e4738
VZ
2594
2595static void TestSocketClient()
2596{
2597 puts("*** Testing wxSocketClient ***\n");
2598
8e907a13
VZ
2599 static const char *hostname = "www.wxwindows.org";
2600
2601 wxIPV4address addr;
2602 addr.Hostname(hostname);
2603 addr.Service(80);
2604
2605 printf("--- Attempting to connect to %s:80...\n", hostname);
2c8e4738
VZ
2606
2607 wxSocketClient client;
8e907a13 2608 if ( !client.Connect(addr) )
2c8e4738 2609 {
8e907a13 2610 printf("ERROR: failed to connect to %s\n", hostname);
2c8e4738
VZ
2611 }
2612 else
2613 {
8e907a13
VZ
2614 printf("--- Connected to %s:%u...\n",
2615 addr.Hostname().c_str(), addr.Service());
2616
2c8e4738
VZ
2617 char buf[8192];
2618
8e907a13
VZ
2619 // could use simply "GET" here I suppose
2620 wxString cmdGet =
2621 wxString::Format("GET http://%s/\r\n", hostname);
2622 client.Write(cmdGet, cmdGet.length());
2623 printf("--- Sent command '%s' to the server\n",
2624 MakePrintable(cmdGet).c_str());
2c8e4738 2625 client.Read(buf, WXSIZEOF(buf));
8e907a13
VZ
2626 printf("--- Server replied:\n%s", buf);
2627 }
2628}
2629
2e907fab
VZ
2630#endif // TEST_SOCKETS
2631
b92fd37c
VZ
2632// ----------------------------------------------------------------------------
2633// FTP
2634// ----------------------------------------------------------------------------
2635
2e907fab
VZ
2636#ifdef TEST_FTP
2637
e84010cf 2638#include "wx/protocol/ftp.h"
2e907fab 2639
b92fd37c
VZ
2640static wxFTP ftp;
2641
2642#define FTP_ANONYMOUS
2643
2644#ifdef FTP_ANONYMOUS
2645 static const char *directory = "/pub";
2646 static const char *filename = "welcome.msg";
2647#else
2648 static const char *directory = "/etc";
2649 static const char *filename = "issue";
2650#endif
2651
2652static bool TestFtpConnect()
8e907a13 2653{
b92fd37c 2654 puts("*** Testing FTP connect ***");
8e907a13 2655
b92fd37c
VZ
2656#ifdef FTP_ANONYMOUS
2657 static const char *hostname = "ftp.wxwindows.org";
2658
2659 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
2660#else // !FTP_ANONYMOUS
2661 static const char *hostname = "localhost";
2662
2663 char user[256];
2664 fgets(user, WXSIZEOF(user), stdin);
2665 user[strlen(user) - 1] = '\0'; // chop off '\n'
2666 ftp.SetUser(user);
2667
2668 char password[256];
2669 printf("Password for %s: ", password);
2670 fgets(password, WXSIZEOF(password), stdin);
2671 password[strlen(password) - 1] = '\0'; // chop off '\n'
2672 ftp.SetPassword(password);
2673
2674 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
2675#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2676
2677 if ( !ftp.Connect(hostname) )
2678 {
2679 printf("ERROR: failed to connect to %s\n", hostname);
2680
2681 return FALSE;
2682 }
2683 else
2684 {
2685 printf("--- Connected to %s, current directory is '%s'\n",
2686 hostname, ftp.Pwd().c_str());
2687 }
2688
2689 return TRUE;
2690}
b1229561 2691
b92fd37c
VZ
2692// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2693static void TestFtpWuFtpd()
2694{
2695 wxFTP ftp;
b1229561
VZ
2696 static const char *hostname = "ftp.eudora.com";
2697 if ( !ftp.Connect(hostname) )
2698 {
2699 printf("ERROR: failed to connect to %s\n", hostname);
2700 }
2701 else
2702 {
2703 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2704 wxInputStream *in = ftp.GetInputStream(filename);
2705 if ( !in )
2706 {
2707 printf("ERROR: couldn't get input stream for %s\n", filename);
2708 }
2709 else
2710 {
2711 size_t size = in->StreamSize();
2712 printf("Reading file %s (%u bytes)...", filename, size);
2713
2714 char *data = new char[size];
2715 if ( !in->Read(data, size) )
2716 {
2717 puts("ERROR: read error");
2718 }
2719 else
2720 {
2721 printf("Successfully retrieved the file.\n");
2722 }
2723
2724 delete [] data;
2725 delete in;
2726 }
2727 }
b92fd37c 2728}
b1229561 2729
b92fd37c
VZ
2730static void TestFtpList()
2731{
2732 puts("*** Testing wxFTP file listing ***\n");
8e907a13 2733
b92fd37c
VZ
2734 // test CWD
2735 if ( !ftp.ChDir(directory) )
2736 {
2737 printf("ERROR: failed to cd to %s\n", directory);
2738 }
2e907fab 2739
b92fd37c 2740 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2e907fab 2741
b92fd37c
VZ
2742 // test NLIST and LIST
2743 wxArrayString files;
2744 if ( !ftp.GetFilesList(files) )
8e907a13 2745 {
b92fd37c 2746 puts("ERROR: failed to get NLIST of files");
8e907a13
VZ
2747 }
2748 else
2749 {
b92fd37c
VZ
2750 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2751 size_t count = files.GetCount();
2752 for ( size_t n = 0; n < count; n++ )
8e907a13 2753 {
b92fd37c 2754 printf("\t%s\n", files[n].c_str());
8e907a13 2755 }
b92fd37c
VZ
2756 puts("End of the file list");
2757 }
8e907a13 2758
b92fd37c
VZ
2759 if ( !ftp.GetDirList(files) )
2760 {
2761 puts("ERROR: failed to get LIST of files");
2762 }
2763 else
2764 {
2765 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2766 size_t count = files.GetCount();
2767 for ( size_t n = 0; n < count; n++ )
8e907a13 2768 {
b92fd37c 2769 printf("\t%s\n", files[n].c_str());
2e907fab 2770 }
b92fd37c
VZ
2771 puts("End of the file list");
2772 }
2773
2774 if ( !ftp.ChDir(_T("..")) )
2775 {
2776 puts("ERROR: failed to cd to ..");
2777 }
2e907fab 2778
b92fd37c
VZ
2779 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2780}
2781
2782static void TestFtpDownload()
2783{
2784 puts("*** Testing wxFTP download ***\n");
2785
2786 // test RETR
2787 wxInputStream *in = ftp.GetInputStream(filename);
2788 if ( !in )
2789 {
2790 printf("ERROR: couldn't get input stream for %s\n", filename);
2791 }
2792 else
2793 {
2794 size_t size = in->StreamSize();
2795 printf("Reading file %s (%u bytes)...", filename, size);
2796 fflush(stdout);
2797
2798 char *data = new char[size];
2799 if ( !in->Read(data, size) )
2e907fab 2800 {
b92fd37c 2801 puts("ERROR: read error");
2e907fab
VZ
2802 }
2803 else
2804 {
b92fd37c 2805 printf("\nContents of %s:\n%s\n", filename, data);
8e907a13
VZ
2806 }
2807
b92fd37c
VZ
2808 delete [] data;
2809 delete in;
2810 }
2811}
8e907a13 2812
b92fd37c
VZ
2813static void TestFtpFileSize()
2814{
2815 puts("*** Testing FTP SIZE command ***");
2816
2817 if ( !ftp.ChDir(directory) )
2818 {
2819 printf("ERROR: failed to cd to %s\n", directory);
2820 }
2821
2822 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2823
2824 if ( ftp.FileExists(filename) )
2825 {
2826 int size = ftp.GetFileSize(filename);
2827 if ( size == -1 )
2828 printf("ERROR: couldn't get size of '%s'\n", filename);
8e907a13 2829 else
b92fd37c
VZ
2830 printf("Size of '%s' is %d bytes.\n", filename, size);
2831 }
2832 else
2833 {
2834 printf("ERROR: '%s' doesn't exist\n", filename);
2835 }
2836}
2837
2838static void TestFtpMisc()
2839{
2840 puts("*** Testing miscellaneous wxFTP functions ***");
2841
2842 if ( ftp.SendCommand("STAT") != '2' )
2843 {
2844 puts("ERROR: STAT failed");
2845 }
2846 else
2847 {
2848 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2849 }
2850
2851 if ( ftp.SendCommand("HELP SITE") != '2' )
2852 {
2853 puts("ERROR: HELP SITE failed");
2854 }
2855 else
2856 {
2857 printf("The list of site-specific commands:\n\n%s\n",
2858 ftp.GetLastResult().c_str());
2859 }
2860}
2861
2862static void TestFtpInteractive()
2863{
2864 puts("\n*** Interactive wxFTP test ***");
2865
2866 char buf[128];
2867
2868 for ( ;; )
2869 {
2870 printf("Enter FTP command: ");
2871 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2872 break;
2873
2874 // kill the last '\n'
2875 buf[strlen(buf) - 1] = 0;
2876
2877 // special handling of LIST and NLST as they require data connection
2878 wxString start(buf, 4);
2879 start.MakeUpper();
2880 if ( start == "LIST" || start == "NLST" )
8e907a13 2881 {
b92fd37c
VZ
2882 wxString wildcard;
2883 if ( strlen(buf) > 4 )
2884 wildcard = buf + 5;
8e907a13 2885
b92fd37c
VZ
2886 wxArrayString files;
2887 if ( !ftp.GetList(files, wildcard, start == "LIST") )
8e907a13 2888 {
b92fd37c 2889 printf("ERROR: failed to get %s of files\n", start.c_str());
8e907a13
VZ
2890 }
2891 else
2892 {
b92fd37c
VZ
2893 printf("--- %s of '%s' under '%s':\n",
2894 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2895 size_t count = files.GetCount();
2896 for ( size_t n = 0; n < count; n++ )
2897 {
2898 printf("\t%s\n", files[n].c_str());
2899 }
2900 puts("--- End of the file list");
8e907a13 2901 }
2e907fab 2902 }
b92fd37c 2903 else // !list
2e907fab 2904 {
b92fd37c
VZ
2905 char ch = ftp.SendCommand(buf);
2906 printf("Command %s", ch ? "succeeded" : "failed");
2907 if ( ch )
2908 {
2909 printf(" (return code %c)", ch);
2910 }
2e907fab 2911
b92fd37c 2912 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2e907fab 2913 }
2c8e4738 2914 }
b92fd37c
VZ
2915
2916 puts("\n*** done ***");
2c8e4738
VZ
2917}
2918
b92fd37c 2919static void TestFtpUpload()
f6bcfd97
BP
2920{
2921 puts("*** Testing wxFTP uploading ***\n");
2922
b92fd37c
VZ
2923 // upload a file
2924 static const char *file1 = "test1";
2925 static const char *file2 = "test2";
2926 wxOutputStream *out = ftp.GetOutputStream(file1);
2927 if ( out )
2928 {
2929 printf("--- Uploading to %s ---\n", file1);
2930 out->Write("First hello", 11);
2931 delete out;
2932 }
f6bcfd97 2933
b92fd37c
VZ
2934 // send a command to check the remote file
2935 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
f6bcfd97 2936 {
b92fd37c 2937 printf("ERROR: STAT %s failed\n", file1);
f6bcfd97
BP
2938 }
2939 else
2940 {
b92fd37c
VZ
2941 printf("STAT %s returned:\n\n%s\n",
2942 file1, ftp.GetLastResult().c_str());
2943 }
2e907fab 2944
b92fd37c
VZ
2945 out = ftp.GetOutputStream(file2);
2946 if ( out )
2947 {
2948 printf("--- Uploading to %s ---\n", file1);
2949 out->Write("Second hello", 12);
2950 delete out;
f6bcfd97
BP
2951 }
2952}
2953
2e907fab 2954#endif // TEST_FTP
2c8e4738 2955
83141d3a
VZ
2956// ----------------------------------------------------------------------------
2957// streams
2958// ----------------------------------------------------------------------------
2959
2960#ifdef TEST_STREAMS
2961
e84010cf
GD
2962#include "wx/wfstream.h"
2963#include "wx/mstream.h"
83141d3a 2964
24f25c8a
VZ
2965static void TestFileStream()
2966{
2967 puts("*** Testing wxFileInputStream ***");
2968
2969 static const wxChar *filename = _T("testdata.fs");
2970 {
2971 wxFileOutputStream fsOut(filename);
2972 fsOut.Write("foo", 3);
2973 }
2974
2975 wxFileInputStream fsIn(filename);
2976 printf("File stream size: %u\n", fsIn.GetSize());
2977 while ( !fsIn.Eof() )
2978 {
2979 putchar(fsIn.GetC());
2980 }
2981
2982 if ( !wxRemoveFile(filename) )
2983 {
2984 printf("ERROR: failed to remove the file '%s'.\n", filename);
2985 }
2986
2987 puts("\n*** wxFileInputStream test done ***");
2988}
2989
83141d3a
VZ
2990static void TestMemoryStream()
2991{
2992 puts("*** Testing wxMemoryInputStream ***");
2993
2994 wxChar buf[1024];
2995 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2996
2997 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2998 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2999 while ( !memInpStream.Eof() )
3000 {
3001 putchar(memInpStream.GetC());
3002 }
3003
3004 puts("\n*** wxMemoryInputStream test done ***");
3005}
3006
3007#endif // TEST_STREAMS
3008
d31b7b68
VZ
3009// ----------------------------------------------------------------------------
3010// timers
3011// ----------------------------------------------------------------------------
3012
3013#ifdef TEST_TIMER
3014
e84010cf
GD
3015#include "wx/timer.h"
3016#include "wx/utils.h"
d31b7b68
VZ
3017
3018static void TestStopWatch()
3019{
3020 puts("*** Testing wxStopWatch ***\n");
3021
3022 wxStopWatch sw;
3023 printf("Sleeping 3 seconds...");
3024 wxSleep(3);
87798c00 3025 printf("\telapsed time: %ldms\n", sw.Time());
d31b7b68
VZ
3026
3027 sw.Pause();
3028 printf("Sleeping 2 more seconds...");
3029 wxSleep(2);
87798c00 3030 printf("\telapsed time: %ldms\n", sw.Time());
d31b7b68
VZ
3031
3032 sw.Resume();
3033 printf("And 3 more seconds...");
3034 wxSleep(3);
87798c00
VZ
3035 printf("\telapsed time: %ldms\n", sw.Time());
3036
3037 wxStopWatch sw2;
3038 puts("\nChecking for 'backwards clock' bug...");
3039 for ( size_t n = 0; n < 70; n++ )
3040 {
3041 sw2.Start();
89e6463c
GRG
3042
3043 for ( size_t m = 0; m < 100000; m++ )
87798c00 3044 {
89e6463c
GRG
3045 if ( sw.Time() < 0 || sw2.Time() < 0 )
3046 {
3047 puts("\ntime is negative - ERROR!");
3048 }
87798c00
VZ
3049 }
3050
3051 putchar('.');
3052 }
3053
3054 puts(", ok.");
d31b7b68
VZ
3055}
3056
3057#endif // TEST_TIMER
3058
f6bcfd97
BP
3059// ----------------------------------------------------------------------------
3060// vCard support
3061// ----------------------------------------------------------------------------
3062
3063#ifdef TEST_VCARD
3064
e84010cf 3065#include "wx/vcard.h"
f6bcfd97
BP
3066
3067static void DumpVObject(size_t level, const wxVCardObject& vcard)
3068{
3069 void *cookie;
3070 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3071 while ( vcObj )
3072 {
3073 printf("%s%s",
3074 wxString(_T('\t'), level).c_str(),
3075 vcObj->GetName().c_str());
3076
3077 wxString value;
3078 switch ( vcObj->GetType() )
3079 {
3080 case wxVCardObject::String:
3081 case wxVCardObject::UString:
3082 {
3083 wxString val;
3084 vcObj->GetValue(&val);
3085 value << _T('"') << val << _T('"');
3086 }
3087 break;
3088
3089 case wxVCardObject::Int:
3090 {
3091 unsigned int i;
3092 vcObj->GetValue(&i);
3093 value.Printf(_T("%u"), i);
3094 }
3095 break;
3096
3097 case wxVCardObject::Long:
3098 {
3099 unsigned long l;
3100 vcObj->GetValue(&l);
3101 value.Printf(_T("%lu"), l);
3102 }
3103 break;
3104
3105 case wxVCardObject::None:
3106 break;
3107
3108 case wxVCardObject::Object:
3109 value = _T("<node>");
3110 break;
3111
3112 default:
3113 value = _T("<unknown value type>");
3114 }
3115
3116 if ( !!value )
3117 printf(" = %s", value.c_str());
3118 putchar('\n');
3119
3120 DumpVObject(level + 1, *vcObj);
3121
3122 delete vcObj;
3123 vcObj = vcard.GetNextProp(&cookie);
3124 }
3125}
3126
3127static void DumpVCardAddresses(const wxVCard& vcard)
3128{
3129 puts("\nShowing all addresses from vCard:\n");
3130
3131 size_t nAdr = 0;
3132 void *cookie;
3133 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3134 while ( addr )
3135 {
3136 wxString flagsStr;
3137 int flags = addr->GetFlags();
3138 if ( flags & wxVCardAddress::Domestic )
3139 {
3140 flagsStr << _T("domestic ");
3141 }
3142 if ( flags & wxVCardAddress::Intl )
3143 {
3144 flagsStr << _T("international ");
3145 }
3146 if ( flags & wxVCardAddress::Postal )
3147 {
3148 flagsStr << _T("postal ");
3149 }
3150 if ( flags & wxVCardAddress::Parcel )
3151 {
3152 flagsStr << _T("parcel ");
3153 }
3154 if ( flags & wxVCardAddress::Home )
3155 {
3156 flagsStr << _T("home ");
3157 }
3158 if ( flags & wxVCardAddress::Work )
3159 {
3160 flagsStr << _T("work ");
3161 }
3162
3163 printf("Address %u:\n"
3164 "\tflags = %s\n"
3165 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3166 ++nAdr,
3167 flagsStr.c_str(),
3168 addr->GetPostOffice().c_str(),
3169 addr->GetExtAddress().c_str(),
3170 addr->GetStreet().c_str(),
3171 addr->GetLocality().c_str(),
3172 addr->GetRegion().c_str(),
3173 addr->GetPostalCode().c_str(),
3174 addr->GetCountry().c_str()
3175 );
3176
3177 delete addr;
3178 addr = vcard.GetNextAddress(&cookie);
3179 }
3180}
3181
3182static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3183{
3184 puts("\nShowing all phone numbers from vCard:\n");
3185
3186 size_t nPhone = 0;
3187 void *cookie;
3188 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3189 while ( phone )
3190 {
3191 wxString flagsStr;
3192 int flags = phone->GetFlags();
3193 if ( flags & wxVCardPhoneNumber::Voice )
3194 {
3195 flagsStr << _T("voice ");
3196 }
3197 if ( flags & wxVCardPhoneNumber::Fax )
3198 {
3199 flagsStr << _T("fax ");
3200 }
3201 if ( flags & wxVCardPhoneNumber::Cellular )
3202 {
3203 flagsStr << _T("cellular ");
3204 }
3205 if ( flags & wxVCardPhoneNumber::Modem )
3206 {
3207 flagsStr << _T("modem ");
3208 }
3209 if ( flags & wxVCardPhoneNumber::Home )
3210 {
3211 flagsStr << _T("home ");
3212 }
3213 if ( flags & wxVCardPhoneNumber::Work )
3214 {
3215 flagsStr << _T("work ");
3216 }
3217
3218 printf("Phone number %u:\n"
3219 "\tflags = %s\n"
3220 "\tvalue = %s\n",
3221 ++nPhone,
3222 flagsStr.c_str(),
3223 phone->GetNumber().c_str()
3224 );
3225
3226 delete phone;
3227 phone = vcard.GetNextPhoneNumber(&cookie);
3228 }
3229}
3230
3231static void TestVCardRead()
3232{
3233 puts("*** Testing wxVCard reading ***\n");
3234
3235 wxVCard vcard(_T("vcard.vcf"));
3236 if ( !vcard.IsOk() )
3237 {
3238 puts("ERROR: couldn't load vCard.");
3239 }
3240 else
3241 {
3242 // read individual vCard properties
3243 wxVCardObject *vcObj = vcard.GetProperty("FN");
3244 wxString value;
3245 if ( vcObj )
3246 {
3247 vcObj->GetValue(&value);
3248 delete vcObj;
3249 }
3250 else
3251 {
3252 value = _T("<none>");
3253 }
3254
3255 printf("Full name retrieved directly: %s\n", value.c_str());
3256
3257
3258 if ( !vcard.GetFullName(&value) )
3259 {
3260 value = _T("<none>");
3261 }
3262
3263 printf("Full name from wxVCard API: %s\n", value.c_str());
3264
3265 // now show how to deal with multiply occuring properties
3266 DumpVCardAddresses(vcard);
3267 DumpVCardPhoneNumbers(vcard);
3268
3269 // and finally show all
3270 puts("\nNow dumping the entire vCard:\n"
3271 "-----------------------------\n");
3272
3273 DumpVObject(0, vcard);
3274 }
3275}
3276
3277static void TestVCardWrite()
3278{
3279 puts("*** Testing wxVCard writing ***\n");
3280
3281 wxVCard vcard;
3282 if ( !vcard.IsOk() )
3283 {
3284 puts("ERROR: couldn't create vCard.");
3285 }
3286 else
3287 {
3288 // set some fields
3289 vcard.SetName("Zeitlin", "Vadim");
3290 vcard.SetFullName("Vadim Zeitlin");
3291 vcard.SetOrganization("wxWindows", "R&D");
3292
3293 // just dump the vCard back
3294 puts("Entire vCard follows:\n");
3295 puts(vcard.Write());
3296 }
3297}
3298
3299#endif // TEST_VCARD
3300
3301// ----------------------------------------------------------------------------
3302// wide char (Unicode) support
3303// ----------------------------------------------------------------------------
3304
3305#ifdef TEST_WCHAR
3306
e84010cf
GD
3307#include "wx/strconv.h"
3308#include "wx/fontenc.h"
3309#include "wx/encconv.h"
3310#include "wx/buffer.h"
f6bcfd97
BP
3311
3312static void TestUtf8()
3313{
3314 puts("*** Testing UTF8 support ***\n");
3315
24f25c8a
VZ
3316 static const char textInUtf8[] =
3317 {
3318 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3319 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3320 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3321 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3322 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3323 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3324 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3325 };
f6bcfd97 3326
24f25c8a
VZ
3327 char buf[1024];
3328 wchar_t wbuf[1024];
3329 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
f6bcfd97 3330 {
24f25c8a 3331 puts("ERROR: UTF-8 decoding failed.");
f6bcfd97 3332 }
24f25c8a
VZ
3333 else
3334 {
3335 // using wxEncodingConverter
3336#if 0
3337 wxEncodingConverter ec;
3338 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3339 ec.Convert(wbuf, buf);
3340#else // using wxCSConv
3341 wxCSConv conv(_T("koi8-r"));
3342 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
3343 {
3344 puts("ERROR: conversion to KOI8-R failed.");
3345 }
3346 else
3347#endif
f6bcfd97 3348
24f25c8a
VZ
3349 printf("The resulting string (in koi8-r): %s\n", buf);
3350 }
f6bcfd97
BP
3351}
3352
3353#endif // TEST_WCHAR
3354
3355// ----------------------------------------------------------------------------
3356// ZIP stream
3357// ----------------------------------------------------------------------------
3358
3359#ifdef TEST_ZIP
3360
2ca8b884
VZ
3361#include "wx/filesys.h"
3362#include "wx/fs_zip.h"
f6bcfd97
BP
3363#include "wx/zipstrm.h"
3364
2ca8b884
VZ
3365static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3366
f6bcfd97
BP
3367static void TestZipStreamRead()
3368{
3369 puts("*** Testing ZIP reading ***\n");
3370
2ca8b884
VZ
3371 static const wxChar *filename = _T("foo");
3372 wxZipInputStream istr(TESTFILE_ZIP, filename);
f6bcfd97
BP
3373 printf("Archive size: %u\n", istr.GetSize());
3374
2ca8b884 3375 printf("Dumping the file '%s':\n", filename);
f6bcfd97
BP
3376 while ( !istr.Eof() )
3377 {
3378 putchar(istr.GetC());
3379 fflush(stdout);
3380 }
3381
3382 puts("\n----- done ------");
3383}
3384
2ca8b884
VZ
3385static void DumpZipDirectory(wxFileSystem& fs,
3386 const wxString& dir,
3387 const wxString& indent)
3388{
3389 wxString prefix = wxString::Format(_T("%s#zip:%s"),
3390 TESTFILE_ZIP, dir.c_str());
3391 wxString wildcard = prefix + _T("/*");
3392
3393 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3394 while ( !dirname.empty() )
3395 {
3396 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3397 {
3398 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3399
3400 break;
3401 }
3402
3403 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3404
3405 DumpZipDirectory(fs, dirname,
3406 indent + wxString(_T(' '), 4));
3407
3408 dirname = fs.FindNext();
3409 }
3410
3411 wxString filename = fs.FindFirst(wildcard, wxFILE);
3412 while ( !filename.empty() )
3413 {
3414 if ( !filename.StartsWith(prefix, &filename) )
3415 {
3416 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3417
3418 break;
3419 }
3420
3421 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3422
3423 filename = fs.FindNext();
3424 }
3425}
3426
3427static void TestZipFileSystem()
3428{
3429 puts("*** Testing ZIP file system ***\n");
3430
3431 wxFileSystem::AddHandler(new wxZipFSHandler);
3432 wxFileSystem fs;
3433 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3434
3435 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3436}
3437
f6bcfd97
BP
3438#endif // TEST_ZIP
3439
3ca6a5f0
BP
3440// ----------------------------------------------------------------------------
3441// ZLIB stream
3442// ----------------------------------------------------------------------------
3443
3444#ifdef TEST_ZLIB
3445
e84010cf
GD
3446#include "wx/zstream.h"
3447#include "wx/wfstream.h"
3ca6a5f0
BP
3448
3449static const wxChar *FILENAME_GZ = _T("test.gz");
3450static const char *TEST_DATA = "hello and hello again";
3451
3452static void TestZlibStreamWrite()
3453{
3454 puts("*** Testing Zlib stream reading ***\n");
3455
3456 wxFileOutputStream fileOutStream(FILENAME_GZ);
3457 wxZlibOutputStream ostr(fileOutStream, 0);
3458 printf("Compressing the test string... ");
3459 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3460 if ( !ostr )
3461 {
3462 puts("(ERROR: failed)");
3463 }
3464 else
3465 {
3466 puts("(ok)");
3467 }
3468
3469 puts("\n----- done ------");
3470}
3471
3472static void TestZlibStreamRead()
3473{
3474 puts("*** Testing Zlib stream reading ***\n");
3475
3476 wxFileInputStream fileInStream(FILENAME_GZ);
3477 wxZlibInputStream istr(fileInStream);
3478 printf("Archive size: %u\n", istr.GetSize());
3479
3480 puts("Dumping the file:");
3481 while ( !istr.Eof() )
3482 {
3483 putchar(istr.GetC());
3484 fflush(stdout);
3485 }
3486
3487 puts("\n----- done ------");
3488}
3489
3490#endif // TEST_ZLIB
3491
b76b015e
VZ
3492// ----------------------------------------------------------------------------
3493// date time
3494// ----------------------------------------------------------------------------
3495
d31b7b68 3496#ifdef TEST_DATETIME
b76b015e 3497
551fe3a6
VZ
3498#include <math.h>
3499
e84010cf
GD
3500#include "wx/date.h"
3501#include "wx/datetime.h"
b76b015e 3502
299fcbfe
VZ
3503// the test data
3504struct Date
3505{
3506 wxDateTime::wxDateTime_t day;
3507 wxDateTime::Month month;
3508 int year;
3509 wxDateTime::wxDateTime_t hour, min, sec;
3510 double jdn;
211c2250 3511 wxDateTime::WeekDay wday;
299fcbfe
VZ
3512 time_t gmticks, ticks;
3513
3514 void Init(const wxDateTime::Tm& tm)
3515 {
3516 day = tm.mday;
3517 month = tm.mon;
3518 year = tm.year;
3519 hour = tm.hour;
3520 min = tm.min;
3521 sec = tm.sec;
3522 jdn = 0.0;
3523 gmticks = ticks = -1;
3524 }
3525
3526 wxDateTime DT() const
3527 { return wxDateTime(day, month, year, hour, min, sec); }
3528
239446b4
VZ
3529 bool SameDay(const wxDateTime::Tm& tm) const
3530 {
3531 return day == tm.mday && month == tm.mon && year == tm.year;
3532 }
3533
299fcbfe
VZ
3534 wxString Format() const
3535 {
3536 wxString s;
3537 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3538 hour, min, sec,
3539 wxDateTime::GetMonthName(month).c_str(),
3540 day,
3541 abs(wxDateTime::ConvertYearToBC(year)),
3542 year > 0 ? "AD" : "BC");
3543 return s;
3544 }
239446b4
VZ
3545
3546 wxString FormatDate() const
3547 {
3548 wxString s;
3549 s.Printf("%02d-%s-%4d%s",
3550 day,
f0f951fa 3551 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
239446b4
VZ
3552 abs(wxDateTime::ConvertYearToBC(year)),
3553 year > 0 ? "AD" : "BC");
3554 return s;
3555 }
299fcbfe
VZ
3556};
3557
3558static const Date testDates[] =
3559{
211c2250
VZ
3560 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3561 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3562 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3563 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3564 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3565 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3566 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3567 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3568 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3569 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
239446b4
VZ
3570 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3571 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3572 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3573 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
211c2250 3574 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
299fcbfe
VZ
3575};
3576
2f02cb89
VZ
3577// this test miscellaneous static wxDateTime functions
3578static void TestTimeStatic()
3579{
3580 puts("\n*** wxDateTime static methods test ***");
3581
3582 // some info about the current date
3583 int year = wxDateTime::GetCurrentYear();
3584 printf("Current year %d is %sa leap one and has %d days.\n",
3585 year,
3586 wxDateTime::IsLeapYear(year) ? "" : "not ",
3587 wxDateTime::GetNumberOfDays(year));
3588
3589 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3590 printf("Current month is '%s' ('%s') and it has %d days\n",
f0f951fa 3591 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
2f02cb89
VZ
3592 wxDateTime::GetMonthName(month).c_str(),
3593 wxDateTime::GetNumberOfDays(month));
3594
3595 // leap year logic
fcc3d7cb
VZ
3596 static const size_t nYears = 5;
3597 static const size_t years[2][nYears] =
2f02cb89
VZ
3598 {
3599 // first line: the years to test
3600 { 1990, 1976, 2000, 2030, 1984, },
3601
3602 // second line: TRUE if leap, FALSE otherwise
3603 { FALSE, TRUE, TRUE, FALSE, TRUE }
3604 };
3605
3606 for ( size_t n = 0; n < nYears; n++ )
3607 {
3608 int year = years[0][n];
239446b4
VZ
3609 bool should = years[1][n] != 0,
3610 is = wxDateTime::IsLeapYear(year);
2f02cb89 3611
239446b4 3612 printf("Year %d is %sa leap year (%s)\n",
2f02cb89 3613 year,
239446b4
VZ
3614 is ? "" : "not ",
3615 should == is ? "ok" : "ERROR");
2f02cb89
VZ
3616
3617 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3618 }
3619}
3620
3621// test constructing wxDateTime objects
3622static void TestTimeSet()
3623{
3624 puts("\n*** wxDateTime construction test ***");
3625
299fcbfe
VZ
3626 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3627 {
3628 const Date& d1 = testDates[n];
3629 wxDateTime dt = d1.DT();
3630
3631 Date d2;
3632 d2.Init(dt.GetTm());
3633
3634 wxString s1 = d1.Format(),
3635 s2 = d2.Format();
3636
3637 printf("Date: %s == %s (%s)\n",
3638 s1.c_str(), s2.c_str(),
3639 s1 == s2 ? "ok" : "ERROR");
3640 }
2f02cb89
VZ
3641}
3642
fcc3d7cb
VZ
3643// test time zones stuff
3644static void TestTimeZones()
3645{
3646 puts("\n*** wxDateTime timezone test ***");
3647
3648 wxDateTime now = wxDateTime::Now();
3649
299fcbfe
VZ
3650 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3651 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3652 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3653 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3654 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3655 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
9d9b7755
VZ
3656
3657 wxDateTime::Tm tm = now.GetTm();
3658 if ( wxDateTime(tm) != now )
3659 {
3660 printf("ERROR: got %s instead of %s\n",
3661 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3662 }
fcc3d7cb
VZ
3663}
3664
e6ec579c
VZ
3665// test some minimal support for the dates outside the standard range
3666static void TestTimeRange()
3667{
3668 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3669
211c2250
VZ
3670 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3671
1ef54dcf 3672 printf("Unix epoch:\t%s\n",
211c2250 3673 wxDateTime(2440587.5).Format(fmt).c_str());
1ef54dcf 3674 printf("Feb 29, 0: \t%s\n",
211c2250 3675 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
e6ec579c 3676 printf("JDN 0: \t%s\n",
211c2250 3677 wxDateTime(0.0).Format(fmt).c_str());
e6ec579c 3678 printf("Jan 1, 1AD:\t%s\n",
211c2250 3679 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
e6ec579c 3680 printf("May 29, 2099:\t%s\n",
211c2250 3681 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
e6ec579c
VZ
3682}
3683
299fcbfe 3684static void TestTimeTicks()
e6ec579c 3685{
299fcbfe 3686 puts("\n*** wxDateTime ticks test ***");
e6ec579c 3687
299fcbfe 3688 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1ef54dcf 3689 {
299fcbfe
VZ
3690 const Date& d = testDates[n];
3691 if ( d.ticks == -1 )
3692 continue;
1ef54dcf 3693
299fcbfe
VZ
3694 wxDateTime dt = d.DT();
3695 long ticks = (dt.GetValue() / 1000).ToLong();
3696 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3697 if ( ticks == d.ticks )
3698 {
3699 puts(" (ok)");
3700 }
3701 else
3702 {
3703 printf(" (ERROR: should be %ld, delta = %ld)\n",
3704 d.ticks, ticks - d.ticks);
3705 }
3706
3707 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3708 ticks = (dt.GetValue() / 1000).ToLong();
3709 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3710 if ( ticks == d.gmticks )
3711 {
3712 puts(" (ok)");
3713 }
3714 else
3715 {
3716 printf(" (ERROR: should be %ld, delta = %ld)\n",
3717 d.gmticks, ticks - d.gmticks);
3718 }
3719 }
3720
3721 puts("");
3722}
3723
3724// test conversions to JDN &c
3725static void TestTimeJDN()
3726{
3727 puts("\n*** wxDateTime to JDN test ***");
1ef54dcf
VZ
3728
3729 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3730 {
3731 const Date& d = testDates[n];
299fcbfe 3732 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1ef54dcf
VZ
3733 double jdn = dt.GetJulianDayNumber();
3734
299fcbfe 3735 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
1ef54dcf
VZ
3736 if ( jdn == d.jdn )
3737 {
3738 puts(" (ok)");
3739 }
3740 else
3741 {
3742 printf(" (ERROR: should be %f, delta = %f)\n",
3743 d.jdn, jdn - d.jdn);
3744 }
3745 }
e6ec579c
VZ
3746}
3747
211c2250
VZ
3748// test week days computation
3749static void TestTimeWDays()
3750{
3751 puts("\n*** wxDateTime weekday test ***");
3752
239446b4
VZ
3753 // test GetWeekDay()
3754 size_t n;
3755 for ( n = 0; n < WXSIZEOF(testDates); n++ )
211c2250
VZ
3756 {
3757 const Date& d = testDates[n];
3758 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3759
3760 wxDateTime::WeekDay wday = dt.GetWeekDay();
3761 printf("%s is: %s",
3762 d.Format().c_str(),
239446b4 3763 wxDateTime::GetWeekDayName(wday).c_str());
211c2250
VZ
3764 if ( wday == d.wday )
3765 {
3766 puts(" (ok)");
3767 }
3768 else
3769 {
3770 printf(" (ERROR: should be %s)\n",
239446b4
VZ
3771 wxDateTime::GetWeekDayName(d.wday).c_str());
3772 }
3773 }
3774
3775 puts("");
3776
3777 // test SetToWeekDay()
3778 struct WeekDateTestData
3779 {
3780 Date date; // the real date (precomputed)
3781 int nWeek; // its week index in the month
3782 wxDateTime::WeekDay wday; // the weekday
3783 wxDateTime::Month month; // the month
3784 int year; // and the year
3785
3786 wxString Format() const
3787 {
3788 wxString s, which;
3789 switch ( nWeek < -1 ? -nWeek : nWeek )
3790 {
3791 case 1: which = "first"; break;
3792 case 2: which = "second"; break;
3793 case 3: which = "third"; break;
3794 case 4: which = "fourth"; break;
3795 case 5: which = "fifth"; break;
3796
3797 case -1: which = "last"; break;
3798 }
3799
3800 if ( nWeek < -1 )
3801 {
3802 which += " from end";
3803 }
3804
3805 s.Printf("The %s %s of %s in %d",
3806 which.c_str(),
3807 wxDateTime::GetWeekDayName(wday).c_str(),
3808 wxDateTime::GetMonthName(month).c_str(),
3809 year);
3810
3811 return s;
3812 }
3813 };
3814
3815 // the array data was generated by the following python program
3816 /*
3817from DateTime import *
3818from whrandom import *
3819from string import *
3820
3821monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3822wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3823
3824week = DateTimeDelta(7)
3825
3826for n in range(20):
3827 year = randint(1900, 2100)
3828 month = randint(1, 12)
3829 day = randint(1, 28)
3830 dt = DateTime(year, month, day)
3831 wday = dt.day_of_week
3832
3833 countFromEnd = choice([-1, 1])
3834 weekNum = 0;
3835
3836 while dt.month is month:
3837 dt = dt - countFromEnd * week
3838 weekNum = weekNum + countFromEnd
3839
3840 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
97e0ceea 3841
239446b4
VZ
3842 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3843 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
97e0ceea 3844 */
239446b4
VZ
3845
3846 static const WeekDateTestData weekDatesTestData[] =
3847 {
3848 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3849 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3850 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3851 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3852 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3853 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3854 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3855 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3856 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3857 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3858 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3859 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3860 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3861 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3862 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3863 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3864 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3865 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3866 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3867 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3868 };
3869
3870 static const char *fmt = "%d-%b-%Y";
3871
3872 wxDateTime dt;
3873 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3874 {
3875 const WeekDateTestData& wd = weekDatesTestData[n];
3876
3877 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3878
3879 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3880
3881 const Date& d = wd.date;
3882 if ( d.SameDay(dt.GetTm()) )
3883 {
3884 puts(" (ok)");
3885 }
3886 else
3887 {
3888 dt.Set(d.day, d.month, d.year);
3889
3890 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
211c2250
VZ
3891 }
3892 }
3893}
3894
239446b4
VZ
3895// test the computation of (ISO) week numbers
3896static void TestTimeWNumber()
3897{
3898 puts("\n*** wxDateTime week number test ***");
3899
3900 struct WeekNumberTestData
3901 {
3902 Date date; // the date
9d9b7755
VZ
3903 wxDateTime::wxDateTime_t week; // the week number in the year
3904 wxDateTime::wxDateTime_t wmon; // the week number in the month
3905 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
239446b4
VZ
3906 wxDateTime::wxDateTime_t dnum; // day number in the year
3907 };
3908
3909 // data generated with the following python script:
3910 /*
3911from DateTime import *
3912from whrandom import *
3913from string import *
3914
3915monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3916wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3917
9d9b7755
VZ
3918def GetMonthWeek(dt):
3919 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3920 if weekNumMonth < 0:
3921 weekNumMonth = weekNumMonth + 53
3922 return weekNumMonth
7c968cee 3923
9d9b7755
VZ
3924def GetLastSundayBefore(dt):
3925 if dt.iso_week[2] == 7:
3926 return dt
3927 else:
3928 return dt - DateTimeDelta(dt.iso_week[2])
3929
239446b4
VZ
3930for n in range(20):
3931 year = randint(1900, 2100)
3932 month = randint(1, 12)
3933 day = randint(1, 28)
3934 dt = DateTime(year, month, day)
3935 dayNum = dt.day_of_year
3936 weekNum = dt.iso_week[1]
9d9b7755
VZ
3937 weekNumMonth = GetMonthWeek(dt)
3938
3939 weekNumMonth2 = 0
3940 dtSunday = GetLastSundayBefore(dt)
3941
3942 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3943 weekNumMonth2 = weekNumMonth2 + 1
3944 dtSunday = dtSunday - DateTimeDelta(7)
3945
3946 data = { 'day': rjust(`day`, 2), \
3947 'month': monthNames[month - 1], \
3948 'year': year, \
3949 'weekNum': rjust(`weekNum`, 2), \
3950 'weekNumMonth': weekNumMonth, \
3951 'weekNumMonth2': weekNumMonth2, \
3952 'dayNum': rjust(`dayNum`, 3) }
3953
3954 print " { { %(day)s, "\
3955 "wxDateTime::%(month)s, "\
3956 "%(year)d }, "\
3957 "%(weekNum)s, "\
3958 "%(weekNumMonth)s, "\
3959 "%(weekNumMonth2)s, "\
239446b4 3960 "%(dayNum)s }," % data
9d9b7755 3961
239446b4
VZ
3962 */
3963 static const WeekNumberTestData weekNumberTestDates[] =
3964 {
9d9b7755
VZ
3965 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3966 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3967 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3968 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3969 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3970 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3971 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3972 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3973 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3974 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3975 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3976 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3977 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3978 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3979 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3980 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3981 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3982 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3983 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3984 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
239446b4
VZ
3985 };
3986
3987 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3988 {
3989 const WeekNumberTestData& wn = weekNumberTestDates[n];
3990 const Date& d = wn.date;
3991
3992 wxDateTime dt = d.DT();
3993
9d9b7755
VZ
3994 wxDateTime::wxDateTime_t
3995 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3996 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3997 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3998 dnum = dt.GetDayOfYear();
239446b4
VZ
3999
4000 printf("%s: the day number is %d",
4001 d.FormatDate().c_str(), dnum);
4002 if ( dnum == wn.dnum )
4003 {
4004 printf(" (ok)");
4005 }
4006 else
4007 {
4008 printf(" (ERROR: should be %d)", wn.dnum);
4009 }
4010
9d9b7755
VZ
4011 printf(", week in month is %d", wmon);
4012 if ( wmon == wn.wmon )
4013 {
4014 printf(" (ok)");
4015 }
4016 else
4017 {
4018 printf(" (ERROR: should be %d)", wn.wmon);
4019 }
4020
4021 printf(" or %d", wmon2);
4022 if ( wmon2 == wn.wmon2 )
4023 {
4024 printf(" (ok)");
4025 }
4026 else
4027 {
4028 printf(" (ERROR: should be %d)", wn.wmon2);
4029 }
4030
4031 printf(", week in year is %d", week);
239446b4
VZ
4032 if ( week == wn.week )
4033 {
4034 puts(" (ok)");
4035 }
4036 else
4037 {
4038 printf(" (ERROR: should be %d)\n", wn.week);
4039 }
4040 }
4041}
4042
4043// test DST calculations
4044static void TestTimeDST()
4045{
4046 puts("\n*** wxDateTime DST test ***");
4047
4048 printf("DST is%s in effect now.\n\n",
4049 wxDateTime::Now().IsDST() ? "" : " not");
4050
4051 // taken from http://www.energy.ca.gov/daylightsaving.html
4052 static const Date datesDST[2][2004 - 1900 + 1] =
4053 {
4054 {
4055 { 1, wxDateTime::Apr, 1990 },
4056 { 7, wxDateTime::Apr, 1991 },
4057 { 5, wxDateTime::Apr, 1992 },
4058 { 4, wxDateTime::Apr, 1993 },
4059 { 3, wxDateTime::Apr, 1994 },
4060 { 2, wxDateTime::Apr, 1995 },
4061 { 7, wxDateTime::Apr, 1996 },
4062 { 6, wxDateTime::Apr, 1997 },
4063 { 5, wxDateTime::Apr, 1998 },
4064 { 4, wxDateTime::Apr, 1999 },
4065 { 2, wxDateTime::Apr, 2000 },
4066 { 1, wxDateTime::Apr, 2001 },
4067 { 7, wxDateTime::Apr, 2002 },
4068 { 6, wxDateTime::Apr, 2003 },
4069 { 4, wxDateTime::Apr, 2004 },
4070 },
4071 {
4072 { 28, wxDateTime::Oct, 1990 },
4073 { 27, wxDateTime::Oct, 1991 },
4074 { 25, wxDateTime::Oct, 1992 },
4075 { 31, wxDateTime::Oct, 1993 },
4076 { 30, wxDateTime::Oct, 1994 },
4077 { 29, wxDateTime::Oct, 1995 },
4078 { 27, wxDateTime::Oct, 1996 },
4079 { 26, wxDateTime::Oct, 1997 },
4080 { 25, wxDateTime::Oct, 1998 },
4081 { 31, wxDateTime::Oct, 1999 },
4082 { 29, wxDateTime::Oct, 2000 },
4083 { 28, wxDateTime::Oct, 2001 },
4084 { 27, wxDateTime::Oct, 2002 },
4085 { 26, wxDateTime::Oct, 2003 },
4086 { 31, wxDateTime::Oct, 2004 },
4087 }
4088 };
4089
4090 int year;
4091 for ( year = 1990; year < 2005; year++ )
4092 {
4093 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4094 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4095
4096 printf("DST period in the US for year %d: from %s to %s",
4097 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
4098
4099 size_t n = year - 1990;
4100 const Date& dBegin = datesDST[0][n];
4101 const Date& dEnd = datesDST[1][n];
97e0ceea 4102
239446b4
VZ
4103 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4104 {
4105 puts(" (ok)");
4106 }
4107 else
4108 {
4109 printf(" (ERROR: should be %s %d to %s %d)\n",
4110 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4111 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
4112 }
4113 }
4114
4115 puts("");
4116
4117 for ( year = 1990; year < 2005; year++ )
4118 {
4119 printf("DST period in Europe for year %d: from %s to %s\n",
4120 year,
4121 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4122 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
4123 }
4124}
4125
68ee7c47
VZ
4126// test wxDateTime -> text conversion
4127static void TestTimeFormat()
4128{
4129 puts("\n*** wxDateTime formatting test ***");
4130
b38e2f7d
VZ
4131 // some information may be lost during conversion, so store what kind
4132 // of info should we recover after a round trip
4133 enum CompareKind
68ee7c47 4134 {
b38e2f7d
VZ
4135 CompareNone, // don't try comparing
4136 CompareBoth, // dates and times should be identical
4137 CompareDate, // dates only
4138 CompareTime // time only
4139 };
4140
4141 static const struct
4142 {
4143 CompareKind compareKind;
4144 const char *format;
4145 } formatTestFormats[] =
4146 {
4147 { CompareBoth, "---> %c" },
4148 { CompareDate, "Date is %A, %d of %B, in year %Y" },
4149 { CompareBoth, "Date is %x, time is %X" },
4150 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
4151 { CompareNone, "The day of year: %j, the week of year: %W" },
f6bcfd97 4152 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
68ee7c47
VZ
4153 };
4154
4155 static const Date formatTestDates[] =
4156 {
68ee7c47
VZ
4157 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4158 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
b38e2f7d
VZ
4159#if 0
4160 // this test can't work for other centuries because it uses two digit
4161 // years in formats, so don't even try it
68ee7c47
VZ
4162 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4163 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4164 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
b38e2f7d 4165#endif
68ee7c47
VZ
4166 };
4167
4168 // an extra test (as it doesn't depend on date, don't do it in the loop)
4169 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
4170
b38e2f7d 4171 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
68ee7c47
VZ
4172 {
4173 puts("");
4174
b38e2f7d 4175 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
68ee7c47
VZ
4176 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4177 {
b38e2f7d 4178 wxString s = dt.Format(formatTestFormats[n].format);
f0f951fa
VZ
4179 printf("%s", s.c_str());
4180
b38e2f7d
VZ
4181 // what can we recover?
4182 int kind = formatTestFormats[n].compareKind;
4183
f0f951fa
VZ
4184 // convert back
4185 wxDateTime dt2;
b38e2f7d 4186 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
f0f951fa
VZ
4187 if ( !result )
4188 {
b38e2f7d
VZ
4189 // converion failed - should it have?
4190 if ( kind == CompareNone )
4191 puts(" (ok)");
4192 else
4193 puts(" (ERROR: conversion back failed)");
f0f951fa
VZ
4194 }
4195 else if ( *result )
4196 {
4197 // should have parsed the entire string
4198 puts(" (ERROR: conversion back stopped too soon)");
4199 }
f0f951fa
VZ
4200 else
4201 {
b38e2f7d
VZ
4202 bool equal = FALSE; // suppress compilaer warning
4203 switch ( kind )
4204 {
4205 case CompareBoth:
4206 equal = dt2 == dt;
4207 break;
4208
4209 case CompareDate:
4210 equal = dt.IsSameDate(dt2);
4211 break;
4212
4213 case CompareTime:
4214 equal = dt.IsSameTime(dt2);
4215 break;
4216 }
4217
4218 if ( !equal )
4219 {
4220 printf(" (ERROR: got back '%s' instead of '%s')\n",
4221 dt2.Format().c_str(), dt.Format().c_str());
4222 }
4223 else
4224 {
4225 puts(" (ok)");
4226 }
f0f951fa 4227 }
68ee7c47
VZ
4228 }
4229 }
4230}
4231
97e0ceea
VZ
4232// test text -> wxDateTime conversion
4233static void TestTimeParse()
4234{
4235 puts("\n*** wxDateTime parse test ***");
4236
4237 struct ParseTestData
4238 {
4239 const char *format;
4240 Date date;
4241 bool good;
4242 };
4243
4244 static const ParseTestData parseTestDates[] =
4245 {
68ee7c47
VZ
4246 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
4247 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
97e0ceea
VZ
4248 };
4249
4250 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4251 {
4252 const char *format = parseTestDates[n].format;
4253
4254 printf("%s => ", format);
4255
4256 wxDateTime dt;
4257 if ( dt.ParseRfc822Date(format) )
4258 {
4259 printf("%s ", dt.Format().c_str());
4260
4261 if ( parseTestDates[n].good )
4262 {
4263 wxDateTime dtReal = parseTestDates[n].date.DT();
4264 if ( dt == dtReal )
4265 {
4266 puts("(ok)");
4267 }
4268 else
4269 {
4270 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
4271 }
4272 }
4273 else
4274 {
4275 puts("(ERROR: bad format)");
4276 }
4277 }
4278 else
4279 {
4280 printf("bad format (%s)\n",
4281 parseTestDates[n].good ? "ERROR" : "ok");
4282 }
4283 }
4284}
4285
b92fd37c 4286static void TestDateTimeInteractive()
9d9b7755
VZ
4287{
4288 puts("\n*** interactive wxDateTime tests ***");
4289
4290 char buf[128];
4291
4292 for ( ;; )
4293 {
4294 printf("Enter a date: ");
4295 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
4296 break;
4297
f6bcfd97
BP
4298 // kill the last '\n'
4299 buf[strlen(buf) - 1] = 0;
4300
9d9b7755 4301 wxDateTime dt;
f6bcfd97
BP
4302 const char *p = dt.ParseDate(buf);
4303 if ( !p )
9d9b7755 4304 {
f6bcfd97 4305 printf("ERROR: failed to parse the date '%s'.\n", buf);
9d9b7755
VZ
4306
4307 continue;
4308 }
f6bcfd97
BP
4309 else if ( *p )
4310 {
4311 printf("WARNING: parsed only first %u characters.\n", p - buf);
4312 }
9d9b7755
VZ
4313
4314 printf("%s: day %u, week of month %u/%u, week of year %u\n",
f6bcfd97 4315 dt.Format("%b %d, %Y").c_str(),
9d9b7755
VZ
4316 dt.GetDayOfYear(),
4317 dt.GetWeekOfMonth(wxDateTime::Monday_First),
4318 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4319 dt.GetWeekOfYear(wxDateTime::Monday_First));
4320 }
4321
4322 puts("\n*** done ***");
4323}
4324
f6bcfd97
BP
4325static void TestTimeMS()
4326{
4327 puts("*** testing millisecond-resolution support in wxDateTime ***");
4328
4329 wxDateTime dt1 = wxDateTime::Now(),
4330 dt2 = wxDateTime::UNow();
4331
4332 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
4333 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
3ca6a5f0
BP
4334 printf("Dummy loop: ");
4335 for ( int i = 0; i < 6000; i++ )
4336 {
4337 //for ( int j = 0; j < 10; j++ )
4338 {
4339 wxString s;
4340 s.Printf("%g", sqrt(i));
4341 }
4342
4343 if ( !(i % 100) )
4344 putchar('.');
4345 }
4346 puts(", done");
4347
4348 dt1 = dt2;
4349 dt2 = wxDateTime::UNow();
4350 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
4351
4352 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
f6bcfd97
BP
4353
4354 puts("\n*** done ***");
4355}
4356
9d9b7755
VZ
4357static void TestTimeArithmetics()
4358{
4359 puts("\n*** testing arithmetic operations on wxDateTime ***");
4360
f6bcfd97 4361 static const struct ArithmData
9d9b7755 4362 {
f6bcfd97
BP
4363 ArithmData(const wxDateSpan& sp, const char *nam)
4364 : span(sp), name(nam) { }
4365
9d9b7755
VZ
4366 wxDateSpan span;
4367 const char *name;
7c968cee 4368 } testArithmData[] =
9d9b7755 4369 {
f6bcfd97
BP
4370 ArithmData(wxDateSpan::Day(), "day"),
4371 ArithmData(wxDateSpan::Week(), "week"),
4372 ArithmData(wxDateSpan::Month(), "month"),
4373 ArithmData(wxDateSpan::Year(), "year"),
4374 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
9d9b7755 4375 };
7c968cee 4376
9d9b7755
VZ
4377 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
4378
4379 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
4380 {
4381 wxDateSpan span = testArithmData[n].span;
4382 dt1 = dt + span;
4383 dt2 = dt - span;
4384
4385 const char *name = testArithmData[n].name;
4386 printf("%s + %s = %s, %s - %s = %s\n",
4387 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
4388 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
4389
4390 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
4391 if ( dt1 - span == dt )
4392 {
4393 puts(" (ok)");
4394 }
4395 else
4396 {
4397 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4398 }
4399
4400 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
4401 if ( dt2 + span == dt )
4402 {
4403 puts(" (ok)");
4404 }
4405 else
4406 {
4407 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4408 }
4409
4410 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
4411 if ( dt2 + 2*span == dt1 )
4412 {
4413 puts(" (ok)");
4414 }
4415 else
4416 {
4417 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
4418 }
4419
4420 puts("");
4421 }
4422}
4423
0de868d9
VZ
4424static void TestTimeHolidays()
4425{
4426 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
4427
4428 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
4429 wxDateTime dtStart(1, tm.mon, tm.year),
4430 dtEnd = dtStart.GetLastMonthDay();
4431
4432 wxDateTimeArray hol;
4433 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
4434
4435 const wxChar *format = "%d-%b-%Y (%a)";
4436
4437 printf("All holidays between %s and %s:\n",
4438 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4439
4440 size_t count = hol.GetCount();
4441 for ( size_t n = 0; n < count; n++ )
4442 {
4443 printf("\t%s\n", hol[n].Format(format).c_str());
4444 }
4445
4446 puts("");
4447}
4448
f6bcfd97
BP
4449static void TestTimeZoneBug()
4450{
4451 puts("\n*** testing for DST/timezone bug ***\n");
4452
4453 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4454 for ( int i = 0; i < 31; i++ )
4455 {
4456 printf("Date %s: week day %s.\n",
4457 date.Format(_T("%d-%m-%Y")).c_str(),
4458 date.GetWeekDayName(date.GetWeekDay()).c_str());
4459
4460 date += wxDateSpan::Day();
4461 }
4462
4463 puts("");
4464}
4465
df05cdc5
VZ
4466static void TestTimeSpanFormat()
4467{
4468 puts("\n*** wxTimeSpan tests ***");
4469
4470 static const char *formats[] =
4471 {
4472 _T("(default) %H:%M:%S"),
4473 _T("%E weeks and %D days"),
4474 _T("%l milliseconds"),
4475 _T("(with ms) %H:%M:%S:%l"),
4476 _T("100%% of minutes is %M"), // test "%%"
4477 _T("%D days and %H hours"),
a8625337 4478 _T("or also %S seconds"),
df05cdc5
VZ
4479 };
4480
4481 wxTimeSpan ts1(1, 2, 3, 4),
4482 ts2(111, 222, 333);
4483 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4484 {
4485 printf("ts1 = %s\tts2 = %s\n",
4486 ts1.Format(formats[n]).c_str(),
4487 ts2.Format(formats[n]).c_str());
4488 }
4489
4490 puts("");
4491}
4492
68ee7c47
VZ
4493#if 0
4494
97e0ceea
VZ
4495// test compatibility with the old wxDate/wxTime classes
4496static void TestTimeCompatibility()
4497{
4498 puts("\n*** wxDateTime compatibility test ***");
4499
4500 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4501 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4502
4503 double jdnNow = wxDateTime::Now().GetJDN();
4504 long jdnMidnight = (long)(jdnNow - 0.5);
4505 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4506
4507 jdnMidnight = wxDate().Set().GetJulianDate();
4508 printf("wxDateTime for today: %s\n",
4509 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4510
4511 int flags = wxEUROPEAN;//wxFULL;
4512 wxDate date;
4513 date.Set();
4514 printf("Today is %s\n", date.FormatDate(flags).c_str());
4515 for ( int n = 0; n < 7; n++ )
4516 {
4517 printf("Previous %s is %s\n",
4518 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4519 date.Previous(n + 1).FormatDate(flags).c_str());
4520 }
4521}
4522
68ee7c47
VZ
4523#endif // 0
4524
d31b7b68 4525#endif // TEST_DATETIME
b76b015e 4526
e87271f3
VZ
4527// ----------------------------------------------------------------------------
4528// threads
4529// ----------------------------------------------------------------------------
4530
4531#ifdef TEST_THREADS
4532
e84010cf 4533#include "wx/thread.h"
37667812 4534
bbfa0322
VZ
4535static size_t gs_counter = (size_t)-1;
4536static wxCriticalSection gs_critsect;
b568d04f 4537static wxCondition gs_cond;
bbfa0322 4538
b568d04f 4539class MyJoinableThread : public wxThread
bbfa0322
VZ
4540{
4541public:
b568d04f
VZ
4542 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4543 { m_n = n; Create(); }
bbfa0322
VZ
4544
4545 // thread execution starts here
b568d04f 4546 virtual ExitCode Entry();
bbfa0322 4547
b568d04f
VZ
4548private:
4549 size_t m_n;
bbfa0322
VZ
4550};
4551
b568d04f 4552wxThread::ExitCode MyJoinableThread::Entry()
bbfa0322 4553{
b568d04f
VZ
4554 unsigned long res = 1;
4555 for ( size_t n = 1; n < m_n; n++ )
4556 {
4557 res *= n;
4558
4559 // it's a loooong calculation :-)
4560 Sleep(100);
4561 }
bbfa0322 4562
b568d04f 4563 return (ExitCode)res;
bbfa0322
VZ
4564}
4565
b568d04f
VZ
4566class MyDetachedThread : public wxThread
4567{
4568public:
fcc3d7cb
VZ
4569 MyDetachedThread(size_t n, char ch)
4570 {
4571 m_n = n;
4572 m_ch = ch;
4573 m_cancelled = FALSE;
4574
4575 Create();
4576 }
b568d04f
VZ
4577
4578 // thread execution starts here
4579 virtual ExitCode Entry();
4580
4581 // and stops here
4582 virtual void OnExit();
4583
4584private:
9fc3ad34
VZ
4585 size_t m_n; // number of characters to write
4586 char m_ch; // character to write
fcc3d7cb
VZ
4587
4588 bool m_cancelled; // FALSE if we exit normally
b568d04f
VZ
4589};
4590
4591wxThread::ExitCode MyDetachedThread::Entry()
bbfa0322
VZ
4592{
4593 {
4594 wxCriticalSectionLocker lock(gs_critsect);
4595 if ( gs_counter == (size_t)-1 )
4596 gs_counter = 1;
4597 else
4598 gs_counter++;
4599 }
4600
9fc3ad34 4601 for ( size_t n = 0; n < m_n; n++ )
bbfa0322
VZ
4602 {
4603 if ( TestDestroy() )
fcc3d7cb
VZ
4604 {
4605 m_cancelled = TRUE;
4606
bbfa0322 4607 break;
fcc3d7cb 4608 }
bbfa0322
VZ
4609
4610 putchar(m_ch);
4611 fflush(stdout);
4612
4613 wxThread::Sleep(100);
4614 }
4615
b568d04f 4616 return 0;
bbfa0322
VZ
4617}
4618
b568d04f 4619void MyDetachedThread::OnExit()
bbfa0322 4620{
9fc3ad34
VZ
4621 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4622
bbfa0322 4623 wxCriticalSectionLocker lock(gs_critsect);
fcc3d7cb 4624 if ( !--gs_counter && !m_cancelled )
b568d04f 4625 gs_cond.Signal();
bbfa0322
VZ
4626}
4627
2f2f3e2a 4628static void TestDetachedThreads()
9fc3ad34 4629{
2f02cb89 4630 puts("\n*** Testing detached threads ***");
9fc3ad34
VZ
4631
4632 static const size_t nThreads = 3;
4633 MyDetachedThread *threads[nThreads];
4634 size_t n;
4635 for ( n = 0; n < nThreads; n++ )
4636 {
4637 threads[n] = new MyDetachedThread(10, 'A' + n);
4638 }
4639
4640 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4641 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4642
4643 for ( n = 0; n < nThreads; n++ )
4644 {
4645 threads[n]->Run();
4646 }
4647
4648 // wait until all threads terminate
4649 gs_cond.Wait();
4650
4651 puts("");
4652}
4653
2f2f3e2a 4654static void TestJoinableThreads()
9fc3ad34 4655{
2f02cb89 4656 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
9fc3ad34
VZ
4657
4658 // calc 10! in the background
4659 MyJoinableThread thread(10);
4660 thread.Run();
4661
4662 printf("\nThread terminated with exit code %lu.\n",
4663 (unsigned long)thread.Wait());
4664}
4665
2f2f3e2a 4666static void TestThreadSuspend()
9fc3ad34 4667{
2f02cb89
VZ
4668 puts("\n*** Testing thread suspend/resume functions ***");
4669
4670 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
9fc3ad34
VZ
4671
4672 thread->Run();
4673
4674 // this is for this demo only, in a real life program we'd use another
4675 // condition variable which would be signaled from wxThread::Entry() to
4676 // tell us that the thread really started running - but here just wait a
4677 // bit and hope that it will be enough (the problem is, of course, that
4678 // the thread might still not run when we call Pause() which will result
4679 // in an error)
4680 wxThread::Sleep(300);
4681
4682 for ( size_t n = 0; n < 3; n++ )
4683 {
4684 thread->Pause();
4685
4686 puts("\nThread suspended");
4687 if ( n > 0 )
4688 {
4689 // don't sleep but resume immediately the first time
4690 wxThread::Sleep(300);
4691 }
4692 puts("Going to resume the thread");
4693
4694 thread->Resume();
4695 }
4696
4c460b34
VZ
4697 puts("Waiting until it terminates now");
4698
9fc3ad34
VZ
4699 // wait until the thread terminates
4700 gs_cond.Wait();
4701
4702 puts("");
4703}
4704
2f2f3e2a 4705static void TestThreadDelete()
2f02cb89
VZ
4706{
4707 // As above, using Sleep() is only for testing here - we must use some
4708 // synchronisation object instead to ensure that the thread is still
4709 // running when we delete it - deleting a detached thread which already
4710 // terminated will lead to a crash!
4711
4712 puts("\n*** Testing thread delete function ***");
4713
4c460b34
VZ
4714 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4715
4716 thread0->Delete();
4717
4718 puts("\nDeleted a thread which didn't start to run yet.");
4719
2f02cb89
VZ
4720 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4721
4722 thread1->Run();
4723
4724 wxThread::Sleep(300);
4725
4726 thread1->Delete();
4727
4728 puts("\nDeleted a running thread.");
4729
4730 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4731
4732 thread2->Run();
4733
4734 wxThread::Sleep(300);
4735
4736 thread2->Pause();
4737
4738 thread2->Delete();
4739
4740 puts("\nDeleted a sleeping thread.");
4741
4c460b34
VZ
4742 MyJoinableThread thread3(20);
4743 thread3.Run();
2f02cb89 4744
4c460b34 4745 thread3.Delete();
2f02cb89
VZ
4746
4747 puts("\nDeleted a joinable thread.");
4748
4c460b34
VZ
4749 MyJoinableThread thread4(2);
4750 thread4.Run();
2f02cb89
VZ
4751
4752 wxThread::Sleep(300);
4753
4c460b34 4754 thread4.Delete();
2f02cb89
VZ
4755
4756 puts("\nDeleted a joinable thread which already terminated.");
4757
4758 puts("");
4759}
4760
2f2f3e2a
VZ
4761class MyWaitingThread : public wxThread
4762{
4763public:
4764 MyWaitingThread(wxCondition *condition)
4765 {
4766 m_condition = condition;
4767
4768 Create();
4769 }
4770
4771 virtual ExitCode Entry()
4772 {
8d5eff60 4773 printf("Thread %lu has started running.\n", GetId());
2f2f3e2a
VZ
4774 fflush(stdout);
4775
4776 gs_cond.Signal();
4777
4778 printf("Thread %lu starts to wait...\n", GetId());
4779 fflush(stdout);
4780
4781 m_condition->Wait();
4782
4783 printf("Thread %lu finished to wait, exiting.\n", GetId());
4784 fflush(stdout);
4785
4786 return 0;
4787 }
4788
4789private:
4790 wxCondition *m_condition;
4791};
4792
4793static void TestThreadConditions()
4794{
4795 wxCondition condition;
4796
8d5eff60
VZ
4797 // otherwise its difficult to understand which log messages pertain to
4798 // which condition
4799 wxLogTrace("thread", "Local condition var is %08x, gs_cond = %08x",
4800 condition.GetId(), gs_cond.GetId());
4801
2f2f3e2a 4802 // create and launch threads
60ce696e 4803 MyWaitingThread *threads[10];
2f2f3e2a
VZ
4804
4805 size_t n;
4806 for ( n = 0; n < WXSIZEOF(threads); n++ )
4807 {
4808 threads[n] = new MyWaitingThread(&condition);
4809 }
4810
4811 for ( n = 0; n < WXSIZEOF(threads); n++ )
4812 {
4813 threads[n]->Run();
4814 }
4815
4816 // wait until all threads run
8d5eff60 4817 puts("Main thread is waiting for the other threads to start");
2f2f3e2a
VZ
4818 fflush(stdout);
4819
4820 size_t nRunning = 0;
4821 while ( nRunning < WXSIZEOF(threads) )
4822 {
4823 gs_cond.Wait();
4824
2f2f3e2a 4825 nRunning++;
8d5eff60
VZ
4826
4827 printf("Main thread: %u already running\n", nRunning);
4828 fflush(stdout);
2f2f3e2a
VZ
4829 }
4830
8d5eff60 4831 puts("Main thread: all threads started up.");
2f2f3e2a
VZ
4832 fflush(stdout);
4833
8d5eff60
VZ
4834 wxThread::Sleep(500);
4835
60ce696e 4836#if 1
8d5eff60 4837 // now wake one of them up
2f2f3e2a
VZ
4838 printf("Main thread: about to signal the condition.\n");
4839 fflush(stdout);
4840 condition.Signal();
8d5eff60 4841#endif
2f2f3e2a 4842
60ce696e
VZ
4843 wxThread::Sleep(200);
4844
8d5eff60 4845 // wake all the (remaining) threads up, so that they can exit
2f2f3e2a
VZ
4846 printf("Main thread: about to broadcast the condition.\n");
4847 fflush(stdout);
4848 condition.Broadcast();
4849
8d5eff60
VZ
4850 // give them time to terminate (dirty!)
4851 wxThread::Sleep(500);
2f2f3e2a
VZ
4852}
4853
e87271f3
VZ
4854#endif // TEST_THREADS
4855
4856// ----------------------------------------------------------------------------
4857// arrays
4858// ----------------------------------------------------------------------------
4859
4860#ifdef TEST_ARRAYS
4861
1a931653 4862#include "wx/dynarray.h"
e87271f3 4863
1a931653
VZ
4864#define DefineCompare(name, T) \
4865 \
4866int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
4867{ \
4868 return first - second; \
4869} \
4870 \
4871int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
4872{ \
4873 return *first - *second; \
4874} \
4875 \
4876int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
4877{ \
4878 return *second - *first; \
4879} \
4880
4881DefineCompare(Short, short);
4882DefineCompare(Int, int);
4883
4884// test compilation of all macros
4885WX_DEFINE_ARRAY(short, wxArrayShort);
4886WX_DEFINE_SORTED_ARRAY(short, wxSortedArrayShortNoCmp);
4887WX_DEFINE_SORTED_ARRAY_CMP(short, ShortCompareValues, wxSortedArrayShort);
4888WX_DEFINE_SORTED_ARRAY_CMP(int, IntCompareValues, wxSortedArrayInt);
e87271f3 4889
1a931653
VZ
4890WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4891#include "wx/arrimpl.cpp"
4892WX_DEFINE_OBJARRAY(ArrayBars);
4893
4894static void PrintArray(const char* name, const wxArrayString& array)
d6c9c1b7
VZ
4895{
4896 printf("Dump of the array '%s'\n", name);
4897
4898 size_t nCount = array.GetCount();
4899 for ( size_t n = 0; n < nCount; n++ )
4900 {
1a931653 4901 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
d6c9c1b7
VZ
4902 }
4903}
4904
4905int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4906 const wxString& second)
f6bcfd97
BP
4907{
4908 return first.length() - second.length();
4909}
4910
1a931653
VZ
4911#define TestArrayOf(name) \
4912 \
4913static void PrintArray(const char* name, const wxSortedArray##name & array) \
4914{ \
4915 printf("Dump of the array '%s'\n", name); \
4916 \
4917 size_t nCount = array.GetCount(); \
4918 for ( size_t n = 0; n < nCount; n++ ) \
4919 { \
4920 printf("\t%s[%u] = %d\n", name, n, array[n]); \
4921 } \
4922} \
4923 \
4924static void PrintArray(const char* name, const wxArray##name & array) \
4925{ \
4926 printf("Dump of the array '%s'\n", name); \
4927 \
4928 size_t nCount = array.GetCount(); \
4929 for ( size_t n = 0; n < nCount; n++ ) \
4930 { \
4931 printf("\t%s[%u] = %d\n", name, n, array[n]); \
4932 } \
4933} \
4934 \
4935static void TestArrayOf ## name ## s() \
4936{ \
4937 printf("*** Testing wxArray%s ***\n", #name); \
4938 \
4939 wxArray##name a; \
4940 a.Add(1); \
4941 a.Add(17); \
4942 a.Add(5); \
4943 a.Add(3); \
4944 \
4945 puts("Initially:"); \
4946 PrintArray("a", a); \
4947 \
4948 puts("After sort:"); \
4949 a.Sort(name ## Compare); \
4950 PrintArray("a", a); \
4951 \
4952 puts("After reverse sort:"); \
4953 a.Sort(name ## RevCompare); \
4954 PrintArray("a", a); \
4955 \
4956 wxSortedArray##name b; \
4957 b.Add(1); \
4958 b.Add(17); \
4959 b.Add(5); \
4960 b.Add(3); \
4961 \
4962 puts("Sorted array initially:"); \
4963 PrintArray("b", b); \
d6c9c1b7
VZ
4964}
4965
1a931653
VZ
4966TestArrayOf(Short);
4967TestArrayOf(Int);
f6bcfd97
BP
4968
4969static void TestArrayOfObjects()
4970{
4971 puts("*** Testing wxObjArray ***\n");
4972
4973 {
4974 ArrayBars bars;
4975 Bar bar("second bar");
4976
4977 printf("Initially: %u objects in the array, %u objects total.\n",
4978 bars.GetCount(), Bar::GetNumber());
4979
4980 bars.Add(new Bar("first bar"));
4981 bars.Add(bar);
4982
4983 printf("Now: %u objects in the array, %u objects total.\n",
4984 bars.GetCount(), Bar::GetNumber());
4985
4986 bars.Empty();
4987
4988 printf("After Empty(): %u objects in the array, %u objects total.\n",
4989 bars.GetCount(), Bar::GetNumber());
4990 }
4991
4992 printf("Finally: no more objects in the array, %u objects total.\n",
4993 Bar::GetNumber());
4994}
4995
e87271f3
VZ
4996#endif // TEST_ARRAYS
4997
9fc3ad34
VZ
4998// ----------------------------------------------------------------------------
4999// strings
5000// ----------------------------------------------------------------------------
5001
5002#ifdef TEST_STRINGS
5003
5004#include "wx/timer.h"
bbf8fc53 5005#include "wx/tokenzr.h"
9fc3ad34 5006
7c968cee
VZ
5007static void TestStringConstruction()
5008{
5009 puts("*** Testing wxString constructores ***");
5010
5011 #define TEST_CTOR(args, res) \
5012 { \
5013 wxString s args ; \
5014 printf("wxString%s = %s ", #args, s.c_str()); \
5015 if ( s == res ) \
5016 { \
5017 puts("(ok)"); \
5018 } \
5019 else \
5020 { \
5021 printf("(ERROR: should be %s)\n", res); \
5022 } \
5023 }
5024
5025 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5026 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5027 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5028 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5029
5030 static const wxChar *s = _T("?really!");
5031 const wxChar *start = wxStrchr(s, _T('r'));
5032 const wxChar *end = wxStrchr(s, _T('!'));
5033 TEST_CTOR((start, end), _T("really"));
5034
5035 puts("");
5036}
5037
299fcbfe 5038static void TestString()
9fc3ad34
VZ
5039{
5040 wxStopWatch sw;
5041
5042 wxString a, b, c;
5043
5044 a.reserve (128);
5045 b.reserve (128);
5046 c.reserve (128);
5047
5048 for (int i = 0; i < 1000000; ++i)
5049 {
5050 a = "Hello";
5051 b = " world";
5052 c = "! How'ya doin'?";
5053 a += b;
5054 a += c;
5055 c = "Hello world! What's up?";
5056 if (c != a)
5057 c = "Doh!";
5058 }
5059
5060 printf ("TestString elapsed time: %ld\n", sw.Time());
5061}
5062
299fcbfe 5063static void TestPChar()
9fc3ad34
VZ
5064{
5065 wxStopWatch sw;
5066
5067 char a [128];
5068 char b [128];
5069 char c [128];
5070
5071 for (int i = 0; i < 1000000; ++i)
5072 {
5073 strcpy (a, "Hello");
5074 strcpy (b, " world");
5075 strcpy (c, "! How'ya doin'?");
5076 strcat (a, b);
5077 strcat (a, c);
5078 strcpy (c, "Hello world! What's up?");
5079 if (strcmp (c, a) == 0)
5080 strcpy (c, "Doh!");
5081 }
5082
5083 printf ("TestPChar elapsed time: %ld\n", sw.Time());
5084}
5085
299fcbfe
VZ
5086static void TestStringSub()
5087{
5088 wxString s("Hello, world!");
5089
5090 puts("*** Testing wxString substring extraction ***");
5091
5092 printf("String = '%s'\n", s.c_str());
5093 printf("Left(5) = '%s'\n", s.Left(5).c_str());
5094 printf("Right(6) = '%s'\n", s.Right(6).c_str());
5095 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
5096 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
5097 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
5098 printf("substr(3) = '%s'\n", s.substr(3).c_str());
5099
f6bcfd97
BP
5100 static const wxChar *prefixes[] =
5101 {
5102 _T("Hello"),
5103 _T("Hello, "),
5104 _T("Hello, world!"),
5105 _T("Hello, world!!!"),
5106 _T(""),
5107 _T("Goodbye"),
5108 _T("Hi"),
5109 };
5110
5111 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5112 {
5113 wxString prefix = prefixes[n], rest;
5114 bool rc = s.StartsWith(prefix, &rest);
5115 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
5116 if ( rc )
5117 {
5118 printf(" (the rest is '%s')\n", rest.c_str());
5119 }
5120 else
5121 {
5122 putchar('\n');
5123 }
5124 }
5125
299fcbfe
VZ
5126 puts("");
5127}
5128
f0f951fa
VZ
5129static void TestStringFormat()
5130{
5131 puts("*** Testing wxString formatting ***");
5132
5133 wxString s;
5134 s.Printf("%03d", 18);
5135
5136 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
5137 printf("Number 18: %s\n", s.c_str());
5138
5139 puts("");
5140}
5141
d71fa6fb
VZ
5142// returns "not found" for npos, value for all others
5143static wxString PosToString(size_t res)
5144{
5145 wxString s = res == wxString::npos ? wxString(_T("not found"))
5146 : wxString::Format(_T("%u"), res);
5147 return s;
5148}
5149
5150static void TestStringFind()
5151{
5152 puts("*** Testing wxString find() functions ***");
5153
5154 static const wxChar *strToFind = _T("ell");
5155 static const struct StringFindTest
5156 {
5157 const wxChar *str;
5158 size_t start,
5159 result; // of searching "ell" in str
5160 } findTestData[] =
5161 {
5162 { _T("Well, hello world"), 0, 1 },
5163 { _T("Well, hello world"), 6, 7 },
5164 { _T("Well, hello world"), 9, wxString::npos },
5165 };
5166
5167 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5168 {
5169 const StringFindTest& ft = findTestData[n];
5170 size_t res = wxString(ft.str).find(strToFind, ft.start);
5171
5172 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
5173 strToFind, ft.str, ft.start, PosToString(res).c_str());
5174
5175 size_t resTrue = ft.result;
5176 if ( res == resTrue )
5177 {
5178 puts(_T("(ok)"));
5179 }
5180 else
5181 {
5182 printf(_T("(ERROR: should be %s)\n"),
5183 PosToString(resTrue).c_str());
5184 }
5185 }
5186
5187 puts("");
5188}
5189
bbf8fc53
VZ
5190static void TestStringTokenizer()
5191{
5192 puts("*** Testing wxStringTokenizer ***");
5193
7c968cee
VZ
5194 static const wxChar *modeNames[] =
5195 {
5196 _T("default"),
5197 _T("return empty"),
5198 _T("return all empty"),
5199 _T("with delims"),
5200 _T("like strtok"),
5201 };
5202
bbf8fc53
VZ
5203 static const struct StringTokenizerTest
5204 {
7c968cee
VZ
5205 const wxChar *str; // string to tokenize
5206 const wxChar *delims; // delimiters to use
5207 size_t count; // count of token
5208 wxStringTokenizerMode mode; // how should we tokenize it
5209 } tokenizerTestData[] =
5210 {
5211 { _T(""), _T(" "), 0 },
5212 { _T("Hello, world"), _T(" "), 2 },
5213 { _T("Hello, world "), _T(" "), 2 },
5214 { _T("Hello, world"), _T(","), 2 },
5215 { _T("Hello, world!"), _T(",!"), 2 },
5216 { _T("Hello,, world!"), _T(",!"), 3 },
5217 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
5218 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
5219 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
5220 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
5221 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
5222 { _T("01/02/99"), _T("/-"), 3 },
5223 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
bbf8fc53
VZ
5224 };
5225
5226 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
5227 {
5228 const StringTokenizerTest& tt = tokenizerTestData[n];
7c968cee 5229 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
bbf8fc53
VZ
5230
5231 size_t count = tkz.CountTokens();
7c968cee
VZ
5232 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
5233 MakePrintable(tt.str).c_str(),
bbf8fc53 5234 count,
7c968cee
VZ
5235 MakePrintable(tt.delims).c_str(),
5236 modeNames[tkz.GetMode()]);
bbf8fc53
VZ
5237 if ( count == tt.count )
5238 {
5239 puts(_T("(ok)"));
5240 }
5241 else
5242 {
5243 printf(_T("(ERROR: should be %u)\n"), tt.count);
5244
5245 continue;
5246 }
5247
7c968cee 5248 // if we emulate strtok(), check that we do it correctly
f6bcfd97 5249 wxChar *buf, *s = NULL, *last;
7c968cee
VZ
5250
5251 if ( tkz.GetMode() == wxTOKEN_STRTOK )
5252 {
5253 buf = new wxChar[wxStrlen(tt.str) + 1];
5254 wxStrcpy(buf, tt.str);
5255
5256 s = wxStrtok(buf, tt.delims, &last);
5257 }
5258 else
5259 {
5260 buf = NULL;
5261 }
5262
bbf8fc53
VZ
5263 // now show the tokens themselves
5264 size_t count2 = 0;
5265 while ( tkz.HasMoreTokens() )
5266 {
7c968cee
VZ
5267 wxString token = tkz.GetNextToken();
5268
5269 printf(_T("\ttoken %u: '%s'"),
bbf8fc53 5270 ++count2,
7c968cee
VZ
5271 MakePrintable(token).c_str());
5272
5273 if ( buf )
5274 {
5275 if ( token == s )
5276 {
5277 puts(" (ok)");
5278 }
5279 else
5280 {
5281 printf(" (ERROR: should be %s)\n", s);
5282 }
5283
5284 s = wxStrtok(NULL, tt.delims, &last);
5285 }
5286 else
5287 {
5288 // nothing to compare with
5289 puts("");
5290 }
bbf8fc53
VZ
5291 }
5292
5293 if ( count2 != count )
5294 {
7c968cee 5295 puts(_T("\tERROR: token count mismatch"));
bbf8fc53 5296 }
7c968cee
VZ
5297
5298 delete [] buf;
bbf8fc53
VZ
5299 }
5300
5301 puts("");
5302}
5303
f6bcfd97
BP
5304static void TestStringReplace()
5305{
5306 puts("*** Testing wxString::replace ***");
5307
5308 static const struct StringReplaceTestData
5309 {
5310 const wxChar *original; // original test string
5311 size_t start, len; // the part to replace
5312 const wxChar *replacement; // the replacement string
5313 const wxChar *result; // and the expected result
5314 } stringReplaceTestData[] =
5315 {
5316 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
5317 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
5318 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
5319 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
5320 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
5321 };
5322
5323 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
5324 {
5325 const StringReplaceTestData data = stringReplaceTestData[n];
5326
5327 wxString original = data.original;
5328 original.replace(data.start, data.len, data.replacement);
5329
5330 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
5331 data.original, data.start, data.len, data.replacement,
5332 original.c_str());
5333
5334 if ( original == data.result )
5335 {
5336 puts("(ok)");
5337 }
5338 else
5339 {
5340 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
5341 }
5342 }
5343
5344 puts("");
5345}
5346
9a4232dc
VZ
5347static void TestStringMatch()
5348{
5349 wxPuts(_T("*** Testing wxString::Matches() ***"));
5350
5351 static const struct StringMatchTestData
5352 {
5353 const wxChar *text;
5354 const wxChar *wildcard;
5355 bool matches;
5356 } stringMatchTestData[] =
5357 {
5358 { _T("foobar"), _T("foo*"), 1 },
5359 { _T("foobar"), _T("*oo*"), 1 },
5360 { _T("foobar"), _T("*bar"), 1 },
5361 { _T("foobar"), _T("??????"), 1 },
5362 { _T("foobar"), _T("f??b*"), 1 },
5363 { _T("foobar"), _T("f?b*"), 0 },
5364 { _T("foobar"), _T("*goo*"), 0 },
5365 { _T("foobar"), _T("*foo"), 0 },
5366 { _T("foobarfoo"), _T("*foo"), 1 },
5367 { _T(""), _T("*"), 1 },
5368 { _T(""), _T("?"), 0 },
5369 };
5370
5371 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
5372 {
5373 const StringMatchTestData& data = stringMatchTestData[n];
5374 bool matches = wxString(data.text).Matches(data.wildcard);
5375 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
5376 data.wildcard,
5377 matches ? _T("matches") : _T("doesn't match"),
5378 data.text,
5379 matches == data.matches ? _T("ok") : _T("ERROR"));
5380 }
5381
5382 wxPuts(_T(""));
5383}
5384
9fc3ad34
VZ
5385#endif // TEST_STRINGS
5386
e87271f3
VZ
5387// ----------------------------------------------------------------------------
5388// entry point
5389// ----------------------------------------------------------------------------
5390
daa2c7d9
VZ
5391#ifdef TEST_SNGLINST
5392 #include "wx/snglinst.h"
5393#endif // TEST_SNGLINST
5394
bbfa0322 5395int main(int argc, char **argv)
37667812 5396{
58b24a56
VZ
5397 wxInitializer initializer;
5398 if ( !initializer )
37667812
VZ
5399 {
5400 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
58b24a56
VZ
5401
5402 return -1;
5403 }
5404
5405#ifdef TEST_SNGLINST
b5299791
VZ
5406 wxSingleInstanceChecker checker;
5407 if ( checker.Create(_T(".wxconsole.lock")) )
58b24a56 5408 {
b5299791
VZ
5409 if ( checker.IsAnotherRunning() )
5410 {
5411 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
58b24a56 5412
b5299791
VZ
5413 return 1;
5414 }
37667812 5415
b5299791
VZ
5416 // wait some time to give time to launch another instance
5417 wxPrintf(_T("Press \"Enter\" to continue..."));
5418 wxFgetc(stdin);
5419 }
5420 else // failed to create
5421 {
5422 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
5423 }
58b24a56
VZ
5424#endif // TEST_SNGLINST
5425
551fe3a6
VZ
5426#ifdef TEST_CHARSET
5427 TestCharset();
5428#endif // TEST_CHARSET
0de868d9 5429
d34bce84 5430#ifdef TEST_CMDLINE
31f6de22
VZ
5431 TestCmdLineConvert();
5432
5433#if wxUSE_CMDLINE_PARSER
d34bce84
VZ
5434 static const wxCmdLineEntryDesc cmdLineDesc[] =
5435 {
31a06b07
VZ
5436 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
5437 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
d34bce84
VZ
5438 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
5439 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
5440
5441 { wxCMD_LINE_OPTION, "o", "output", "output file" },
5442 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
31a06b07
VZ
5443 { wxCMD_LINE_OPTION, "s", "size", "output block size",
5444 wxCMD_LINE_VAL_NUMBER },
5445 { wxCMD_LINE_OPTION, "d", "date", "output file date",
5446 wxCMD_LINE_VAL_DATE },
d34bce84
VZ
5447
5448 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
5449 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
5450
5451 { wxCMD_LINE_NONE }
5452 };
5453
5454 wxCmdLineParser parser(cmdLineDesc, argc, argv);
5455
f6bcfd97
BP
5456 parser.AddOption("project_name", "", "full path to project file",
5457 wxCMD_LINE_VAL_STRING,
5458 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
5459
d34bce84
VZ
5460 switch ( parser.Parse() )
5461 {
5462 case -1:
5463 wxLogMessage("Help was given, terminating.");
5464 break;
5465
5466 case 0:
5467 ShowCmdLine(parser);
5468 break;
5469
5470 default:
5471 wxLogMessage("Syntax error detected, aborting.");
5472 break;
5473 }
31f6de22
VZ
5474#endif // wxUSE_CMDLINE_PARSER
5475
d34bce84
VZ
5476#endif // TEST_CMDLINE
5477
9fc3ad34 5478#ifdef TEST_STRINGS
daa2c7d9 5479 if ( TEST_ALL )
299fcbfe
VZ
5480 {
5481 TestPChar();
5482 TestString();
f6bcfd97 5483 TestStringSub();
7c968cee 5484 TestStringConstruction();
d71fa6fb 5485 TestStringFormat();
bbf8fc53 5486 TestStringFind();
7c968cee 5487 TestStringTokenizer();
f6bcfd97 5488 TestStringReplace();
ee6e1b1d 5489 }
daa2c7d9
VZ
5490 else
5491 {
5492 TestStringMatch();
5493 }
9fc3ad34
VZ
5494#endif // TEST_STRINGS
5495
e87271f3 5496#ifdef TEST_ARRAYS
daa2c7d9 5497 if ( TEST_ALL )
d6c9c1b7 5498 {
daa2c7d9
VZ
5499 wxArrayString a1;
5500 a1.Add("tiger");
5501 a1.Add("cat");
5502 a1.Add("lion");
5503 a1.Add("dog");
5504 a1.Add("human");
5505 a1.Add("ape");
e87271f3 5506
daa2c7d9 5507 puts("*** Initially:");
e87271f3 5508
daa2c7d9 5509 PrintArray("a1", a1);
e87271f3 5510
daa2c7d9
VZ
5511 wxArrayString a2(a1);
5512 PrintArray("a2", a2);
e87271f3 5513
daa2c7d9
VZ
5514 wxSortedArrayString a3(a1);
5515 PrintArray("a3", a3);
e87271f3 5516
daa2c7d9
VZ
5517 puts("*** After deleting a string from a1");
5518 a1.Remove(2);
e87271f3 5519
daa2c7d9
VZ
5520 PrintArray("a1", a1);
5521 PrintArray("a2", a2);
5522 PrintArray("a3", a3);
e87271f3 5523
daa2c7d9
VZ
5524 puts("*** After reassigning a1 to a2 and a3");
5525 a3 = a2 = a1;
5526 PrintArray("a2", a2);
5527 PrintArray("a3", a3);
f6bcfd97 5528
daa2c7d9
VZ
5529 puts("*** After sorting a1");
5530 a1.Sort();
5531 PrintArray("a1", a1);
f6bcfd97 5532
daa2c7d9
VZ
5533 puts("*** After sorting a1 in reverse order");
5534 a1.Sort(TRUE);
5535 PrintArray("a1", a1);
f6bcfd97 5536
daa2c7d9
VZ
5537 puts("*** After sorting a1 by the string length");
5538 a1.Sort(StringLenCompare);
5539 PrintArray("a1", a1);
f6bcfd97 5540
daa2c7d9 5541 TestArrayOfObjects();
1a931653 5542 TestArrayOfShorts();
daa2c7d9 5543 }
1a931653
VZ
5544
5545 TestArrayOfInts();
e87271f3
VZ
5546#endif // TEST_ARRAYS
5547
1944c6bd 5548#ifdef TEST_DIR
daa2c7d9
VZ
5549 if ( TEST_ALL )
5550 {
35332784 5551 TestDirEnum();
daa2c7d9
VZ
5552 TestDirTraverse();
5553 }
1944c6bd
VZ
5554#endif // TEST_DIR
5555
f6bcfd97
BP
5556#ifdef TEST_DLLLOADER
5557 TestDllLoad();
5558#endif // TEST_DLLLOADER
5559
8fd0d89b
VZ
5560#ifdef TEST_ENVIRON
5561 TestEnvironment();
5562#endif // TEST_ENVIRON
5563
d93c719a
VZ
5564#ifdef TEST_EXECUTE
5565 TestExecute();
5566#endif // TEST_EXECUTE
5567
ee6e1b1d
VZ
5568#ifdef TEST_FILECONF
5569 TestFileConfRead();
5570#endif // TEST_FILECONF
5571
f6bcfd97
BP
5572#ifdef TEST_LIST
5573 TestListCtor();
5574#endif // TEST_LIST
5575
ec37df57
VZ
5576#ifdef TEST_LOCALE
5577 TestDefaultLang();
5578#endif // TEST_LOCALE
5579
378b05f7
VZ
5580#ifdef TEST_LOG
5581 wxString s;
5582 for ( size_t n = 0; n < 8000; n++ )
5583 {
5584 s << (char)('A' + (n % 26));
5585 }
5586
5587 wxString msg;
5588 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5589
5590 // this one shouldn't be truncated
5591 printf(msg);
5592
5593 // but this one will because log functions use fixed size buffer
b568d04f
VZ
5594 // (note that it doesn't need '\n' at the end neither - will be added
5595 // by wxLog anyhow)
5596 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
378b05f7
VZ
5597#endif // TEST_LOG
5598
f6bcfd97 5599#ifdef TEST_FILE
daa2c7d9 5600 if ( TEST_ALL )
a339970a 5601 {
3ca6a5f0 5602 TestFileRead();
a339970a 5603 TestTextFileRead();
daa2c7d9 5604 TestFileCopy();
a339970a 5605 }
f6bcfd97
BP
5606#endif // TEST_FILE
5607
844f90fb 5608#ifdef TEST_FILENAME
353f41cb 5609 if ( 1 )
81f25632
VZ
5610 {
5611 wxFileName fn;
5612 fn.Assign("c:\\foo", "bar.baz");
5613
5614 DumpFileName(fn);
5615 }
5616
daa2c7d9 5617 if ( TEST_ALL )
9e8d8607 5618 {
daa2c7d9
VZ
5619 TestFileNameConstruction();
5620 TestFileNameMakeRelative();
5621 TestFileNameSplit();
5622 TestFileNameTemp();
9e8d8607
VZ
5623 TestFileNameCwd();
5624 TestFileNameComparison();
5625 TestFileNameOperations();
5626 }
844f90fb
VZ
5627#endif // TEST_FILENAME
5628
d56e2b97
VZ
5629#ifdef TEST_FILETIME
5630 TestFileGetTimes();
5631 TestFileSetTimes();
5632#endif // TEST_FILETIME
5633
07a56e45
VZ
5634#ifdef TEST_FTP
5635 wxLog::AddTraceMask(FTP_TRACE_MASK);
5636 if ( TestFtpConnect() )
5637 {
daa2c7d9 5638 if ( TEST_ALL )
07a56e45
VZ
5639 {
5640 TestFtpList();
5641 TestFtpDownload();
5642 TestFtpMisc();
daa2c7d9 5643 TestFtpFileSize();
07a56e45
VZ
5644 TestFtpUpload();
5645 }
daa2c7d9
VZ
5646
5647 if ( TEST_INTERACTIVE )
5648 TestFtpInteractive();
07a56e45
VZ
5649 }
5650 //else: connecting to the FTP server failed
5651
5652 if ( 0 )
5653 TestFtpWuFtpd();
5654#endif // TEST_FTP
5655
b76b015e 5656#ifdef TEST_LONGLONG
2a310492
VZ
5657 // seed pseudo random generator
5658 srand((unsigned)time(NULL));
5659
b76b015e 5660 if ( 0 )
2a310492 5661 {
b76b015e 5662 TestSpeed();
2a310492 5663 }
daa2c7d9
VZ
5664
5665 if ( TEST_ALL )
2a310492 5666 {
f6bcfd97 5667 TestMultiplication();
b76b015e 5668 TestDivision();
2a310492
VZ
5669 TestAddition();
5670 TestLongLongConversion();
5671 TestBitOperations();
3a994742 5672 TestLongLongComparison();
daa2c7d9 5673 TestLongLongPrint();
2a310492 5674 }
b76b015e
VZ
5675#endif // TEST_LONGLONG
5676
2c8e4738
VZ
5677#ifdef TEST_HASH
5678 TestHash();
5679#endif // TEST_HASH
5680
0508ba2a
MB
5681#ifdef TEST_HASHMAP
5682 TestHashMap();
5683#endif // TEST_HASHMAP
5684
696e1ea0 5685#ifdef TEST_MIME
f6bcfd97 5686 wxLog::AddTraceMask(_T("mime"));
8d5eff60 5687 if ( TEST_ALL )
c7ce8392 5688 {
f6bcfd97 5689 TestMimeEnum();
c7ce8392
VZ
5690 TestMimeOverride();
5691 TestMimeFilename();
5692 }
8d5eff60
VZ
5693
5694 TestMimeAssociate();
696e1ea0
VZ
5695#endif // TEST_MIME
5696
89e60357 5697#ifdef TEST_INFO_FUNCTIONS
daa2c7d9 5698 if ( TEST_ALL )
3a994742
VZ
5699 {
5700 TestOsInfo();
5701 TestUserInfo();
19f45995
VZ
5702
5703 if ( TEST_INTERACTIVE )
5704 TestDiskInfo();
3a994742 5705 }
89e60357
VZ
5706#endif // TEST_INFO_FUNCTIONS
5707
39189b9d
VZ
5708#ifdef TEST_PATHLIST
5709 TestPathList();
5710#endif // TEST_PATHLIST
5711
8d5eff60
VZ
5712#ifdef TEST_ODBC
5713 TestDbOpen();
5714#endif // TEST_ODBC
5715
7ba4fbeb
VZ
5716#ifdef TEST_REGCONF
5717 TestRegConfWrite();
5718#endif // TEST_REGCONF
5719
07a56e45
VZ
5720#ifdef TEST_REGEX
5721 // TODO: write a real test using src/regex/tests file
daa2c7d9 5722 if ( TEST_ALL )
07a56e45
VZ
5723 {
5724 TestRegExCompile();
5725 TestRegExMatch();
5726 TestRegExSubmatch();
daa2c7d9
VZ
5727 TestRegExReplacement();
5728
5729 if ( TEST_INTERACTIVE )
5730 TestRegExInteractive();
07a56e45 5731 }
07a56e45
VZ
5732#endif // TEST_REGEX
5733
6dfec4b8 5734#ifdef TEST_REGISTRY
daa2c7d9 5735 TestRegistryRead();
6ba63600 5736 TestRegistryAssociation();
6dfec4b8
VZ
5737#endif // TEST_REGISTRY
5738
2c8e4738 5739#ifdef TEST_SOCKETS
daa2c7d9
VZ
5740 TestSocketServer();
5741 TestSocketClient();
2c8e4738
VZ
5742#endif // TEST_SOCKETS
5743
83141d3a 5744#ifdef TEST_STREAMS
24f25c8a 5745 TestFileStream();
83141d3a
VZ
5746 TestMemoryStream();
5747#endif // TEST_STREAMS
5748
8d5eff60
VZ
5749#ifdef TEST_THREADS
5750 int nCPUs = wxThread::GetCPUCount();
5751 printf("This system has %d CPUs\n", nCPUs);
5752 if ( nCPUs != -1 )
5753 wxThread::SetConcurrency(nCPUs);
5754
5755 if ( TEST_ALL )
5756 {
5757 TestDetachedThreads();
5758 TestJoinableThreads();
5759 TestThreadSuspend();
5760 TestThreadDelete();
5761 }
5762
5763 TestThreadConditions();
5764#endif // TEST_THREADS
5765
d31b7b68
VZ
5766#ifdef TEST_TIMER
5767 TestStopWatch();
5768#endif // TEST_TIMER
5769
5770#ifdef TEST_DATETIME
daa2c7d9 5771 if ( TEST_ALL )
299fcbfe 5772 {
9d9b7755
VZ
5773 TestTimeSet();
5774 TestTimeStatic();
5775 TestTimeRange();
5776 TestTimeZones();
5777 TestTimeTicks();
5778 TestTimeJDN();
5779 TestTimeDST();
5780 TestTimeWDays();
5781 TestTimeWNumber();
5782 TestTimeParse();
9d9b7755 5783 TestTimeArithmetics();
f6bcfd97
BP
5784 TestTimeHolidays();
5785 TestTimeFormat();
daa2c7d9 5786 TestTimeSpanFormat();
3ca6a5f0 5787 TestTimeMS();
f6bcfd97
BP
5788
5789 TestTimeZoneBug();
41acf5c0 5790 }
daa2c7d9
VZ
5791
5792 if ( TEST_INTERACTIVE )
b92fd37c 5793 TestDateTimeInteractive();
d31b7b68 5794#endif // TEST_DATETIME
b76b015e 5795
551fe3a6
VZ
5796#ifdef TEST_USLEEP
5797 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5798 wxUsleep(3000);
5799#endif // TEST_USLEEP
5800
f6bcfd97 5801#ifdef TEST_VCARD
f6bcfd97
BP
5802 TestVCardRead();
5803 TestVCardWrite();
5804#endif // TEST_VCARD
5805
5806#ifdef TEST_WCHAR
5807 TestUtf8();
5808#endif // TEST_WCHAR
5809
5810#ifdef TEST_ZIP
daa2c7d9 5811 TestZipStreamRead();
2ca8b884 5812 TestZipFileSystem();
f6bcfd97
BP
5813#endif // TEST_ZIP
5814
3ca6a5f0 5815#ifdef TEST_ZLIB
3ca6a5f0
BP
5816 TestZlibStreamWrite();
5817 TestZlibStreamRead();
5818#endif // TEST_ZLIB
5819
37667812
VZ
5820 return 0;
5821}
f6bcfd97 5822