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