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