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