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