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