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