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