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