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