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