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