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