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