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