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