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