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