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