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