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