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