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