added printf() test suite
[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 <float.h>
2490
2491 static void rfg1 (void);
2492 static void rfg2 (void);
2493
2494
2495 static void
2496 fmtchk (const wxChar *fmt)
2497 {
2498 (void) wxPrintf(_T("%s:\t`"), fmt);
2499 (void) wxPrintf(fmt, 0x12);
2500 (void) wxPrintf(_T("'\n"));
2501 }
2502
2503 static void
2504 fmtst1chk (const wxChar *fmt)
2505 {
2506 (void) wxPrintf(_T("%s:\t`"), fmt);
2507 (void) wxPrintf(fmt, 4, 0x12);
2508 (void) wxPrintf(_T("'\n"));
2509 }
2510
2511 static void
2512 fmtst2chk (const wxChar *fmt)
2513 {
2514 (void) wxPrintf(_T("%s:\t`"), fmt);
2515 (void) wxPrintf(fmt, 4, 4, 0x12);
2516 (void) wxPrintf(_T("'\n"));
2517 }
2518
2519 /* This page is covered by the following copyright: */
2520
2521 /* (C) Copyright C E Chew
2522 *
2523 * Feel free to copy, use and distribute this software provided:
2524 *
2525 * 1. you do not pretend that you wrote it
2526 * 2. you leave this copyright notice intact.
2527 */
2528
2529 /*
2530 * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
2531 */
2532
2533 #define DEC -123
2534 #define INT 255
2535 #define UNS (~0)
2536
2537 /* Formatted Output Test
2538 *
2539 * This exercises the output formatting code.
2540 */
2541
2542 static void
2543 fp_test (void)
2544 {
2545 int i, j, k, l;
2546 wxChar buf[7];
2547 wxChar *prefix = buf;
2548 wxChar tp[20];
2549
2550 wxPuts(_T("\nFormatted output test"));
2551 wxPrintf(_T("prefix 6d 6o 6x 6X 6u\n"));
2552 wxStrcpy(prefix, _T("%"));
2553 for (i = 0; i < 2; i++) {
2554 for (j = 0; j < 2; j++) {
2555 for (k = 0; k < 2; k++) {
2556 for (l = 0; l < 2; l++) {
2557 wxStrcpy(prefix, _T("%"));
2558 if (i == 0) wxStrcat(prefix, _T("-"));
2559 if (j == 0) wxStrcat(prefix, _T("+"));
2560 if (k == 0) wxStrcat(prefix, _T("#"));
2561 if (l == 0) wxStrcat(prefix, _T("0"));
2562 wxPrintf(_T("%5s |"), prefix);
2563 wxStrcpy(tp, prefix);
2564 wxStrcat(tp, _T("6d |"));
2565 wxPrintf(tp, DEC);
2566 wxStrcpy(tp, prefix);
2567 wxStrcat(tp, _T("6o |"));
2568 wxPrintf(tp, INT);
2569 wxStrcpy(tp, prefix);
2570 wxStrcat(tp, _T("6x |"));
2571 wxPrintf(tp, INT);
2572 wxStrcpy(tp, prefix);
2573 wxStrcat(tp, _T("6X |"));
2574 wxPrintf(tp, INT);
2575 wxStrcpy(tp, prefix);
2576 wxStrcat(tp, _T("6u |"));
2577 wxPrintf(tp, UNS);
2578 wxPrintf(_T("\n"));
2579 }
2580 }
2581 }
2582 }
2583 wxPrintf(_T("%10s\n"), (wxChar *) NULL);
2584 wxPrintf(_T("%-10s\n"), (wxChar *) NULL);
2585 }
2586
2587 static void TestPrintf()
2588 {
2589 static wxChar shortstr[] = _T("Hi, Z.");
2590 static wxChar longstr[] = "Good morning, Doctor Chandra. This is Hal. \
2591 I am ready for my first lesson today.";
2592 int result = 0;
2593
2594 fmtchk(_T("%.4x"));
2595 fmtchk(_T("%04x"));
2596 fmtchk(_T("%4.4x"));
2597 fmtchk(_T("%04.4x"));
2598 fmtchk(_T("%4.3x"));
2599 fmtchk(_T("%04.3x"));
2600
2601 fmtst1chk(_T("%.*x"));
2602 fmtst1chk(_T("%0*x"));
2603 fmtst2chk(_T("%*.*x"));
2604 fmtst2chk(_T("%0*.*x"));
2605
2606 wxPrintf(_T("bad format:\t\"%b\"\n"));
2607 wxPrintf(_T("nil pointer (padded):\t\"%10p\"\n"), (void *) NULL);
2608
2609 wxPrintf(_T("decimal negative:\t\"%d\"\n"), -2345);
2610 wxPrintf(_T("octal negative:\t\"%o\"\n"), -2345);
2611 wxPrintf(_T("hex negative:\t\"%x\"\n"), -2345);
2612 wxPrintf(_T("long decimal number:\t\"%ld\"\n"), -123456L);
2613 wxPrintf(_T("long octal negative:\t\"%lo\"\n"), -2345L);
2614 wxPrintf(_T("long unsigned decimal number:\t\"%lu\"\n"), -123456L);
2615 wxPrintf(_T("zero-padded LDN:\t\"%010ld\"\n"), -123456L);
2616 wxPrintf(_T("left-adjusted ZLDN:\t\"%-010ld\"\n"), -123456);
2617 wxPrintf(_T("space-padded LDN:\t\"%10ld\"\n"), -123456L);
2618 wxPrintf(_T("left-adjusted SLDN:\t\"%-10ld\"\n"), -123456L);
2619
2620 wxPrintf(_T("zero-padded string:\t\"%010s\"\n"), shortstr);
2621 wxPrintf(_T("left-adjusted Z string:\t\"%-010s\"\n"), shortstr);
2622 wxPrintf(_T("space-padded string:\t\"%10s\"\n"), shortstr);
2623 wxPrintf(_T("left-adjusted S string:\t\"%-10s\"\n"), shortstr);
2624 wxPrintf(_T("null string:\t\"%s\"\n"), (wxChar *)NULL);
2625 wxPrintf(_T("limited string:\t\"%.22s\"\n"), longstr);
2626
2627 wxPrintf(_T("e-style >= 1:\t\"%e\"\n"), 12.34);
2628 wxPrintf(_T("e-style >= .1:\t\"%e\"\n"), 0.1234);
2629 wxPrintf(_T("e-style < .1:\t\"%e\"\n"), 0.001234);
2630 wxPrintf(_T("e-style big:\t\"%.60e\"\n"), 1e20);
2631 wxPrintf(_T("e-style == .1:\t\"%e\"\n"), 0.1);
2632 wxPrintf(_T("f-style >= 1:\t\"%f\"\n"), 12.34);
2633 wxPrintf(_T("f-style >= .1:\t\"%f\"\n"), 0.1234);
2634 wxPrintf(_T("f-style < .1:\t\"%f\"\n"), 0.001234);
2635 wxPrintf(_T("g-style >= 1:\t\"%g\"\n"), 12.34);
2636 wxPrintf(_T("g-style >= .1:\t\"%g\"\n"), 0.1234);
2637 wxPrintf(_T("g-style < .1:\t\"%g\"\n"), 0.001234);
2638 wxPrintf(_T("g-style big:\t\"%.60g\"\n"), 1e20);
2639
2640 wxPrintf (_T(" %6.5f\n"), .099999999860301614);
2641 wxPrintf (_T(" %6.5f\n"), .1);
2642 wxPrintf (_T("x%5.4fx\n"), .5);
2643
2644 wxPrintf (_T("%#03x\n"), 1);
2645
2646 //wxPrintf (_T("something really insane: %.10000f\n"), 1.0);
2647
2648 {
2649 double d = FLT_MIN;
2650 int niter = 17;
2651
2652 while (niter-- != 0)
2653 wxPrintf (_T("%.17e\n"), d / 2);
2654 fflush (stdout);
2655 }
2656
2657 wxPrintf (_T("%15.5e\n"), 4.9406564584124654e-324);
2658
2659 #define FORMAT _T("|%12.4f|%12.4e|%12.4g|\n")
2660 wxPrintf (FORMAT, 0.0, 0.0, 0.0);
2661 wxPrintf (FORMAT, 1.0, 1.0, 1.0);
2662 wxPrintf (FORMAT, -1.0, -1.0, -1.0);
2663 wxPrintf (FORMAT, 100.0, 100.0, 100.0);
2664 wxPrintf (FORMAT, 1000.0, 1000.0, 1000.0);
2665 wxPrintf (FORMAT, 10000.0, 10000.0, 10000.0);
2666 wxPrintf (FORMAT, 12345.0, 12345.0, 12345.0);
2667 wxPrintf (FORMAT, 100000.0, 100000.0, 100000.0);
2668 wxPrintf (FORMAT, 123456.0, 123456.0, 123456.0);
2669 #undef FORMAT
2670
2671 {
2672 wxChar buf[20];
2673 int rc = wxSnprintf (buf, WXSIZEOF(buf), _T("%30s"), _T("foo"));
2674
2675 wxPrintf(_T("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n"),
2676 rc, WXSIZEOF(buf), buf);
2677 #if 0
2678 wxChar buf2[512];
2679 wxPrintf ("snprintf (\"%%.999999u\", 10)\n",
2680 wxSnprintf(buf2, WXSIZEOFbuf2), "%.999999u", 10));
2681 #endif
2682 }
2683
2684 fp_test ();
2685
2686 wxPrintf (_T("%e should be 1.234568e+06\n"), 1234567.8);
2687 wxPrintf (_T("%f should be 1234567.800000\n"), 1234567.8);
2688 wxPrintf (_T("%g should be 1.23457e+06\n"), 1234567.8);
2689 wxPrintf (_T("%g should be 123.456\n"), 123.456);
2690 wxPrintf (_T("%g should be 1e+06\n"), 1000000.0);
2691 wxPrintf (_T("%g should be 10\n"), 10.0);
2692 wxPrintf (_T("%g should be 0.02\n"), 0.02);
2693
2694 {
2695 double x=1.0;
2696 wxPrintf(_T("%.17f\n"),(1.0/x/10.0+1.0)*x-x);
2697 }
2698
2699 {
2700 wxChar buf[200];
2701
2702 wxSprintf(buf,_T("%*s%*s%*s"),-1,_T("one"),-20,_T("two"),-30,_T("three"));
2703
2704 result |= wxStrcmp (buf,
2705 _T("onetwo three "));
2706
2707 wxPuts (result != 0 ? _T("Test failed!") : _T("Test ok."));
2708 }
2709
2710 {
2711 wxChar buf[200];
2712
2713 wxSprintf (buf, _T("%07Lo"), 040000000000ll);
2714 wxPrintf (_T("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s"), buf);
2715
2716 if (wxStrcmp (buf, _T("40000000000")) != 0)
2717 {
2718 result = 1;
2719 wxPuts (_T("\tFAILED"));
2720 }
2721 wxPuts ("");
2722 }
2723
2724 wxPrintf (_T("printf (\"%%hhu\", %u) = %hhu\n"), UCHAR_MAX + 2, UCHAR_MAX + 2);
2725 wxPrintf (_T("printf (\"%%hu\", %u) = %hu\n"), USHRT_MAX + 2, USHRT_MAX + 2);
2726
2727 wxPuts (_T("--- Should be no further output. ---"));
2728 rfg1 ();
2729 rfg2 ();
2730
2731 #if 0
2732 {
2733 wxChar bytes[7];
2734 wxChar buf[20];
2735
2736 memset (bytes, '\xff', sizeof bytes);
2737 wxSprintf (buf, _T("foo%hhn\n"), &bytes[3]);
2738 if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
2739 || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
2740 {
2741 wxPuts (_T("%hhn overwrite more bytes"));
2742 result = 1;
2743 }
2744 if (bytes[3] != 3)
2745 {
2746 wxPuts (_T("%hhn wrote incorrect value"));
2747 result = 1;
2748 }
2749 }
2750 #endif
2751 }
2752
2753 static void
2754 rfg1 (void)
2755 {
2756 wxChar buf[100];
2757
2758 wxSprintf (buf, _T("%5.s"), _T("xyz"));
2759 if (wxStrcmp (buf, _T(" ")) != 0)
2760 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" "));
2761 wxSprintf (buf, _T("%5.f"), 33.3);
2762 if (wxStrcmp (buf, _T(" 33")) != 0)
2763 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 33"));
2764 wxSprintf (buf, _T("%8.e"), 33.3e7);
2765 if (wxStrcmp (buf, _T(" 3e+08")) != 0)
2766 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3e+08"));
2767 wxSprintf (buf, _T("%8.E"), 33.3e7);
2768 if (wxStrcmp (buf, _T(" 3E+08")) != 0)
2769 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3E+08"));
2770 wxSprintf (buf, _T("%.g"), 33.3);
2771 if (wxStrcmp (buf, _T("3e+01")) != 0)
2772 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3e+01"));
2773 wxSprintf (buf, _T("%.G"), 33.3);
2774 if (wxStrcmp (buf, _T("3E+01")) != 0)
2775 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3E+01"));
2776 }
2777
2778 static void
2779 rfg2 (void)
2780 {
2781 int prec;
2782 wxChar buf[100];
2783
2784 prec = 0;
2785 wxSprintf (buf, _T("%.*g"), prec, 3.3);
2786 if (wxStrcmp (buf, _T("3")) != 0)
2787 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
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("%7.*G"), prec, 3.33);
2794 if (wxStrcmp (buf, _T(" 3")) != 0)
2795 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 3"));
2796 prec = 3;
2797 wxSprintf (buf, _T("%04.*o"), prec, 33);
2798 if (wxStrcmp (buf, _T(" 041")) != 0)
2799 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 041"));
2800 prec = 7;
2801 wxSprintf (buf, _T("%09.*u"), prec, 33);
2802 if (wxStrcmp (buf, _T(" 0000033")) != 0)
2803 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 0000033"));
2804 prec = 3;
2805 wxSprintf (buf, _T("%04.*x"), prec, 33);
2806 if (wxStrcmp (buf, _T(" 021")) != 0)
2807 wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
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 }
2813
2814 #endif // TEST_PRINTF
2815
2816 // ----------------------------------------------------------------------------
2817 // registry and related stuff
2818 // ----------------------------------------------------------------------------
2819
2820 // this is for MSW only
2821 #ifndef __WXMSW__
2822 #undef TEST_REGCONF
2823 #undef TEST_REGISTRY
2824 #endif
2825
2826 #ifdef TEST_REGCONF
2827
2828 #include "wx/confbase.h"
2829 #include "wx/msw/regconf.h"
2830
2831 static void TestRegConfWrite()
2832 {
2833 wxRegConfig regconf(_T("console"), _T("wxwindows"));
2834 regconf.Write(_T("Hello"), wxString(_T("world")));
2835 }
2836
2837 #endif // TEST_REGCONF
2838
2839 #ifdef TEST_REGISTRY
2840
2841 #include "wx/msw/registry.h"
2842
2843 // I chose this one because I liked its name, but it probably only exists under
2844 // NT
2845 static const wxChar *TESTKEY =
2846 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2847
2848 static void TestRegistryRead()
2849 {
2850 wxPuts(_T("*** testing registry reading ***"));
2851
2852 wxRegKey key(TESTKEY);
2853 wxPrintf(_T("The test key name is '%s'.\n"), key.GetName().c_str());
2854 if ( !key.Open() )
2855 {
2856 wxPuts(_T("ERROR: test key can't be opened, aborting test."));
2857
2858 return;
2859 }
2860
2861 size_t nSubKeys, nValues;
2862 if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2863 {
2864 wxPrintf(_T("It has %u subkeys and %u values.\n"), nSubKeys, nValues);
2865 }
2866
2867 wxPrintf(_T("Enumerating values:\n"));
2868
2869 long dummy;
2870 wxString value;
2871 bool cont = key.GetFirstValue(value, dummy);
2872 while ( cont )
2873 {
2874 wxPrintf(_T("Value '%s': type "), value.c_str());
2875 switch ( key.GetValueType(value) )
2876 {
2877 case wxRegKey::Type_None: wxPrintf(_T("ERROR (none)")); break;
2878 case wxRegKey::Type_String: wxPrintf(_T("SZ")); break;
2879 case wxRegKey::Type_Expand_String: wxPrintf(_T("EXPAND_SZ")); break;
2880 case wxRegKey::Type_Binary: wxPrintf(_T("BINARY")); break;
2881 case wxRegKey::Type_Dword: wxPrintf(_T("DWORD")); break;
2882 case wxRegKey::Type_Multi_String: wxPrintf(_T("MULTI_SZ")); break;
2883 default: wxPrintf(_T("other (unknown)")); break;
2884 }
2885
2886 wxPrintf(_T(", value = "));
2887 if ( key.IsNumericValue(value) )
2888 {
2889 long val;
2890 key.QueryValue(value, &val);
2891 wxPrintf(_T("%ld"), val);
2892 }
2893 else // string
2894 {
2895 wxString val;
2896 key.QueryValue(value, val);
2897 wxPrintf(_T("'%s'"), val.c_str());
2898
2899 key.QueryRawValue(value, val);
2900 wxPrintf(_T(" (raw value '%s')"), val.c_str());
2901 }
2902
2903 putchar('\n');
2904
2905 cont = key.GetNextValue(value, dummy);
2906 }
2907 }
2908
2909 static void TestRegistryAssociation()
2910 {
2911 /*
2912 The second call to deleteself genertaes an error message, with a
2913 messagebox saying .flo is crucial to system operation, while the .ddf
2914 call also fails, but with no error message
2915 */
2916
2917 wxRegKey key;
2918
2919 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2920 key.Create();
2921 key = "ddxf_auto_file" ;
2922 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2923 key.Create();
2924 key = "ddxf_auto_file" ;
2925 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2926 key.Create();
2927 key = "program,0" ;
2928 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2929 key.Create();
2930 key = "program \"%1\"" ;
2931
2932 key.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2933 key.DeleteSelf();
2934 key.SetName("HKEY_CLASSES_ROOT\\.flo" );
2935 key.DeleteSelf();
2936 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2937 key.DeleteSelf();
2938 key.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2939 key.DeleteSelf();
2940 }
2941
2942 #endif // TEST_REGISTRY
2943
2944 // ----------------------------------------------------------------------------
2945 // sockets
2946 // ----------------------------------------------------------------------------
2947
2948 #ifdef TEST_SOCKETS
2949
2950 #include "wx/socket.h"
2951 #include "wx/protocol/protocol.h"
2952 #include "wx/protocol/http.h"
2953
2954 static void TestSocketServer()
2955 {
2956 wxPuts(_T("*** Testing wxSocketServer ***\n"));
2957
2958 static const int PORT = 3000;
2959
2960 wxIPV4address addr;
2961 addr.Service(PORT);
2962
2963 wxSocketServer *server = new wxSocketServer(addr);
2964 if ( !server->Ok() )
2965 {
2966 wxPuts(_T("ERROR: failed to bind"));
2967
2968 return;
2969 }
2970
2971 for ( ;; )
2972 {
2973 wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT);
2974
2975 wxSocketBase *socket = server->Accept();
2976 if ( !socket )
2977 {
2978 wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
2979 break;
2980 }
2981
2982 wxPuts(_T("Server: got a client."));
2983
2984 server->SetTimeout(60); // 1 min
2985
2986 while ( socket->IsConnected() )
2987 {
2988 wxString s;
2989 wxChar ch = _T('\0');
2990 for ( ;; )
2991 {
2992 if ( socket->Read(&ch, sizeof(ch)).Error() )
2993 {
2994 // don't log error if the client just close the connection
2995 if ( socket->IsConnected() )
2996 {
2997 wxPuts(_T("ERROR: in wxSocket::Read."));
2998 }
2999
3000 break;
3001 }
3002
3003 if ( ch == '\r' )
3004 continue;
3005
3006 if ( ch == '\n' )
3007 break;
3008
3009 s += ch;
3010 }
3011
3012 if ( ch != '\n' )
3013 {
3014 break;
3015 }
3016
3017 wxPrintf(_T("Server: got '%s'.\n"), s.c_str());
3018 if ( s == _T("bye") )
3019 {
3020 delete socket;
3021
3022 break;
3023 }
3024
3025 socket->Write(s.MakeUpper().c_str(), s.length());
3026 socket->Write("\r\n", 2);
3027 wxPrintf(_T("Server: wrote '%s'.\n"), s.c_str());
3028 }
3029
3030 wxPuts(_T("Server: lost a client."));
3031
3032 socket->Destroy();
3033 }
3034
3035 // same as "delete server" but is consistent with GUI programs
3036 server->Destroy();
3037 }
3038
3039 static void TestSocketClient()
3040 {
3041 wxPuts(_T("*** Testing wxSocketClient ***\n"));
3042
3043 static const wxChar *hostname = _T("www.wxwindows.org");
3044
3045 wxIPV4address addr;
3046 addr.Hostname(hostname);
3047 addr.Service(80);
3048
3049 wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname);
3050
3051 wxSocketClient client;
3052 if ( !client.Connect(addr) )
3053 {
3054 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
3055 }
3056 else
3057 {
3058 wxPrintf(_T("--- Connected to %s:%u...\n"),
3059 addr.Hostname().c_str(), addr.Service());
3060
3061 wxChar buf[8192];
3062
3063 // could use simply "GET" here I suppose
3064 wxString cmdGet =
3065 wxString::Format(_T("GET http://%s/\r\n"), hostname);
3066 client.Write(cmdGet, cmdGet.length());
3067 wxPrintf(_T("--- Sent command '%s' to the server\n"),
3068 MakePrintable(cmdGet).c_str());
3069 client.Read(buf, WXSIZEOF(buf));
3070 wxPrintf(_T("--- Server replied:\n%s"), buf);
3071 }
3072 }
3073
3074 #endif // TEST_SOCKETS
3075
3076 // ----------------------------------------------------------------------------
3077 // FTP
3078 // ----------------------------------------------------------------------------
3079
3080 #ifdef TEST_FTP
3081
3082 #include "wx/protocol/ftp.h"
3083
3084 static wxFTP ftp;
3085
3086 #define FTP_ANONYMOUS
3087
3088 #ifdef FTP_ANONYMOUS
3089 static const wxChar *directory = _T("/pub");
3090 static const wxChar *filename = _T("welcome.msg");
3091 #else
3092 static const wxChar *directory = _T("/etc");
3093 static const wxChar *filename = _T("issue");
3094 #endif
3095
3096 static bool TestFtpConnect()
3097 {
3098 wxPuts(_T("*** Testing FTP connect ***"));
3099
3100 #ifdef FTP_ANONYMOUS
3101 static const wxChar *hostname = _T("ftp.wxwindows.org");
3102
3103 wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname);
3104 #else // !FTP_ANONYMOUS
3105 static const wxChar *hostname = "localhost";
3106
3107 wxChar user[256];
3108 wxFgets(user, WXSIZEOF(user), stdin);
3109 user[wxStrlen(user) - 1] = '\0'; // chop off '\n'
3110 ftp.SetUser(user);
3111
3112 wxChar password[256];
3113 wxPrintf(_T("Password for %s: "), password);
3114 wxFgets(password, WXSIZEOF(password), stdin);
3115 password[wxStrlen(password) - 1] = '\0'; // chop off '\n'
3116 ftp.SetPassword(password);
3117
3118 wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname, user);
3119 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
3120
3121 if ( !ftp.Connect(hostname) )
3122 {
3123 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
3124
3125 return FALSE;
3126 }
3127 else
3128 {
3129 wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
3130 hostname, ftp.Pwd().c_str());
3131 }
3132
3133 return TRUE;
3134 }
3135
3136 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
3137 static void TestFtpWuFtpd()
3138 {
3139 wxFTP ftp;
3140 static const wxChar *hostname = _T("ftp.eudora.com");
3141 if ( !ftp.Connect(hostname) )
3142 {
3143 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
3144 }
3145 else
3146 {
3147 static const wxChar *filename = _T("eudora/pubs/draft-gellens-submit-09.txt");
3148 wxInputStream *in = ftp.GetInputStream(filename);
3149 if ( !in )
3150 {
3151 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
3152 }
3153 else
3154 {
3155 size_t size = in->StreamSize();
3156 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
3157
3158 wxChar *data = new wxChar[size];
3159 if ( !in->Read(data, size) )
3160 {
3161 wxPuts(_T("ERROR: read error"));
3162 }
3163 else
3164 {
3165 wxPrintf(_T("Successfully retrieved the file.\n"));
3166 }
3167
3168 delete [] data;
3169 delete in;
3170 }
3171 }
3172 }
3173
3174 static void TestFtpList()
3175 {
3176 wxPuts(_T("*** Testing wxFTP file listing ***\n"));
3177
3178 // test CWD
3179 if ( !ftp.ChDir(directory) )
3180 {
3181 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
3182 }
3183
3184 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
3185
3186 // test NLIST and LIST
3187 wxArrayString files;
3188 if ( !ftp.GetFilesList(files) )
3189 {
3190 wxPuts(_T("ERROR: failed to get NLIST of files"));
3191 }
3192 else
3193 {
3194 wxPrintf(_T("Brief list of files under '%s':\n"), ftp.Pwd().c_str());
3195 size_t count = files.GetCount();
3196 for ( size_t n = 0; n < count; n++ )
3197 {
3198 wxPrintf(_T("\t%s\n"), files[n].c_str());
3199 }
3200 wxPuts(_T("End of the file list"));
3201 }
3202
3203 if ( !ftp.GetDirList(files) )
3204 {
3205 wxPuts(_T("ERROR: failed to get LIST of files"));
3206 }
3207 else
3208 {
3209 wxPrintf(_T("Detailed list of files under '%s':\n"), ftp.Pwd().c_str());
3210 size_t count = files.GetCount();
3211 for ( size_t n = 0; n < count; n++ )
3212 {
3213 wxPrintf(_T("\t%s\n"), files[n].c_str());
3214 }
3215 wxPuts(_T("End of the file list"));
3216 }
3217
3218 if ( !ftp.ChDir(_T("..")) )
3219 {
3220 wxPuts(_T("ERROR: failed to cd to .."));
3221 }
3222
3223 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
3224 }
3225
3226 static void TestFtpDownload()
3227 {
3228 wxPuts(_T("*** Testing wxFTP download ***\n"));
3229
3230 // test RETR
3231 wxInputStream *in = ftp.GetInputStream(filename);
3232 if ( !in )
3233 {
3234 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
3235 }
3236 else
3237 {
3238 size_t size = in->StreamSize();
3239 wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
3240 fflush(stdout);
3241
3242 wxChar *data = new wxChar[size];
3243 if ( !in->Read(data, size) )
3244 {
3245 wxPuts(_T("ERROR: read error"));
3246 }
3247 else
3248 {
3249 wxPrintf(_T("\nContents of %s:\n%s\n"), filename, data);
3250 }
3251
3252 delete [] data;
3253 delete in;
3254 }
3255 }
3256
3257 static void TestFtpFileSize()
3258 {
3259 wxPuts(_T("*** Testing FTP SIZE command ***"));
3260
3261 if ( !ftp.ChDir(directory) )
3262 {
3263 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
3264 }
3265
3266 wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
3267
3268 if ( ftp.FileExists(filename) )
3269 {
3270 int size = ftp.GetFileSize(filename);
3271 if ( size == -1 )
3272 wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename);
3273 else
3274 wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename, size);
3275 }
3276 else
3277 {
3278 wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename);
3279 }
3280 }
3281
3282 static void TestFtpMisc()
3283 {
3284 wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
3285
3286 if ( ftp.SendCommand("STAT") != '2' )
3287 {
3288 wxPuts(_T("ERROR: STAT failed"));
3289 }
3290 else
3291 {
3292 wxPrintf(_T("STAT returned:\n\n%s\n"), ftp.GetLastResult().c_str());
3293 }
3294
3295 if ( ftp.SendCommand("HELP SITE") != '2' )
3296 {
3297 wxPuts(_T("ERROR: HELP SITE failed"));
3298 }
3299 else
3300 {
3301 wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
3302 ftp.GetLastResult().c_str());
3303 }
3304 }
3305
3306 static void TestFtpInteractive()
3307 {
3308 wxPuts(_T("\n*** Interactive wxFTP test ***"));
3309
3310 wxChar buf[128];
3311
3312 for ( ;; )
3313 {
3314 wxPrintf(_T("Enter FTP command: "));
3315 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
3316 break;
3317
3318 // kill the last '\n'
3319 buf[wxStrlen(buf) - 1] = 0;
3320
3321 // special handling of LIST and NLST as they require data connection
3322 wxString start(buf, 4);
3323 start.MakeUpper();
3324 if ( start == "LIST" || start == "NLST" )
3325 {
3326 wxString wildcard;
3327 if ( wxStrlen(buf) > 4 )
3328 wildcard = buf + 5;
3329
3330 wxArrayString files;
3331 if ( !ftp.GetList(files, wildcard, start == "LIST") )
3332 {
3333 wxPrintf(_T("ERROR: failed to get %s of files\n"), start.c_str());
3334 }
3335 else
3336 {
3337 wxPrintf(_T("--- %s of '%s' under '%s':\n"),
3338 start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
3339 size_t count = files.GetCount();
3340 for ( size_t n = 0; n < count; n++ )
3341 {
3342 wxPrintf(_T("\t%s\n"), files[n].c_str());
3343 }
3344 wxPuts(_T("--- End of the file list"));
3345 }
3346 }
3347 else // !list
3348 {
3349 wxChar ch = ftp.SendCommand(buf);
3350 wxPrintf(_T("Command %s"), ch ? _T("succeeded") : _T("failed"));
3351 if ( ch )
3352 {
3353 wxPrintf(_T(" (return code %c)"), ch);
3354 }
3355
3356 wxPrintf(_T(", server reply:\n%s\n\n"), ftp.GetLastResult().c_str());
3357 }
3358 }
3359
3360 wxPuts(_T("\n*** done ***"));
3361 }
3362
3363 static void TestFtpUpload()
3364 {
3365 wxPuts(_T("*** Testing wxFTP uploading ***\n"));
3366
3367 // upload a file
3368 static const wxChar *file1 = _T("test1");
3369 static const wxChar *file2 = _T("test2");
3370 wxOutputStream *out = ftp.GetOutputStream(file1);
3371 if ( out )
3372 {
3373 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
3374 out->Write("First hello", 11);
3375 delete out;
3376 }
3377
3378 // send a command to check the remote file
3379 if ( ftp.SendCommand(wxString("STAT ") + file1) != '2' )
3380 {
3381 wxPrintf(_T("ERROR: STAT %s failed\n"), file1);
3382 }
3383 else
3384 {
3385 wxPrintf(_T("STAT %s returned:\n\n%s\n"),
3386 file1, ftp.GetLastResult().c_str());
3387 }
3388
3389 out = ftp.GetOutputStream(file2);
3390 if ( out )
3391 {
3392 wxPrintf(_T("--- Uploading to %s ---\n"), file1);
3393 out->Write("Second hello", 12);
3394 delete out;
3395 }
3396 }
3397
3398 #endif // TEST_FTP
3399
3400 // ----------------------------------------------------------------------------
3401 // streams
3402 // ----------------------------------------------------------------------------
3403
3404 #ifdef TEST_STREAMS
3405
3406 #include "wx/wfstream.h"
3407 #include "wx/mstream.h"
3408
3409 static void TestFileStream()
3410 {
3411 wxPuts(_T("*** Testing wxFileInputStream ***"));
3412
3413 static const wxChar *filename = _T("testdata.fs");
3414 {
3415 wxFileOutputStream fsOut(filename);
3416 fsOut.Write("foo", 3);
3417 }
3418
3419 wxFileInputStream fsIn(filename);
3420 wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
3421 while ( !fsIn.Eof() )
3422 {
3423 putchar(fsIn.GetC());
3424 }
3425
3426 if ( !wxRemoveFile(filename) )
3427 {
3428 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename);
3429 }
3430
3431 wxPuts(_T("\n*** wxFileInputStream test done ***"));
3432 }
3433
3434 static void TestMemoryStream()
3435 {
3436 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
3437
3438 wxMemoryOutputStream memOutStream;
3439 wxPrintf(_T("Initially out stream offset: %lu\n"),
3440 (unsigned long)memOutStream.TellO());
3441
3442 for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
3443 {
3444 memOutStream.PutC(*p);
3445 }
3446
3447 wxPrintf(_T("Final out stream offset: %lu\n"),
3448 (unsigned long)memOutStream.TellO());
3449
3450 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
3451
3452 wxChar buf[1024];
3453 size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
3454
3455 wxMemoryInputStream memInpStream(buf, len);
3456 wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
3457 while ( !memInpStream.Eof() )
3458 {
3459 putchar(memInpStream.GetC());
3460 }
3461
3462 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
3463 }
3464
3465 #endif // TEST_STREAMS
3466
3467 // ----------------------------------------------------------------------------
3468 // timers
3469 // ----------------------------------------------------------------------------
3470
3471 #ifdef TEST_TIMER
3472
3473 #include "wx/timer.h"
3474 #include "wx/utils.h"
3475
3476 static void TestStopWatch()
3477 {
3478 wxPuts(_T("*** Testing wxStopWatch ***\n"));
3479
3480 wxStopWatch sw;
3481 sw.Pause();
3482 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
3483 fflush(stdout);
3484 wxSleep(2);
3485 wxPrintf(_T("\t%ldms\n"), sw.Time());
3486
3487 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
3488 fflush(stdout);
3489 sw.Resume();
3490 wxSleep(3);
3491 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
3492
3493 sw.Pause();
3494 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
3495 fflush(stdout);
3496 wxSleep(2);
3497 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
3498
3499 sw.Resume();
3500 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
3501 fflush(stdout);
3502 wxSleep(2);
3503 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
3504
3505 wxStopWatch sw2;
3506 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
3507 for ( size_t n = 0; n < 70; n++ )
3508 {
3509 sw2.Start();
3510
3511 for ( size_t m = 0; m < 100000; m++ )
3512 {
3513 if ( sw.Time() < 0 || sw2.Time() < 0 )
3514 {
3515 wxPuts(_T("\ntime is negative - ERROR!"));
3516 }
3517 }
3518
3519 putchar('.');
3520 fflush(stdout);
3521 }
3522
3523 wxPuts(_T(", ok."));
3524 }
3525
3526 #endif // TEST_TIMER
3527
3528 // ----------------------------------------------------------------------------
3529 // vCard support
3530 // ----------------------------------------------------------------------------
3531
3532 #ifdef TEST_VCARD
3533
3534 #include "wx/vcard.h"
3535
3536 static void DumpVObject(size_t level, const wxVCardObject& vcard)
3537 {
3538 void *cookie;
3539 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
3540 while ( vcObj )
3541 {
3542 wxPrintf(_T("%s%s"),
3543 wxString(_T('\t'), level).c_str(),
3544 vcObj->GetName().c_str());
3545
3546 wxString value;
3547 switch ( vcObj->GetType() )
3548 {
3549 case wxVCardObject::String:
3550 case wxVCardObject::UString:
3551 {
3552 wxString val;
3553 vcObj->GetValue(&val);
3554 value << _T('"') << val << _T('"');
3555 }
3556 break;
3557
3558 case wxVCardObject::Int:
3559 {
3560 unsigned int i;
3561 vcObj->GetValue(&i);
3562 value.Printf(_T("%u"), i);
3563 }
3564 break;
3565
3566 case wxVCardObject::Long:
3567 {
3568 unsigned long l;
3569 vcObj->GetValue(&l);
3570 value.Printf(_T("%lu"), l);
3571 }
3572 break;
3573
3574 case wxVCardObject::None:
3575 break;
3576
3577 case wxVCardObject::Object:
3578 value = _T("<node>");
3579 break;
3580
3581 default:
3582 value = _T("<unknown value type>");
3583 }
3584
3585 if ( !!value )
3586 wxPrintf(_T(" = %s"), value.c_str());
3587 putchar('\n');
3588
3589 DumpVObject(level + 1, *vcObj);
3590
3591 delete vcObj;
3592 vcObj = vcard.GetNextProp(&cookie);
3593 }
3594 }
3595
3596 static void DumpVCardAddresses(const wxVCard& vcard)
3597 {
3598 wxPuts(_T("\nShowing all addresses from vCard:\n"));
3599
3600 size_t nAdr = 0;
3601 void *cookie;
3602 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3603 while ( addr )
3604 {
3605 wxString flagsStr;
3606 int flags = addr->GetFlags();
3607 if ( flags & wxVCardAddress::Domestic )
3608 {
3609 flagsStr << _T("domestic ");
3610 }
3611 if ( flags & wxVCardAddress::Intl )
3612 {
3613 flagsStr << _T("international ");
3614 }
3615 if ( flags & wxVCardAddress::Postal )
3616 {
3617 flagsStr << _T("postal ");
3618 }
3619 if ( flags & wxVCardAddress::Parcel )
3620 {
3621 flagsStr << _T("parcel ");
3622 }
3623 if ( flags & wxVCardAddress::Home )
3624 {
3625 flagsStr << _T("home ");
3626 }
3627 if ( flags & wxVCardAddress::Work )
3628 {
3629 flagsStr << _T("work ");
3630 }
3631
3632 wxPrintf(_T("Address %u:\n")
3633 "\tflags = %s\n"
3634 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3635 ++nAdr,
3636 flagsStr.c_str(),
3637 addr->GetPostOffice().c_str(),
3638 addr->GetExtAddress().c_str(),
3639 addr->GetStreet().c_str(),
3640 addr->GetLocality().c_str(),
3641 addr->GetRegion().c_str(),
3642 addr->GetPostalCode().c_str(),
3643 addr->GetCountry().c_str()
3644 );
3645
3646 delete addr;
3647 addr = vcard.GetNextAddress(&cookie);
3648 }
3649 }
3650
3651 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3652 {
3653 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
3654
3655 size_t nPhone = 0;
3656 void *cookie;
3657 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3658 while ( phone )
3659 {
3660 wxString flagsStr;
3661 int flags = phone->GetFlags();
3662 if ( flags & wxVCardPhoneNumber::Voice )
3663 {
3664 flagsStr << _T("voice ");
3665 }
3666 if ( flags & wxVCardPhoneNumber::Fax )
3667 {
3668 flagsStr << _T("fax ");
3669 }
3670 if ( flags & wxVCardPhoneNumber::Cellular )
3671 {
3672 flagsStr << _T("cellular ");
3673 }
3674 if ( flags & wxVCardPhoneNumber::Modem )
3675 {
3676 flagsStr << _T("modem ");
3677 }
3678 if ( flags & wxVCardPhoneNumber::Home )
3679 {
3680 flagsStr << _T("home ");
3681 }
3682 if ( flags & wxVCardPhoneNumber::Work )
3683 {
3684 flagsStr << _T("work ");
3685 }
3686
3687 wxPrintf(_T("Phone number %u:\n")
3688 "\tflags = %s\n"
3689 "\tvalue = %s\n",
3690 ++nPhone,
3691 flagsStr.c_str(),
3692 phone->GetNumber().c_str()
3693 );
3694
3695 delete phone;
3696 phone = vcard.GetNextPhoneNumber(&cookie);
3697 }
3698 }
3699
3700 static void TestVCardRead()
3701 {
3702 wxPuts(_T("*** Testing wxVCard reading ***\n"));
3703
3704 wxVCard vcard(_T("vcard.vcf"));
3705 if ( !vcard.IsOk() )
3706 {
3707 wxPuts(_T("ERROR: couldn't load vCard."));
3708 }
3709 else
3710 {
3711 // read individual vCard properties
3712 wxVCardObject *vcObj = vcard.GetProperty("FN");
3713 wxString value;
3714 if ( vcObj )
3715 {
3716 vcObj->GetValue(&value);
3717 delete vcObj;
3718 }
3719 else
3720 {
3721 value = _T("<none>");
3722 }
3723
3724 wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
3725
3726
3727 if ( !vcard.GetFullName(&value) )
3728 {
3729 value = _T("<none>");
3730 }
3731
3732 wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
3733
3734 // now show how to deal with multiply occuring properties
3735 DumpVCardAddresses(vcard);
3736 DumpVCardPhoneNumbers(vcard);
3737
3738 // and finally show all
3739 wxPuts(_T("\nNow dumping the entire vCard:\n")
3740 "-----------------------------\n");
3741
3742 DumpVObject(0, vcard);
3743 }
3744 }
3745
3746 static void TestVCardWrite()
3747 {
3748 wxPuts(_T("*** Testing wxVCard writing ***\n"));
3749
3750 wxVCard vcard;
3751 if ( !vcard.IsOk() )
3752 {
3753 wxPuts(_T("ERROR: couldn't create vCard."));
3754 }
3755 else
3756 {
3757 // set some fields
3758 vcard.SetName("Zeitlin", "Vadim");
3759 vcard.SetFullName("Vadim Zeitlin");
3760 vcard.SetOrganization("wxWindows", "R&D");
3761
3762 // just dump the vCard back
3763 wxPuts(_T("Entire vCard follows:\n"));
3764 wxPuts(vcard.Write());
3765 }
3766 }
3767
3768 #endif // TEST_VCARD
3769
3770 // ----------------------------------------------------------------------------
3771 // wxVolume tests
3772 // ----------------------------------------------------------------------------
3773
3774 #if !defined(__WIN32__) || !wxUSE_FSVOLUME
3775 #undef TEST_VOLUME
3776 #endif
3777
3778 #ifdef TEST_VOLUME
3779
3780 #include "wx/volume.h"
3781
3782 static const wxChar *volumeKinds[] =
3783 {
3784 _T("floppy"),
3785 _T("hard disk"),
3786 _T("CD-ROM"),
3787 _T("DVD-ROM"),
3788 _T("network volume"),
3789 _T("other volume"),
3790 };
3791
3792 static void TestFSVolume()
3793 {
3794 wxPuts(_T("*** Testing wxFSVolume class ***"));
3795
3796 wxArrayString volumes = wxFSVolume::GetVolumes();
3797 size_t count = volumes.GetCount();
3798
3799 if ( !count )
3800 {
3801 wxPuts(_T("ERROR: no mounted volumes?"));
3802 return;
3803 }
3804
3805 wxPrintf(_T("%u mounted volumes found:\n"), count);
3806
3807 for ( size_t n = 0; n < count; n++ )
3808 {
3809 wxFSVolume vol(volumes[n]);
3810 if ( !vol.IsOk() )
3811 {
3812 wxPuts(_T("ERROR: couldn't create volume"));
3813 continue;
3814 }
3815
3816 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3817 n + 1,
3818 vol.GetDisplayName().c_str(),
3819 vol.GetName().c_str(),
3820 volumeKinds[vol.GetKind()],
3821 vol.IsWritable() ? _T("rw") : _T("ro"),
3822 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3823 : _T("fixed"));
3824 }
3825 }
3826
3827 #endif // TEST_VOLUME
3828
3829 // ----------------------------------------------------------------------------
3830 // wide char and Unicode support
3831 // ----------------------------------------------------------------------------
3832
3833 #ifdef TEST_UNICODE
3834
3835 static void TestUnicodeToFromAscii()
3836 {
3837 wxPuts(_T("Testing wxString::To/FromAscii()\n"));
3838
3839 static const char *msg = "Hello, world!";
3840 wxString s = wxString::FromAscii(msg);
3841
3842 wxPrintf(_T("Message in Unicode: %s\n"), s.c_str());
3843 printf("Message in ASCII: %s\n", (const char *)s.ToAscii());
3844
3845 wxPutchar(_T('\n'));
3846 }
3847
3848 #endif // TEST_UNICODE
3849
3850 #ifdef TEST_WCHAR
3851
3852 #include "wx/strconv.h"
3853 #include "wx/fontenc.h"
3854 #include "wx/encconv.h"
3855 #include "wx/buffer.h"
3856
3857 static const unsigned char textInUtf8_[] =
3858 {
3859 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3860 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3861 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3862 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3863 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3864 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3865 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3866 };
3867
3868 #define textInUtf8 ((const char *)textInUtf8_)
3869
3870 static void TestUtf8()
3871 {
3872 wxPuts(_T("*** Testing UTF8 support ***\n"));
3873
3874 char buf[1024];
3875 wchar_t wbuf[1024];
3876 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
3877 {
3878 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3879 }
3880 else
3881 {
3882 wxCSConv conv(_T("koi8-r"));
3883 if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
3884 {
3885 wxPuts(_T("ERROR: conversion to KOI8-R failed."));
3886 }
3887 else
3888 {
3889 wxPrintf(_T("The resulting string (in KOI8-R): %s\n"), buf);
3890 }
3891 }
3892
3893 if ( wxConvUTF8.WC2MB(buf, L"à la", WXSIZEOF(buf)) <= 0 )
3894 {
3895 wxPuts(_T("ERROR: conversion to UTF-8 failed."));
3896 }
3897 else
3898 {
3899 wxPrintf(_T("The string in UTF-8: %s\n"), buf);
3900 }
3901
3902 wxPuts(_T(""));
3903 }
3904
3905 static void TestEncodingConverter()
3906 {
3907 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3908
3909 // using wxEncodingConverter should give the same result as above
3910 char buf[1024];
3911 wchar_t wbuf[1024];
3912 if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
3913 {
3914 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3915 }
3916 else
3917 {
3918 wxEncodingConverter ec;
3919 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3920 ec.Convert(wbuf, buf);
3921 wxPrintf(_T("The same string obtained using wxEC: %s\n"), buf);
3922 }
3923
3924 wxPuts(_T(""));
3925 }
3926
3927 #endif // TEST_WCHAR
3928
3929 // ----------------------------------------------------------------------------
3930 // ZIP stream
3931 // ----------------------------------------------------------------------------
3932
3933 #ifdef TEST_ZIP
3934
3935 #include "wx/filesys.h"
3936 #include "wx/fs_zip.h"
3937 #include "wx/zipstrm.h"
3938
3939 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3940
3941 static void TestZipStreamRead()
3942 {
3943 wxPuts(_T("*** Testing ZIP reading ***\n"));
3944
3945 static const wxChar *filename = _T("foo");
3946 wxZipInputStream istr(TESTFILE_ZIP, filename);
3947 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3948
3949 wxPrintf(_T("Dumping the file '%s':\n"), filename);
3950 while ( !istr.Eof() )
3951 {
3952 putchar(istr.GetC());
3953 fflush(stdout);
3954 }
3955
3956 wxPuts(_T("\n----- done ------"));
3957 }
3958
3959 static void DumpZipDirectory(wxFileSystem& fs,
3960 const wxString& dir,
3961 const wxString& indent)
3962 {
3963 wxString prefix = wxString::Format(_T("%s#zip:%s"),
3964 TESTFILE_ZIP, dir.c_str());
3965 wxString wildcard = prefix + _T("/*");
3966
3967 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3968 while ( !dirname.empty() )
3969 {
3970 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3971 {
3972 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3973
3974 break;
3975 }
3976
3977 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3978
3979 DumpZipDirectory(fs, dirname,
3980 indent + wxString(_T(' '), 4));
3981
3982 dirname = fs.FindNext();
3983 }
3984
3985 wxString filename = fs.FindFirst(wildcard, wxFILE);
3986 while ( !filename.empty() )
3987 {
3988 if ( !filename.StartsWith(prefix, &filename) )
3989 {
3990 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3991
3992 break;
3993 }
3994
3995 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3996
3997 filename = fs.FindNext();
3998 }
3999 }
4000
4001 static void TestZipFileSystem()
4002 {
4003 wxPuts(_T("*** Testing ZIP file system ***\n"));
4004
4005 wxFileSystem::AddHandler(new wxZipFSHandler);
4006 wxFileSystem fs;
4007 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
4008
4009 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
4010 }
4011
4012 #endif // TEST_ZIP
4013
4014 // ----------------------------------------------------------------------------
4015 // ZLIB stream
4016 // ----------------------------------------------------------------------------
4017
4018 #ifdef TEST_ZLIB
4019
4020 #include "wx/zstream.h"
4021 #include "wx/wfstream.h"
4022
4023 static const wxChar *FILENAME_GZ = _T("test.gz");
4024 static const wxChar *TEST_DATA = _T("hello and hello and hello and hello and hello");
4025
4026 static void TestZlibStreamWrite()
4027 {
4028 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
4029
4030 wxFileOutputStream fileOutStream(FILENAME_GZ);
4031 wxZlibOutputStream ostr(fileOutStream);
4032 wxPrintf(_T("Compressing the test string... "));
4033 ostr.Write(TEST_DATA, wxStrlen(TEST_DATA) + 1);
4034 if ( !ostr )
4035 {
4036 wxPuts(_T("(ERROR: failed)"));
4037 }
4038 else
4039 {
4040 wxPuts(_T("(ok)"));
4041 }
4042
4043 wxPuts(_T("\n----- done ------"));
4044 }
4045
4046 static void TestZlibStreamRead()
4047 {
4048 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
4049
4050 wxFileInputStream fileInStream(FILENAME_GZ);
4051 wxZlibInputStream istr(fileInStream);
4052 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
4053
4054 wxPuts(_T("Dumping the file:"));
4055 while ( !istr.Eof() )
4056 {
4057 putchar(istr.GetC());
4058 fflush(stdout);
4059 }
4060
4061 wxPuts(_T("\n----- done ------"));
4062 }
4063
4064 #endif // TEST_ZLIB
4065
4066 // ----------------------------------------------------------------------------
4067 // date time
4068 // ----------------------------------------------------------------------------
4069
4070 #ifdef TEST_DATETIME
4071
4072 #include <math.h>
4073
4074 #include "wx/date.h"
4075 #include "wx/datetime.h"
4076
4077 // the test data
4078 struct Date
4079 {
4080 wxDateTime::wxDateTime_t day;
4081 wxDateTime::Month month;
4082 int year;
4083 wxDateTime::wxDateTime_t hour, min, sec;
4084 double jdn;
4085 wxDateTime::WeekDay wday;
4086 time_t gmticks, ticks;
4087
4088 void Init(const wxDateTime::Tm& tm)
4089 {
4090 day = tm.mday;
4091 month = tm.mon;
4092 year = tm.year;
4093 hour = tm.hour;
4094 min = tm.min;
4095 sec = tm.sec;
4096 jdn = 0.0;
4097 gmticks = ticks = -1;
4098 }
4099
4100 wxDateTime DT() const
4101 { return wxDateTime(day, month, year, hour, min, sec); }
4102
4103 bool SameDay(const wxDateTime::Tm& tm) const
4104 {
4105 return day == tm.mday && month == tm.mon && year == tm.year;
4106 }
4107
4108 wxString Format() const
4109 {
4110 wxString s;
4111 s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"),
4112 hour, min, sec,
4113 wxDateTime::GetMonthName(month).c_str(),
4114 day,
4115 abs(wxDateTime::ConvertYearToBC(year)),
4116 year > 0 ? _T("AD") : _T("BC"));
4117 return s;
4118 }
4119
4120 wxString FormatDate() const
4121 {
4122 wxString s;
4123 s.Printf(_T("%02d-%s-%4d%s"),
4124 day,
4125 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
4126 abs(wxDateTime::ConvertYearToBC(year)),
4127 year > 0 ? _T("AD") : _T("BC"));
4128 return s;
4129 }
4130 };
4131
4132 static const Date testDates[] =
4133 {
4134 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
4135 { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 },
4136 { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 },
4137 { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 },
4138 { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 },
4139 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
4140 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
4141 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
4142 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
4143 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
4144 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
4145 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
4146 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
4147 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
4148 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
4149 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
4150 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
4151 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
4152 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
4153 };
4154
4155 // this test miscellaneous static wxDateTime functions
4156 static void TestTimeStatic()
4157 {
4158 wxPuts(_T("\n*** wxDateTime static methods test ***"));
4159
4160 // some info about the current date
4161 int year = wxDateTime::GetCurrentYear();
4162 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
4163 year,
4164 wxDateTime::IsLeapYear(year) ? "" : "not ",
4165 wxDateTime::GetNumberOfDays(year));
4166
4167 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
4168 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
4169 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
4170 wxDateTime::GetMonthName(month).c_str(),
4171 wxDateTime::GetNumberOfDays(month));
4172
4173 // leap year logic
4174 static const size_t nYears = 5;
4175 static const size_t years[2][nYears] =
4176 {
4177 // first line: the years to test
4178 { 1990, 1976, 2000, 2030, 1984, },
4179
4180 // second line: TRUE if leap, FALSE otherwise
4181 { FALSE, TRUE, TRUE, FALSE, TRUE }
4182 };
4183
4184 for ( size_t n = 0; n < nYears; n++ )
4185 {
4186 int year = years[0][n];
4187 bool should = years[1][n] != 0,
4188 is = wxDateTime::IsLeapYear(year);
4189
4190 wxPrintf(_T("Year %d is %sa leap year (%s)\n"),
4191 year,
4192 is ? "" : "not ",
4193 should == is ? "ok" : "ERROR");
4194
4195 wxASSERT( should == wxDateTime::IsLeapYear(year) );
4196 }
4197 }
4198
4199 // test constructing wxDateTime objects
4200 static void TestTimeSet()
4201 {
4202 wxPuts(_T("\n*** wxDateTime construction test ***"));
4203
4204 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4205 {
4206 const Date& d1 = testDates[n];
4207 wxDateTime dt = d1.DT();
4208
4209 Date d2;
4210 d2.Init(dt.GetTm());
4211
4212 wxString s1 = d1.Format(),
4213 s2 = d2.Format();
4214
4215 wxPrintf(_T("Date: %s == %s (%s)\n"),
4216 s1.c_str(), s2.c_str(),
4217 s1 == s2 ? _T("ok") : _T("ERROR"));
4218 }
4219 }
4220
4221 // test time zones stuff
4222 static void TestTimeZones()
4223 {
4224 wxPuts(_T("\n*** wxDateTime timezone test ***"));
4225
4226 wxDateTime now = wxDateTime::Now();
4227
4228 wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
4229 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
4230 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
4231 wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
4232 wxPrintf(_T(" Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
4233 wxPrintf(_T(" New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
4234
4235 wxDateTime::Tm tm = now.GetTm();
4236 if ( wxDateTime(tm) != now )
4237 {
4238 wxPrintf(_T("ERROR: got %s instead of %s\n"),
4239 wxDateTime(tm).Format().c_str(), now.Format().c_str());
4240 }
4241 }
4242
4243 // test some minimal support for the dates outside the standard range
4244 static void TestTimeRange()
4245 {
4246 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
4247
4248 static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
4249
4250 wxPrintf(_T("Unix epoch:\t%s\n"),
4251 wxDateTime(2440587.5).Format(fmt).c_str());
4252 wxPrintf(_T("Feb 29, 0: \t%s\n"),
4253 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
4254 wxPrintf(_T("JDN 0: \t%s\n"),
4255 wxDateTime(0.0).Format(fmt).c_str());
4256 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
4257 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
4258 wxPrintf(_T("May 29, 2099:\t%s\n"),
4259 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
4260 }
4261
4262 static void TestTimeTicks()
4263 {
4264 wxPuts(_T("\n*** wxDateTime ticks test ***"));
4265
4266 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4267 {
4268 const Date& d = testDates[n];
4269 if ( d.ticks == -1 )
4270 continue;
4271
4272 wxDateTime dt = d.DT();
4273 long ticks = (dt.GetValue() / 1000).ToLong();
4274 wxPrintf(_T("Ticks of %s:\t% 10ld"), d.Format().c_str(), ticks);
4275 if ( ticks == d.ticks )
4276 {
4277 wxPuts(_T(" (ok)"));
4278 }
4279 else
4280 {
4281 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4282 (long)d.ticks, (long)(ticks - d.ticks));
4283 }
4284
4285 dt = d.DT().ToTimezone(wxDateTime::GMT0);
4286 ticks = (dt.GetValue() / 1000).ToLong();
4287 wxPrintf(_T("GMtks of %s:\t% 10ld"), d.Format().c_str(), ticks);
4288 if ( ticks == d.gmticks )
4289 {
4290 wxPuts(_T(" (ok)"));
4291 }
4292 else
4293 {
4294 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
4295 (long)d.gmticks, (long)(ticks - d.gmticks));
4296 }
4297 }
4298
4299 wxPuts(_T(""));
4300 }
4301
4302 // test conversions to JDN &c
4303 static void TestTimeJDN()
4304 {
4305 wxPuts(_T("\n*** wxDateTime to JDN test ***"));
4306
4307 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
4308 {
4309 const Date& d = testDates[n];
4310 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
4311 double jdn = dt.GetJulianDayNumber();
4312
4313 wxPrintf(_T("JDN of %s is:\t% 15.6f"), d.Format().c_str(), jdn);
4314 if ( jdn == d.jdn )
4315 {
4316 wxPuts(_T(" (ok)"));
4317 }
4318 else
4319 {
4320 wxPrintf(_T(" (ERROR: should be %f, delta = %f)\n"),
4321 d.jdn, jdn - d.jdn);
4322 }
4323 }
4324 }
4325
4326 // test week days computation
4327 static void TestTimeWDays()
4328 {
4329 wxPuts(_T("\n*** wxDateTime weekday test ***"));
4330
4331 // test GetWeekDay()
4332 size_t n;
4333 for ( n = 0; n < WXSIZEOF(testDates); n++ )
4334 {
4335 const Date& d = testDates[n];
4336 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
4337
4338 wxDateTime::WeekDay wday = dt.GetWeekDay();
4339 wxPrintf(_T("%s is: %s"),
4340 d.Format().c_str(),
4341 wxDateTime::GetWeekDayName(wday).c_str());
4342 if ( wday == d.wday )
4343 {
4344 wxPuts(_T(" (ok)"));
4345 }
4346 else
4347 {
4348 wxPrintf(_T(" (ERROR: should be %s)\n"),
4349 wxDateTime::GetWeekDayName(d.wday).c_str());
4350 }
4351 }
4352
4353 wxPuts(_T(""));
4354
4355 // test SetToWeekDay()
4356 struct WeekDateTestData
4357 {
4358 Date date; // the real date (precomputed)
4359 int nWeek; // its week index in the month
4360 wxDateTime::WeekDay wday; // the weekday
4361 wxDateTime::Month month; // the month
4362 int year; // and the year
4363
4364 wxString Format() const
4365 {
4366 wxString s, which;
4367 switch ( nWeek < -1 ? -nWeek : nWeek )
4368 {
4369 case 1: which = _T("first"); break;
4370 case 2: which = _T("second"); break;
4371 case 3: which = _T("third"); break;
4372 case 4: which = _T("fourth"); break;
4373 case 5: which = _T("fifth"); break;
4374
4375 case -1: which = _T("last"); break;
4376 }
4377
4378 if ( nWeek < -1 )
4379 {
4380 which += _T(" from end");
4381 }
4382
4383 s.Printf(_T("The %s %s of %s in %d"),
4384 which.c_str(),
4385 wxDateTime::GetWeekDayName(wday).c_str(),
4386 wxDateTime::GetMonthName(month).c_str(),
4387 year);
4388
4389 return s;
4390 }
4391 };
4392
4393 // the array data was generated by the following python program
4394 /*
4395 from DateTime import *
4396 from whrandom import *
4397 from string import *
4398
4399 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4400 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4401
4402 week = DateTimeDelta(7)
4403
4404 for n in range(20):
4405 year = randint(1900, 2100)
4406 month = randint(1, 12)
4407 day = randint(1, 28)
4408 dt = DateTime(year, month, day)
4409 wday = dt.day_of_week
4410
4411 countFromEnd = choice([-1, 1])
4412 weekNum = 0;
4413
4414 while dt.month is month:
4415 dt = dt - countFromEnd * week
4416 weekNum = weekNum + countFromEnd
4417
4418 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
4419
4420 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
4421 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
4422 */
4423
4424 static const WeekDateTestData weekDatesTestData[] =
4425 {
4426 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
4427 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
4428 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
4429 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
4430 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
4431 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
4432 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
4433 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
4434 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
4435 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
4436 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
4437 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
4438 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
4439 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
4440 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
4441 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
4442 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
4443 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
4444 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
4445 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
4446 };
4447
4448 static const wxChar *fmt = _T("%d-%b-%Y");
4449
4450 wxDateTime dt;
4451 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
4452 {
4453 const WeekDateTestData& wd = weekDatesTestData[n];
4454
4455 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
4456
4457 wxPrintf(_T("%s is %s"), wd.Format().c_str(), dt.Format(fmt).c_str());
4458
4459 const Date& d = wd.date;
4460 if ( d.SameDay(dt.GetTm()) )
4461 {
4462 wxPuts(_T(" (ok)"));
4463 }
4464 else
4465 {
4466 dt.Set(d.day, d.month, d.year);
4467
4468 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.Format(fmt).c_str());
4469 }
4470 }
4471 }
4472
4473 // test the computation of (ISO) week numbers
4474 static void TestTimeWNumber()
4475 {
4476 wxPuts(_T("\n*** wxDateTime week number test ***"));
4477
4478 struct WeekNumberTestData
4479 {
4480 Date date; // the date
4481 wxDateTime::wxDateTime_t week; // the week number in the year
4482 wxDateTime::wxDateTime_t wmon; // the week number in the month
4483 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
4484 wxDateTime::wxDateTime_t dnum; // day number in the year
4485 };
4486
4487 // data generated with the following python script:
4488 /*
4489 from DateTime import *
4490 from whrandom import *
4491 from string import *
4492
4493 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4494 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4495
4496 def GetMonthWeek(dt):
4497 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4498 if weekNumMonth < 0:
4499 weekNumMonth = weekNumMonth + 53
4500 return weekNumMonth
4501
4502 def GetLastSundayBefore(dt):
4503 if dt.iso_week[2] == 7:
4504 return dt
4505 else:
4506 return dt - DateTimeDelta(dt.iso_week[2])
4507
4508 for n in range(20):
4509 year = randint(1900, 2100)
4510 month = randint(1, 12)
4511 day = randint(1, 28)
4512 dt = DateTime(year, month, day)
4513 dayNum = dt.day_of_year
4514 weekNum = dt.iso_week[1]
4515 weekNumMonth = GetMonthWeek(dt)
4516
4517 weekNumMonth2 = 0
4518 dtSunday = GetLastSundayBefore(dt)
4519
4520 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4521 weekNumMonth2 = weekNumMonth2 + 1
4522 dtSunday = dtSunday - DateTimeDelta(7)
4523
4524 data = { 'day': rjust(`day`, 2), \
4525 'month': monthNames[month - 1], \
4526 'year': year, \
4527 'weekNum': rjust(`weekNum`, 2), \
4528 'weekNumMonth': weekNumMonth, \
4529 'weekNumMonth2': weekNumMonth2, \
4530 'dayNum': rjust(`dayNum`, 3) }
4531
4532 print " { { %(day)s, "\
4533 "wxDateTime::%(month)s, "\
4534 "%(year)d }, "\
4535 "%(weekNum)s, "\
4536 "%(weekNumMonth)s, "\
4537 "%(weekNumMonth2)s, "\
4538 "%(dayNum)s }," % data
4539
4540 */
4541 static const WeekNumberTestData weekNumberTestDates[] =
4542 {
4543 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
4544 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
4545 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
4546 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
4547 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
4548 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
4549 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
4550 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
4551 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
4552 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
4553 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
4554 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
4555 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
4556 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
4557 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
4558 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
4559 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
4560 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
4561 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
4562 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
4563 };
4564
4565 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
4566 {
4567 const WeekNumberTestData& wn = weekNumberTestDates[n];
4568 const Date& d = wn.date;
4569
4570 wxDateTime dt = d.DT();
4571
4572 wxDateTime::wxDateTime_t
4573 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
4574 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
4575 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4576 dnum = dt.GetDayOfYear();
4577
4578 wxPrintf(_T("%s: the day number is %d"), d.FormatDate().c_str(), dnum);
4579 if ( dnum == wn.dnum )
4580 {
4581 wxPrintf(_T(" (ok)"));
4582 }
4583 else
4584 {
4585 wxPrintf(_T(" (ERROR: should be %d)"), wn.dnum);
4586 }
4587
4588 wxPrintf(_T(", week in month is %d"), wmon);
4589 if ( wmon == wn.wmon )
4590 {
4591 wxPrintf(_T(" (ok)"));
4592 }
4593 else
4594 {
4595 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon);
4596 }
4597
4598 wxPrintf(_T(" or %d"), wmon2);
4599 if ( wmon2 == wn.wmon2 )
4600 {
4601 wxPrintf(_T(" (ok)"));
4602 }
4603 else
4604 {
4605 wxPrintf(_T(" (ERROR: should be %d)"), wn.wmon2);
4606 }
4607
4608 wxPrintf(_T(", week in year is %d"), week);
4609 if ( week == wn.week )
4610 {
4611 wxPuts(_T(" (ok)"));
4612 }
4613 else
4614 {
4615 wxPrintf(_T(" (ERROR: should be %d)\n"), wn.week);
4616 }
4617 }
4618 }
4619
4620 // test DST calculations
4621 static void TestTimeDST()
4622 {
4623 wxPuts(_T("\n*** wxDateTime DST test ***"));
4624
4625 wxPrintf(_T("DST is%s in effect now.\n\n"),
4626 wxDateTime::Now().IsDST() ? _T("") : _T(" not"));
4627
4628 // taken from http://www.energy.ca.gov/daylightsaving.html
4629 static const Date datesDST[2][2004 - 1900 + 1] =
4630 {
4631 {
4632 { 1, wxDateTime::Apr, 1990 },
4633 { 7, wxDateTime::Apr, 1991 },
4634 { 5, wxDateTime::Apr, 1992 },
4635 { 4, wxDateTime::Apr, 1993 },
4636 { 3, wxDateTime::Apr, 1994 },
4637 { 2, wxDateTime::Apr, 1995 },
4638 { 7, wxDateTime::Apr, 1996 },
4639 { 6, wxDateTime::Apr, 1997 },
4640 { 5, wxDateTime::Apr, 1998 },
4641 { 4, wxDateTime::Apr, 1999 },
4642 { 2, wxDateTime::Apr, 2000 },
4643 { 1, wxDateTime::Apr, 2001 },
4644 { 7, wxDateTime::Apr, 2002 },
4645 { 6, wxDateTime::Apr, 2003 },
4646 { 4, wxDateTime::Apr, 2004 },
4647 },
4648 {
4649 { 28, wxDateTime::Oct, 1990 },
4650 { 27, wxDateTime::Oct, 1991 },
4651 { 25, wxDateTime::Oct, 1992 },
4652 { 31, wxDateTime::Oct, 1993 },
4653 { 30, wxDateTime::Oct, 1994 },
4654 { 29, wxDateTime::Oct, 1995 },
4655 { 27, wxDateTime::Oct, 1996 },
4656 { 26, wxDateTime::Oct, 1997 },
4657 { 25, wxDateTime::Oct, 1998 },
4658 { 31, wxDateTime::Oct, 1999 },
4659 { 29, wxDateTime::Oct, 2000 },
4660 { 28, wxDateTime::Oct, 2001 },
4661 { 27, wxDateTime::Oct, 2002 },
4662 { 26, wxDateTime::Oct, 2003 },
4663 { 31, wxDateTime::Oct, 2004 },
4664 }
4665 };
4666
4667 int year;
4668 for ( year = 1990; year < 2005; year++ )
4669 {
4670 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
4671 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
4672
4673 wxPrintf(_T("DST period in the US for year %d: from %s to %s"),
4674 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
4675
4676 size_t n = year - 1990;
4677 const Date& dBegin = datesDST[0][n];
4678 const Date& dEnd = datesDST[1][n];
4679
4680 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
4681 {
4682 wxPuts(_T(" (ok)"));
4683 }
4684 else
4685 {
4686 wxPrintf(_T(" (ERROR: should be %s %d to %s %d)\n"),
4687 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
4688 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
4689 }
4690 }
4691
4692 wxPuts(_T(""));
4693
4694 for ( year = 1990; year < 2005; year++ )
4695 {
4696 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
4697 year,
4698 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
4699 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
4700 }
4701 }
4702
4703 // test wxDateTime -> text conversion
4704 static void TestTimeFormat()
4705 {
4706 wxPuts(_T("\n*** wxDateTime formatting test ***"));
4707
4708 // some information may be lost during conversion, so store what kind
4709 // of info should we recover after a round trip
4710 enum CompareKind
4711 {
4712 CompareNone, // don't try comparing
4713 CompareBoth, // dates and times should be identical
4714 CompareDate, // dates only
4715 CompareTime // time only
4716 };
4717
4718 static const struct
4719 {
4720 CompareKind compareKind;
4721 const wxChar *format;
4722 } formatTestFormats[] =
4723 {
4724 { CompareBoth, _T("---> %c") },
4725 { CompareDate, _T("Date is %A, %d of %B, in year %Y") },
4726 { CompareBoth, _T("Date is %x, time is %X") },
4727 { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") },
4728 { CompareNone, _T("The day of year: %j, the week of year: %W") },
4729 { CompareDate, _T("ISO date without separators: %Y%m%d") },
4730 };
4731
4732 static const Date formatTestDates[] =
4733 {
4734 { 29, wxDateTime::May, 1976, 18, 30, 00 },
4735 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
4736 #if 0
4737 // this test can't work for other centuries because it uses two digit
4738 // years in formats, so don't even try it
4739 { 29, wxDateTime::May, 2076, 18, 30, 00 },
4740 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
4741 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
4742 #endif
4743 };
4744
4745 // an extra test (as it doesn't depend on date, don't do it in the loop)
4746 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
4747
4748 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
4749 {
4750 wxPuts(_T(""));
4751
4752 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
4753 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
4754 {
4755 wxString s = dt.Format(formatTestFormats[n].format);
4756 wxPrintf(_T("%s"), s.c_str());
4757
4758 // what can we recover?
4759 int kind = formatTestFormats[n].compareKind;
4760
4761 // convert back
4762 wxDateTime dt2;
4763 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
4764 if ( !result )
4765 {
4766 // converion failed - should it have?
4767 if ( kind == CompareNone )
4768 wxPuts(_T(" (ok)"));
4769 else
4770 wxPuts(_T(" (ERROR: conversion back failed)"));
4771 }
4772 else if ( *result )
4773 {
4774 // should have parsed the entire string
4775 wxPuts(_T(" (ERROR: conversion back stopped too soon)"));
4776 }
4777 else
4778 {
4779 bool equal = FALSE; // suppress compilaer warning
4780 switch ( kind )
4781 {
4782 case CompareBoth:
4783 equal = dt2 == dt;
4784 break;
4785
4786 case CompareDate:
4787 equal = dt.IsSameDate(dt2);
4788 break;
4789
4790 case CompareTime:
4791 equal = dt.IsSameTime(dt2);
4792 break;
4793 }
4794
4795 if ( !equal )
4796 {
4797 wxPrintf(_T(" (ERROR: got back '%s' instead of '%s')\n"),
4798 dt2.Format().c_str(), dt.Format().c_str());
4799 }
4800 else
4801 {
4802 wxPuts(_T(" (ok)"));
4803 }
4804 }
4805 }
4806 }
4807 }
4808
4809 // test text -> wxDateTime conversion
4810 static void TestTimeParse()
4811 {
4812 wxPuts(_T("\n*** wxDateTime parse test ***"));
4813
4814 struct ParseTestData
4815 {
4816 const wxChar *format;
4817 Date date;
4818 bool good;
4819 };
4820
4821 static const ParseTestData parseTestDates[] =
4822 {
4823 { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
4824 { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
4825 };
4826
4827 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
4828 {
4829 const wxChar *format = parseTestDates[n].format;
4830
4831 wxPrintf(_T("%s => "), format);
4832
4833 wxDateTime dt;
4834 if ( dt.ParseRfc822Date(format) )
4835 {
4836 wxPrintf(_T("%s "), dt.Format().c_str());
4837
4838 if ( parseTestDates[n].good )
4839 {
4840 wxDateTime dtReal = parseTestDates[n].date.DT();
4841 if ( dt == dtReal )
4842 {
4843 wxPuts(_T("(ok)"));
4844 }
4845 else
4846 {
4847 wxPrintf(_T("(ERROR: should be %s)\n"), dtReal.Format().c_str());
4848 }
4849 }
4850 else
4851 {
4852 wxPuts(_T("(ERROR: bad format)"));
4853 }
4854 }
4855 else
4856 {
4857 wxPrintf(_T("bad format (%s)\n"),
4858 parseTestDates[n].good ? "ERROR" : "ok");
4859 }
4860 }
4861 }
4862
4863 static void TestDateTimeInteractive()
4864 {
4865 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
4866
4867 wxChar buf[128];
4868
4869 for ( ;; )
4870 {
4871 wxPrintf(_T("Enter a date: "));
4872 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
4873 break;
4874
4875 // kill the last '\n'
4876 buf[wxStrlen(buf) - 1] = 0;
4877
4878 wxDateTime dt;
4879 const wxChar *p = dt.ParseDate(buf);
4880 if ( !p )
4881 {
4882 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
4883
4884 continue;
4885 }
4886 else if ( *p )
4887 {
4888 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
4889 }
4890
4891 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
4892 dt.Format(_T("%b %d, %Y")).c_str(),
4893 dt.GetDayOfYear(),
4894 dt.GetWeekOfMonth(wxDateTime::Monday_First),
4895 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
4896 dt.GetWeekOfYear(wxDateTime::Monday_First));
4897 }
4898
4899 wxPuts(_T("\n*** done ***"));
4900 }
4901
4902 static void TestTimeMS()
4903 {
4904 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
4905
4906 wxDateTime dt1 = wxDateTime::Now(),
4907 dt2 = wxDateTime::UNow();
4908
4909 wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
4910 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
4911 wxPrintf(_T("Dummy loop: "));
4912 for ( int i = 0; i < 6000; i++ )
4913 {
4914 //for ( int j = 0; j < 10; j++ )
4915 {
4916 wxString s;
4917 s.Printf(_T("%g"), sqrt(i));
4918 }
4919
4920 if ( !(i % 100) )
4921 putchar('.');
4922 }
4923 wxPuts(_T(", done"));
4924
4925 dt1 = dt2;
4926 dt2 = wxDateTime::UNow();
4927 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
4928
4929 wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
4930
4931 wxPuts(_T("\n*** done ***"));
4932 }
4933
4934 static void TestTimeArithmetics()
4935 {
4936 wxPuts(_T("\n*** testing arithmetic operations on wxDateTime ***"));
4937
4938 static const struct ArithmData
4939 {
4940 ArithmData(const wxDateSpan& sp, const wxChar *nam)
4941 : span(sp), name(nam) { }
4942
4943 wxDateSpan span;
4944 const wxChar *name;
4945 } testArithmData[] =
4946 {
4947 ArithmData(wxDateSpan::Day(), _T("day")),
4948 ArithmData(wxDateSpan::Week(), _T("week")),
4949 ArithmData(wxDateSpan::Month(), _T("month")),
4950 ArithmData(wxDateSpan::Year(), _T("year")),
4951 ArithmData(wxDateSpan(1, 2, 3, 4), _T("year, 2 months, 3 weeks, 4 days")),
4952 };
4953
4954 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
4955
4956 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
4957 {
4958 wxDateSpan span = testArithmData[n].span;
4959 dt1 = dt + span;
4960 dt2 = dt - span;
4961
4962 const wxChar *name = testArithmData[n].name;
4963 wxPrintf(_T("%s + %s = %s, %s - %s = %s\n"),
4964 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
4965 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
4966
4967 wxPrintf(_T("Going back: %s"), (dt1 - span).FormatISODate().c_str());
4968 if ( dt1 - span == dt )
4969 {
4970 wxPuts(_T(" (ok)"));
4971 }
4972 else
4973 {
4974 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
4975 }
4976
4977 wxPrintf(_T("Going forward: %s"), (dt2 + span).FormatISODate().c_str());
4978 if ( dt2 + span == dt )
4979 {
4980 wxPuts(_T(" (ok)"));
4981 }
4982 else
4983 {
4984 wxPrintf(_T(" (ERROR: should be %s)\n"), dt.FormatISODate().c_str());
4985 }
4986
4987 wxPrintf(_T("Double increment: %s"), (dt2 + 2*span).FormatISODate().c_str());
4988 if ( dt2 + 2*span == dt1 )
4989 {
4990 wxPuts(_T(" (ok)"));
4991 }
4992 else
4993 {
4994 wxPrintf(_T(" (ERROR: should be %s)\n"), dt2.FormatISODate().c_str());
4995 }
4996
4997 wxPuts(_T(""));
4998 }
4999 }
5000
5001 static void TestTimeHolidays()
5002 {
5003 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
5004
5005 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
5006 wxDateTime dtStart(1, tm.mon, tm.year),
5007 dtEnd = dtStart.GetLastMonthDay();
5008
5009 wxDateTimeArray hol;
5010 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
5011
5012 const wxChar *format = _T("%d-%b-%Y (%a)");
5013
5014 wxPrintf(_T("All holidays between %s and %s:\n"),
5015 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
5016
5017 size_t count = hol.GetCount();
5018 for ( size_t n = 0; n < count; n++ )
5019 {
5020 wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
5021 }
5022
5023 wxPuts(_T(""));
5024 }
5025
5026 static void TestTimeZoneBug()
5027 {
5028 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
5029
5030 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
5031 for ( int i = 0; i < 31; i++ )
5032 {
5033 wxPrintf(_T("Date %s: week day %s.\n"),
5034 date.Format(_T("%d-%m-%Y")).c_str(),
5035 date.GetWeekDayName(date.GetWeekDay()).c_str());
5036
5037 date += wxDateSpan::Day();
5038 }
5039
5040 wxPuts(_T(""));
5041 }
5042
5043 static void TestTimeSpanFormat()
5044 {
5045 wxPuts(_T("\n*** wxTimeSpan tests ***"));
5046
5047 static const wxChar *formats[] =
5048 {
5049 _T("(default) %H:%M:%S"),
5050 _T("%E weeks and %D days"),
5051 _T("%l milliseconds"),
5052 _T("(with ms) %H:%M:%S:%l"),
5053 _T("100%% of minutes is %M"), // test "%%"
5054 _T("%D days and %H hours"),
5055 _T("or also %S seconds"),
5056 };
5057
5058 wxTimeSpan ts1(1, 2, 3, 4),
5059 ts2(111, 222, 333);
5060 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
5061 {
5062 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
5063 ts1.Format(formats[n]).c_str(),
5064 ts2.Format(formats[n]).c_str());
5065 }
5066
5067 wxPuts(_T(""));
5068 }
5069
5070 #if 0
5071
5072 // test compatibility with the old wxDate/wxTime classes
5073 static void TestTimeCompatibility()
5074 {
5075 wxPuts(_T("\n*** wxDateTime compatibility test ***"));
5076
5077 wxPrintf(_T("wxDate for JDN 0: %s\n"), wxDate(0l).FormatDate().c_str());
5078 wxPrintf(_T("wxDate for MJD 0: %s\n"), wxDate(2400000).FormatDate().c_str());
5079
5080 double jdnNow = wxDateTime::Now().GetJDN();
5081 long jdnMidnight = (long)(jdnNow - 0.5);
5082 wxPrintf(_T("wxDate for today: %s\n"), wxDate(jdnMidnight).FormatDate().c_str());
5083
5084 jdnMidnight = wxDate().Set().GetJulianDate();
5085 wxPrintf(_T("wxDateTime for today: %s\n"),
5086 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
5087
5088 int flags = wxEUROPEAN;//wxFULL;
5089 wxDate date;
5090 date.Set();
5091 wxPrintf(_T("Today is %s\n"), date.FormatDate(flags).c_str());
5092 for ( int n = 0; n < 7; n++ )
5093 {
5094 wxPrintf(_T("Previous %s is %s\n"),
5095 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
5096 date.Previous(n + 1).FormatDate(flags).c_str());
5097 }
5098 }
5099
5100 #endif // 0
5101
5102 #endif // TEST_DATETIME
5103
5104 // ----------------------------------------------------------------------------
5105 // threads
5106 // ----------------------------------------------------------------------------
5107
5108 #ifdef TEST_THREADS
5109
5110 #include "wx/thread.h"
5111
5112 static size_t gs_counter = (size_t)-1;
5113 static wxCriticalSection gs_critsect;
5114 static wxSemaphore gs_cond;
5115
5116 class MyJoinableThread : public wxThread
5117 {
5118 public:
5119 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
5120 { m_n = n; Create(); }
5121
5122 // thread execution starts here
5123 virtual ExitCode Entry();
5124
5125 private:
5126 size_t m_n;
5127 };
5128
5129 wxThread::ExitCode MyJoinableThread::Entry()
5130 {
5131 unsigned long res = 1;
5132 for ( size_t n = 1; n < m_n; n++ )
5133 {
5134 res *= n;
5135
5136 // it's a loooong calculation :-)
5137 Sleep(100);
5138 }
5139
5140 return (ExitCode)res;
5141 }
5142
5143 class MyDetachedThread : public wxThread
5144 {
5145 public:
5146 MyDetachedThread(size_t n, wxChar ch)
5147 {
5148 m_n = n;
5149 m_ch = ch;
5150 m_cancelled = FALSE;
5151
5152 Create();
5153 }
5154
5155 // thread execution starts here
5156 virtual ExitCode Entry();
5157
5158 // and stops here
5159 virtual void OnExit();
5160
5161 private:
5162 size_t m_n; // number of characters to write
5163 wxChar m_ch; // character to write
5164
5165 bool m_cancelled; // FALSE if we exit normally
5166 };
5167
5168 wxThread::ExitCode MyDetachedThread::Entry()
5169 {
5170 {
5171 wxCriticalSectionLocker lock(gs_critsect);
5172 if ( gs_counter == (size_t)-1 )
5173 gs_counter = 1;
5174 else
5175 gs_counter++;
5176 }
5177
5178 for ( size_t n = 0; n < m_n; n++ )
5179 {
5180 if ( TestDestroy() )
5181 {
5182 m_cancelled = TRUE;
5183
5184 break;
5185 }
5186
5187 putchar(m_ch);
5188 fflush(stdout);
5189
5190 wxThread::Sleep(100);
5191 }
5192
5193 return 0;
5194 }
5195
5196 void MyDetachedThread::OnExit()
5197 {
5198 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
5199
5200 wxCriticalSectionLocker lock(gs_critsect);
5201 if ( !--gs_counter && !m_cancelled )
5202 gs_cond.Post();
5203 }
5204
5205 static void TestDetachedThreads()
5206 {
5207 wxPuts(_T("\n*** Testing detached threads ***"));
5208
5209 static const size_t nThreads = 3;
5210 MyDetachedThread *threads[nThreads];
5211 size_t n;
5212 for ( n = 0; n < nThreads; n++ )
5213 {
5214 threads[n] = new MyDetachedThread(10, 'A' + n);
5215 }
5216
5217 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
5218 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
5219
5220 for ( n = 0; n < nThreads; n++ )
5221 {
5222 threads[n]->Run();
5223 }
5224
5225 // wait until all threads terminate
5226 gs_cond.Wait();
5227
5228 wxPuts(_T(""));
5229 }
5230
5231 static void TestJoinableThreads()
5232 {
5233 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
5234
5235 // calc 10! in the background
5236 MyJoinableThread thread(10);
5237 thread.Run();
5238
5239 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
5240 (unsigned long)thread.Wait());
5241 }
5242
5243 static void TestThreadSuspend()
5244 {
5245 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
5246
5247 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
5248
5249 thread->Run();
5250
5251 // this is for this demo only, in a real life program we'd use another
5252 // condition variable which would be signaled from wxThread::Entry() to
5253 // tell us that the thread really started running - but here just wait a
5254 // bit and hope that it will be enough (the problem is, of course, that
5255 // the thread might still not run when we call Pause() which will result
5256 // in an error)
5257 wxThread::Sleep(300);
5258
5259 for ( size_t n = 0; n < 3; n++ )
5260 {
5261 thread->Pause();
5262
5263 wxPuts(_T("\nThread suspended"));
5264 if ( n > 0 )
5265 {
5266 // don't sleep but resume immediately the first time
5267 wxThread::Sleep(300);
5268 }
5269 wxPuts(_T("Going to resume the thread"));
5270
5271 thread->Resume();
5272 }
5273
5274 wxPuts(_T("Waiting until it terminates now"));
5275
5276 // wait until the thread terminates
5277 gs_cond.Wait();
5278
5279 wxPuts(_T(""));
5280 }
5281
5282 static void TestThreadDelete()
5283 {
5284 // As above, using Sleep() is only for testing here - we must use some
5285 // synchronisation object instead to ensure that the thread is still
5286 // running when we delete it - deleting a detached thread which already
5287 // terminated will lead to a crash!
5288
5289 wxPuts(_T("\n*** Testing thread delete function ***"));
5290
5291 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
5292
5293 thread0->Delete();
5294
5295 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
5296
5297 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
5298
5299 thread1->Run();
5300
5301 wxThread::Sleep(300);
5302
5303 thread1->Delete();
5304
5305 wxPuts(_T("\nDeleted a running thread."));
5306
5307 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
5308
5309 thread2->Run();
5310
5311 wxThread::Sleep(300);
5312
5313 thread2->Pause();
5314
5315 thread2->Delete();
5316
5317 wxPuts(_T("\nDeleted a sleeping thread."));
5318
5319 MyJoinableThread thread3(20);
5320 thread3.Run();
5321
5322 thread3.Delete();
5323
5324 wxPuts(_T("\nDeleted a joinable thread."));
5325
5326 MyJoinableThread thread4(2);
5327 thread4.Run();
5328
5329 wxThread::Sleep(300);
5330
5331 thread4.Delete();
5332
5333 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
5334
5335 wxPuts(_T(""));
5336 }
5337
5338 class MyWaitingThread : public wxThread
5339 {
5340 public:
5341 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
5342 {
5343 m_mutex = mutex;
5344 m_condition = condition;
5345
5346 Create();
5347 }
5348
5349 virtual ExitCode Entry()
5350 {
5351 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
5352 fflush(stdout);
5353
5354 gs_cond.Post();
5355
5356 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
5357 fflush(stdout);
5358
5359 m_mutex->Lock();
5360 m_condition->Wait();
5361 m_mutex->Unlock();
5362
5363 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
5364 fflush(stdout);
5365
5366 return 0;
5367 }
5368
5369 private:
5370 wxMutex *m_mutex;
5371 wxCondition *m_condition;
5372 };
5373
5374 static void TestThreadConditions()
5375 {
5376 wxMutex mutex;
5377 wxCondition condition(mutex);
5378
5379 // otherwise its difficult to understand which log messages pertain to
5380 // which condition
5381 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
5382 // condition.GetId(), gs_cond.GetId());
5383
5384 // create and launch threads
5385 MyWaitingThread *threads[10];
5386
5387 size_t n;
5388 for ( n = 0; n < WXSIZEOF(threads); n++ )
5389 {
5390 threads[n] = new MyWaitingThread( &mutex, &condition );
5391 }
5392
5393 for ( n = 0; n < WXSIZEOF(threads); n++ )
5394 {
5395 threads[n]->Run();
5396 }
5397
5398 // wait until all threads run
5399 wxPuts(_T("Main thread is waiting for the other threads to start"));
5400 fflush(stdout);
5401
5402 size_t nRunning = 0;
5403 while ( nRunning < WXSIZEOF(threads) )
5404 {
5405 gs_cond.Wait();
5406
5407 nRunning++;
5408
5409 wxPrintf(_T("Main thread: %u already running\n"), nRunning);
5410 fflush(stdout);
5411 }
5412
5413 wxPuts(_T("Main thread: all threads started up."));
5414 fflush(stdout);
5415
5416 wxThread::Sleep(500);
5417
5418 #if 1
5419 // now wake one of them up
5420 wxPrintf(_T("Main thread: about to signal the condition.\n"));
5421 fflush(stdout);
5422 condition.Signal();
5423 #endif
5424
5425 wxThread::Sleep(200);
5426
5427 // wake all the (remaining) threads up, so that they can exit
5428 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
5429 fflush(stdout);
5430 condition.Broadcast();
5431
5432 // give them time to terminate (dirty!)
5433 wxThread::Sleep(500);
5434 }
5435
5436 #include "wx/utils.h"
5437
5438 class MyExecThread : public wxThread
5439 {
5440 public:
5441 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
5442 m_command(command)
5443 {
5444 Create();
5445 }
5446
5447 virtual ExitCode Entry()
5448 {
5449 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
5450 }
5451
5452 private:
5453 wxString m_command;
5454 };
5455
5456 static void TestThreadExec()
5457 {
5458 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
5459
5460 MyExecThread thread(_T("true"));
5461 thread.Run();
5462
5463 wxPrintf(_T("Main program exit code: %ld.\n"),
5464 wxExecute(_T("false"), wxEXEC_SYNC));
5465
5466 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
5467 }
5468
5469 // semaphore tests
5470 #include "wx/datetime.h"
5471
5472 class MySemaphoreThread : public wxThread
5473 {
5474 public:
5475 MySemaphoreThread(int i, wxSemaphore *sem)
5476 : wxThread(wxTHREAD_JOINABLE),
5477 m_sem(sem),
5478 m_i(i)
5479 {
5480 Create();
5481 }
5482
5483 virtual ExitCode Entry()
5484 {
5485 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
5486 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
5487
5488 m_sem->Wait();
5489
5490 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
5491 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
5492
5493 Sleep(1000);
5494
5495 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
5496 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
5497
5498 m_sem->Post();
5499
5500 return 0;
5501 }
5502
5503 private:
5504 wxSemaphore *m_sem;
5505 int m_i;
5506 };
5507
5508 WX_DEFINE_ARRAY(wxThread *, ArrayThreads);
5509
5510 static void TestSemaphore()
5511 {
5512 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5513
5514 static const int SEM_LIMIT = 3;
5515
5516 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
5517 ArrayThreads threads;
5518
5519 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
5520 {
5521 threads.Add(new MySemaphoreThread(i, &sem));
5522 threads.Last()->Run();
5523 }
5524
5525 for ( size_t n = 0; n < threads.GetCount(); n++ )
5526 {
5527 threads[n]->Wait();
5528 delete threads[n];
5529 }
5530 }
5531
5532 #endif // TEST_THREADS
5533
5534 // ----------------------------------------------------------------------------
5535 // arrays
5536 // ----------------------------------------------------------------------------
5537
5538 #ifdef TEST_ARRAYS
5539
5540 #include "wx/dynarray.h"
5541
5542 typedef unsigned short ushort;
5543
5544 #define DefineCompare(name, T) \
5545 \
5546 int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
5547 { \
5548 return first - second; \
5549 } \
5550 \
5551 int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
5552 { \
5553 return *first - *second; \
5554 } \
5555 \
5556 int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
5557 { \
5558 return *second - *first; \
5559 } \
5560
5561 DefineCompare(UShort, ushort);
5562 DefineCompare(Int, int);
5563
5564 // test compilation of all macros
5565 WX_DEFINE_ARRAY_SHORT(ushort, wxArrayUShort);
5566 WX_DEFINE_SORTED_ARRAY_SHORT(ushort, wxSortedArrayUShortNoCmp);
5567 WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort, UShortCompareValues, wxSortedArrayUShort);
5568 WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues, wxSortedArrayInt);
5569
5570 WX_DECLARE_OBJARRAY(Bar, ArrayBars);
5571 #include "wx/arrimpl.cpp"
5572 WX_DEFINE_OBJARRAY(ArrayBars);
5573
5574 static void PrintArray(const wxChar* name, const wxArrayString& array)
5575 {
5576 wxPrintf(_T("Dump of the array '%s'\n"), name);
5577
5578 size_t nCount = array.GetCount();
5579 for ( size_t n = 0; n < nCount; n++ )
5580 {
5581 wxPrintf(_T("\t%s[%u] = '%s'\n"), name, n, array[n].c_str());
5582 }
5583 }
5584
5585 int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
5586 const wxString& second)
5587 {
5588 return first.length() - second.length();
5589 }
5590
5591 #define TestArrayOf(name) \
5592 \
5593 static void PrintArray(const wxChar* name, const wxSortedArray##name & array) \
5594 { \
5595 wxPrintf(_T("Dump of the array '%s'\n"), name); \
5596 \
5597 size_t nCount = array.GetCount(); \
5598 for ( size_t n = 0; n < nCount; n++ ) \
5599 { \
5600 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
5601 } \
5602 } \
5603 \
5604 static void PrintArray(const wxChar* name, const wxArray##name & array) \
5605 { \
5606 wxPrintf(_T("Dump of the array '%s'\n"), name); \
5607 \
5608 size_t nCount = array.GetCount(); \
5609 for ( size_t n = 0; n < nCount; n++ ) \
5610 { \
5611 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
5612 } \
5613 } \
5614 \
5615 static void TestArrayOf ## name ## s() \
5616 { \
5617 wxPrintf(_T("*** Testing wxArray%s ***\n"), #name); \
5618 \
5619 wxArray##name a; \
5620 a.Add(1); \
5621 a.Add(17,2); \
5622 a.Add(5,3); \
5623 a.Add(3,4); \
5624 \
5625 wxPuts(_T("Initially:")); \
5626 PrintArray(_T("a"), a); \
5627 \
5628 wxPuts(_T("After sort:")); \
5629 a.Sort(name ## Compare); \
5630 PrintArray(_T("a"), a); \
5631 \
5632 wxPuts(_T("After reverse sort:")); \
5633 a.Sort(name ## RevCompare); \
5634 PrintArray(_T("a"), a); \
5635 \
5636 wxSortedArray##name b; \
5637 b.Add(1); \
5638 b.Add(17); \
5639 b.Add(5); \
5640 b.Add(3); \
5641 \
5642 wxPuts(_T("Sorted array initially:")); \
5643 PrintArray(_T("b"), b); \
5644 }
5645
5646 TestArrayOf(UShort);
5647 TestArrayOf(Int);
5648
5649 static void TestArrayOfObjects()
5650 {
5651 wxPuts(_T("*** Testing wxObjArray ***\n"));
5652
5653 {
5654 ArrayBars bars;
5655 Bar bar("second bar (two copies!)");
5656
5657 wxPrintf(_T("Initially: %u objects in the array, %u objects total.\n"),
5658 bars.GetCount(), Bar::GetNumber());
5659
5660 bars.Add(new Bar("first bar"));
5661 bars.Add(bar,2);
5662
5663 wxPrintf(_T("Now: %u objects in the array, %u objects total.\n"),
5664 bars.GetCount(), Bar::GetNumber());
5665
5666 bars.RemoveAt(1, bars.GetCount() - 1);
5667
5668 wxPrintf(_T("After removing all but first element: %u objects in the ")
5669 _T("array, %u objects total.\n"),
5670 bars.GetCount(), Bar::GetNumber());
5671
5672 bars.Empty();
5673
5674 wxPrintf(_T("After Empty(): %u objects in the array, %u objects total.\n"),
5675 bars.GetCount(), Bar::GetNumber());
5676 }
5677
5678 wxPrintf(_T("Finally: no more objects in the array, %u objects total.\n"),
5679 Bar::GetNumber());
5680 }
5681
5682 #endif // TEST_ARRAYS
5683
5684 // ----------------------------------------------------------------------------
5685 // strings
5686 // ----------------------------------------------------------------------------
5687
5688 #ifdef TEST_STRINGS
5689
5690 #include "wx/timer.h"
5691 #include "wx/tokenzr.h"
5692
5693 static void TestStringConstruction()
5694 {
5695 wxPuts(_T("*** Testing wxString constructores ***"));
5696
5697 #define TEST_CTOR(args, res) \
5698 { \
5699 wxString s args ; \
5700 wxPrintf(_T("wxString%s = %s "), #args, s.c_str()); \
5701 if ( s == res ) \
5702 { \
5703 wxPuts(_T("(ok)")); \
5704 } \
5705 else \
5706 { \
5707 wxPrintf(_T("(ERROR: should be %s)\n"), res); \
5708 } \
5709 }
5710
5711 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5712 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5713 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5714 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5715
5716 static const wxChar *s = _T("?really!");
5717 const wxChar *start = wxStrchr(s, _T('r'));
5718 const wxChar *end = wxStrchr(s, _T('!'));
5719 TEST_CTOR((start, end), _T("really"));
5720
5721 wxPuts(_T(""));
5722 }
5723
5724 static void TestString()
5725 {
5726 wxStopWatch sw;
5727
5728 wxString a, b, c;
5729
5730 a.reserve (128);
5731 b.reserve (128);
5732 c.reserve (128);
5733
5734 for (int i = 0; i < 1000000; ++i)
5735 {
5736 a = "Hello";
5737 b = " world";
5738 c = "! How'ya doin'?";
5739 a += b;
5740 a += c;
5741 c = "Hello world! What's up?";
5742 if (c != a)
5743 c = "Doh!";
5744 }
5745
5746 wxPrintf(_T("TestString elapsed time: %ld\n"), sw.Time());
5747 }
5748
5749 static void TestPChar()
5750 {
5751 wxStopWatch sw;
5752
5753 wxChar a [128];
5754 wxChar b [128];
5755 wxChar c [128];
5756
5757 for (int i = 0; i < 1000000; ++i)
5758 {
5759 wxStrcpy (a, _T("Hello"));
5760 wxStrcpy (b, _T(" world"));
5761 wxStrcpy (c, _T("! How'ya doin'?"));
5762 wxStrcat (a, b);
5763 wxStrcat (a, c);
5764 wxStrcpy (c, _T("Hello world! What's up?"));
5765 if (wxStrcmp (c, a) == 0)
5766 wxStrcpy (c, _T("Doh!"));
5767 }
5768
5769 wxPrintf(_T("TestPChar elapsed time: %ld\n"), sw.Time());
5770 }
5771
5772 static void TestStringSub()
5773 {
5774 wxString s("Hello, world!");
5775
5776 wxPuts(_T("*** Testing wxString substring extraction ***"));
5777
5778 wxPrintf(_T("String = '%s'\n"), s.c_str());
5779 wxPrintf(_T("Left(5) = '%s'\n"), s.Left(5).c_str());
5780 wxPrintf(_T("Right(6) = '%s'\n"), s.Right(6).c_str());
5781 wxPrintf(_T("Mid(3, 5) = '%s'\n"), s(3, 5).c_str());
5782 wxPrintf(_T("Mid(3) = '%s'\n"), s.Mid(3).c_str());
5783 wxPrintf(_T("substr(3, 5) = '%s'\n"), s.substr(3, 5).c_str());
5784 wxPrintf(_T("substr(3) = '%s'\n"), s.substr(3).c_str());
5785
5786 static const wxChar *prefixes[] =
5787 {
5788 _T("Hello"),
5789 _T("Hello, "),
5790 _T("Hello, world!"),
5791 _T("Hello, world!!!"),
5792 _T(""),
5793 _T("Goodbye"),
5794 _T("Hi"),
5795 };
5796
5797 for ( size_t n = 0; n < WXSIZEOF(prefixes); n++ )
5798 {
5799 wxString prefix = prefixes[n], rest;
5800 bool rc = s.StartsWith(prefix, &rest);
5801 wxPrintf(_T("StartsWith('%s') = %s"), prefix.c_str(), rc ? _T("TRUE") : _T("FALSE"));
5802 if ( rc )
5803 {
5804 wxPrintf(_T(" (the rest is '%s')\n"), rest.c_str());
5805 }
5806 else
5807 {
5808 putchar('\n');
5809 }
5810 }
5811
5812 wxPuts(_T(""));
5813 }
5814
5815 static void TestStringFormat()
5816 {
5817 wxPuts(_T("*** Testing wxString formatting ***"));
5818
5819 wxString s;
5820 s.Printf(_T("%03d"), 18);
5821
5822 wxPrintf(_T("Number 18: %s\n"), wxString::Format(_T("%03d"), 18).c_str());
5823 wxPrintf(_T("Number 18: %s\n"), s.c_str());
5824
5825 wxPuts(_T(""));
5826 }
5827
5828 // returns "not found" for npos, value for all others
5829 static wxString PosToString(size_t res)
5830 {
5831 wxString s = res == wxString::npos ? wxString(_T("not found"))
5832 : wxString::Format(_T("%u"), res);
5833 return s;
5834 }
5835
5836 static void TestStringFind()
5837 {
5838 wxPuts(_T("*** Testing wxString find() functions ***"));
5839
5840 static const wxChar *strToFind = _T("ell");
5841 static const struct StringFindTest
5842 {
5843 const wxChar *str;
5844 size_t start,
5845 result; // of searching "ell" in str
5846 } findTestData[] =
5847 {
5848 { _T("Well, hello world"), 0, 1 },
5849 { _T("Well, hello world"), 6, 7 },
5850 { _T("Well, hello world"), 9, wxString::npos },
5851 };
5852
5853 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
5854 {
5855 const StringFindTest& ft = findTestData[n];
5856 size_t res = wxString(ft.str).find(strToFind, ft.start);
5857
5858 wxPrintf(_T("Index of '%s' in '%s' starting from %u is %s "),
5859 strToFind, ft.str, ft.start, PosToString(res).c_str());
5860
5861 size_t resTrue = ft.result;
5862 if ( res == resTrue )
5863 {
5864 wxPuts(_T("(ok)"));
5865 }
5866 else
5867 {
5868 wxPrintf(_T("(ERROR: should be %s)\n"),
5869 PosToString(resTrue).c_str());
5870 }
5871 }
5872
5873 wxPuts(_T(""));
5874 }
5875
5876 static void TestStringTokenizer()
5877 {
5878 wxPuts(_T("*** Testing wxStringTokenizer ***"));
5879
5880 static const wxChar *modeNames[] =
5881 {
5882 _T("default"),
5883 _T("return empty"),
5884 _T("return all empty"),
5885 _T("with delims"),
5886 _T("like strtok"),
5887 };
5888
5889 static const struct StringTokenizerTest
5890 {
5891 const wxChar *str; // string to tokenize
5892 const wxChar *delims; // delimiters to use
5893 size_t count; // count of token
5894 wxStringTokenizerMode mode; // how should we tokenize it
5895 } tokenizerTestData[] =
5896 {
5897 { _T(""), _T(" "), 0 },
5898 { _T("Hello, world"), _T(" "), 2 },
5899 { _T("Hello, world "), _T(" "), 2 },
5900 { _T("Hello, world"), _T(","), 2 },
5901 { _T("Hello, world!"), _T(",!"), 2 },
5902 { _T("Hello,, world!"), _T(",!"), 3 },
5903 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
5904 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
5905 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
5906 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
5907 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
5908 { _T("01/02/99"), _T("/-"), 3 },
5909 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
5910 };
5911
5912 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
5913 {
5914 const StringTokenizerTest& tt = tokenizerTestData[n];
5915 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
5916
5917 size_t count = tkz.CountTokens();
5918 wxPrintf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
5919 MakePrintable(tt.str).c_str(),
5920 count,
5921 MakePrintable(tt.delims).c_str(),
5922 modeNames[tkz.GetMode()]);
5923 if ( count == tt.count )
5924 {
5925 wxPuts(_T("(ok)"));
5926 }
5927 else
5928 {
5929 wxPrintf(_T("(ERROR: should be %u)\n"), tt.count);
5930
5931 continue;
5932 }
5933
5934 // if we emulate strtok(), check that we do it correctly
5935 wxChar *buf, *s = NULL, *last;
5936
5937 if ( tkz.GetMode() == wxTOKEN_STRTOK )
5938 {
5939 buf = new wxChar[wxStrlen(tt.str) + 1];
5940 wxStrcpy(buf, tt.str);
5941
5942 s = wxStrtok(buf, tt.delims, &last);
5943 }
5944 else
5945 {
5946 buf = NULL;
5947 }
5948
5949 // now show the tokens themselves
5950 size_t count2 = 0;
5951 while ( tkz.HasMoreTokens() )
5952 {
5953 wxString token = tkz.GetNextToken();
5954
5955 wxPrintf(_T("\ttoken %u: '%s'"),
5956 ++count2,
5957 MakePrintable(token).c_str());
5958
5959 if ( buf )
5960 {
5961 if ( token == s )
5962 {
5963 wxPuts(_T(" (ok)"));
5964 }
5965 else
5966 {
5967 wxPrintf(_T(" (ERROR: should be %s)\n"), s);
5968 }
5969
5970 s = wxStrtok(NULL, tt.delims, &last);
5971 }
5972 else
5973 {
5974 // nothing to compare with
5975 wxPuts(_T(""));
5976 }
5977 }
5978
5979 if ( count2 != count )
5980 {
5981 wxPuts(_T("\tERROR: token count mismatch"));
5982 }
5983
5984 delete [] buf;
5985 }
5986
5987 wxPuts(_T(""));
5988 }
5989
5990 static void TestStringReplace()
5991 {
5992 wxPuts(_T("*** Testing wxString::replace ***"));
5993
5994 static const struct StringReplaceTestData
5995 {
5996 const wxChar *original; // original test string
5997 size_t start, len; // the part to replace
5998 const wxChar *replacement; // the replacement string
5999 const wxChar *result; // and the expected result
6000 } stringReplaceTestData[] =
6001 {
6002 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
6003 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
6004 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
6005 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
6006 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
6007 };
6008
6009 for ( size_t n = 0; n < WXSIZEOF(stringReplaceTestData); n++ )
6010 {
6011 const StringReplaceTestData data = stringReplaceTestData[n];
6012
6013 wxString original = data.original;
6014 original.replace(data.start, data.len, data.replacement);
6015
6016 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
6017 data.original, data.start, data.len, data.replacement,
6018 original.c_str());
6019
6020 if ( original == data.result )
6021 {
6022 wxPuts(_T("(ok)"));
6023 }
6024 else
6025 {
6026 wxPrintf(_T("(ERROR: should be '%s')\n"), data.result);
6027 }
6028 }
6029
6030 wxPuts(_T(""));
6031 }
6032
6033 static void TestStringMatch()
6034 {
6035 wxPuts(_T("*** Testing wxString::Matches() ***"));
6036
6037 static const struct StringMatchTestData
6038 {
6039 const wxChar *text;
6040 const wxChar *wildcard;
6041 bool matches;
6042 } stringMatchTestData[] =
6043 {
6044 { _T("foobar"), _T("foo*"), 1 },
6045 { _T("foobar"), _T("*oo*"), 1 },
6046 { _T("foobar"), _T("*bar"), 1 },
6047 { _T("foobar"), _T("??????"), 1 },
6048 { _T("foobar"), _T("f??b*"), 1 },
6049 { _T("foobar"), _T("f?b*"), 0 },
6050 { _T("foobar"), _T("*goo*"), 0 },
6051 { _T("foobar"), _T("*foo"), 0 },
6052 { _T("foobarfoo"), _T("*foo"), 1 },
6053 { _T(""), _T("*"), 1 },
6054 { _T(""), _T("?"), 0 },
6055 };
6056
6057 for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
6058 {
6059 const StringMatchTestData& data = stringMatchTestData[n];
6060 bool matches = wxString(data.text).Matches(data.wildcard);
6061 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
6062 data.wildcard,
6063 matches ? _T("matches") : _T("doesn't match"),
6064 data.text,
6065 matches == data.matches ? _T("ok") : _T("ERROR"));
6066 }
6067
6068 wxPuts(_T(""));
6069 }
6070
6071 #endif // TEST_STRINGS
6072
6073 // ----------------------------------------------------------------------------
6074 // entry point
6075 // ----------------------------------------------------------------------------
6076
6077 #ifdef TEST_SNGLINST
6078 #include "wx/snglinst.h"
6079 #endif // TEST_SNGLINST
6080
6081 int main(int argc, char **argv)
6082 {
6083 wxApp::CheckBuildOptions(wxBuildOptions());
6084
6085 wxInitializer initializer;
6086 if ( !initializer )
6087 {
6088 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
6089
6090 return -1;
6091 }
6092
6093 #ifdef TEST_SNGLINST
6094 wxSingleInstanceChecker checker;
6095 if ( checker.Create(_T(".wxconsole.lock")) )
6096 {
6097 if ( checker.IsAnotherRunning() )
6098 {
6099 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
6100
6101 return 1;
6102 }
6103
6104 // wait some time to give time to launch another instance
6105 wxPrintf(_T("Press \"Enter\" to continue..."));
6106 wxFgetc(stdin);
6107 }
6108 else // failed to create
6109 {
6110 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
6111 }
6112 #endif // TEST_SNGLINST
6113
6114 #ifdef TEST_CHARSET
6115 TestCharset();
6116 #endif // TEST_CHARSET
6117
6118 #ifdef TEST_CMDLINE
6119 TestCmdLineConvert();
6120
6121 #if wxUSE_CMDLINE_PARSER
6122 static const wxCmdLineEntryDesc cmdLineDesc[] =
6123 {
6124 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
6125 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
6126 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
6127 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },
6128
6129 { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },
6130 { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },
6131 { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),
6132 wxCMD_LINE_VAL_NUMBER },
6133 { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),
6134 wxCMD_LINE_VAL_DATE },
6135
6136 { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),
6137 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
6138
6139 { wxCMD_LINE_NONE }
6140 };
6141
6142 #if wxUSE_UNICODE
6143 wxChar **wargv = new wxChar *[argc + 1];
6144
6145 {
6146 for ( int n = 0; n < argc; n++ )
6147 {
6148 wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
6149 wargv[n] = wxStrdup(warg);
6150 }
6151
6152 wargv[n] = NULL;
6153 }
6154
6155 #define argv wargv
6156 #endif // wxUSE_UNICODE
6157
6158 wxCmdLineParser parser(cmdLineDesc, argc, argv);
6159
6160 #if wxUSE_UNICODE
6161 {
6162 for ( int n = 0; n < argc; n++ )
6163 free(wargv[n]);
6164
6165 delete [] wargv;
6166 }
6167 #endif // wxUSE_UNICODE
6168
6169 parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
6170 wxCMD_LINE_VAL_STRING,
6171 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
6172
6173 switch ( parser.Parse() )
6174 {
6175 case -1:
6176 wxLogMessage(_T("Help was given, terminating."));
6177 break;
6178
6179 case 0:
6180 ShowCmdLine(parser);
6181 break;
6182
6183 default:
6184 wxLogMessage(_T("Syntax error detected, aborting."));
6185 break;
6186 }
6187 #endif // wxUSE_CMDLINE_PARSER
6188
6189 #endif // TEST_CMDLINE
6190
6191 #ifdef TEST_STRINGS
6192 if ( TEST_ALL )
6193 {
6194 TestPChar();
6195 TestString();
6196 TestStringSub();
6197 TestStringConstruction();
6198 TestStringFormat();
6199 TestStringFind();
6200 TestStringTokenizer();
6201 TestStringReplace();
6202 }
6203 else
6204 {
6205 TestStringMatch();
6206 }
6207 #endif // TEST_STRINGS
6208
6209 #ifdef TEST_ARRAYS
6210 if ( TEST_ALL )
6211 {
6212 wxArrayString a1;
6213 a1.Add(_T("tiger"));
6214 a1.Add(_T("cat"));
6215 a1.Add(_T("lion"), 3);
6216 a1.Add(_T("dog"));
6217 a1.Add(_T("human"));
6218 a1.Add(_T("ape"));
6219
6220 wxPuts(_T("*** Initially:"));
6221
6222 PrintArray(_T("a1"), a1);
6223
6224 wxArrayString a2(a1);
6225 PrintArray(_T("a2"), a2);
6226
6227 wxSortedArrayString a3(a1);
6228 PrintArray(_T("a3"), a3);
6229
6230 wxPuts(_T("*** After deleting three strings from a1"));
6231 a1.Remove(2,3);
6232
6233 PrintArray(_T("a1"), a1);
6234 PrintArray(_T("a2"), a2);
6235 PrintArray(_T("a3"), a3);
6236
6237 wxPuts(_T("*** After reassigning a1 to a2 and a3"));
6238 a3 = a2 = a1;
6239 PrintArray(_T("a2"), a2);
6240 PrintArray(_T("a3"), a3);
6241
6242 wxPuts(_T("*** After sorting a1"));
6243 a1.Sort();
6244 PrintArray(_T("a1"), a1);
6245
6246 wxPuts(_T("*** After sorting a1 in reverse order"));
6247 a1.Sort(TRUE);
6248 PrintArray(_T("a1"), a1);
6249
6250 wxPuts(_T("*** After sorting a1 by the string length"));
6251 a1.Sort(StringLenCompare);
6252 PrintArray(_T("a1"), a1);
6253
6254 TestArrayOfObjects();
6255 TestArrayOfUShorts();
6256 }
6257
6258 TestArrayOfInts();
6259 #endif // TEST_ARRAYS
6260
6261 #ifdef TEST_DIR
6262 if ( TEST_ALL )
6263 {
6264 TestDirExists();
6265 TestDirTraverse();
6266 }
6267 TestDirEnum();
6268 #endif // TEST_DIR
6269
6270 #ifdef TEST_DLLLOADER
6271 TestDllLoad();
6272 #endif // TEST_DLLLOADER
6273
6274 #ifdef TEST_ENVIRON
6275 TestEnvironment();
6276 #endif // TEST_ENVIRON
6277
6278 #ifdef TEST_EXECUTE
6279 TestExecute();
6280 #endif // TEST_EXECUTE
6281
6282 #ifdef TEST_FILECONF
6283 TestFileConfRead();
6284 #endif // TEST_FILECONF
6285
6286 #ifdef TEST_LIST
6287 TestListCtor();
6288 #endif // TEST_LIST
6289
6290 #ifdef TEST_LOCALE
6291 TestDefaultLang();
6292 #endif // TEST_LOCALE
6293
6294 #ifdef TEST_LOG
6295 wxString s;
6296 for ( size_t n = 0; n < 8000; n++ )
6297 {
6298 s << (wxChar)(_T('A') + (n % 26));
6299 }
6300
6301 wxString msg;
6302 msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
6303
6304 // this one shouldn't be truncated
6305 wxPrintf(msg);
6306
6307 // but this one will because log functions use fixed size buffer
6308 // (note that it doesn't need '\n' at the end neither - will be added
6309 // by wxLog anyhow)
6310 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
6311 #endif // TEST_LOG
6312
6313 #ifdef TEST_FILE
6314 if ( TEST_ALL )
6315 {
6316 TestFileRead();
6317 TestTextFileRead();
6318 TestFileCopy();
6319 }
6320 #endif // TEST_FILE
6321
6322 #ifdef TEST_FILENAME
6323 if ( 0 )
6324 {
6325 wxFileName fn;
6326 fn.Assign(_T("c:\\foo"), _T("bar.baz"));
6327 fn.Assign(_T("/u/os9-port/Viewer/tvision/WEI2HZ-3B3-14_05-04-00MSC1.asc"));
6328
6329 DumpFileName(fn);
6330 }
6331
6332 TestFileNameConstruction();
6333 if ( TEST_ALL )
6334 {
6335 TestFileNameConstruction();
6336 TestFileNameMakeRelative();
6337 TestFileNameSplit();
6338 TestFileNameTemp();
6339 TestFileNameCwd();
6340 TestFileNameComparison();
6341 TestFileNameOperations();
6342 }
6343 #endif // TEST_FILENAME
6344
6345 #ifdef TEST_FILETIME
6346 TestFileGetTimes();
6347 if ( 0 )
6348 TestFileSetTimes();
6349 #endif // TEST_FILETIME
6350
6351 #ifdef TEST_FTP
6352 wxLog::AddTraceMask(FTP_TRACE_MASK);
6353 if ( TestFtpConnect() )
6354 {
6355 if ( TEST_ALL )
6356 {
6357 TestFtpList();
6358 TestFtpDownload();
6359 TestFtpMisc();
6360 TestFtpFileSize();
6361 TestFtpUpload();
6362 }
6363
6364 if ( TEST_INTERACTIVE )
6365 TestFtpInteractive();
6366 }
6367 //else: connecting to the FTP server failed
6368
6369 if ( 0 )
6370 TestFtpWuFtpd();
6371 #endif // TEST_FTP
6372
6373 #ifdef TEST_LONGLONG
6374 // seed pseudo random generator
6375 srand((unsigned)time(NULL));
6376
6377 if ( 0 )
6378 {
6379 TestSpeed();
6380 }
6381
6382 if ( TEST_ALL )
6383 {
6384 TestMultiplication();
6385 TestDivision();
6386 TestAddition();
6387 TestLongLongConversion();
6388 TestBitOperations();
6389 TestLongLongComparison();
6390 TestLongLongPrint();
6391 }
6392 #endif // TEST_LONGLONG
6393
6394 #ifdef TEST_HASH
6395 TestHash();
6396 #endif // TEST_HASH
6397
6398 #ifdef TEST_HASHMAP
6399 TestHashMap();
6400 #endif // TEST_HASHMAP
6401
6402 #ifdef TEST_MIME
6403 wxLog::AddTraceMask(_T("mime"));
6404 if ( TEST_ALL )
6405 {
6406 TestMimeEnum();
6407 TestMimeOverride();
6408 TestMimeAssociate();
6409 }
6410 TestMimeFilename();
6411 #endif // TEST_MIME
6412
6413 #ifdef TEST_INFO_FUNCTIONS
6414 if ( TEST_ALL )
6415 {
6416 TestOsInfo();
6417 TestUserInfo();
6418
6419 if ( TEST_INTERACTIVE )
6420 TestDiskInfo();
6421 }
6422 #endif // TEST_INFO_FUNCTIONS
6423
6424 #ifdef TEST_PATHLIST
6425 TestPathList();
6426 #endif // TEST_PATHLIST
6427
6428 #ifdef TEST_ODBC
6429 TestDbOpen();
6430 #endif // TEST_ODBC
6431
6432 #ifdef TEST_PRINTF
6433 TestPrintf();
6434 #endif // TEST_PRINTF
6435
6436 #ifdef TEST_REGCONF
6437 TestRegConfWrite();
6438 #endif // TEST_REGCONF
6439
6440 #ifdef TEST_REGEX
6441 // TODO: write a real test using src/regex/tests file
6442 if ( TEST_ALL )
6443 {
6444 TestRegExCompile();
6445 TestRegExMatch();
6446 TestRegExSubmatch();
6447 TestRegExReplacement();
6448
6449 if ( TEST_INTERACTIVE )
6450 TestRegExInteractive();
6451 }
6452 #endif // TEST_REGEX
6453
6454 #ifdef TEST_REGISTRY
6455 TestRegistryRead();
6456 TestRegistryAssociation();
6457 #endif // TEST_REGISTRY
6458
6459 #ifdef TEST_SOCKETS
6460 TestSocketServer();
6461 TestSocketClient();
6462 #endif // TEST_SOCKETS
6463
6464 #ifdef TEST_STREAMS
6465 if ( TEST_ALL )
6466 {
6467 TestFileStream();
6468 }
6469 TestMemoryStream();
6470 #endif // TEST_STREAMS
6471
6472 #ifdef TEST_THREADS
6473 int nCPUs = wxThread::GetCPUCount();
6474 wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
6475 if ( nCPUs != -1 )
6476 wxThread::SetConcurrency(nCPUs);
6477
6478 TestDetachedThreads();
6479 if ( TEST_ALL )
6480 {
6481 TestJoinableThreads();
6482 TestThreadSuspend();
6483 TestThreadDelete();
6484 TestThreadConditions();
6485 TestThreadExec();
6486 TestSemaphore();
6487 }
6488 #endif // TEST_THREADS
6489
6490 #ifdef TEST_TIMER
6491 TestStopWatch();
6492 #endif // TEST_TIMER
6493
6494 #ifdef TEST_DATETIME
6495 if ( TEST_ALL )
6496 {
6497 TestTimeSet();
6498 TestTimeStatic();
6499 TestTimeRange();
6500 TestTimeZones();
6501 TestTimeTicks();
6502 TestTimeJDN();
6503 TestTimeDST();
6504 TestTimeWDays();
6505 TestTimeWNumber();
6506 TestTimeParse();
6507 TestTimeArithmetics();
6508 TestTimeHolidays();
6509 TestTimeFormat();
6510 TestTimeSpanFormat();
6511 TestTimeMS();
6512
6513 TestTimeZoneBug();
6514 }
6515 TestTimeFormat();
6516
6517 if ( TEST_INTERACTIVE )
6518 TestDateTimeInteractive();
6519 #endif // TEST_DATETIME
6520
6521 #ifdef TEST_USLEEP
6522 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
6523 wxUsleep(3000);
6524 #endif // TEST_USLEEP
6525
6526 #ifdef TEST_VCARD
6527 TestVCardRead();
6528 TestVCardWrite();
6529 #endif // TEST_VCARD
6530
6531 #ifdef TEST_VOLUME
6532 TestFSVolume();
6533 #endif // TEST_VOLUME
6534
6535 #ifdef TEST_UNICODE
6536 TestUnicodeToFromAscii();
6537 #endif // TEST_UNICODE
6538
6539 #ifdef TEST_WCHAR
6540 TestUtf8();
6541 TestEncodingConverter();
6542 #endif // TEST_WCHAR
6543
6544 #ifdef TEST_ZIP
6545 TestZipStreamRead();
6546 TestZipFileSystem();
6547 #endif // TEST_ZIP
6548
6549 #ifdef TEST_ZLIB
6550 TestZlibStreamWrite();
6551 TestZlibStreamRead();
6552 #endif // TEST_ZLIB
6553
6554 return 0;
6555 }
6556