]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
bracketed include def for CW nothrow flag for MAKINGDLL only
[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 = FALSE;
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 long (not wxLongLong for now) to divide it with
1951 long l = rand();
1952 q = ll / l;
1953 r = ll % l;
1954
1955 #if wxUSE_LONGLONG_NATIVE
1956 wxLongLongNative m(ll.GetHi(), ll.GetLo());
1957
1958 wxLongLongNative p = m / l, s = m % l;
1959 wxASSERT_MSG( q == p && r == s, "division failure" );
1960 #else // !wxUSE_LONGLONG_NATIVE
1961 // verify the result
1962 wxASSERT_MSG( ll == q*l + r, "division failure" );
1963 #endif // wxUSE_LONGLONG_NATIVE
1964
1965 if ( !(nTested % 1000) )
1966 {
1967 putchar('.');
1968 fflush(stdout);
1969 }
1970
1971 nTested++;
1972 }
1973
1974 puts(" done!");
1975 }
1976
1977 static void TestAddition()
1978 {
1979 puts("*** Testing wxLongLong addition ***\n");
1980
1981 wxLongLong a, b, c;
1982 size_t nTested = 0;
1983 for ( size_t n = 0; n < 100000; n++ )
1984 {
1985 a = RAND_LL();
1986 b = RAND_LL();
1987 c = a + b;
1988
1989 #if wxUSE_LONGLONG_NATIVE
1990 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
1991 wxLongLongNative(b.GetHi(), b.GetLo()),
1992 "addition failure" );
1993 #else // !wxUSE_LONGLONG_NATIVE
1994 wxASSERT_MSG( c - b == a, "addition failure" );
1995 #endif // wxUSE_LONGLONG_NATIVE
1996
1997 if ( !(nTested % 1000) )
1998 {
1999 putchar('.');
2000 fflush(stdout);
2001 }
2002
2003 nTested++;
2004 }
2005
2006 puts(" done!");
2007 }
2008
2009 static void TestBitOperations()
2010 {
2011 puts("*** Testing wxLongLong bit operation ***\n");
2012
2013 wxLongLong ll;
2014 size_t nTested = 0;
2015 for ( size_t n = 0; n < 100000; n++ )
2016 {
2017 ll = RAND_LL();
2018
2019 #if wxUSE_LONGLONG_NATIVE
2020 for ( size_t n = 0; n < 33; n++ )
2021 {
2022 }
2023 #else // !wxUSE_LONGLONG_NATIVE
2024 puts("Can't do it without native long long type, test skipped.");
2025
2026 return;
2027 #endif // wxUSE_LONGLONG_NATIVE
2028
2029 if ( !(nTested % 1000) )
2030 {
2031 putchar('.');
2032 fflush(stdout);
2033 }
2034
2035 nTested++;
2036 }
2037
2038 puts(" done!");
2039 }
2040
2041 static void TestLongLongComparison()
2042 {
2043 #if wxUSE_LONGLONG_WX
2044 puts("*** Testing wxLongLong comparison ***\n");
2045
2046 static const long ls[2] =
2047 {
2048 0x1234,
2049 -0x1234,
2050 };
2051
2052 wxLongLongWx lls[2];
2053 lls[0] = ls[0];
2054 lls[1] = ls[1];
2055
2056 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2057 {
2058 bool res;
2059
2060 for ( size_t m = 0; m < WXSIZEOF(lls); m++ )
2061 {
2062 res = lls[m] > testLongs[n];
2063 printf("0x%lx > 0x%lx is %s (%s)\n",
2064 ls[m], testLongs[n], res ? "true" : "false",
2065 res == (ls[m] > testLongs[n]) ? "ok" : "ERROR");
2066
2067 res = lls[m] < testLongs[n];
2068 printf("0x%lx < 0x%lx is %s (%s)\n",
2069 ls[m], testLongs[n], res ? "true" : "false",
2070 res == (ls[m] < testLongs[n]) ? "ok" : "ERROR");
2071
2072 res = lls[m] == testLongs[n];
2073 printf("0x%lx == 0x%lx is %s (%s)\n",
2074 ls[m], testLongs[n], res ? "true" : "false",
2075 res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
2076 }
2077 }
2078 #endif // wxUSE_LONGLONG_WX
2079 }
2080
2081 static void TestLongLongPrint()
2082 {
2083 wxPuts(_T("*** Testing wxLongLong printing ***\n"));
2084
2085 for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
2086 {
2087 wxLongLong ll = testLongs[n];
2088 wxPrintf(_T("%ld == %s\n"), testLongs[n], ll.ToString().c_str());
2089 }
2090
2091 wxLongLong ll(0x12345678, 0x87654321);
2092 wxPrintf(_T("0x1234567887654321 = %s\n"), ll.ToString().c_str());
2093
2094 ll.Negate();
2095 wxPrintf(_T("-0x1234567887654321 = %s\n"), ll.ToString().c_str());
2096 }
2097
2098 #undef MAKE_LL
2099 #undef RAND_LL
2100
2101 #endif // TEST_LONGLONG
2102
2103 // ----------------------------------------------------------------------------
2104 // path list
2105 // ----------------------------------------------------------------------------
2106
2107 #ifdef TEST_PATHLIST
2108
2109 static void TestPathList()
2110 {
2111 puts("*** Testing wxPathList ***\n");
2112
2113 wxPathList pathlist;
2114 pathlist.AddEnvList("PATH");
2115 wxString path = pathlist.FindValidPath("ls");
2116 if ( path.empty() )
2117 {
2118 printf("ERROR: command not found in the path.\n");
2119 }
2120 else
2121 {
2122 printf("Command found in the path as '%s'.\n", path.c_str());
2123 }
2124 }
2125
2126 #endif // TEST_PATHLIST
2127
2128 // ----------------------------------------------------------------------------
2129 // regular expressions
2130 // ----------------------------------------------------------------------------
2131
2132 #ifdef TEST_REGEX
2133
2134 #include "wx/regex.h"
2135
2136 static void TestRegExCompile()
2137 {
2138 wxPuts(_T("*** Testing RE compilation ***\n"));
2139
2140 static struct RegExCompTestData
2141 {
2142 const wxChar *pattern;
2143 bool correct;
2144 } regExCompTestData[] =
2145 {
2146 { _T("foo"), TRUE },
2147 { _T("foo("), FALSE },
2148 { _T("foo(bar"), FALSE },
2149 { _T("foo(bar)"), TRUE },
2150 { _T("foo["), FALSE },
2151 { _T("foo[bar"), FALSE },
2152 { _T("foo[bar]"), TRUE },
2153 { _T("foo{"), TRUE },
2154 { _T("foo{1"), FALSE },
2155 { _T("foo{bar"), TRUE },
2156 { _T("foo{1}"), TRUE },
2157 { _T("foo{1,2}"), TRUE },
2158 { _T("foo{bar}"), TRUE },
2159 { _T("foo*"), TRUE },
2160 { _T("foo**"), FALSE },
2161 { _T("foo+"), TRUE },
2162 { _T("foo++"), FALSE },
2163 { _T("foo?"), TRUE },
2164 { _T("foo??"), FALSE },
2165 { _T("foo?+"), FALSE },
2166 };
2167
2168 wxRegEx re;
2169 for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
2170 {
2171 const RegExCompTestData& data = regExCompTestData[n];
2172 bool ok = re.Compile(data.pattern);
2173
2174 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
2175 data.pattern,
2176 ok ? _T("") : _T("not "),
2177 ok == data.correct ? _T("ok") : _T("ERROR"));
2178 }
2179 }
2180
2181 static void TestRegExMatch()
2182 {
2183 wxPuts(_T("*** Testing RE matching ***\n"));
2184
2185 static struct RegExMatchTestData
2186 {
2187 const wxChar *pattern;
2188 const wxChar *text;
2189 bool correct;
2190 } regExMatchTestData[] =
2191 {
2192 { _T("foo"), _T("bar"), FALSE },
2193 { _T("foo"), _T("foobar"), TRUE },
2194 { _T("^foo"), _T("foobar"), TRUE },
2195 { _T("^foo"), _T("barfoo"), FALSE },
2196 { _T("bar$"), _T("barbar"), TRUE },
2197 { _T("bar$"), _T("barbar "), FALSE },
2198 };
2199
2200 for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
2201 {
2202 const RegExMatchTestData& data = regExMatchTestData[n];
2203
2204 wxRegEx re(data.pattern);
2205 bool ok = re.Matches(data.text);
2206
2207 wxPrintf(_T("'%s' %s %s (%s)\n"),
2208 data.pattern,
2209 ok ? _T("matches") : _T("doesn't match"),
2210 data.text,
2211 ok == data.correct ? _T("ok") : _T("ERROR"));
2212 }
2213 }
2214
2215 static void TestRegExSubmatch()
2216 {
2217 wxPuts(_T("*** Testing RE subexpressions ***\n"));
2218
2219 wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
2220 if ( !re.IsValid() )
2221 {
2222 wxPuts(_T("ERROR: compilation failed."));
2223 return;
2224 }
2225
2226 wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
2227
2228 if ( !re.Matches(text) )
2229 {
2230 wxPuts(_T("ERROR: match expected."));
2231 }
2232 else
2233 {
2234 wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
2235
2236 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
2237 re.GetMatch(text, 3).c_str(),
2238 re.GetMatch(text, 2).c_str(),
2239 re.GetMatch(text, 4).c_str(),
2240 re.GetMatch(text, 1).c_str());
2241 }
2242 }
2243
2244 static void TestRegExReplacement()
2245 {
2246 wxPuts(_T("*** Testing RE replacement ***"));
2247
2248 static struct RegExReplTestData
2249 {
2250 const wxChar *text;
2251 const wxChar *repl;
2252 const wxChar *result;
2253 size_t count;
2254 } regExReplTestData[] =
2255 {
2256 { _T("foo123"), _T("bar"), _T("bar"), 1 },
2257 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
2258 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
2259 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
2260 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
2261 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
2262 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
2263 };
2264
2265 const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
2266 wxRegEx re(pattern);
2267
2268 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
2269
2270 for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
2271 {
2272 const RegExReplTestData& data = regExReplTestData[n];
2273
2274 wxString text = data.text;
2275 size_t nRepl = re.Replace(&text, data.repl);
2276
2277 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
2278 data.text, data.repl,
2279 nRepl, nRepl == 1 ? _T("") : _T("es"),
2280 text.c_str());
2281 if ( text == data.result && nRepl == data.count )
2282 {
2283 wxPuts(_T("ok)"));
2284 }
2285 else
2286 {
2287 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
2288 data.count, data.result);
2289 }
2290 }
2291 }
2292
2293 static void TestRegExInteractive()
2294 {
2295 wxPuts(_T("*** Testing RE interactively ***"));
2296
2297 for ( ;; )
2298 {
2299 char pattern[128];
2300 printf("\nEnter a pattern: ");
2301 if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
2302 break;
2303
2304 // kill the last '\n'
2305 pattern[strlen(pattern) - 1] = 0;
2306
2307 wxRegEx re;
2308 if ( !re.Compile(pattern) )
2309 {
2310 continue;
2311 }
2312
2313 char text[128];
2314 for ( ;; )
2315 {
2316 printf("Enter text to match: ");
2317 if ( !fgets(text, WXSIZEOF(text), stdin) )
2318 break;
2319
2320 // kill the last '\n'
2321 text[strlen(text) - 1] = 0;
2322
2323 if ( !re.Matches(text) )
2324 {
2325 printf("No match.\n");
2326 }
2327 else
2328 {
2329 printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
2330
2331 size_t start, len;
2332 for ( size_t n = 1; ; n++ )
2333 {
2334 if ( !re.GetMatch(&start, &len, n) )
2335 {
2336 break;
2337 }
2338
2339 printf("Subexpr %u matched '%s'\n",
2340 n, wxString(text + start, len).c_str());
2341 }
2342 }
2343 }
2344 }
2345 }
2346
2347 #endif // TEST_REGEX
2348
2349 // ----------------------------------------------------------------------------
2350 // database
2351 // ----------------------------------------------------------------------------
2352
2353 #ifdef TEST_ODBC
2354
2355 #include <wx/db.h>
2356
2357 static void TestDbOpen()
2358 {
2359 HENV henv;
2360 wxDb db(henv);
2361 }
2362
2363 #endif // TEST_ODBC
2364
2365 // ----------------------------------------------------------------------------
2366 // registry and related stuff
2367 // ----------------------------------------------------------------------------
2368
2369 // this is for MSW only
2370 #ifndef __WXMSW__
2371 #undef TEST_REGCONF
2372 #undef TEST_REGISTRY
2373 #endif
2374
2375 #ifdef TEST_REGCONF
2376
2377 #include "wx/confbase.h"
2378 #include "wx/msw/regconf.h"
2379
2380 static void TestRegConfWrite()
2381 {
2382 wxRegConfig regconf(_T("console"), _T("wxwindows"));
2383 regconf.Write(_T("Hello"), wxString(_T("world")));
2384 }
2385
2386 #endif // TEST_REGCONF
2387
2388 #ifdef TEST_REGISTRY
2389
2390 #include "wx/msw/registry.h"
2391
2392 // I chose this one because I liked its name, but it probably only exists under
2393 // NT
2394 static const wxChar *TESTKEY =
2395 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2396
2397 static void TestRegistryRead()
2398 {
2399 puts("*** testing registry reading ***");
2400
2401 wxRegKey key(TESTKEY);
2402 printf("The test key name is '%s'.\n", key.GetName().c_str());
2403 if ( !key.Open() )
2404 {
2405 puts("ERROR: test key can't be opened, aborting test.");
2406
2407 return;
2408 }
2409
2410 size_t nSubKeys, nValues;
2411 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2412 {
2413 printf("It has %u subkeys and %u values.\n", nSubKeys, nValues);
2414 }
2415
2416 printf("Enumerating values:\n");
2417
2418 long dummy;
2419 wxString value;
2420 bool cont = key.GetFirstValue(value, dummy);
2421 while ( cont )
2422 {
2423 printf("Value '%s': type ", value.c_str());
2424 switch ( key.GetValueType(value) )
2425 {
2426 case wxRegKey::Type_None: printf("ERROR (none)"); break;
2427 case wxRegKey::Type_String: printf("SZ"); break;
2428 case wxRegKey::Type_Expand_String: printf("EXPAND_SZ"); break;
2429 case wxRegKey::Type_Binary: printf("BINARY"); break;
2430 case wxRegKey::Type_Dword: printf("DWORD"); break;
2431 case wxRegKey::Type_Multi_String: printf("MULTI_SZ"); break;
2432 default: printf("other (unknown)"); break;
2433 }
2434
2435 printf(", value = ");
2436 if ( key.IsNumericValue(value) )
2437 {
2438 long val;
2439 key.QueryValue(value, &val);
2440 printf("%ld", val);
2441 }
2442 else // string
2443 {
2444 wxString val;
2445 key.QueryValue(value, val);
2446 printf("'%s'", val.c_str());
2447
2448 key.QueryRawValue(value, val);
2449 printf(" (raw value '%s')", val.c_str());
2450 }
2451
2452 putchar('\n');
2453
2454 cont = key.GetNextValue(value, dummy);
2455 }
2456 }
2457
2458 static void TestRegistryAssociation()
2459 {
2460 /*
2461 The second call to deleteself genertaes an error message, with a
2462 messagebox saying .flo is crucial to system operation, while the .ddf
2463 call also fails, but with no error message
2464 */
2465
2466 wxRegKey key;
2467
2468 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2469 key.Create();
2470 key = "ddxf_auto_file" ;
2471 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2472 key.Create();
2473 key = "ddxf_auto_file" ;
2474 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2475 key.Create();
2476 key = "program,0" ;
2477 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2478 key.Create();
2479 key = "program \"%1\"" ;
2480
2481 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2482 key.DeleteSelf();
2483 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2484 key.DeleteSelf();
2485 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2486 key.DeleteSelf();
2487 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2488 key.DeleteSelf();
2489 }
2490
2491 #endif // TEST_REGISTRY
2492
2493 // ----------------------------------------------------------------------------
2494 // sockets
2495 // ----------------------------------------------------------------------------
2496
2497 #ifdef TEST_SOCKETS
2498
2499 #include "wx/socket.h"
2500 #include "wx/protocol/protocol.h"
2501 #include "wx/protocol/http.h"
2502
2503 static void TestSocketServer()
2504 {
2505 puts("*** Testing wxSocketServer ***\n");
2506
2507 static const int PORT = 3000;
2508
2509 wxIPV4address addr;
2510 addr.Service(PORT);
2511
2512 wxSocketServer *server = new wxSocketServer(addr);
2513 if ( !server->Ok() )
2514 {
2515 puts("ERROR: failed to bind");
2516
2517 return;
2518 }
2519
2520 for ( ;; )
2521 {
2522 printf("Server: waiting for connection on port %d...\n", PORT);
2523
2524 wxSocketBase *socket = server->Accept();
2525 if ( !socket )
2526 {
2527 puts("ERROR: wxSocketServer::Accept() failed.");
2528 break;
2529 }
2530
2531 puts("Server: got a client.");
2532
2533 server->SetTimeout(60); // 1 min
2534
2535 while ( socket->IsConnected() )
2536 {
2537 wxString s;
2538 char ch = '\0';
2539 for ( ;; )
2540 {
2541 if ( socket->Read(&ch, sizeof(ch)).Error() )
2542 {
2543 // don't log error if the client just close the connection
2544 if ( socket->IsConnected() )
2545 {
2546 puts("ERROR: in wxSocket::Read.");
2547 }
2548
2549 break;
2550 }
2551
2552 if ( ch == '\r' )
2553 continue;
2554
2555 if ( ch == '\n' )
2556 break;
2557
2558 s += ch;
2559 }
2560
2561 if ( ch != '\n' )
2562 {
2563 break;
2564 }
2565
2566 printf("Server: got '%s'.\n", s.c_str());
2567 if ( s == _T("bye") )
2568 {
2569 delete socket;
2570
2571 break;
2572 }
2573
2574 socket->Write(s.MakeUpper().c_str(), s.length());
2575 socket->Write("\r\n", 2);
2576 printf("Server: wrote '%s'.\n", s.c_str());
2577 }
2578
2579 puts("Server: lost a client.");
2580
2581 socket->Destroy();
2582 }
2583
2584 // same as "delete server" but is consistent with GUI programs
2585 server->Destroy();
2586 }
2587
2588 static void TestSocketClient()
2589 {
2590 puts("*** Testing wxSocketClient ***\n");
2591
2592 static const char *hostname = "www.wxwindows.org";
2593
2594 wxIPV4address addr;
2595 addr.Hostname(hostname);
2596 addr.Service(80);
2597
2598 printf("--- Attempting to connect to %s:80...\n", hostname);
2599
2600 wxSocketClient client;
2601 if ( !client.Connect(addr) )
2602 {
2603 printf("ERROR: failed to connect to %s\n", hostname);
2604 }
2605 else
2606 {
2607 printf("--- Connected to %s:%u...\n",
2608 addr.Hostname().c_str(), addr.Service());
2609
2610 char buf[8192];
2611
2612 // could use simply "GET" here I suppose
2613 wxString cmdGet =
2614 wxString::Format("GET http://%s/\r\n", hostname);
2615 client.Write(cmdGet, cmdGet.length());
2616 printf("--- Sent command '%s' to the server\n",
2617 MakePrintable(cmdGet).c_str());
2618 client.Read(buf, WXSIZEOF(buf));
2619 printf("--- Server replied:\n%s", buf);
2620 }
2621 }
2622
2623 #endif // TEST_SOCKETS
2624
2625 // ----------------------------------------------------------------------------
2626 // FTP
2627 // ----------------------------------------------------------------------------
2628
2629 #ifdef TEST_FTP
2630
2631 #include "wx/protocol/ftp.h"
2632
2633 static wxFTP ftp;
2634
2635 #define FTP_ANONYMOUS
2636
2637 #ifdef FTP_ANONYMOUS
2638 static const char *directory = "/pub";
2639 static const char *filename = "welcome.msg";
2640 #else
2641 static const char *directory = "/etc";
2642 static const char *filename = "issue";
2643 #endif
2644
2645 static bool TestFtpConnect()
2646 {
2647 puts("*** Testing FTP connect ***");
2648
2649 #ifdef FTP_ANONYMOUS
2650 static const char *hostname = "ftp.wxwindows.org";
2651
2652 printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
2653 #else // !FTP_ANONYMOUS
2654 static const char *hostname = "localhost";
2655
2656 char user[256];
2657 fgets(user, WXSIZEOF(user), stdin);
2658 user[strlen(user) - 1] = '\0'; // chop off '\n'
2659 ftp.SetUser(user);
2660
2661 char password[256];
2662 printf("Password for %s: ", password);
2663 fgets(password, WXSIZEOF(password), stdin);
2664 password[strlen(password) - 1] = '\0'; // chop off '\n'
2665 ftp.SetPassword(password);
2666
2667 printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
2668 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2669
2670 if ( !ftp.Connect(hostname) )
2671 {
2672 printf("ERROR: failed to connect to %s\n", hostname);
2673
2674 return FALSE;
2675 }
2676 else
2677 {
2678 printf("--- Connected to %s, current directory is '%s'\n",
2679 hostname, ftp.Pwd().c_str());
2680 }
2681
2682 return TRUE;
2683 }
2684
2685 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2686 static void TestFtpWuFtpd()
2687 {
2688 wxFTP ftp;
2689 static const char *hostname = "ftp.eudora.com";
2690 if ( !ftp.Connect(hostname) )
2691 {
2692 printf("ERROR: failed to connect to %s\n", hostname);
2693 }
2694 else
2695 {
2696 static const char *filename = "eudora/pubs/draft-gellens-submit-09.txt";
2697 wxInputStream *in = ftp.GetInputStream(filename);
2698 if ( !in )
2699 {
2700 printf("ERROR: couldn't get input stream for %s\n", filename);
2701 }
2702 else
2703 {
2704 size_t size = in->StreamSize();
2705 printf("Reading file %s (%u bytes)...", filename, size);
2706
2707 char *data = new char[size];
2708 if ( !in->Read(data, size) )
2709 {
2710 puts("ERROR: read error");
2711 }
2712 else
2713 {
2714 printf("Successfully retrieved the file.\n");
2715 }
2716
2717 delete [] data;
2718 delete in;
2719 }
2720 }
2721 }
2722
2723 static void TestFtpList()
2724 {
2725 puts("*** Testing wxFTP file listing ***\n");
2726
2727 // test CWD
2728 if ( !ftp.ChDir(directory) )
2729 {
2730 printf("ERROR: failed to cd to %s\n", directory);
2731 }
2732
2733 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2734
2735 // test NLIST and LIST
2736 wxArrayString files;
2737 if ( !ftp.GetFilesList(files) )
2738 {
2739 puts("ERROR: failed to get NLIST of files");
2740 }
2741 else
2742 {
2743 printf("Brief list of files under '%s':\n", ftp.Pwd().c_str());
2744 size_t count = files.GetCount();
2745 for ( size_t n = 0; n < count; n++ )
2746 {
2747 printf("\t%s\n", files[n].c_str());
2748 }
2749 puts("End of the file list");
2750 }
2751
2752 if ( !ftp.GetDirList(files) )
2753 {
2754 puts("ERROR: failed to get LIST of files");
2755 }
2756 else
2757 {
2758 printf("Detailed list of files under '%s':\n", ftp.Pwd().c_str());
2759 size_t count = files.GetCount();
2760 for ( size_t n = 0; n < count; n++ )
2761 {
2762 printf("\t%s\n", files[n].c_str());
2763 }
2764 puts("End of the file list");
2765 }
2766
2767 if ( !ftp.ChDir(_T("..")) )
2768 {
2769 puts("ERROR: failed to cd to ..");
2770 }
2771
2772 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2773 }
2774
2775 static void TestFtpDownload()
2776 {
2777 puts("*** Testing wxFTP download ***\n");
2778
2779 // test RETR
2780 wxInputStream *in = ftp.GetInputStream(filename);
2781 if ( !in )
2782 {
2783 printf("ERROR: couldn't get input stream for %s\n", filename);
2784 }
2785 else
2786 {
2787 size_t size = in->StreamSize();
2788 printf("Reading file %s (%u bytes)...", filename, size);
2789 fflush(stdout);
2790
2791 char *data = new char[size];
2792 if ( !in->Read(data, size) )
2793 {
2794 puts("ERROR: read error");
2795 }
2796 else
2797 {
2798 printf("\nContents of %s:\n%s\n", filename, data);
2799 }
2800
2801 delete [] data;
2802 delete in;
2803 }
2804 }
2805
2806 static void TestFtpFileSize()
2807 {
2808 puts("*** Testing FTP SIZE command ***");
2809
2810 if ( !ftp.ChDir(directory) )
2811 {
2812 printf("ERROR: failed to cd to %s\n", directory);
2813 }
2814
2815 printf("Current directory is '%s'\n", ftp.Pwd().c_str());
2816
2817 if ( ftp.FileExists(filename) )
2818 {
2819 int size = ftp.GetFileSize(filename);
2820 if ( size == -1 )
2821 printf("ERROR: couldn't get size of '%s'\n", filename);
2822 else
2823 printf("Size of '%s' is %d bytes.\n", filename, size);
2824 }
2825 else
2826 {
2827 printf("ERROR: '%s' doesn't exist\n", filename);
2828 }
2829 }
2830
2831 static void TestFtpMisc()
2832 {
2833 puts("*** Testing miscellaneous wxFTP functions ***");
2834
2835 if ( ftp.SendCommand("STAT") != '2' )
2836 {
2837 puts("ERROR: STAT failed");
2838 }
2839 else
2840 {
2841 printf("STAT returned:\n\n%s\n", ftp.GetLastResult().c_str());
2842 }
2843
2844 if ( ftp.SendCommand("HELP SITE") != '2' )
2845 {
2846 puts("ERROR: HELP SITE failed");
2847 }
2848 else
2849 {
2850 printf("The list of site-specific commands:\n\n%s\n",
2851 ftp.GetLastResult().c_str());
2852 }
2853 }
2854
2855 static void TestFtpInteractive()
2856 {
2857 puts("\n*** Interactive wxFTP test ***");
2858
2859 char buf[128];
2860
2861 for ( ;; )
2862 {
2863 printf("Enter FTP command: ");
2864 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
2865 break;
2866
2867 // kill the last '\n'
2868 buf[strlen(buf) - 1] = 0;
2869
2870 // special handling of LIST and NLST as they require data connection
2871 wxString start(buf, 4);
2872 start.MakeUpper();
2873 if ( start == "LIST" || start == "NLST" )
2874 {
2875 wxString wildcard;
2876 if ( strlen(buf) > 4 )
2877 wildcard = buf + 5;
2878
2879 wxArrayString files;
2880 if ( !ftp.GetList(files, wildcard, start == "LIST") )
2881 {
2882 printf("ERROR: failed to get %s of files\n", start.c_str());
2883 }
2884 else
2885 {
2886 printf("--- %s of '%s' under '%s':\n",
2887 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2888 size_t count = files.GetCount();
2889 for ( size_t n = 0; n < count; n++ )
2890 {
2891 printf("\t%s\n", files[n].c_str());
2892 }
2893 puts("--- End of the file list");
2894 }
2895 }
2896 else // !list
2897 {
2898 char ch = ftp.SendCommand(buf);
2899 printf("Command %s", ch ? "succeeded" : "failed");
2900 if ( ch )
2901 {
2902 printf(" (return code %c)", ch);
2903 }
2904
2905 printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
2906 }
2907 }
2908
2909 puts("\n*** done ***");
2910 }
2911
2912 static void TestFtpUpload()
2913 {
2914 puts("*** Testing wxFTP uploading ***\n");
2915
2916 // upload a file
2917 static const char *file1 = "test1";
2918 static const char *file2 = "test2";
2919 wxOutputStream *out = ftp.GetOutputStream(file1);
2920 if ( out )
2921 {
2922 printf("--- Uploading to %s ---\n", file1);
2923 out->Write("First hello", 11);
2924 delete out;
2925 }
2926
2927 // send a command to check the remote file
2928 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
2929 {
2930 printf("ERROR: STAT %s failed\n", file1);
2931 }
2932 else
2933 {
2934 printf("STAT %s returned:\n\n%s\n",
2935 file1, ftp.GetLastResult().c_str());
2936 }
2937
2938 out = ftp.GetOutputStream(file2);
2939 if ( out )
2940 {
2941 printf("--- Uploading to %s ---\n", file1);
2942 out->Write("Second hello", 12);
2943 delete out;
2944 }
2945 }
2946
2947 #endif // TEST_FTP
2948
2949 // ----------------------------------------------------------------------------
2950 // streams
2951 // ----------------------------------------------------------------------------
2952
2953 #ifdef TEST_STREAMS
2954
2955 #include "wx/wfstream.h"
2956 #include "wx/mstream.h"
2957
2958 static void TestFileStream()
2959 {
2960 puts("*** Testing wxFileInputStream ***");
2961
2962 static const wxChar *filename = _T("testdata.fs");
2963 {
2964 wxFileOutputStream fsOut(filename);
2965 fsOut.Write("foo", 3);
2966 }
2967
2968 wxFileInputStream fsIn(filename);
2969 printf("File stream size: %u\n", fsIn.GetSize());
2970 while ( !fsIn.Eof() )
2971 {
2972 putchar(fsIn.GetC());
2973 }
2974
2975 if ( !wxRemoveFile(filename) )
2976 {
2977 printf("ERROR: failed to remove the file '%s'.\n", filename);
2978 }
2979
2980 puts("\n*** wxFileInputStream test done ***");
2981 }
2982
2983 static void TestMemoryStream()
2984 {
2985 puts("*** Testing wxMemoryInputStream ***");
2986
2987 wxChar buf[1024];
2988 wxStrncpy(buf, _T("Hello, stream!"), WXSIZEOF(buf));
2989
2990 wxMemoryInputStream memInpStream(buf, wxStrlen(buf));
2991 printf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2992 while ( !memInpStream.Eof() )
2993 {
2994 putchar(memInpStream.GetC());
2995 }
2996
2997 puts("\n*** wxMemoryInputStream test done ***");
2998 }
2999
3000 #endif // TEST_STREAMS
3001
3002 // ----------------------------------------------------------------------------
3003 // timers
3004 // ----------------------------------------------------------------------------
3005
3006 #ifdef TEST_TIMER
3007
3008 #include "wx/timer.h"
3009 #include "wx/utils.h"
3010
3011 static void TestStopWatch()
3012 {
3013 puts("*** Testing wxStopWatch ***\n");
3014
3015 wxStopWatch sw;
3016 printf("Sleeping 3 seconds...");
3017 wxSleep(3);
3018 printf("\telapsed time: %ldms\n", sw.Time());
3019
3020 sw.Pause();
3021 printf("Sleeping 2 more seconds...");
3022 wxSleep(2);
3023 printf("\telapsed time: %ldms\n", sw.Time());
3024
3025 sw.Resume();
3026 printf("And 3 more seconds...");
3027 wxSleep(3);
3028 printf("\telapsed time: %ldms\n", sw.Time());
3029
3030 wxStopWatch sw2;
3031 puts("\nChecking for 'backwards clock' bug...");
3032 for ( size_t n = 0; n < 70; n++ )
3033 {
3034 sw2.Start();
3035
3036 for ( size_t m = 0; m < 100000; m++ )
3037 {
3038 if ( sw.Time() < 0 || sw2.Time() < 0 )
3039 {
3040 puts("\ntime is negative - ERROR!");
3041 }
3042 }
3043
3044 putchar('.');
3045 }
3046
3047 puts(", ok.");
3048 }
3049
3050 #endif // TEST_TIMER
3051
3052 // ----------------------------------------------------------------------------
3053 // vCard support
3054 // ----------------------------------------------------------------------------
3055
3056 #ifdef TEST_VCARD
3057
3058 #include "wx/vcard.h"
3059
3060 static void DumpVObject(size_t level, const wxVCardObject& vcard)
3061 {
3062 void *cookie;
3063 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3064 while ( vcObj )
3065 {
3066 printf("%s%s",
3067 wxString(_T('\t'), level).c_str(),
3068 vcObj->GetName().c_str());
3069
3070 wxString value;
3071 switch ( vcObj->GetType() )
3072 {
3073 case wxVCardObject::String:
3074 case wxVCardObject::UString:
3075 {
3076 wxString val;
3077 vcObj->GetValue(&val);
3078 value << _T('"') << val << _T('"');
3079 }
3080 break;
3081
3082 case wxVCardObject::Int:
3083 {
3084 unsigned int i;
3085 vcObj->GetValue(&i);
3086 value.Printf(_T("%u"), i);
3087 }
3088 break;
3089
3090 case wxVCardObject::Long:
3091 {
3092 unsigned long l;
3093 vcObj->GetValue(&l);
3094 value.Printf(_T("%lu"), l);
3095 }
3096 break;
3097
3098 case wxVCardObject::None:
3099 break;
3100
3101 case wxVCardObject::Object:
3102 value = _T("<node>");
3103 break;
3104
3105 default:
3106 value = _T("<unknown value type>");
3107 }
3108
3109 if ( !!value )
3110 printf(" = %s", value.c_str());
3111 putchar('\n');
3112
3113 DumpVObject(level + 1, *vcObj);
3114
3115 delete vcObj;
3116 vcObj = vcard.GetNextProp(&cookie);
3117 }
3118 }
3119
3120 static void DumpVCardAddresses(const wxVCard& vcard)
3121 {
3122 puts("\nShowing all addresses from vCard:\n");
3123
3124 size_t nAdr = 0;
3125 void *cookie;
3126 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3127 while ( addr )
3128 {
3129 wxString flagsStr;
3130 int flags = addr->GetFlags();
3131 if ( flags & wxVCardAddress::Domestic )
3132 {
3133 flagsStr << _T("domestic ");
3134 }
3135 if ( flags & wxVCardAddress::Intl )
3136 {
3137 flagsStr << _T("international ");
3138 }
3139 if ( flags & wxVCardAddress::Postal )
3140 {
3141 flagsStr << _T("postal ");
3142 }
3143 if ( flags & wxVCardAddress::Parcel )
3144 {
3145 flagsStr << _T("parcel ");
3146 }
3147 if ( flags & wxVCardAddress::Home )
3148 {
3149 flagsStr << _T("home ");
3150 }
3151 if ( flags & wxVCardAddress::Work )
3152 {
3153 flagsStr << _T("work ");
3154 }
3155
3156 printf("Address %u:\n"
3157 "\tflags = %s\n"
3158 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3159 ++nAdr,
3160 flagsStr.c_str(),
3161 addr->GetPostOffice().c_str(),
3162 addr->GetExtAddress().c_str(),
3163 addr->GetStreet().c_str(),
3164 addr->GetLocality().c_str(),
3165 addr->GetRegion().c_str(),
3166 addr->GetPostalCode().c_str(),
3167 addr->GetCountry().c_str()
3168 );
3169
3170 delete addr;
3171 addr = vcard.GetNextAddress(&cookie);
3172 }
3173 }
3174
3175 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3176 {
3177 puts("\nShowing all phone numbers from vCard:\n");
3178
3179 size_t nPhone = 0;
3180 void *cookie;
3181 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3182 while ( phone )
3183 {
3184 wxString flagsStr;
3185 int flags = phone->GetFlags();
3186 if ( flags & wxVCardPhoneNumber::Voice )
3187 {
3188 flagsStr << _T("voice ");
3189 }
3190 if ( flags & wxVCardPhoneNumber::Fax )
3191 {
3192 flagsStr << _T("fax ");
3193 }
3194 if ( flags & wxVCardPhoneNumber::Cellular )
3195 {
3196 flagsStr << _T("cellular ");
3197 }
3198 if ( flags & wxVCardPhoneNumber::Modem )
3199 {
3200 flagsStr << _T("modem ");
3201 }
3202 if ( flags & wxVCardPhoneNumber::Home )
3203 {
3204 flagsStr << _T("home ");
3205 }
3206 if ( flags & wxVCardPhoneNumber::Work )
3207 {
3208 flagsStr << _T("work ");
3209 }
3210
3211 printf("Phone number %u:\n"
3212 "\tflags = %s\n"
3213 "\tvalue = %s\n",
3214 ++nPhone,
3215 flagsStr.c_str(),
3216 phone->GetNumber().c_str()
3217 );
3218
3219 delete phone;
3220 phone = vcard.GetNextPhoneNumber(&cookie);
3221 }
3222 }
3223
3224 static void TestVCardRead()
3225 {
3226 puts("*** Testing wxVCard reading ***\n");
3227
3228 wxVCard vcard(_T("vcard.vcf"));
3229 if ( !vcard.IsOk() )
3230 {
3231 puts("ERROR: couldn't load vCard.");
3232 }
3233 else
3234 {
3235 // read individual vCard properties
3236 wxVCardObject *vcObj = vcard.GetProperty("FN");
3237 wxString value;
3238 if ( vcObj )
3239 {
3240 vcObj->GetValue(&value);
3241 delete vcObj;
3242 }
3243 else
3244 {
3245 value = _T("<none>");
3246 }
3247
3248 printf("Full name retrieved directly: %s\n", value.c_str());
3249
3250
3251 if ( !vcard.GetFullName(&value) )
3252 {
3253 value = _T("<none>");
3254 }
3255
3256 printf("Full name from wxVCard API: %s\n", value.c_str());
3257
3258 // now show how to deal with multiply occuring properties
3259 DumpVCardAddresses(vcard);
3260 DumpVCardPhoneNumbers(vcard);
3261
3262 // and finally show all
3263 puts("\nNow dumping the entire vCard:\n"
3264 "-----------------------------\n");
3265
3266 DumpVObject(0, vcard);
3267 }
3268 }
3269
3270 static void TestVCardWrite()
3271 {
3272 puts("*** Testing wxVCard writing ***\n");
3273
3274 wxVCard vcard;
3275 if ( !vcard.IsOk() )
3276 {
3277 puts("ERROR: couldn't create vCard.");
3278 }
3279 else
3280 {
3281 // set some fields
3282 vcard.SetName("Zeitlin", "Vadim");
3283 vcard.SetFullName("Vadim Zeitlin");
3284 vcard.SetOrganization("wxWindows", "R&D");
3285
3286 // just dump the vCard back
3287 puts("Entire vCard follows:\n");
3288 puts(vcard.Write());
3289 }
3290 }
3291
3292 #endif // TEST_VCARD
3293
3294 // ----------------------------------------------------------------------------
3295 // wide char (Unicode) support
3296 // ----------------------------------------------------------------------------
3297
3298 #ifdef TEST_WCHAR
3299
3300 #include "wx/strconv.h"
3301 #include "wx/fontenc.h"
3302 #include "wx/encconv.h"
3303 #include "wx/buffer.h"
3304
3305 static void TestUtf8()
3306 {
3307 puts("*** Testing UTF8 support ***\n");
3308
3309 static const char textInUtf8[] =
3310 {
3311 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3312 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3313 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3314 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3315 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3316 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3317 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3318 };
3319
3320 char buf[1024];
3321 wchar_t wbuf[1024];
3322 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
3323 {
3324 puts("ERROR: UTF-8 decoding failed.");
3325 }
3326 else
3327 {
3328 // using wxEncodingConverter
3329 #if 0
3330 wxEncodingConverter ec;
3331 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3332 ec.Convert(wbuf, buf);
3333 #else // using wxCSConv
3334 wxCSConv conv(_T("koi8-r"));
3335 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
3336 {
3337 puts("ERROR: conversion to KOI8-R failed.");
3338 }
3339 else
3340 #endif
3341
3342 printf("The resulting string (in koi8-r): %s\n", buf);
3343 }
3344 }
3345
3346 #endif // TEST_WCHAR
3347
3348 // ----------------------------------------------------------------------------
3349 // ZIP stream
3350 // ----------------------------------------------------------------------------
3351
3352 #ifdef TEST_ZIP
3353
3354 #include "wx/filesys.h"
3355 #include "wx/fs_zip.h"
3356 #include "wx/zipstrm.h"
3357
3358 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3359
3360 static void TestZipStreamRead()
3361 {
3362 puts("*** Testing ZIP reading ***\n");
3363
3364 static const wxChar *filename = _T("foo");
3365 wxZipInputStream istr(TESTFILE_ZIP, filename);
3366 printf("Archive size: %u\n", istr.GetSize());
3367
3368 printf("Dumping the file '%s':\n", filename);
3369 while ( !istr.Eof() )
3370 {
3371 putchar(istr.GetC());
3372 fflush(stdout);
3373 }
3374
3375 puts("\n----- done ------");
3376 }
3377
3378 static void DumpZipDirectory(wxFileSystem& fs,
3379 const wxString& dir,
3380 const wxString& indent)
3381 {
3382 wxString prefix = wxString::Format(_T("%s#zip:%s"),
3383 TESTFILE_ZIP, dir.c_str());
3384 wxString wildcard = prefix + _T("/*");
3385
3386 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3387 while ( !dirname.empty() )
3388 {
3389 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3390 {
3391 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3392
3393 break;
3394 }
3395
3396 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3397
3398 DumpZipDirectory(fs, dirname,
3399 indent + wxString(_T(' '), 4));
3400
3401 dirname = fs.FindNext();
3402 }
3403
3404 wxString filename = fs.FindFirst(wildcard, wxFILE);
3405 while ( !filename.empty() )
3406 {
3407 if ( !filename.StartsWith(prefix, &filename) )
3408 {
3409 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3410
3411 break;
3412 }
3413
3414 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3415
3416 filename = fs.FindNext();
3417 }
3418 }
3419
3420 static void TestZipFileSystem()
3421 {
3422 puts("*** Testing ZIP file system ***\n");
3423
3424 wxFileSystem::AddHandler(new wxZipFSHandler);
3425 wxFileSystem fs;
3426 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3427
3428 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3429 }
3430
3431 #endif // TEST_ZIP
3432
3433 // ----------------------------------------------------------------------------
3434 // ZLIB stream
3435 // ----------------------------------------------------------------------------
3436
3437 #ifdef TEST_ZLIB
3438
3439 #include "wx/zstream.h"
3440 #include "wx/wfstream.h"
3441
3442 static const wxChar *FILENAME_GZ = _T("test.gz");
3443 static const char *TEST_DATA = "hello and hello again";
3444
3445 static void TestZlibStreamWrite()
3446 {
3447 puts("*** Testing Zlib stream reading ***\n");
3448
3449 wxFileOutputStream fileOutStream(FILENAME_GZ);
3450 wxZlibOutputStream ostr(fileOutStream, 0);
3451 printf("Compressing the test string... ");
3452 ostr.Write(TEST_DATA, sizeof(TEST_DATA));
3453 if ( !ostr )
3454 {
3455 puts("(ERROR: failed)");
3456 }
3457 else
3458 {
3459 puts("(ok)");
3460 }
3461
3462 puts("\n----- done ------");
3463 }
3464
3465 static void TestZlibStreamRead()
3466 {
3467 puts("*** Testing Zlib stream reading ***\n");
3468
3469 wxFileInputStream fileInStream(FILENAME_GZ);
3470 wxZlibInputStream istr(fileInStream);
3471 printf("Archive size: %u\n", istr.GetSize());
3472
3473 puts("Dumping the file:");
3474 while ( !istr.Eof() )
3475 {
3476 putchar(istr.GetC());
3477 fflush(stdout);
3478 }
3479
3480 puts("\n----- done ------");
3481 }
3482
3483 #endif // TEST_ZLIB
3484
3485 // ----------------------------------------------------------------------------
3486 // date time
3487 // ----------------------------------------------------------------------------
3488
3489 #ifdef TEST_DATETIME
3490
3491 #include <math.h>
3492
3493 #include "wx/date.h"
3494 #include "wx/datetime.h"
3495
3496 // the test data
3497 struct Date
3498 {
3499 wxDateTime::wxDateTime_t day;
3500 wxDateTime::Month month;
3501 int year;
3502 wxDateTime::wxDateTime_t hour, min, sec;
3503 double jdn;
3504 wxDateTime::WeekDay wday;
3505 time_t gmticks, ticks;
3506
3507 void Init(const wxDateTime::Tm& tm)
3508 {
3509 day = tm.mday;
3510 month = tm.mon;
3511 year = tm.year;
3512 hour = tm.hour;
3513 min = tm.min;
3514 sec = tm.sec;
3515 jdn = 0.0;
3516 gmticks = ticks = -1;
3517 }
3518
3519 wxDateTime DT() const
3520 { return wxDateTime(day, month, year, hour, min, sec); }
3521
3522 bool SameDay(const wxDateTime::Tm& tm) const
3523 {
3524 return day == tm.mday && month == tm.mon && year == tm.year;
3525 }
3526
3527 wxString Format() const
3528 {
3529 wxString s;
3530 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
3531 hour, min, sec,
3532 wxDateTime::GetMonthName(month).c_str(),
3533 day,
3534 abs(wxDateTime::ConvertYearToBC(year)),
3535 year > 0 ? "AD" : "BC");
3536 return s;
3537 }
3538
3539 wxString FormatDate() const
3540 {
3541 wxString s;
3542 s.Printf("%02d-%s-%4d%s",
3543 day,
3544 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3545 abs(wxDateTime::ConvertYearToBC(year)),
3546 year > 0 ? "AD" : "BC");
3547 return s;
3548 }
3549 };
3550
3551 static const Date testDates[] =
3552 {
3553 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
3554 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
3555 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
3556 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
3557 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
3558 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
3559 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
3560 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
3561 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
3562 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
3563 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
3564 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
3565 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
3566 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
3567 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
3568 };
3569
3570 // this test miscellaneous static wxDateTime functions
3571 static void TestTimeStatic()
3572 {
3573 puts("\n*** wxDateTime static methods test ***");
3574
3575 // some info about the current date
3576 int year = wxDateTime::GetCurrentYear();
3577 printf("Current year %d is %sa leap one and has %d days.\n",
3578 year,
3579 wxDateTime::IsLeapYear(year) ? "" : "not ",
3580 wxDateTime::GetNumberOfDays(year));
3581
3582 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3583 printf("Current month is '%s' ('%s') and it has %d days\n",
3584 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3585 wxDateTime::GetMonthName(month).c_str(),
3586 wxDateTime::GetNumberOfDays(month));
3587
3588 // leap year logic
3589 static const size_t nYears = 5;
3590 static const size_t years[2][nYears] =
3591 {
3592 // first line: the years to test
3593 { 1990, 1976, 2000, 2030, 1984, },
3594
3595 // second line: TRUE if leap, FALSE otherwise
3596 { FALSE, TRUE, TRUE, FALSE, TRUE }
3597 };
3598
3599 for ( size_t n = 0; n < nYears; n++ )
3600 {
3601 int year = years[0][n];
3602 bool should = years[1][n] != 0,
3603 is = wxDateTime::IsLeapYear(year);
3604
3605 printf("Year %d is %sa leap year (%s)\n",
3606 year,
3607 is ? "" : "not ",
3608 should == is ? "ok" : "ERROR");
3609
3610 wxASSERT( should == wxDateTime::IsLeapYear(year) );
3611 }
3612 }
3613
3614 // test constructing wxDateTime objects
3615 static void TestTimeSet()
3616 {
3617 puts("\n*** wxDateTime construction test ***");
3618
3619 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3620 {
3621 const Date& d1 = testDates[n];
3622 wxDateTime dt = d1.DT();
3623
3624 Date d2;
3625 d2.Init(dt.GetTm());
3626
3627 wxString s1 = d1.Format(),
3628 s2 = d2.Format();
3629
3630 printf("Date: %s == %s (%s)\n",
3631 s1.c_str(), s2.c_str(),
3632 s1 == s2 ? "ok" : "ERROR");
3633 }
3634 }
3635
3636 // test time zones stuff
3637 static void TestTimeZones()
3638 {
3639 puts("\n*** wxDateTime timezone test ***");
3640
3641 wxDateTime now = wxDateTime::Now();
3642
3643 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
3644 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
3645 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
3646 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
3647 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
3648 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
3649
3650 wxDateTime::Tm tm = now.GetTm();
3651 if ( wxDateTime(tm) != now )
3652 {
3653 printf("ERROR: got %s instead of %s\n",
3654 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3655 }
3656 }
3657
3658 // test some minimal support for the dates outside the standard range
3659 static void TestTimeRange()
3660 {
3661 puts("\n*** wxDateTime out-of-standard-range dates test ***");
3662
3663 static const char *fmt = "%d-%b-%Y %H:%M:%S";
3664
3665 printf("Unix epoch:\t%s\n",
3666 wxDateTime(2440587.5).Format(fmt).c_str());
3667 printf("Feb 29, 0: \t%s\n",
3668 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3669 printf("JDN 0: \t%s\n",
3670 wxDateTime(0.0).Format(fmt).c_str());
3671 printf("Jan 1, 1AD:\t%s\n",
3672 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3673 printf("May 29, 2099:\t%s\n",
3674 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3675 }
3676
3677 static void TestTimeTicks()
3678 {
3679 puts("\n*** wxDateTime ticks test ***");
3680
3681 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3682 {
3683 const Date& d = testDates[n];
3684 if ( d.ticks == -1 )
3685 continue;
3686
3687 wxDateTime dt = d.DT();
3688 long ticks = (dt.GetValue() / 1000).ToLong();
3689 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
3690 if ( ticks == d.ticks )
3691 {
3692 puts(" (ok)");
3693 }
3694 else
3695 {
3696 printf(" (ERROR: should be %ld, delta = %ld)\n",
3697 d.ticks, ticks - d.ticks);
3698 }
3699
3700 dt = d.DT().ToTimezone(wxDateTime::GMT0);
3701 ticks = (dt.GetValue() / 1000).ToLong();
3702 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
3703 if ( ticks == d.gmticks )
3704 {
3705 puts(" (ok)");
3706 }
3707 else
3708 {
3709 printf(" (ERROR: should be %ld, delta = %ld)\n",
3710 d.gmticks, ticks - d.gmticks);
3711 }
3712 }
3713
3714 puts("");
3715 }
3716
3717 // test conversions to JDN &c
3718 static void TestTimeJDN()
3719 {
3720 puts("\n*** wxDateTime to JDN test ***");
3721
3722 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
3723 {
3724 const Date& d = testDates[n];
3725 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3726 double jdn = dt.GetJulianDayNumber();
3727
3728 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
3729 if ( jdn == d.jdn )
3730 {
3731 puts(" (ok)");
3732 }
3733 else
3734 {
3735 printf(" (ERROR: should be %f, delta = %f)\n",
3736 d.jdn, jdn - d.jdn);
3737 }
3738 }
3739 }
3740
3741 // test week days computation
3742 static void TestTimeWDays()
3743 {
3744 puts("\n*** wxDateTime weekday test ***");
3745
3746 // test GetWeekDay()
3747 size_t n;
3748 for ( n = 0; n < WXSIZEOF(testDates); n++ )
3749 {
3750 const Date& d = testDates[n];
3751 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
3752
3753 wxDateTime::WeekDay wday = dt.GetWeekDay();
3754 printf("%s is: %s",
3755 d.Format().c_str(),
3756 wxDateTime::GetWeekDayName(wday).c_str());
3757 if ( wday == d.wday )
3758 {
3759 puts(" (ok)");
3760 }
3761 else
3762 {
3763 printf(" (ERROR: should be %s)\n",
3764 wxDateTime::GetWeekDayName(d.wday).c_str());
3765 }
3766 }
3767
3768 puts("");
3769
3770 // test SetToWeekDay()
3771 struct WeekDateTestData
3772 {
3773 Date date; // the real date (precomputed)
3774 int nWeek; // its week index in the month
3775 wxDateTime::WeekDay wday; // the weekday
3776 wxDateTime::Month month; // the month
3777 int year; // and the year
3778
3779 wxString Format() const
3780 {
3781 wxString s, which;
3782 switch ( nWeek < -1 ? -nWeek : nWeek )
3783 {
3784 case 1: which = "first"; break;
3785 case 2: which = "second"; break;
3786 case 3: which = "third"; break;
3787 case 4: which = "fourth"; break;
3788 case 5: which = "fifth"; break;
3789
3790 case -1: which = "last"; break;
3791 }
3792
3793 if ( nWeek < -1 )
3794 {
3795 which += " from end";
3796 }
3797
3798 s.Printf("The %s %s of %s in %d",
3799 which.c_str(),
3800 wxDateTime::GetWeekDayName(wday).c_str(),
3801 wxDateTime::GetMonthName(month).c_str(),
3802 year);
3803
3804 return s;
3805 }
3806 };
3807
3808 // the array data was generated by the following python program
3809 /*
3810 from DateTime import *
3811 from whrandom import *
3812 from string import *
3813
3814 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3815 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3816
3817 week = DateTimeDelta(7)
3818
3819 for n in range(20):
3820 year = randint(1900, 2100)
3821 month = randint(1, 12)
3822 day = randint(1, 28)
3823 dt = DateTime(year, month, day)
3824 wday = dt.day_of_week
3825
3826 countFromEnd = choice([-1, 1])
3827 weekNum = 0;
3828
3829 while dt.month is month:
3830 dt = dt - countFromEnd * week
3831 weekNum = weekNum + countFromEnd
3832
3833 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
3834
3835 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
3836 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
3837 */
3838
3839 static const WeekDateTestData weekDatesTestData[] =
3840 {
3841 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
3842 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
3843 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
3844 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
3845 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
3846 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
3847 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
3848 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
3849 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
3850 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
3851 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
3852 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
3853 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
3854 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
3855 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
3856 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
3857 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
3858 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
3859 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
3860 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
3861 };
3862
3863 static const char *fmt = "%d-%b-%Y";
3864
3865 wxDateTime dt;
3866 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
3867 {
3868 const WeekDateTestData& wd = weekDatesTestData[n];
3869
3870 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
3871
3872 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
3873
3874 const Date& d = wd.date;
3875 if ( d.SameDay(dt.GetTm()) )
3876 {
3877 puts(" (ok)");
3878 }
3879 else
3880 {
3881 dt.Set(d.day, d.month, d.year);
3882
3883 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
3884 }
3885 }
3886 }
3887
3888 // test the computation of (ISO) week numbers
3889 static void TestTimeWNumber()
3890 {
3891 puts("\n*** wxDateTime week number test ***");
3892
3893 struct WeekNumberTestData
3894 {
3895 Date date; // the date
3896 wxDateTime::wxDateTime_t week; // the week number in the year
3897 wxDateTime::wxDateTime_t wmon; // the week number in the month
3898 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
3899 wxDateTime::wxDateTime_t dnum; // day number in the year
3900 };
3901
3902 // data generated with the following python script:
3903 /*
3904 from DateTime import *
3905 from whrandom import *
3906 from string import *
3907
3908 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
3909 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
3910
3911 def GetMonthWeek(dt):
3912 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
3913 if weekNumMonth < 0:
3914 weekNumMonth = weekNumMonth + 53
3915 return weekNumMonth
3916
3917 def GetLastSundayBefore(dt):
3918 if dt.iso_week[2] == 7:
3919 return dt
3920 else:
3921 return dt - DateTimeDelta(dt.iso_week[2])
3922
3923 for n in range(20):
3924 year = randint(1900, 2100)
3925 month = randint(1, 12)
3926 day = randint(1, 28)
3927 dt = DateTime(year, month, day)
3928 dayNum = dt.day_of_year
3929 weekNum = dt.iso_week[1]
3930 weekNumMonth = GetMonthWeek(dt)
3931
3932 weekNumMonth2 = 0
3933 dtSunday = GetLastSundayBefore(dt)
3934
3935 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
3936 weekNumMonth2 = weekNumMonth2 + 1
3937 dtSunday = dtSunday - DateTimeDelta(7)
3938
3939 data = { 'day': rjust(`day`, 2), \
3940 'month': monthNames[month - 1], \
3941 'year': year, \
3942 'weekNum': rjust(`weekNum`, 2), \
3943 'weekNumMonth': weekNumMonth, \
3944 'weekNumMonth2': weekNumMonth2, \
3945 'dayNum': rjust(`dayNum`, 3) }
3946
3947 print " { { %(day)s, "\
3948 "wxDateTime::%(month)s, "\
3949 "%(year)d }, "\
3950 "%(weekNum)s, "\
3951 "%(weekNumMonth)s, "\
3952 "%(weekNumMonth2)s, "\
3953 "%(dayNum)s }," % data
3954
3955 */
3956 static const WeekNumberTestData weekNumberTestDates[] =
3957 {
3958 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
3959 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
3960 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
3961 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
3962 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
3963 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
3964 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
3965 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
3966 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
3967 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
3968 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
3969 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
3970 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
3971 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
3972 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
3973 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
3974 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
3975 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
3976 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
3977 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
3978 };
3979
3980 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
3981 {
3982 const WeekNumberTestData& wn = weekNumberTestDates[n];
3983 const Date& d = wn.date;
3984
3985 wxDateTime dt = d.DT();
3986
3987 wxDateTime::wxDateTime_t
3988 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
3989 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
3990 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3991 dnum = dt.GetDayOfYear();
3992
3993 printf("%s: the day number is %d",
3994 d.FormatDate().c_str(), dnum);
3995 if ( dnum == wn.dnum )
3996 {
3997 printf(" (ok)");
3998 }
3999 else
4000 {
4001 printf(" (ERROR: should be %d)", wn.dnum);
4002 }
4003
4004 printf(", week in month is %d", wmon);
4005 if ( wmon == wn.wmon )
4006 {
4007 printf(" (ok)");
4008 }
4009 else
4010 {
4011 printf(" (ERROR: should be %d)", wn.wmon);
4012 }
4013
4014 printf(" or %d", wmon2);
4015 if ( wmon2 == wn.wmon2 )
4016 {
4017 printf(" (ok)");
4018 }
4019 else
4020 {
4021 printf(" (ERROR: should be %d)", wn.wmon2);
4022 }
4023
4024 printf(", week in year is %d", week);
4025 if ( week == wn.week )
4026 {
4027 puts(" (ok)");
4028 }
4029 else
4030 {
4031 printf(" (ERROR: should be %d)\n", wn.week);
4032 }
4033 }
4034 }
4035
4036 // test DST calculations
4037 static void TestTimeDST()
4038 {
4039 puts("\n*** wxDateTime DST test ***");
4040
4041 printf("DST is%s in effect now.\n\n",
4042 wxDateTime::Now().IsDST() ? "" : " not");
4043
4044 // taken from http://www.energy.ca.gov/daylightsaving.html
4045 static const Date datesDST[2][2004 - 1900 + 1] =
4046 {
4047 {
4048 { 1, wxDateTime::Apr, 1990 },
4049 { 7, wxDateTime::Apr, 1991 },
4050 { 5, wxDateTime::Apr, 1992 },
4051 { 4, wxDateTime::Apr, 1993 },
4052 { 3, wxDateTime::Apr, 1994 },
4053 { 2, wxDateTime::Apr, 1995 },
4054 { 7, wxDateTime::Apr, 1996 },
4055 { 6, wxDateTime::Apr, 1997 },
4056 { 5, wxDateTime::Apr, 1998 },
4057 { 4, wxDateTime::Apr, 1999 },
4058 { 2, wxDateTime::Apr, 2000 },
4059 { 1, wxDateTime::Apr, 2001 },
4060 { 7, wxDateTime::Apr, 2002 },
4061 { 6, wxDateTime::Apr, 2003 },
4062 { 4, wxDateTime::Apr, 2004 },
4063 },
4064 {
4065 { 28, wxDateTime::Oct, 1990 },
4066 { 27, wxDateTime::Oct, 1991 },
4067 { 25, wxDateTime::Oct, 1992 },
4068 { 31, wxDateTime::Oct, 1993 },
4069 { 30, wxDateTime::Oct, 1994 },
4070 { 29, wxDateTime::Oct, 1995 },
4071 { 27, wxDateTime::Oct, 1996 },
4072 { 26, wxDateTime::Oct, 1997 },
4073 { 25, wxDateTime::Oct, 1998 },
4074 { 31, wxDateTime::Oct, 1999 },
4075 { 29, wxDateTime::Oct, 2000 },
4076 { 28, wxDateTime::Oct, 2001 },
4077 { 27, wxDateTime::Oct, 2002 },
4078 { 26, wxDateTime::Oct, 2003 },
4079 { 31, wxDateTime::Oct, 2004 },
4080 }
4081 };
4082
4083 int year;
4084 for ( year = 1990; year < 2005; year++ )
4085 {
4086 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4087 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4088
4089 printf("DST period in the US for year %d: from %s to %s",
4090 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
4091
4092 size_t n = year - 1990;
4093 const Date& dBegin = datesDST[0][n];
4094 const Date& dEnd = datesDST[1][n];
4095
4096 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4097 {
4098 puts(" (ok)");
4099 }
4100 else
4101 {
4102 printf(" (ERROR: should be %s %d to %s %d)\n",
4103 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4104 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
4105 }
4106 }
4107
4108 puts("");
4109
4110 for ( year = 1990; year < 2005; year++ )
4111 {
4112 printf("DST period in Europe for year %d: from %s to %s\n",
4113 year,
4114 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4115 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
4116 }
4117 }
4118
4119 // test wxDateTime -> text conversion
4120 static void TestTimeFormat()
4121 {
4122 puts("\n*** wxDateTime formatting test ***");
4123
4124 // some information may be lost during conversion, so store what kind
4125 // of info should we recover after a round trip
4126 enum CompareKind
4127 {
4128 CompareNone, // don't try comparing
4129 CompareBoth, // dates and times should be identical
4130 CompareDate, // dates only
4131 CompareTime // time only
4132 };
4133
4134 static const struct
4135 {
4136 CompareKind compareKind;
4137 const char *format;
4138 } formatTestFormats[] =
4139 {
4140 { CompareBoth, "---> %c" },
4141 { CompareDate, "Date is %A, %d of %B, in year %Y" },
4142 { CompareBoth, "Date is %x, time is %X" },
4143 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
4144 { CompareNone, "The day of year: %j, the week of year: %W" },
4145 { CompareDate, "ISO date without separators: %4Y%2m%2d" },
4146 };
4147
4148 static const Date formatTestDates[] =
4149 {
4150 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4151 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
4152 #if 0
4153 // this test can't work for other centuries because it uses two digit
4154 // years in formats, so don't even try it
4155 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4156 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4157 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
4158 #endif
4159 };
4160
4161 // an extra test (as it doesn't depend on date, don't do it in the loop)
4162 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
4163
4164 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
4165 {
4166 puts("");
4167
4168 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
4169 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4170 {
4171 wxString s = dt.Format(formatTestFormats[n].format);
4172 printf("%s", s.c_str());
4173
4174 // what can we recover?
4175 int kind = formatTestFormats[n].compareKind;
4176
4177 // convert back
4178 wxDateTime dt2;
4179 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
4180 if ( !result )
4181 {
4182 // converion failed - should it have?
4183 if ( kind == CompareNone )
4184 puts(" (ok)");
4185 else
4186 puts(" (ERROR: conversion back failed)");
4187 }
4188 else if ( *result )
4189 {
4190 // should have parsed the entire string
4191 puts(" (ERROR: conversion back stopped too soon)");
4192 }
4193 else
4194 {
4195 bool equal = FALSE; // suppress compilaer warning
4196 switch ( kind )
4197 {
4198 case CompareBoth:
4199 equal = dt2 == dt;
4200 break;
4201
4202 case CompareDate:
4203 equal = dt.IsSameDate(dt2);
4204 break;
4205
4206 case CompareTime:
4207 equal = dt.IsSameTime(dt2);
4208 break;
4209 }
4210
4211 if ( !equal )
4212 {
4213 printf(" (ERROR: got back '%s' instead of '%s')\n",
4214 dt2.Format().c_str(), dt.Format().c_str());
4215 }
4216 else
4217 {
4218 puts(" (ok)");
4219 }
4220 }
4221 }
4222 }
4223 }
4224
4225 // test text -> wxDateTime conversion
4226 static void TestTimeParse()
4227 {
4228 puts("\n*** wxDateTime parse test ***");
4229
4230 struct ParseTestData
4231 {
4232 const char *format;
4233 Date date;
4234 bool good;
4235 };
4236
4237 static const ParseTestData parseTestDates[] =
4238 {
4239 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
4240 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
4241 };
4242
4243 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4244 {
4245 const char *format = parseTestDates[n].format;
4246
4247 printf("%s => ", format);
4248
4249 wxDateTime dt;
4250 if ( dt.ParseRfc822Date(format) )
4251 {
4252 printf("%s ", dt.Format().c_str());
4253
4254 if ( parseTestDates[n].good )
4255 {
4256 wxDateTime dtReal = parseTestDates[n].date.DT();
4257 if ( dt == dtReal )
4258 {
4259 puts("(ok)");
4260 }
4261 else
4262 {
4263 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
4264 }
4265 }
4266 else
4267 {
4268 puts("(ERROR: bad format)");
4269 }
4270 }
4271 else
4272 {
4273 printf("bad format (%s)\n",
4274 parseTestDates[n].good ? "ERROR" : "ok");
4275 }
4276 }
4277 }
4278
4279 static void TestDateTimeInteractive()
4280 {
4281 puts("\n*** interactive wxDateTime tests ***");
4282
4283 char buf[128];
4284
4285 for ( ;; )
4286 {
4287 printf("Enter a date: ");
4288 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
4289 break;
4290
4291 // kill the last '\n'
4292 buf[strlen(buf) - 1] = 0;
4293
4294 wxDateTime dt;
4295 const char *p = dt.ParseDate(buf);
4296 if ( !p )
4297 {
4298 printf("ERROR: failed to parse the date '%s'.\n", buf);
4299
4300 continue;
4301 }
4302 else if ( *p )
4303 {
4304 printf("WARNING: parsed only first %u characters.\n", p - buf);
4305 }
4306
4307 printf("%s: day %u, week of month %u/%u, week of year %u\n",
4308 dt.Format("%b %d, %Y").c_str(),
4309 dt.GetDayOfYear(),
4310 dt.GetWeekOfMonth(wxDateTime::Monday_First),
4311 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4312 dt.GetWeekOfYear(wxDateTime::Monday_First));
4313 }
4314
4315 puts("\n*** done ***");
4316 }
4317
4318 static void TestTimeMS()
4319 {
4320 puts("*** testing millisecond-resolution support in wxDateTime ***");
4321
4322 wxDateTime dt1 = wxDateTime::Now(),
4323 dt2 = wxDateTime::UNow();
4324
4325 printf("Now = %s\n", dt1.Format("%H:%M:%S:%l").c_str());
4326 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
4327 printf("Dummy loop: ");
4328 for ( int i = 0; i < 6000; i++ )
4329 {
4330 //for ( int j = 0; j < 10; j++ )
4331 {
4332 wxString s;
4333 s.Printf("%g", sqrt(i));
4334 }
4335
4336 if ( !(i % 100) )
4337 putchar('.');
4338 }
4339 puts(", done");
4340
4341 dt1 = dt2;
4342 dt2 = wxDateTime::UNow();
4343 printf("UNow = %s\n", dt2.Format("%H:%M:%S:%l").c_str());
4344
4345 printf("Loop executed in %s ms\n", (dt2 - dt1).Format("%l").c_str());
4346
4347 puts("\n*** done ***");
4348 }
4349
4350 static void TestTimeArithmetics()
4351 {
4352 puts("\n*** testing arithmetic operations on wxDateTime ***");
4353
4354 static const struct ArithmData
4355 {
4356 ArithmData(const wxDateSpan& sp, const char *nam)
4357 : span(sp), name(nam) { }
4358
4359 wxDateSpan span;
4360 const char *name;
4361 } testArithmData[] =
4362 {
4363 ArithmData(wxDateSpan::Day(), "day"),
4364 ArithmData(wxDateSpan::Week(), "week"),
4365 ArithmData(wxDateSpan::Month(), "month"),
4366 ArithmData(wxDateSpan::Year(), "year"),
4367 ArithmData(wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days"),
4368 };
4369
4370 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
4371
4372 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
4373 {
4374 wxDateSpan span = testArithmData[n].span;
4375 dt1 = dt + span;
4376 dt2 = dt - span;
4377
4378 const char *name = testArithmData[n].name;
4379 printf("%s + %s = %s, %s - %s = %s\n",
4380 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
4381 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
4382
4383 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
4384 if ( dt1 - span == dt )
4385 {
4386 puts(" (ok)");
4387 }
4388 else
4389 {
4390 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4391 }
4392
4393 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
4394 if ( dt2 + span == dt )
4395 {
4396 puts(" (ok)");
4397 }
4398 else
4399 {
4400 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
4401 }
4402
4403 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
4404 if ( dt2 + 2*span == dt1 )
4405 {
4406 puts(" (ok)");
4407 }
4408 else
4409 {
4410 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
4411 }
4412
4413 puts("");
4414 }
4415 }
4416
4417 static void TestTimeHolidays()
4418 {
4419 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
4420
4421 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
4422 wxDateTime dtStart(1, tm.mon, tm.year),
4423 dtEnd = dtStart.GetLastMonthDay();
4424
4425 wxDateTimeArray hol;
4426 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
4427
4428 const wxChar *format = "%d-%b-%Y (%a)";
4429
4430 printf("All holidays between %s and %s:\n",
4431 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
4432
4433 size_t count = hol.GetCount();
4434 for ( size_t n = 0; n < count; n++ )
4435 {
4436 printf("\t%s\n", hol[n].Format(format).c_str());
4437 }
4438
4439 puts("");
4440 }
4441
4442 static void TestTimeZoneBug()
4443 {
4444 puts("\n*** testing for DST/timezone bug ***\n");
4445
4446 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
4447 for ( int i = 0; i < 31; i++ )
4448 {
4449 printf("Date %s: week day %s.\n",
4450 date.Format(_T("%d-%m-%Y")).c_str(),
4451 date.GetWeekDayName(date.GetWeekDay()).c_str());
4452
4453 date += wxDateSpan::Day();
4454 }
4455
4456 puts("");
4457 }
4458
4459 static void TestTimeSpanFormat()
4460 {
4461 puts("\n*** wxTimeSpan tests ***");
4462
4463 static const char *formats[] =
4464 {
4465 _T("(default) %H:%M:%S"),
4466 _T("%E weeks and %D days"),
4467 _T("%l milliseconds"),
4468 _T("(with ms) %H:%M:%S:%l"),
4469 _T("100%% of minutes is %M"), // test "%%"
4470 _T("%D days and %H hours"),
4471 _T("or also %S seconds"),
4472 };
4473
4474 wxTimeSpan ts1(1, 2, 3, 4),
4475 ts2(111, 222, 333);
4476 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
4477 {
4478 printf("ts1 = %s\tts2 = %s\n",
4479 ts1.Format(formats[n]).c_str(),
4480 ts2.Format(formats[n]).c_str());
4481 }
4482
4483 puts("");
4484 }
4485
4486 #if 0
4487
4488 // test compatibility with the old wxDate/wxTime classes
4489 static void TestTimeCompatibility()
4490 {
4491 puts("\n*** wxDateTime compatibility test ***");
4492
4493 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
4494 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
4495
4496 double jdnNow = wxDateTime::Now().GetJDN();
4497 long jdnMidnight = (long)(jdnNow - 0.5);
4498 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
4499
4500 jdnMidnight = wxDate().Set().GetJulianDate();
4501 printf("wxDateTime for today: %s\n",
4502 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
4503
4504 int flags = wxEUROPEAN;//wxFULL;
4505 wxDate date;
4506 date.Set();
4507 printf("Today is %s\n", date.FormatDate(flags).c_str());
4508 for ( int n = 0; n < 7; n++ )
4509 {
4510 printf("Previous %s is %s\n",
4511 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
4512 date.Previous(n + 1).FormatDate(flags).c_str());
4513 }
4514 }
4515
4516 #endif // 0
4517
4518 #endif // TEST_DATETIME
4519
4520 // ----------------------------------------------------------------------------
4521 // threads
4522 // ----------------------------------------------------------------------------
4523
4524 #ifdef TEST_THREADS
4525
4526 #include "wx/thread.h"
4527
4528 static size_t gs_counter = (size_t)-1;
4529 static wxCriticalSection gs_critsect;
4530 static wxCondition gs_cond;
4531
4532 class MyJoinableThread : public wxThread
4533 {
4534 public:
4535 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
4536 { m_n = n; Create(); }
4537
4538 // thread execution starts here
4539 virtual ExitCode Entry();
4540
4541 private:
4542 size_t m_n;
4543 };
4544
4545 wxThread::ExitCode MyJoinableThread::Entry()
4546 {
4547 unsigned long res = 1;
4548 for ( size_t n = 1; n < m_n; n++ )
4549 {
4550 res *= n;
4551
4552 // it's a loooong calculation :-)
4553 Sleep(100);
4554 }
4555
4556 return (ExitCode)res;
4557 }
4558
4559 class MyDetachedThread : public wxThread
4560 {
4561 public:
4562 MyDetachedThread(size_t n, char ch)
4563 {
4564 m_n = n;
4565 m_ch = ch;
4566 m_cancelled = FALSE;
4567
4568 Create();
4569 }
4570
4571 // thread execution starts here
4572 virtual ExitCode Entry();
4573
4574 // and stops here
4575 virtual void OnExit();
4576
4577 private:
4578 size_t m_n; // number of characters to write
4579 char m_ch; // character to write
4580
4581 bool m_cancelled; // FALSE if we exit normally
4582 };
4583
4584 wxThread::ExitCode MyDetachedThread::Entry()
4585 {
4586 {
4587 wxCriticalSectionLocker lock(gs_critsect);
4588 if ( gs_counter == (size_t)-1 )
4589 gs_counter = 1;
4590 else
4591 gs_counter++;
4592 }
4593
4594 for ( size_t n = 0; n < m_n; n++ )
4595 {
4596 if ( TestDestroy() )
4597 {
4598 m_cancelled = TRUE;
4599
4600 break;
4601 }
4602
4603 putchar(m_ch);
4604 fflush(stdout);
4605
4606 wxThread::Sleep(100);
4607 }
4608
4609 return 0;
4610 }
4611
4612 void MyDetachedThread::OnExit()
4613 {
4614 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
4615
4616 wxCriticalSectionLocker lock(gs_critsect);
4617 if ( !--gs_counter && !m_cancelled )
4618 gs_cond.Signal();
4619 }
4620
4621 static void TestDetachedThreads()
4622 {
4623 puts("\n*** Testing detached threads ***");
4624
4625 static const size_t nThreads = 3;
4626 MyDetachedThread *threads[nThreads];
4627 size_t n;
4628 for ( n = 0; n < nThreads; n++ )
4629 {
4630 threads[n] = new MyDetachedThread(10, 'A' + n);
4631 }
4632
4633 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
4634 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
4635
4636 for ( n = 0; n < nThreads; n++ )
4637 {
4638 threads[n]->Run();
4639 }
4640
4641 // wait until all threads terminate
4642 gs_cond.Wait();
4643
4644 puts("");
4645 }
4646
4647 static void TestJoinableThreads()
4648 {
4649 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
4650
4651 // calc 10! in the background
4652 MyJoinableThread thread(10);
4653 thread.Run();
4654
4655 printf("\nThread terminated with exit code %lu.\n",
4656 (unsigned long)thread.Wait());
4657 }
4658
4659 static void TestThreadSuspend()
4660 {
4661 puts("\n*** Testing thread suspend/resume functions ***");
4662
4663 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
4664
4665 thread->Run();
4666
4667 // this is for this demo only, in a real life program we'd use another
4668 // condition variable which would be signaled from wxThread::Entry() to
4669 // tell us that the thread really started running - but here just wait a
4670 // bit and hope that it will be enough (the problem is, of course, that
4671 // the thread might still not run when we call Pause() which will result
4672 // in an error)
4673 wxThread::Sleep(300);
4674
4675 for ( size_t n = 0; n < 3; n++ )
4676 {
4677 thread->Pause();
4678
4679 puts("\nThread suspended");
4680 if ( n > 0 )
4681 {
4682 // don't sleep but resume immediately the first time
4683 wxThread::Sleep(300);
4684 }
4685 puts("Going to resume the thread");
4686
4687 thread->Resume();
4688 }
4689
4690 puts("Waiting until it terminates now");
4691
4692 // wait until the thread terminates
4693 gs_cond.Wait();
4694
4695 puts("");
4696 }
4697
4698 static void TestThreadDelete()
4699 {
4700 // As above, using Sleep() is only for testing here - we must use some
4701 // synchronisation object instead to ensure that the thread is still
4702 // running when we delete it - deleting a detached thread which already
4703 // terminated will lead to a crash!
4704
4705 puts("\n*** Testing thread delete function ***");
4706
4707 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
4708
4709 thread0->Delete();
4710
4711 puts("\nDeleted a thread which didn't start to run yet.");
4712
4713 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
4714
4715 thread1->Run();
4716
4717 wxThread::Sleep(300);
4718
4719 thread1->Delete();
4720
4721 puts("\nDeleted a running thread.");
4722
4723 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
4724
4725 thread2->Run();
4726
4727 wxThread::Sleep(300);
4728
4729 thread2->Pause();
4730
4731 thread2->Delete();
4732
4733 puts("\nDeleted a sleeping thread.");
4734
4735 MyJoinableThread thread3(20);
4736 thread3.Run();
4737
4738 thread3.Delete();
4739
4740 puts("\nDeleted a joinable thread.");
4741
4742 MyJoinableThread thread4(2);
4743 thread4.Run();
4744
4745 wxThread::Sleep(300);
4746
4747 thread4.Delete();
4748
4749 puts("\nDeleted a joinable thread which already terminated.");
4750
4751 puts("");
4752 }
4753
4754 class MyWaitingThread : public wxThread
4755 {
4756 public:
4757 MyWaitingThread(wxCondition *condition)
4758 {
4759 m_condition = condition;
4760
4761 Create();
4762 }
4763
4764 virtual ExitCode Entry()
4765 {
4766 printf("Thread %lu has started running.\n", GetId());
4767 fflush(stdout);
4768
4769 gs_cond.Signal();
4770
4771 printf("Thread %lu starts to wait...\n", GetId());
4772 fflush(stdout);
4773
4774 m_condition->Wait();
4775
4776 printf("Thread %lu finished to wait, exiting.\n", GetId());
4777 fflush(stdout);
4778
4779 return 0;
4780 }
4781
4782 private:
4783 wxCondition *m_condition;
4784 };
4785
4786 static void TestThreadConditions()
4787 {
4788 wxCondition condition;
4789
4790 // otherwise its difficult to understand which log messages pertain to
4791 // which condition
4792 wxLogTrace("thread", "Local condition var is %08x, gs_cond = %08x",
4793 condition.GetId(), gs_cond.GetId());
4794
4795 // create and launch threads
4796 MyWaitingThread *threads[10];
4797
4798 size_t n;
4799 for ( n = 0; n < WXSIZEOF(threads); n++ )
4800 {
4801 threads[n] = new MyWaitingThread(&condition);
4802 }
4803
4804 for ( n = 0; n < WXSIZEOF(threads); n++ )
4805 {
4806 threads[n]->Run();
4807 }
4808
4809 // wait until all threads run
4810 puts("Main thread is waiting for the other threads to start");
4811 fflush(stdout);
4812
4813 size_t nRunning = 0;
4814 while ( nRunning < WXSIZEOF(threads) )
4815 {
4816 gs_cond.Wait();
4817
4818 nRunning++;
4819
4820 printf("Main thread: %u already running\n", nRunning);
4821 fflush(stdout);
4822 }
4823
4824 puts("Main thread: all threads started up.");
4825 fflush(stdout);
4826
4827 wxThread::Sleep(500);
4828
4829 #if 1
4830 // now wake one of them up
4831 printf("Main thread: about to signal the condition.\n");
4832 fflush(stdout);
4833 condition.Signal();
4834 #endif
4835
4836 wxThread::Sleep(200);
4837
4838 // wake all the (remaining) threads up, so that they can exit
4839 printf("Main thread: about to broadcast the condition.\n");
4840 fflush(stdout);
4841 condition.Broadcast();
4842
4843 // give them time to terminate (dirty!)
4844 wxThread::Sleep(500);
4845 }
4846
4847 #endif // TEST_THREADS
4848
4849 // ----------------------------------------------------------------------------
4850 // arrays
4851 // ----------------------------------------------------------------------------
4852
4853 #ifdef TEST_ARRAYS
4854
4855 #include "wx/dynarray.h"
4856
4857 #define DefineCompare(name, T) \
4858 \
4859 int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
4860 { \
4861 return first - second; \
4862 } \
4863 \
4864 int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
4865 { \
4866 return *first - *second; \
4867 } \
4868 \
4869 int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
4870 { \
4871 return *second - *first; \
4872 } \
4873
4874 DefineCompare(Short, short);
4875 DefineCompare(Int, int);
4876
4877 // test compilation of all macros
4878 WX_DEFINE_ARRAY(short, wxArrayShort);
4879 WX_DEFINE_SORTED_ARRAY(short, wxSortedArrayShortNoCmp);
4880 WX_DEFINE_SORTED_ARRAY_CMP(short, ShortCompareValues, wxSortedArrayShort);
4881 WX_DEFINE_SORTED_ARRAY_CMP(int, IntCompareValues, wxSortedArrayInt);
4882
4883 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
4884 #include "wx/arrimpl.cpp"
4885 WX_DEFINE_OBJARRAY(ArrayBars);
4886
4887 static void PrintArray(const char* name, const wxArrayString& array)
4888 {
4889 printf("Dump of the array '%s'\n", name);
4890
4891 size_t nCount = array.GetCount();
4892 for ( size_t n = 0; n < nCount; n++ )
4893 {
4894 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
4895 }
4896 }
4897
4898 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
4899 const wxString& second)
4900 {
4901 return first.length() - second.length();
4902 }
4903
4904 #define TestArrayOf(name) \
4905 \
4906 static void PrintArray(const char* name, const wxSortedArray##name & array) \
4907 { \
4908 printf("Dump of the array '%s'\n", name); \
4909 \
4910 size_t nCount = array.GetCount(); \
4911 for ( size_t n = 0; n < nCount; n++ ) \
4912 { \
4913 printf("\t%s[%u] = %d\n", name, n, array[n]); \
4914 } \
4915 } \
4916 \
4917 static void PrintArray(const char* name, const wxArray##name & array) \
4918 { \
4919 printf("Dump of the array '%s'\n", name); \
4920 \
4921 size_t nCount = array.GetCount(); \
4922 for ( size_t n = 0; n < nCount; n++ ) \
4923 { \
4924 printf("\t%s[%u] = %d\n", name, n, array[n]); \
4925 } \
4926 } \
4927 \
4928 static void TestArrayOf ## name ## s() \
4929 { \
4930 printf("*** Testing wxArray%s ***\n", #name); \
4931 \
4932 wxArray##name a; \
4933 a.Add(1); \
4934 a.Add(17); \
4935 a.Add(5); \
4936 a.Add(3); \
4937 \
4938 puts("Initially:"); \
4939 PrintArray("a", a); \
4940 \
4941 puts("After sort:"); \
4942 a.Sort(name ## Compare); \
4943 PrintArray("a", a); \
4944 \
4945 puts("After reverse sort:"); \
4946 a.Sort(name ## RevCompare); \
4947 PrintArray("a", a); \
4948 \
4949 wxSortedArray##name b; \
4950 b.Add(1); \
4951 b.Add(17); \
4952 b.Add(5); \
4953 b.Add(3); \
4954 \
4955 puts("Sorted array initially:"); \
4956 PrintArray("b", b); \
4957 }
4958
4959 TestArrayOf(Short);
4960 TestArrayOf(Int);
4961
4962 static void TestArrayOfObjects()
4963 {
4964 puts("*** Testing wxObjArray ***\n");
4965
4966 {
4967 ArrayBars bars;
4968 Bar bar("second bar");
4969
4970 printf("Initially: %u objects in the array, %u objects total.\n",
4971 bars.GetCount(), Bar::GetNumber());
4972
4973 bars.Add(new Bar("first bar"));
4974 bars.Add(bar);
4975
4976 printf("Now: %u objects in the array, %u objects total.\n",
4977 bars.GetCount(), Bar::GetNumber());
4978
4979 bars.Empty();
4980
4981 printf("After Empty(): %u objects in the array, %u objects total.\n",
4982 bars.GetCount(), Bar::GetNumber());
4983 }
4984
4985 printf("Finally: no more objects in the array, %u objects total.\n",
4986 Bar::GetNumber());
4987 }
4988
4989 #endif // TEST_ARRAYS
4990
4991 // ----------------------------------------------------------------------------
4992 // strings
4993 // ----------------------------------------------------------------------------
4994
4995 #ifdef TEST_STRINGS
4996
4997 #include "wx/timer.h"
4998 #include "wx/tokenzr.h"
4999
5000 static void TestStringConstruction()
5001 {
5002 puts("*** Testing wxString constructores ***");
5003
5004 #define TEST_CTOR(args, res) \
5005 { \
5006 wxString s args ; \
5007 printf("wxString%s = %s ", #args, s.c_str()); \
5008 if ( s == res ) \
5009 { \
5010 puts("(ok)"); \
5011 } \
5012 else \
5013 { \
5014 printf("(ERROR: should be %s)\n", res); \
5015 } \
5016 }
5017
5018 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5019 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5020 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5021 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5022
5023 static const wxChar *s = _T("?really!");
5024 const wxChar *start = wxStrchr(s, _T('r'));
5025 const wxChar *end = wxStrchr(s, _T('!'));
5026 TEST_CTOR((start, end), _T("really"));
5027
5028 puts("");
5029 }
5030
5031 static void TestString()
5032 {
5033 wxStopWatch sw;
5034
5035 wxString a, b, c;
5036
5037 a.reserve (128);
5038 b.reserve (128);
5039 c.reserve (128);
5040
5041 for (int i = 0; i < 1000000; ++i)
5042 {
5043 a = "Hello";
5044 b = " world";
5045 c = "! How'ya doin'?";
5046 a += b;
5047 a += c;
5048 c = "Hello world! What's up?";
5049 if (c != a)
5050 c = "Doh!";
5051 }
5052
5053 printf ("TestString elapsed time: %ld\n", sw.Time());
5054 }
5055
5056 static void TestPChar()
5057 {
5058 wxStopWatch sw;
5059
5060 char a [128];
5061 char b [128];
5062 char c [128];
5063
5064 for (int i = 0; i < 1000000; ++i)
5065 {
5066 strcpy (a, "Hello");
5067 strcpy (b, " world");
5068 strcpy (c, "! How'ya doin'?");
5069 strcat (a, b);
5070 strcat (a, c);
5071 strcpy (c, "Hello world! What's up?");
5072 if (strcmp (c, a) == 0)
5073 strcpy (c, "Doh!");
5074 }
5075
5076 printf ("TestPChar elapsed time: %ld\n", sw.Time());
5077 }
5078
5079 static void TestStringSub()
5080 {
5081 wxString s("Hello, world!");
5082
5083 puts("*** Testing wxString substring extraction ***");
5084
5085 printf("String = '%s'\n", s.c_str());
5086 printf("Left(5) = '%s'\n", s.Left(5).c_str());
5087 printf("Right(6) = '%s'\n", s.Right(6).c_str());
5088 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
5089 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
5090 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
5091 printf("substr(3) = '%s'\n", s.substr(3).c_str());
5092
5093 static const wxChar *prefixes[] =
5094 {
5095 _T("Hello"),
5096 _T("Hello, "),
5097 _T("Hello, world!"),
5098 _T("Hello, world!!!"),
5099 _T(""),
5100 _T("Goodbye"),
5101 _T("Hi"),
5102 };
5103
5104 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5105 {
5106 wxString prefix = prefixes[n], rest;
5107 bool rc = s.StartsWith(prefix, &rest);
5108 printf("StartsWith('%s') = %s", prefix.c_str(), rc ? "TRUE" : "FALSE");
5109 if ( rc )
5110 {
5111 printf(" (the rest is '%s')\n", rest.c_str());
5112 }
5113 else
5114 {
5115 putchar('\n');
5116 }
5117 }
5118
5119 puts("");
5120 }
5121
5122 static void TestStringFormat()
5123 {
5124 puts("*** Testing wxString formatting ***");
5125
5126 wxString s;
5127 s.Printf("%03d", 18);
5128
5129 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
5130 printf("Number 18: %s\n", s.c_str());
5131
5132 puts("");
5133 }
5134
5135 // returns "not found" for npos, value for all others
5136 static wxString PosToString(size_t res)
5137 {
5138 wxString s = res == wxString::npos ? wxString(_T("not found"))
5139 : wxString::Format(_T("%u"), res);
5140 return s;
5141 }
5142
5143 static void TestStringFind()
5144 {
5145 puts("*** Testing wxString find() functions ***");
5146
5147 static const wxChar *strToFind = _T("ell");
5148 static const struct StringFindTest
5149 {
5150 const wxChar *str;
5151 size_t start,
5152 result; // of searching "ell" in str
5153 } findTestData[] =
5154 {
5155 { _T("Well, hello world"), 0, 1 },
5156 { _T("Well, hello world"), 6, 7 },
5157 { _T("Well, hello world"), 9, wxString::npos },
5158 };
5159
5160 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5161 {
5162 const StringFindTest& ft = findTestData[n];
5163 size_t res = wxString(ft.str).find(strToFind, ft.start);
5164
5165 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
5166 strToFind, ft.str, ft.start, PosToString(res).c_str());
5167
5168 size_t resTrue = ft.result;
5169 if ( res == resTrue )
5170 {
5171 puts(_T("(ok)"));
5172 }
5173 else
5174 {
5175 printf(_T("(ERROR: should be %s)\n"),
5176 PosToString(resTrue).c_str());
5177 }
5178 }
5179
5180 puts("");
5181 }
5182
5183 static void TestStringTokenizer()
5184 {
5185 puts("*** Testing wxStringTokenizer ***");
5186
5187 static const wxChar *modeNames[] =
5188 {
5189 _T("default"),
5190 _T("return empty"),
5191 _T("return all empty"),
5192 _T("with delims"),
5193 _T("like strtok"),
5194 };
5195
5196 static const struct StringTokenizerTest
5197 {
5198 const wxChar *str; // string to tokenize
5199 const wxChar *delims; // delimiters to use
5200 size_t count; // count of token
5201 wxStringTokenizerMode mode; // how should we tokenize it
5202 } tokenizerTestData[] =
5203 {
5204 { _T(""), _T(" "), 0 },
5205 { _T("Hello, world"), _T(" "), 2 },
5206 { _T("Hello, world "), _T(" "), 2 },
5207 { _T("Hello, world"), _T(","), 2 },
5208 { _T("Hello, world!"), _T(",!"), 2 },
5209 { _T("Hello,, world!"), _T(",!"), 3 },
5210 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
5211 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
5212 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
5213 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
5214 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
5215 { _T("01/02/99"), _T("/-"), 3 },
5216 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
5217 };
5218
5219 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
5220 {
5221 const StringTokenizerTest& tt = tokenizerTestData[n];
5222 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
5223
5224 size_t count = tkz.CountTokens();
5225 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
5226 MakePrintable(tt.str).c_str(),
5227 count,
5228 MakePrintable(tt.delims).c_str(),
5229 modeNames[tkz.GetMode()]);
5230 if ( count == tt.count )
5231 {
5232 puts(_T("(ok)"));
5233 }
5234 else
5235 {
5236 printf(_T("(ERROR: should be %u)\n"), tt.count);
5237
5238 continue;
5239 }
5240
5241 // if we emulate strtok(), check that we do it correctly
5242 wxChar *buf, *s = NULL, *last;
5243
5244 if ( tkz.GetMode() == wxTOKEN_STRTOK )
5245 {
5246 buf = new wxChar[wxStrlen(tt.str) + 1];
5247 wxStrcpy(buf, tt.str);
5248
5249 s = wxStrtok(buf, tt.delims, &last);
5250 }
5251 else
5252 {
5253 buf = NULL;
5254 }
5255
5256 // now show the tokens themselves
5257 size_t count2 = 0;
5258 while ( tkz.HasMoreTokens() )
5259 {
5260 wxString token = tkz.GetNextToken();
5261
5262 printf(_T("\ttoken %u: '%s'"),
5263 ++count2,
5264 MakePrintable(token).c_str());
5265
5266 if ( buf )
5267 {
5268 if ( token == s )
5269 {
5270 puts(" (ok)");
5271 }
5272 else
5273 {
5274 printf(" (ERROR: should be %s)\n", s);
5275 }
5276
5277 s = wxStrtok(NULL, tt.delims, &last);
5278 }
5279 else
5280 {
5281 // nothing to compare with
5282 puts("");
5283 }
5284 }
5285
5286 if ( count2 != count )
5287 {
5288 puts(_T("\tERROR: token count mismatch"));
5289 }
5290
5291 delete [] buf;
5292 }
5293
5294 puts("");
5295 }
5296
5297 static void TestStringReplace()
5298 {
5299 puts("*** Testing wxString::replace ***");
5300
5301 static const struct StringReplaceTestData
5302 {
5303 const wxChar *original; // original test string
5304 size_t start, len; // the part to replace
5305 const wxChar *replacement; // the replacement string
5306 const wxChar *result; // and the expected result
5307 } stringReplaceTestData[] =
5308 {
5309 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
5310 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
5311 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
5312 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
5313 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
5314 };
5315
5316 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
5317 {
5318 const StringReplaceTestData data = stringReplaceTestData[n];
5319
5320 wxString original = data.original;
5321 original.replace(data.start, data.len, data.replacement);
5322
5323 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
5324 data.original, data.start, data.len, data.replacement,
5325 original.c_str());
5326
5327 if ( original == data.result )
5328 {
5329 puts("(ok)");
5330 }
5331 else
5332 {
5333 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
5334 }
5335 }
5336
5337 puts("");
5338 }
5339
5340 static void TestStringMatch()
5341 {
5342 wxPuts(_T("*** Testing wxString::Matches() ***"));
5343
5344 static const struct StringMatchTestData
5345 {
5346 const wxChar *text;
5347 const wxChar *wildcard;
5348 bool matches;
5349 } stringMatchTestData[] =
5350 {
5351 { _T("foobar"), _T("foo*"), 1 },
5352 { _T("foobar"), _T("*oo*"), 1 },
5353 { _T("foobar"), _T("*bar"), 1 },
5354 { _T("foobar"), _T("??????"), 1 },
5355 { _T("foobar"), _T("f??b*"), 1 },
5356 { _T("foobar"), _T("f?b*"), 0 },
5357 { _T("foobar"), _T("*goo*"), 0 },
5358 { _T("foobar"), _T("*foo"), 0 },
5359 { _T("foobarfoo"), _T("*foo"), 1 },
5360 { _T(""), _T("*"), 1 },
5361 { _T(""), _T("?"), 0 },
5362 };
5363
5364 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
5365 {
5366 const StringMatchTestData& data = stringMatchTestData[n];
5367 bool matches = wxString(data.text).Matches(data.wildcard);
5368 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
5369 data.wildcard,
5370 matches ? _T("matches") : _T("doesn't match"),
5371 data.text,
5372 matches == data.matches ? _T("ok") : _T("ERROR"));
5373 }
5374
5375 wxPuts(_T(""));
5376 }
5377
5378 #endif // TEST_STRINGS
5379
5380 // ----------------------------------------------------------------------------
5381 // entry point
5382 // ----------------------------------------------------------------------------
5383
5384 #ifdef TEST_SNGLINST
5385 #include "wx/snglinst.h"
5386 #endif // TEST_SNGLINST
5387
5388 int main(int argc, char **argv)
5389 {
5390 wxInitializer initializer;
5391 if ( !initializer )
5392 {
5393 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
5394
5395 return -1;
5396 }
5397
5398 #ifdef TEST_SNGLINST
5399 wxSingleInstanceChecker checker;
5400 if ( checker.Create(_T(".wxconsole.lock")) )
5401 {
5402 if ( checker.IsAnotherRunning() )
5403 {
5404 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
5405
5406 return 1;
5407 }
5408
5409 // wait some time to give time to launch another instance
5410 wxPrintf(_T("Press \"Enter\" to continue..."));
5411 wxFgetc(stdin);
5412 }
5413 else // failed to create
5414 {
5415 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
5416 }
5417 #endif // TEST_SNGLINST
5418
5419 #ifdef TEST_CHARSET
5420 TestCharset();
5421 #endif // TEST_CHARSET
5422
5423 #ifdef TEST_CMDLINE
5424 TestCmdLineConvert();
5425
5426 #if wxUSE_CMDLINE_PARSER
5427 static const wxCmdLineEntryDesc cmdLineDesc[] =
5428 {
5429 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
5430 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
5431 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
5432 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
5433
5434 { wxCMD_LINE_OPTION, "o", "output", "output file" },
5435 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
5436 { wxCMD_LINE_OPTION, "s", "size", "output block size",
5437 wxCMD_LINE_VAL_NUMBER },
5438 { wxCMD_LINE_OPTION, "d", "date", "output file date",
5439 wxCMD_LINE_VAL_DATE },
5440
5441 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
5442 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
5443
5444 { wxCMD_LINE_NONE }
5445 };
5446
5447 wxCmdLineParser parser(cmdLineDesc, argc, argv);
5448
5449 parser.AddOption("project_name", "", "full path to project file",
5450 wxCMD_LINE_VAL_STRING,
5451 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
5452
5453 switch ( parser.Parse() )
5454 {
5455 case -1:
5456 wxLogMessage("Help was given, terminating.");
5457 break;
5458
5459 case 0:
5460 ShowCmdLine(parser);
5461 break;
5462
5463 default:
5464 wxLogMessage("Syntax error detected, aborting.");
5465 break;
5466 }
5467 #endif // wxUSE_CMDLINE_PARSER
5468
5469 #endif // TEST_CMDLINE
5470
5471 #ifdef TEST_STRINGS
5472 if ( TEST_ALL )
5473 {
5474 TestPChar();
5475 TestString();
5476 TestStringSub();
5477 TestStringConstruction();
5478 TestStringFormat();
5479 TestStringFind();
5480 TestStringTokenizer();
5481 TestStringReplace();
5482 }
5483 else
5484 {
5485 TestStringMatch();
5486 }
5487 #endif // TEST_STRINGS
5488
5489 #ifdef TEST_ARRAYS
5490 if ( TEST_ALL )
5491 {
5492 wxArrayString a1;
5493 a1.Add("tiger");
5494 a1.Add("cat");
5495 a1.Add("lion");
5496 a1.Add("dog");
5497 a1.Add("human");
5498 a1.Add("ape");
5499
5500 puts("*** Initially:");
5501
5502 PrintArray("a1", a1);
5503
5504 wxArrayString a2(a1);
5505 PrintArray("a2", a2);
5506
5507 wxSortedArrayString a3(a1);
5508 PrintArray("a3", a3);
5509
5510 puts("*** After deleting a string from a1");
5511 a1.Remove(2);
5512
5513 PrintArray("a1", a1);
5514 PrintArray("a2", a2);
5515 PrintArray("a3", a3);
5516
5517 puts("*** After reassigning a1 to a2 and a3");
5518 a3 = a2 = a1;
5519 PrintArray("a2", a2);
5520 PrintArray("a3", a3);
5521
5522 puts("*** After sorting a1");
5523 a1.Sort();
5524 PrintArray("a1", a1);
5525
5526 puts("*** After sorting a1 in reverse order");
5527 a1.Sort(TRUE);
5528 PrintArray("a1", a1);
5529
5530 puts("*** After sorting a1 by the string length");
5531 a1.Sort(StringLenCompare);
5532 PrintArray("a1", a1);
5533
5534 TestArrayOfObjects();
5535 TestArrayOfShorts();
5536 }
5537
5538 TestArrayOfInts();
5539 #endif // TEST_ARRAYS
5540
5541 #ifdef TEST_DIR
5542 if ( TEST_ALL )
5543 {
5544 TestDirEnum();
5545 TestDirTraverse();
5546 }
5547 #endif // TEST_DIR
5548
5549 #ifdef TEST_DLLLOADER
5550 TestDllLoad();
5551 #endif // TEST_DLLLOADER
5552
5553 #ifdef TEST_ENVIRON
5554 TestEnvironment();
5555 #endif // TEST_ENVIRON
5556
5557 #ifdef TEST_EXECUTE
5558 TestExecute();
5559 #endif // TEST_EXECUTE
5560
5561 #ifdef TEST_FILECONF
5562 TestFileConfRead();
5563 #endif // TEST_FILECONF
5564
5565 #ifdef TEST_LIST
5566 TestListCtor();
5567 #endif // TEST_LIST
5568
5569 #ifdef TEST_LOCALE
5570 TestDefaultLang();
5571 #endif // TEST_LOCALE
5572
5573 #ifdef TEST_LOG
5574 wxString s;
5575 for ( size_t n = 0; n < 8000; n++ )
5576 {
5577 s << (char)('A' + (n % 26));
5578 }
5579
5580 wxString msg;
5581 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
5582
5583 // this one shouldn't be truncated
5584 printf(msg);
5585
5586 // but this one will because log functions use fixed size buffer
5587 // (note that it doesn't need '\n' at the end neither - will be added
5588 // by wxLog anyhow)
5589 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
5590 #endif // TEST_LOG
5591
5592 #ifdef TEST_FILE
5593 if ( TEST_ALL )
5594 {
5595 TestFileRead();
5596 TestTextFileRead();
5597 TestFileCopy();
5598 }
5599 #endif // TEST_FILE
5600
5601 #ifdef TEST_FILENAME
5602 if ( 1 )
5603 {
5604 wxFileName fn;
5605 fn.Assign("c:\\foo", "bar.baz");
5606
5607 DumpFileName(fn);
5608 }
5609
5610 if ( TEST_ALL )
5611 {
5612 TestFileNameConstruction();
5613 TestFileNameMakeRelative();
5614 TestFileNameSplit();
5615 TestFileNameTemp();
5616 TestFileNameCwd();
5617 TestFileNameComparison();
5618 TestFileNameOperations();
5619 }
5620 #endif // TEST_FILENAME
5621
5622 #ifdef TEST_FILETIME
5623 TestFileGetTimes();
5624 TestFileSetTimes();
5625 #endif // TEST_FILETIME
5626
5627 #ifdef TEST_FTP
5628 wxLog::AddTraceMask(FTP_TRACE_MASK);
5629 if ( TestFtpConnect() )
5630 {
5631 if ( TEST_ALL )
5632 {
5633 TestFtpList();
5634 TestFtpDownload();
5635 TestFtpMisc();
5636 TestFtpFileSize();
5637 TestFtpUpload();
5638 }
5639
5640 if ( TEST_INTERACTIVE )
5641 TestFtpInteractive();
5642 }
5643 //else: connecting to the FTP server failed
5644
5645 if ( 0 )
5646 TestFtpWuFtpd();
5647 #endif // TEST_FTP
5648
5649 #ifdef TEST_LONGLONG
5650 // seed pseudo random generator
5651 srand((unsigned)time(NULL));
5652
5653 if ( 0 )
5654 {
5655 TestSpeed();
5656 }
5657
5658 if ( TEST_ALL )
5659 {
5660 TestMultiplication();
5661 TestDivision();
5662 TestAddition();
5663 TestLongLongConversion();
5664 TestBitOperations();
5665 TestLongLongComparison();
5666 TestLongLongPrint();
5667 }
5668 #endif // TEST_LONGLONG
5669
5670 #ifdef TEST_HASH
5671 TestHash();
5672 #endif // TEST_HASH
5673
5674 #ifdef TEST_HASHMAP
5675 TestHashMap();
5676 #endif // TEST_HASHMAP
5677
5678 #ifdef TEST_MIME
5679 wxLog::AddTraceMask(_T("mime"));
5680 if ( TEST_ALL )
5681 {
5682 TestMimeEnum();
5683 TestMimeOverride();
5684 TestMimeFilename();
5685 }
5686
5687 TestMimeAssociate();
5688 #endif // TEST_MIME
5689
5690 #ifdef TEST_INFO_FUNCTIONS
5691 if ( TEST_ALL )
5692 {
5693 TestOsInfo();
5694 TestUserInfo();
5695 TestDiskInfo();
5696 }
5697 #endif // TEST_INFO_FUNCTIONS
5698
5699 #ifdef TEST_PATHLIST
5700 TestPathList();
5701 #endif // TEST_PATHLIST
5702
5703 #ifdef TEST_ODBC
5704 TestDbOpen();
5705 #endif // TEST_ODBC
5706
5707 #ifdef TEST_REGCONF
5708 TestRegConfWrite();
5709 #endif // TEST_REGCONF
5710
5711 #ifdef TEST_REGEX
5712 // TODO: write a real test using src/regex/tests file
5713 if ( TEST_ALL )
5714 {
5715 TestRegExCompile();
5716 TestRegExMatch();
5717 TestRegExSubmatch();
5718 TestRegExReplacement();
5719
5720 if ( TEST_INTERACTIVE )
5721 TestRegExInteractive();
5722 }
5723 #endif // TEST_REGEX
5724
5725 #ifdef TEST_REGISTRY
5726 TestRegistryRead();
5727 TestRegistryAssociation();
5728 #endif // TEST_REGISTRY
5729
5730 #ifdef TEST_SOCKETS
5731 TestSocketServer();
5732 TestSocketClient();
5733 #endif // TEST_SOCKETS
5734
5735 #ifdef TEST_STREAMS
5736 TestFileStream();
5737 TestMemoryStream();
5738 #endif // TEST_STREAMS
5739
5740 #ifdef TEST_THREADS
5741 int nCPUs = wxThread::GetCPUCount();
5742 printf("This system has %d CPUs\n", nCPUs);
5743 if ( nCPUs != -1 )
5744 wxThread::SetConcurrency(nCPUs);
5745
5746 if ( TEST_ALL )
5747 {
5748 TestDetachedThreads();
5749 TestJoinableThreads();
5750 TestThreadSuspend();
5751 TestThreadDelete();
5752 }
5753
5754 TestThreadConditions();
5755 #endif // TEST_THREADS
5756
5757 #ifdef TEST_TIMER
5758 TestStopWatch();
5759 #endif // TEST_TIMER
5760
5761 #ifdef TEST_DATETIME
5762 if ( TEST_ALL )
5763 {
5764 TestTimeSet();
5765 TestTimeStatic();
5766 TestTimeRange();
5767 TestTimeZones();
5768 TestTimeTicks();
5769 TestTimeJDN();
5770 TestTimeDST();
5771 TestTimeWDays();
5772 TestTimeWNumber();
5773 TestTimeParse();
5774 TestTimeArithmetics();
5775 TestTimeHolidays();
5776 TestTimeFormat();
5777 TestTimeSpanFormat();
5778 TestTimeMS();
5779
5780 TestTimeZoneBug();
5781 }
5782
5783 if ( TEST_INTERACTIVE )
5784 TestDateTimeInteractive();
5785 #endif // TEST_DATETIME
5786
5787 #ifdef TEST_USLEEP
5788 puts("Sleeping for 3 seconds... z-z-z-z-z...");
5789 wxUsleep(3000);
5790 #endif // TEST_USLEEP
5791
5792 #ifdef TEST_VCARD
5793 TestVCardRead();
5794 TestVCardWrite();
5795 #endif // TEST_VCARD
5796
5797 #ifdef TEST_WCHAR
5798 TestUtf8();
5799 #endif // TEST_WCHAR
5800
5801 #ifdef TEST_ZIP
5802 TestZipStreamRead();
5803 TestZipFileSystem();
5804 #endif // TEST_ZIP
5805
5806 #ifdef TEST_ZLIB
5807 TestZlibStreamWrite();
5808 TestZlibStreamRead();
5809 #endif // TEST_ZLIB
5810
5811 return 0;
5812 }
5813