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