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