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