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