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