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