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