1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/console/console.cpp
3 // Purpose: a sample console (as opposed to GUI) progam using wxWindows
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
23 #error "This sample can't be compiled in GUI mode."
28 #include "wx/string.h"
32 // without this pragma, the stupid compiler precompiles #defines below so that
33 // changing them doesn't "take place" later!
38 // ----------------------------------------------------------------------------
39 // conditional compilation
40 // ----------------------------------------------------------------------------
43 A note about all these conditional compilation macros: this file is used
44 both as a test suite for various non-GUI wxWindows classes and as a
45 scratchpad for quick tests. So there are two compilation modes: if you
46 define TEST_ALL all tests are run, otherwise you may enable the individual
47 tests individually in the "#else" branch below.
50 // what to test (in alphabetic order)? uncomment the line below to do all tests
58 #define TEST_DLLLOADER
68 #define TEST_INFO_FUNCTIONS
86 // #define TEST_VCARD -- don't enable this (VZ)
93 static const bool TEST_ALL
= TRUE
;
97 static const bool TEST_ALL
= FALSE
;
100 // some tests are interactive, define this to run them
101 #ifdef TEST_INTERACTIVE
102 #undef TEST_INTERACTIVE
104 static const bool TEST_INTERACTIVE
= TRUE
;
106 static const bool TEST_INTERACTIVE
= FALSE
;
109 // ----------------------------------------------------------------------------
110 // test class for container objects
111 // ----------------------------------------------------------------------------
113 #if defined(TEST_ARRAYS) || defined(TEST_LIST)
115 class Bar
// Foo is already taken in the hash test
118 Bar(const wxString
& name
) : m_name(name
) { ms_bars
++; }
119 Bar(const Bar
& bar
) : m_name(bar
.m_name
) { ms_bars
++; }
120 ~Bar() { ms_bars
--; }
122 static size_t GetNumber() { return ms_bars
; }
124 const wxChar
*GetName() const { return m_name
; }
129 static size_t ms_bars
;
132 size_t Bar::ms_bars
= 0;
134 #endif // defined(TEST_ARRAYS) || defined(TEST_LIST)
136 // ============================================================================
138 // ============================================================================
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
144 #if defined(TEST_STRINGS) || defined(TEST_SOCKETS)
146 // replace TABs with \t and CRs with \n
147 static wxString
MakePrintable(const wxChar
*s
)
150 (void)str
.Replace(_T("\t"), _T("\\t"));
151 (void)str
.Replace(_T("\n"), _T("\\n"));
152 (void)str
.Replace(_T("\r"), _T("\\r"));
157 #endif // MakePrintable() is used
159 // ----------------------------------------------------------------------------
160 // wxFontMapper::CharsetToEncoding
161 // ----------------------------------------------------------------------------
165 #include "wx/fontmap.h"
167 static void TestCharset()
169 static const wxChar
*charsets
[] =
171 // some vali charsets
180 // and now some bogus ones
187 for ( size_t n
= 0; n
< WXSIZEOF(charsets
); n
++ )
189 wxFontEncoding enc
= wxFontMapper::Get()->CharsetToEncoding(charsets
[n
]);
190 wxPrintf(_T("Charset: %s\tEncoding: %s (%s)\n"),
192 wxFontMapper::Get()->GetEncodingName(enc
).c_str(),
193 wxFontMapper::Get()->GetEncodingDescription(enc
).c_str());
197 #endif // TEST_CHARSET
199 // ----------------------------------------------------------------------------
201 // ----------------------------------------------------------------------------
205 #include "wx/cmdline.h"
206 #include "wx/datetime.h"
209 #if wxUSE_CMDLINE_PARSER
211 static void ShowCmdLine(const wxCmdLineParser
& parser
)
213 wxString s
= _T("Input files: ");
215 size_t count
= parser
.GetParamCount();
216 for ( size_t param
= 0; param
< count
; param
++ )
218 s
<< parser
.GetParam(param
) << ' ';
222 << _T("Verbose:\t") << (parser
.Found(_T("v")) ? _T("yes") : _T("no")) << '\n'
223 << _T("Quiet:\t") << (parser
.Found(_T("q")) ? _T("yes") : _T("no")) << '\n';
228 if ( parser
.Found(_T("o"), &strVal
) )
229 s
<< _T("Output file:\t") << strVal
<< '\n';
230 if ( parser
.Found(_T("i"), &strVal
) )
231 s
<< _T("Input dir:\t") << strVal
<< '\n';
232 if ( parser
.Found(_T("s"), &lVal
) )
233 s
<< _T("Size:\t") << lVal
<< '\n';
234 if ( parser
.Found(_T("d"), &dt
) )
235 s
<< _T("Date:\t") << dt
.FormatISODate() << '\n';
236 if ( parser
.Found(_T("project_name"), &strVal
) )
237 s
<< _T("Project:\t") << strVal
<< '\n';
242 #endif // wxUSE_CMDLINE_PARSER
244 static void TestCmdLineConvert()
246 static const wxChar
*cmdlines
[] =
249 _T("-a \"-bstring 1\" -c\"string 2\" \"string 3\""),
250 _T("literal \\\" and \"\""),
253 for ( size_t n
= 0; n
< WXSIZEOF(cmdlines
); n
++ )
255 const wxChar
*cmdline
= cmdlines
[n
];
256 wxPrintf(_T("Parsing: %s\n"), cmdline
);
257 wxArrayString args
= wxCmdLineParser::ConvertStringToArgs(cmdline
);
259 size_t count
= args
.GetCount();
260 wxPrintf(_T("\targc = %u\n"), count
);
261 for ( size_t arg
= 0; arg
< count
; arg
++ )
263 wxPrintf(_T("\targv[%u] = %s\n"), arg
, args
[arg
].c_str());
268 #endif // TEST_CMDLINE
270 // ----------------------------------------------------------------------------
272 // ----------------------------------------------------------------------------
279 static const wxChar
*ROOTDIR
= _T("/");
280 static const wxChar
*TESTDIR
= _T("/usr");
281 #elif defined(__WXMSW__)
282 static const wxChar
*ROOTDIR
= _T("c:\\");
283 static const wxChar
*TESTDIR
= _T("d:\\");
285 #error "don't know where the root directory is"
288 static void TestDirEnumHelper(wxDir
& dir
,
289 int flags
= wxDIR_DEFAULT
,
290 const wxString
& filespec
= wxEmptyString
)
294 if ( !dir
.IsOpened() )
297 bool cont
= dir
.GetFirst(&filename
, filespec
, flags
);
300 wxPrintf(_T("\t%s\n"), filename
.c_str());
302 cont
= dir
.GetNext(&filename
);
308 static void TestDirEnum()
310 wxPuts(_T("*** Testing wxDir::GetFirst/GetNext ***"));
312 wxString cwd
= wxGetCwd();
313 if ( !wxDir::Exists(cwd
) )
315 wxPrintf(_T("ERROR: current directory '%s' doesn't exist?\n"), cwd
.c_str());
320 if ( !dir
.IsOpened() )
322 wxPrintf(_T("ERROR: failed to open current directory '%s'.\n"), cwd
.c_str());
326 wxPuts(_T("Enumerating everything in current directory:"));
327 TestDirEnumHelper(dir
);
329 wxPuts(_T("Enumerating really everything in current directory:"));
330 TestDirEnumHelper(dir
, wxDIR_DEFAULT
| wxDIR_DOTDOT
);
332 wxPuts(_T("Enumerating object files in current directory:"));
333 TestDirEnumHelper(dir
, wxDIR_DEFAULT
, "*.o*");
335 wxPuts(_T("Enumerating directories in current directory:"));
336 TestDirEnumHelper(dir
, wxDIR_DIRS
);
338 wxPuts(_T("Enumerating files in current directory:"));
339 TestDirEnumHelper(dir
, wxDIR_FILES
);
341 wxPuts(_T("Enumerating files including hidden in current directory:"));
342 TestDirEnumHelper(dir
, wxDIR_FILES
| wxDIR_HIDDEN
);
346 wxPuts(_T("Enumerating everything in root directory:"));
347 TestDirEnumHelper(dir
, wxDIR_DEFAULT
);
349 wxPuts(_T("Enumerating directories in root directory:"));
350 TestDirEnumHelper(dir
, wxDIR_DIRS
);
352 wxPuts(_T("Enumerating files in root directory:"));
353 TestDirEnumHelper(dir
, wxDIR_FILES
);
355 wxPuts(_T("Enumerating files including hidden in root directory:"));
356 TestDirEnumHelper(dir
, wxDIR_FILES
| wxDIR_HIDDEN
);
358 wxPuts(_T("Enumerating files in non existing directory:"));
359 wxDir
dirNo("nosuchdir");
360 TestDirEnumHelper(dirNo
);
363 class DirPrintTraverser
: public wxDirTraverser
366 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
368 return wxDIR_CONTINUE
;
371 virtual wxDirTraverseResult
OnDir(const wxString
& dirname
)
373 wxString path
, name
, ext
;
374 wxSplitPath(dirname
, &path
, &name
, &ext
);
377 name
<< _T('.') << ext
;
380 for ( const wxChar
*p
= path
.c_str(); *p
; p
++ )
382 if ( wxIsPathSeparator(*p
) )
386 wxPrintf(_T("%s%s\n"), indent
.c_str(), name
.c_str());
388 return wxDIR_CONTINUE
;
392 static void TestDirTraverse()
394 wxPuts(_T("*** Testing wxDir::Traverse() ***"));
398 size_t n
= wxDir::GetAllFiles(TESTDIR
, &files
);
399 wxPrintf(_T("There are %u files under '%s'\n"), n
, TESTDIR
);
402 wxPrintf(_T("First one is '%s'\n"), files
[0u].c_str());
403 wxPrintf(_T(" last one is '%s'\n"), files
[n
- 1].c_str());
406 // enum again with custom traverser
408 DirPrintTraverser traverser
;
409 dir
.Traverse(traverser
, _T(""), wxDIR_DIRS
| wxDIR_HIDDEN
);
412 static void TestDirExists()
414 wxPuts(_T("*** Testing wxDir::Exists() ***"));
416 static const wxChar
*dirnames
[] =
419 #if defined(__WXMSW__)
422 _T("\\\\share\\file"),
426 _T("c:\\autoexec.bat"),
427 #elif defined(__UNIX__)
436 for ( size_t n
= 0; n
< WXSIZEOF(dirnames
); n
++ )
438 wxPrintf(_T("%-40s: %s\n"),
440 wxDir::Exists(dirnames
[n
]) ? _T("exists")
441 : _T("doesn't exist"));
447 // ----------------------------------------------------------------------------
449 // ----------------------------------------------------------------------------
451 #ifdef TEST_DLLLOADER
453 #include "wx/dynlib.h"
455 static void TestDllLoad()
457 #if defined(__WXMSW__)
458 static const wxChar
*LIB_NAME
= _T("kernel32.dll");
459 static const wxChar
*FUNC_NAME
= _T("lstrlenA");
460 #elif defined(__UNIX__)
461 // weird: using just libc.so does *not* work!
462 static const wxChar
*LIB_NAME
= _T("/lib/libc-2.0.7.so");
463 static const wxChar
*FUNC_NAME
= _T("strlen");
465 #error "don't know how to test wxDllLoader on this platform"
468 wxPuts(_T("*** testing wxDllLoader ***\n"));
470 wxDynamicLibrary
lib(LIB_NAME
);
471 if ( !lib
.IsLoaded() )
473 wxPrintf(_T("ERROR: failed to load '%s'.\n"), LIB_NAME
);
477 typedef int (*wxStrlenType
)(const char *);
478 wxStrlenType pfnStrlen
= (wxStrlenType
)lib
.GetSymbol(FUNC_NAME
);
481 wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
482 FUNC_NAME
, LIB_NAME
);
486 if ( pfnStrlen("foo") != 3 )
488 wxPrintf(_T("ERROR: loaded function is not wxStrlen()!\n"));
492 wxPuts(_T("... ok"));
498 #endif // TEST_DLLLOADER
500 // ----------------------------------------------------------------------------
502 // ----------------------------------------------------------------------------
506 #include "wx/utils.h"
508 static wxString
MyGetEnv(const wxString
& var
)
511 if ( !wxGetEnv(var
, &val
) )
514 val
= wxString(_T('\'')) + val
+ _T('\'');
519 static void TestEnvironment()
521 const wxChar
*var
= _T("wxTestVar");
523 wxPuts(_T("*** testing environment access functions ***"));
525 wxPrintf(_T("Initially getenv(%s) = %s\n"), var
, MyGetEnv(var
).c_str());
526 wxSetEnv(var
, _T("value for wxTestVar"));
527 wxPrintf(_T("After wxSetEnv: getenv(%s) = %s\n"), var
, MyGetEnv(var
).c_str());
528 wxSetEnv(var
, _T("another value"));
529 wxPrintf(_T("After 2nd wxSetEnv: getenv(%s) = %s\n"), var
, MyGetEnv(var
).c_str());
531 wxPrintf(_T("After wxUnsetEnv: getenv(%s) = %s\n"), var
, MyGetEnv(var
).c_str());
532 wxPrintf(_T("PATH = %s\n"), MyGetEnv(_T("PATH")).c_str());
535 #endif // TEST_ENVIRON
537 // ----------------------------------------------------------------------------
539 // ----------------------------------------------------------------------------
543 #include "wx/utils.h"
545 static void TestExecute()
547 wxPuts(_T("*** testing wxExecute ***"));
550 #define COMMAND "cat -n ../../Makefile" // "echo hi"
551 #define SHELL_COMMAND "echo hi from shell"
552 #define REDIRECT_COMMAND COMMAND // "date"
553 #elif defined(__WXMSW__)
554 #define COMMAND "command.com /c echo hi"
555 #define SHELL_COMMAND "echo hi"
556 #define REDIRECT_COMMAND COMMAND
558 #error "no command to exec"
561 wxPrintf(_T("Testing wxShell: "));
563 if ( wxShell(SHELL_COMMAND
) )
566 wxPuts(_T("ERROR."));
568 wxPrintf(_T("Testing wxExecute: "));
570 if ( wxExecute(COMMAND
, TRUE
/* sync */) == 0 )
573 wxPuts(_T("ERROR."));
575 #if 0 // no, it doesn't work (yet?)
576 wxPrintf(_T("Testing async wxExecute: "));
578 if ( wxExecute(COMMAND
) != 0 )
579 wxPuts(_T("Ok (command launched)."));
581 wxPuts(_T("ERROR."));
584 wxPrintf(_T("Testing wxExecute with redirection:\n"));
585 wxArrayString output
;
586 if ( wxExecute(REDIRECT_COMMAND
, output
) != 0 )
588 wxPuts(_T("ERROR."));
592 size_t count
= output
.GetCount();
593 for ( size_t n
= 0; n
< count
; n
++ )
595 wxPrintf(_T("\t%s\n"), output
[n
].c_str());
602 #endif // TEST_EXECUTE
604 // ----------------------------------------------------------------------------
606 // ----------------------------------------------------------------------------
611 #include "wx/ffile.h"
612 #include "wx/textfile.h"
614 static void TestFileRead()
616 wxPuts(_T("*** wxFile read test ***"));
618 wxFile
file(_T("testdata.fc"));
619 if ( file
.IsOpened() )
621 wxPrintf(_T("File length: %lu\n"), file
.Length());
623 wxPuts(_T("File dump:\n----------"));
625 static const off_t len
= 1024;
629 off_t nRead
= file
.Read(buf
, len
);
630 if ( nRead
== wxInvalidOffset
)
632 wxPrintf(_T("Failed to read the file."));
636 fwrite(buf
, nRead
, 1, stdout
);
642 wxPuts(_T("----------"));
646 wxPrintf(_T("ERROR: can't open test file.\n"));
652 static void TestTextFileRead()
654 wxPuts(_T("*** wxTextFile read test ***"));
656 wxTextFile
file(_T("testdata.fc"));
659 wxPrintf(_T("Number of lines: %u\n"), file
.GetLineCount());
660 wxPrintf(_T("Last line: '%s'\n"), file
.GetLastLine().c_str());
664 wxPuts(_T("\nDumping the entire file:"));
665 for ( s
= file
.GetFirstLine(); !file
.Eof(); s
= file
.GetNextLine() )
667 wxPrintf(_T("%6u: %s\n"), file
.GetCurrentLine() + 1, s
.c_str());
669 wxPrintf(_T("%6u: %s\n"), file
.GetCurrentLine() + 1, s
.c_str());
671 wxPuts(_T("\nAnd now backwards:"));
672 for ( s
= file
.GetLastLine();
673 file
.GetCurrentLine() != 0;
674 s
= file
.GetPrevLine() )
676 wxPrintf(_T("%6u: %s\n"), file
.GetCurrentLine() + 1, s
.c_str());
678 wxPrintf(_T("%6u: %s\n"), file
.GetCurrentLine() + 1, s
.c_str());
682 wxPrintf(_T("ERROR: can't open '%s'\n"), file
.GetName());
688 static void TestFileCopy()
690 wxPuts(_T("*** Testing wxCopyFile ***"));
692 static const wxChar
*filename1
= _T("testdata.fc");
693 static const wxChar
*filename2
= _T("test2");
694 if ( !wxCopyFile(filename1
, filename2
) )
696 wxPuts(_T("ERROR: failed to copy file"));
700 wxFFile
f1(filename1
, "rb"),
703 if ( !f1
.IsOpened() || !f2
.IsOpened() )
705 wxPuts(_T("ERROR: failed to open file(s)"));
710 if ( !f1
.ReadAll(&s1
) || !f2
.ReadAll(&s2
) )
712 wxPuts(_T("ERROR: failed to read file(s)"));
716 if ( (s1
.length() != s2
.length()) ||
717 (memcmp(s1
.c_str(), s2
.c_str(), s1
.length()) != 0) )
719 wxPuts(_T("ERROR: copy error!"));
723 wxPuts(_T("File was copied ok."));
729 if ( !wxRemoveFile(filename2
) )
731 wxPuts(_T("ERROR: failed to remove the file"));
739 // ----------------------------------------------------------------------------
741 // ----------------------------------------------------------------------------
745 #include "wx/confbase.h"
746 #include "wx/fileconf.h"
748 static const struct FileConfTestData
750 const wxChar
*name
; // value name
751 const wxChar
*value
; // the value from the file
754 { _T("value1"), _T("one") },
755 { _T("value2"), _T("two") },
756 { _T("novalue"), _T("default") },
759 static void TestFileConfRead()
761 wxPuts(_T("*** testing wxFileConfig loading/reading ***"));
763 wxFileConfig
fileconf(_T("test"), wxEmptyString
,
764 _T("testdata.fc"), wxEmptyString
,
765 wxCONFIG_USE_RELATIVE_PATH
);
767 // test simple reading
768 wxPuts(_T("\nReading config file:"));
769 wxString
defValue(_T("default")), value
;
770 for ( size_t n
= 0; n
< WXSIZEOF(fcTestData
); n
++ )
772 const FileConfTestData
& data
= fcTestData
[n
];
773 value
= fileconf
.Read(data
.name
, defValue
);
774 wxPrintf(_T("\t%s = %s "), data
.name
, value
.c_str());
775 if ( value
== data
.value
)
781 wxPrintf(_T("(ERROR: should be %s)\n"), data
.value
);
785 // test enumerating the entries
786 wxPuts(_T("\nEnumerating all root entries:"));
789 bool cont
= fileconf
.GetFirstEntry(name
, dummy
);
792 wxPrintf(_T("\t%s = %s\n"),
794 fileconf
.Read(name
.c_str(), _T("ERROR")).c_str());
796 cont
= fileconf
.GetNextEntry(name
, dummy
);
800 #endif // TEST_FILECONF
802 // ----------------------------------------------------------------------------
804 // ----------------------------------------------------------------------------
808 #include "wx/filename.h"
810 static void DumpFileName(const wxFileName
& fn
)
812 wxString full
= fn
.GetFullPath();
814 wxString vol
, path
, name
, ext
;
815 wxFileName::SplitPath(full
, &vol
, &path
, &name
, &ext
);
817 wxPrintf(_T("'%s'-> vol '%s', path '%s', name '%s', ext '%s'\n"),
818 full
.c_str(), vol
.c_str(), path
.c_str(), name
.c_str(), ext
.c_str());
820 wxFileName::SplitPath(full
, &path
, &name
, &ext
);
821 wxPrintf(_T("or\t\t-> path '%s', name '%s', ext '%s'\n"),
822 path
.c_str(), name
.c_str(), ext
.c_str());
824 wxPrintf(_T("path is also:\t'%s'\n"), fn
.GetPath().c_str());
825 wxPrintf(_T("with volume: \t'%s'\n"),
826 fn
.GetPath(wxPATH_GET_VOLUME
).c_str());
827 wxPrintf(_T("with separator:\t'%s'\n"),
828 fn
.GetPath(wxPATH_GET_SEPARATOR
).c_str());
829 wxPrintf(_T("with both: \t'%s'\n"),
830 fn
.GetPath(wxPATH_GET_SEPARATOR
| wxPATH_GET_VOLUME
).c_str());
832 wxPuts(_T("The directories in the path are:"));
833 wxArrayString dirs
= fn
.GetDirs();
834 size_t count
= dirs
.GetCount();
835 for ( size_t n
= 0; n
< count
; n
++ )
837 wxPrintf(_T("\t%u: %s\n"), n
, dirs
[n
].c_str());
841 static struct FileNameInfo
843 const wxChar
*fullname
;
844 const wxChar
*volume
;
853 { _T("/usr/bin/ls"), _T(""), _T("/usr/bin"), _T("ls"), _T(""), TRUE
, wxPATH_UNIX
},
854 { _T("/usr/bin/"), _T(""), _T("/usr/bin"), _T(""), _T(""), TRUE
, wxPATH_UNIX
},
855 { _T("~/.zshrc"), _T(""), _T("~"), _T(".zshrc"), _T(""), TRUE
, wxPATH_UNIX
},
856 { _T("../../foo"), _T(""), _T("../.."), _T("foo"), _T(""), FALSE
, wxPATH_UNIX
},
857 { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), FALSE
, wxPATH_UNIX
},
858 { _T("~/foo.bar"), _T(""), _T("~"), _T("foo"), _T("bar"), TRUE
, wxPATH_UNIX
},
859 { _T("/foo"), _T(""), _T("/"), _T("foo"), _T(""), TRUE
, wxPATH_UNIX
},
860 { _T("Mahogany-0.60/foo.bar"), _T(""), _T("Mahogany-0.60"), _T("foo"), _T("bar"), FALSE
, wxPATH_UNIX
},
861 { _T("/tmp/wxwin.tar.bz"), _T(""), _T("/tmp"), _T("wxwin.tar"), _T("bz"), TRUE
, wxPATH_UNIX
},
863 // Windows file names
864 { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), FALSE
, wxPATH_DOS
},
865 { _T("\\foo.bar"), _T(""), _T("\\"), _T("foo"), _T("bar"), FALSE
, wxPATH_DOS
},
866 { _T("c:foo.bar"), _T("c"), _T(""), _T("foo"), _T("bar"), FALSE
, wxPATH_DOS
},
867 { _T("c:\\foo.bar"), _T("c"), _T("\\"), _T("foo"), _T("bar"), TRUE
, wxPATH_DOS
},
868 { _T("c:\\Windows\\command.com"), _T("c"), _T("\\Windows"), _T("command"), _T("com"), TRUE
, wxPATH_DOS
},
869 { _T("\\\\server\\foo.bar"), _T("server"), _T("\\"), _T("foo"), _T("bar"), TRUE
, wxPATH_DOS
},
870 { _T("\\\\server\\dir\\foo.bar"), _T("server"), _T("\\dir"), _T("foo"), _T("bar"), TRUE
, wxPATH_DOS
},
872 // wxFileName support for Mac file names is broken currently
875 { _T("Volume:Dir:File"), _T("Volume"), _T("Dir"), _T("File"), _T(""), TRUE
, wxPATH_MAC
},
876 { _T("Volume:Dir:Subdir:File"), _T("Volume"), _T("Dir:Subdir"), _T("File"), _T(""), TRUE
, wxPATH_MAC
},
877 { _T("Volume:"), _T("Volume"), _T(""), _T(""), _T(""), TRUE
, wxPATH_MAC
},
878 { _T(":Dir:File"), _T(""), _T("Dir"), _T("File"), _T(""), FALSE
, wxPATH_MAC
},
879 { _T(":File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), FALSE
, wxPATH_MAC
},
880 { _T("File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), FALSE
, wxPATH_MAC
},
884 { _T("device:[dir1.dir2.dir3]file.txt"), _T("device"), _T("dir1.dir2.dir3"), _T("file"), _T("txt"), TRUE
, wxPATH_VMS
},
885 { _T("file.txt"), _T(""), _T(""), _T("file"), _T("txt"), FALSE
, wxPATH_VMS
},
888 static void TestFileNameConstruction()
890 wxPuts(_T("*** testing wxFileName construction ***"));
892 for ( size_t n
= 0; n
< WXSIZEOF(filenames
); n
++ )
894 const FileNameInfo
& fni
= filenames
[n
];
896 wxFileName
fn(fni
.fullname
, fni
.format
);
898 wxString fullname
= fn
.GetFullPath(fni
.format
);
899 if ( fullname
!= fni
.fullname
)
901 wxPrintf(_T("ERROR: fullname should be '%s'\n"), fni
.fullname
);
904 bool isAbsolute
= fn
.IsAbsolute(fni
.format
);
905 wxPrintf(_T("'%s' is %s (%s)\n\t"),
907 isAbsolute
? "absolute" : "relative",
908 isAbsolute
== fni
.isAbsolute
? "ok" : "ERROR");
910 if ( !fn
.Normalize(wxPATH_NORM_ALL
, _T(""), fni
.format
) )
912 wxPuts(_T("ERROR (couldn't be normalized)"));
916 wxPrintf(_T("normalized: '%s'\n"), fn
.GetFullPath(fni
.format
).c_str());
923 static void TestFileNameSplit()
925 wxPuts(_T("*** testing wxFileName splitting ***"));
927 for ( size_t n
= 0; n
< WXSIZEOF(filenames
); n
++ )
929 const FileNameInfo
& fni
= filenames
[n
];
930 wxString volume
, path
, name
, ext
;
931 wxFileName::SplitPath(fni
.fullname
,
932 &volume
, &path
, &name
, &ext
, fni
.format
);
934 wxPrintf(_T("%s -> volume = '%s', path = '%s', name = '%s', ext = '%s'"),
936 volume
.c_str(), path
.c_str(), name
.c_str(), ext
.c_str());
938 if ( volume
!= fni
.volume
)
939 wxPrintf(_T(" (ERROR: volume = '%s')"), fni
.volume
);
940 if ( path
!= fni
.path
)
941 wxPrintf(_T(" (ERROR: path = '%s')"), fni
.path
);
942 if ( name
!= fni
.name
)
943 wxPrintf(_T(" (ERROR: name = '%s')"), fni
.name
);
944 if ( ext
!= fni
.ext
)
945 wxPrintf(_T(" (ERROR: ext = '%s')"), fni
.ext
);
951 static void TestFileNameTemp()
953 wxPuts(_T("*** testing wxFileName temp file creation ***"));
955 static const wxChar
*tmpprefixes
[] =
963 _T("/tmp/foo/bar"), // this one must be an error
967 for ( size_t n
= 0; n
< WXSIZEOF(tmpprefixes
); n
++ )
969 wxString path
= wxFileName::CreateTempFileName(tmpprefixes
[n
]);
972 // "error" is not in upper case because it may be ok
973 wxPrintf(_T("Prefix '%s'\t-> error\n"), tmpprefixes
[n
]);
977 wxPrintf(_T("Prefix '%s'\t-> temp file '%s'\n"),
978 tmpprefixes
[n
], path
.c_str());
980 if ( !wxRemoveFile(path
) )
982 wxLogWarning(_T("Failed to remove temp file '%s'"),
989 static void TestFileNameMakeRelative()
991 wxPuts(_T("*** testing wxFileName::MakeRelativeTo() ***"));
993 for ( size_t n
= 0; n
< WXSIZEOF(filenames
); n
++ )
995 const FileNameInfo
& fni
= filenames
[n
];
997 wxFileName
fn(fni
.fullname
, fni
.format
);
999 // choose the base dir of the same format
1001 switch ( fni
.format
)
1013 // TODO: I don't know how this is supposed to work there
1016 case wxPATH_NATIVE
: // make gcc happy
1018 wxFAIL_MSG( "unexpected path format" );
1021 wxPrintf(_T("'%s' relative to '%s': "),
1022 fn
.GetFullPath(fni
.format
).c_str(), base
.c_str());
1024 if ( !fn
.MakeRelativeTo(base
, fni
.format
) )
1026 wxPuts(_T("unchanged"));
1030 wxPrintf(_T("'%s'\n"), fn
.GetFullPath(fni
.format
).c_str());
1035 static void TestFileNameComparison()
1040 static void TestFileNameOperations()
1045 static void TestFileNameCwd()
1050 #endif // TEST_FILENAME
1052 // ----------------------------------------------------------------------------
1053 // wxFileName time functions
1054 // ----------------------------------------------------------------------------
1056 #ifdef TEST_FILETIME
1058 #include <wx/filename.h>
1059 #include <wx/datetime.h>
1061 static void TestFileGetTimes()
1063 wxFileName
fn(_T("testdata.fc"));
1065 wxDateTime dtAccess
, dtMod
, dtCreate
;
1066 if ( !fn
.GetTimes(&dtAccess
, &dtMod
, &dtCreate
) )
1068 wxPrintf(_T("ERROR: GetTimes() failed.\n"));
1072 static const wxChar
*fmt
= _T("%Y-%b-%d %H:%M:%S");
1074 wxPrintf(_T("File times for '%s':\n"), fn
.GetFullPath().c_str());
1075 wxPrintf(_T("Creation: \t%s\n"), dtCreate
.Format(fmt
).c_str());
1076 wxPrintf(_T("Last read: \t%s\n"), dtAccess
.Format(fmt
).c_str());
1077 wxPrintf(_T("Last write: \t%s\n"), dtMod
.Format(fmt
).c_str());
1081 static void TestFileSetTimes()
1083 wxFileName
fn(_T("testdata.fc"));
1087 wxPrintf(_T("ERROR: Touch() failed.\n"));
1091 #endif // TEST_FILETIME
1093 // ----------------------------------------------------------------------------
1095 // ----------------------------------------------------------------------------
1099 #include "wx/hash.h"
1103 Foo(int n_
) { n
= n_
; count
++; }
1108 static size_t count
;
1111 size_t Foo::count
= 0;
1113 WX_DECLARE_LIST(Foo
, wxListFoos
);
1114 WX_DECLARE_HASH(Foo
, wxListFoos
, wxHashFoos
);
1116 #include "wx/listimpl.cpp"
1118 WX_DEFINE_LIST(wxListFoos
);
1120 static void TestHash()
1122 wxPuts(_T("*** Testing wxHashTable ***\n"));
1126 hash
.DeleteContents(TRUE
);
1128 wxPrintf(_T("Hash created: %u foos in hash, %u foos totally\n"),
1129 hash
.GetCount(), Foo::count
);
1131 static const int hashTestData
[] =
1133 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
1137 for ( n
= 0; n
< WXSIZEOF(hashTestData
); n
++ )
1139 hash
.Put(hashTestData
[n
], n
, new Foo(n
));
1142 wxPrintf(_T("Hash filled: %u foos in hash, %u foos totally\n"),
1143 hash
.GetCount(), Foo::count
);
1145 wxPuts(_T("Hash access test:"));
1146 for ( n
= 0; n
< WXSIZEOF(hashTestData
); n
++ )
1148 wxPrintf(_T("\tGetting element with key %d, value %d: "),
1149 hashTestData
[n
], n
);
1150 Foo
*foo
= hash
.Get(hashTestData
[n
], n
);
1153 wxPrintf(_T("ERROR, not found.\n"));
1157 wxPrintf(_T("%d (%s)\n"), foo
->n
,
1158 (size_t)foo
->n
== n
? "ok" : "ERROR");
1162 wxPrintf(_T("\nTrying to get an element not in hash: "));
1164 if ( hash
.Get(1234) || hash
.Get(1, 0) )
1166 wxPuts(_T("ERROR: found!"));
1170 wxPuts(_T("ok (not found)"));
1174 wxPrintf(_T("Hash destroyed: %u foos left\n"), Foo::count
);
1179 // ----------------------------------------------------------------------------
1181 // ----------------------------------------------------------------------------
1185 #include "wx/hashmap.h"
1187 // test compilation of basic map types
1188 WX_DECLARE_HASH_MAP( int*, int*, wxPointerHash
, wxPointerEqual
, myPtrHashMap
);
1189 WX_DECLARE_HASH_MAP( long, long, wxIntegerHash
, wxIntegerEqual
, myLongHashMap
);
1190 WX_DECLARE_HASH_MAP( unsigned long, unsigned, wxIntegerHash
, wxIntegerEqual
,
1191 myUnsignedHashMap
);
1192 WX_DECLARE_HASH_MAP( unsigned int, unsigned, wxIntegerHash
, wxIntegerEqual
,
1194 WX_DECLARE_HASH_MAP( int, unsigned, wxIntegerHash
, wxIntegerEqual
,
1196 WX_DECLARE_HASH_MAP( short, unsigned, wxIntegerHash
, wxIntegerEqual
,
1198 WX_DECLARE_HASH_MAP( unsigned short, unsigned, wxIntegerHash
, wxIntegerEqual
,
1202 // WX_DECLARE_HASH_MAP( wxString, wxString, wxStringHash, wxStringEqual,
1203 // myStringHashMap );
1204 WX_DECLARE_STRING_HASH_MAP(wxString
, myStringHashMap
);
1206 typedef myStringHashMap::iterator Itor
;
1208 static void TestHashMap()
1210 wxPuts(_T("*** Testing wxHashMap ***\n"));
1211 myStringHashMap
sh(0); // as small as possible
1214 const size_t count
= 10000;
1216 // init with some data
1217 for( i
= 0; i
< count
; ++i
)
1219 buf
.Printf(wxT("%d"), i
);
1220 sh
[buf
] = wxT("A") + buf
+ wxT("C");
1223 // test that insertion worked
1224 if( sh
.size() != count
)
1226 wxPrintf(_T("*** ERROR: %u ELEMENTS, SHOULD BE %u ***\n"), sh
.size(), count
);
1229 for( i
= 0; i
< count
; ++i
)
1231 buf
.Printf(wxT("%d"), i
);
1232 if( sh
[buf
] != wxT("A") + buf
+ wxT("C") )
1234 wxPrintf(_T("*** ERROR INSERTION BROKEN! STOPPING NOW! ***\n"));
1239 // check that iterators work
1241 for( i
= 0, it
= sh
.begin(); it
!= sh
.end(); ++it
, ++i
)
1245 wxPrintf(_T("*** ERROR ITERATORS DO NOT TERMINATE! STOPPING NOW! ***\n"));
1249 if( it
->second
!= sh
[it
->first
] )
1251 wxPrintf(_T("*** ERROR ITERATORS BROKEN! STOPPING NOW! ***\n"));
1256 if( sh
.size() != i
)
1258 wxPrintf(_T("*** ERROR: %u ELEMENTS ITERATED, SHOULD BE %u ***\n"), i
, count
);
1261 // test copy ctor, assignment operator
1262 myStringHashMap
h1( sh
), h2( 0 );
1265 for( i
= 0, it
= sh
.begin(); it
!= sh
.end(); ++it
, ++i
)
1267 if( h1
[it
->first
] != it
->second
)
1269 wxPrintf(_T("*** ERROR: COPY CTOR BROKEN %s ***\n"), it
->first
.c_str());
1272 if( h2
[it
->first
] != it
->second
)
1274 wxPrintf(_T("*** ERROR: OPERATOR= BROKEN %s ***\n"), it
->first
.c_str());
1279 for( i
= 0; i
< count
; ++i
)
1281 buf
.Printf(wxT("%d"), i
);
1282 size_t sz
= sh
.size();
1284 // test find() and erase(it)
1287 it
= sh
.find( buf
);
1288 if( it
!= sh
.end() )
1292 if( sh
.find( buf
) != sh
.end() )
1294 wxPrintf(_T("*** ERROR: FOUND DELETED ELEMENT %u ***\n"), i
);
1298 wxPrintf(_T("*** ERROR: CANT FIND ELEMENT %u ***\n"), i
);
1303 size_t c
= sh
.erase( buf
);
1305 wxPrintf(_T("*** ERROR: SHOULD RETURN 1 ***\n"));
1307 if( sh
.find( buf
) != sh
.end() )
1309 wxPrintf(_T("*** ERROR: FOUND DELETED ELEMENT %u ***\n"), i
);
1313 // count should decrease
1314 if( sh
.size() != sz
- 1 )
1316 wxPrintf(_T("*** ERROR: COUNT DID NOT DECREASE ***\n"));
1320 wxPrintf(_T("*** Finished testing wxHashMap ***\n"));
1323 #endif // TEST_HASHMAP
1325 // ----------------------------------------------------------------------------
1327 // ----------------------------------------------------------------------------
1331 #include "wx/list.h"
1333 WX_DECLARE_LIST(Bar
, wxListBars
);
1334 #include "wx/listimpl.cpp"
1335 WX_DEFINE_LIST(wxListBars
);
1337 static void TestListCtor()
1339 wxPuts(_T("*** Testing wxList construction ***\n"));
1343 list1
.Append(new Bar(_T("first")));
1344 list1
.Append(new Bar(_T("second")));
1346 wxPrintf(_T("After 1st list creation: %u objects in the list, %u objects total.\n"),
1347 list1
.GetCount(), Bar::GetNumber());
1352 wxPrintf(_T("After 2nd list creation: %u and %u objects in the lists, %u objects total.\n"),
1353 list1
.GetCount(), list2
.GetCount(), Bar::GetNumber());
1355 list1
.DeleteContents(TRUE
);
1358 wxPrintf(_T("After list destruction: %u objects left.\n"), Bar::GetNumber());
1363 // ----------------------------------------------------------------------------
1365 // ----------------------------------------------------------------------------
1369 #include "wx/intl.h"
1370 #include "wx/utils.h" // for wxSetEnv
1372 static wxLocale
gs_localeDefault(wxLANGUAGE_ENGLISH
);
1374 // find the name of the language from its value
1375 static const wxChar
*GetLangName(int lang
)
1377 static const wxChar
*languageNames
[] =
1387 _T("ARABIC_ALGERIA"),
1388 _T("ARABIC_BAHRAIN"),
1391 _T("ARABIC_JORDAN"),
1392 _T("ARABIC_KUWAIT"),
1393 _T("ARABIC_LEBANON"),
1395 _T("ARABIC_MOROCCO"),
1398 _T("ARABIC_SAUDI_ARABIA"),
1401 _T("ARABIC_TUNISIA"),
1408 _T("AZERI_CYRILLIC"),
1423 _T("CHINESE_SIMPLIFIED"),
1424 _T("CHINESE_TRADITIONAL"),
1425 _T("CHINESE_HONGKONG"),
1426 _T("CHINESE_MACAU"),
1427 _T("CHINESE_SINGAPORE"),
1428 _T("CHINESE_TAIWAN"),
1434 _T("DUTCH_BELGIAN"),
1438 _T("ENGLISH_AUSTRALIA"),
1439 _T("ENGLISH_BELIZE"),
1440 _T("ENGLISH_BOTSWANA"),
1441 _T("ENGLISH_CANADA"),
1442 _T("ENGLISH_CARIBBEAN"),
1443 _T("ENGLISH_DENMARK"),
1445 _T("ENGLISH_JAMAICA"),
1446 _T("ENGLISH_NEW_ZEALAND"),
1447 _T("ENGLISH_PHILIPPINES"),
1448 _T("ENGLISH_SOUTH_AFRICA"),
1449 _T("ENGLISH_TRINIDAD"),
1450 _T("ENGLISH_ZIMBABWE"),
1458 _T("FRENCH_BELGIAN"),
1459 _T("FRENCH_CANADIAN"),
1460 _T("FRENCH_LUXEMBOURG"),
1461 _T("FRENCH_MONACO"),
1467 _T("GERMAN_AUSTRIAN"),
1468 _T("GERMAN_BELGIUM"),
1469 _T("GERMAN_LIECHTENSTEIN"),
1470 _T("GERMAN_LUXEMBOURG"),
1488 _T("ITALIAN_SWISS"),
1493 _T("KASHMIRI_INDIA"),
1511 _T("MALAY_BRUNEI_DARUSSALAM"),
1512 _T("MALAY_MALAYSIA"),
1522 _T("NORWEGIAN_BOKMAL"),
1523 _T("NORWEGIAN_NYNORSK"),
1530 _T("PORTUGUESE_BRAZILIAN"),
1533 _T("RHAETO_ROMANCE"),
1536 _T("RUSSIAN_UKRAINE"),
1542 _T("SERBIAN_CYRILLIC"),
1543 _T("SERBIAN_LATIN"),
1544 _T("SERBO_CROATIAN"),
1555 _T("SPANISH_ARGENTINA"),
1556 _T("SPANISH_BOLIVIA"),
1557 _T("SPANISH_CHILE"),
1558 _T("SPANISH_COLOMBIA"),
1559 _T("SPANISH_COSTA_RICA"),
1560 _T("SPANISH_DOMINICAN_REPUBLIC"),
1561 _T("SPANISH_ECUADOR"),
1562 _T("SPANISH_EL_SALVADOR"),
1563 _T("SPANISH_GUATEMALA"),
1564 _T("SPANISH_HONDURAS"),
1565 _T("SPANISH_MEXICAN"),
1566 _T("SPANISH_MODERN"),
1567 _T("SPANISH_NICARAGUA"),
1568 _T("SPANISH_PANAMA"),
1569 _T("SPANISH_PARAGUAY"),
1571 _T("SPANISH_PUERTO_RICO"),
1572 _T("SPANISH_URUGUAY"),
1574 _T("SPANISH_VENEZUELA"),
1578 _T("SWEDISH_FINLAND"),
1596 _T("URDU_PAKISTAN"),
1598 _T("UZBEK_CYRILLIC"),
1611 if ( (size_t)lang
< WXSIZEOF(languageNames
) )
1612 return languageNames
[lang
];
1614 return _T("INVALID");
1617 static void TestDefaultLang()
1619 wxPuts(_T("*** Testing wxLocale::GetSystemLanguage ***"));
1621 static const wxChar
*langStrings
[] =
1623 NULL
, // system default
1630 _T("de_DE.iso88591"),
1632 _T("?"), // invalid lang spec
1633 _T("klingonese"), // I bet on some systems it does exist...
1636 wxPrintf(_T("The default system encoding is %s (%d)\n"),
1637 wxLocale::GetSystemEncodingName().c_str(),
1638 wxLocale::GetSystemEncoding());
1640 for ( size_t n
= 0; n
< WXSIZEOF(langStrings
); n
++ )
1642 const wxChar
*langStr
= langStrings
[n
];
1645 // FIXME: this doesn't do anything at all under Windows, we need
1646 // to create a new wxLocale!
1647 wxSetEnv(_T("LC_ALL"), langStr
);
1650 int lang
= gs_localeDefault
.GetSystemLanguage();
1651 wxPrintf(_T("Locale for '%s' is %s.\n"),
1652 langStr
? langStr
: _T("system default"), GetLangName(lang
));
1656 #endif // TEST_LOCALE
1658 // ----------------------------------------------------------------------------
1660 // ----------------------------------------------------------------------------
1664 #include "wx/mimetype.h"
1666 static void TestMimeEnum()
1668 wxPuts(_T("*** Testing wxMimeTypesManager::EnumAllFileTypes() ***\n"));
1670 wxArrayString mimetypes
;
1672 size_t count
= wxTheMimeTypesManager
->EnumAllFileTypes(mimetypes
);
1674 wxPrintf(_T("*** All %u known filetypes: ***\n"), count
);
1679 for ( size_t n
= 0; n
< count
; n
++ )
1681 wxFileType
*filetype
=
1682 wxTheMimeTypesManager
->GetFileTypeFromMimeType(mimetypes
[n
]);
1685 wxPrintf(_T("nothing known about the filetype '%s'!\n"),
1686 mimetypes
[n
].c_str());
1690 filetype
->GetDescription(&desc
);
1691 filetype
->GetExtensions(exts
);
1693 filetype
->GetIcon(NULL
);
1696 for ( size_t e
= 0; e
< exts
.GetCount(); e
++ )
1699 extsAll
<< _T(", ");
1703 wxPrintf(_T("\t%s: %s (%s)\n"),
1704 mimetypes
[n
].c_str(), desc
.c_str(), extsAll
.c_str());
1710 static void TestMimeOverride()
1712 wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
1714 static const wxChar
*mailcap
= _T("/tmp/mailcap");
1715 static const wxChar
*mimetypes
= _T("/tmp/mime.types");
1717 if ( wxFile::Exists(mailcap
) )
1718 wxPrintf(_T("Loading mailcap from '%s': %s\n"),
1720 wxTheMimeTypesManager
->ReadMailcap(mailcap
) ? _T("ok") : _T("ERROR"));
1722 wxPrintf(_T("WARN: mailcap file '%s' doesn't exist, not loaded.\n"),
1725 if ( wxFile::Exists(mimetypes
) )
1726 wxPrintf(_T("Loading mime.types from '%s': %s\n"),
1728 wxTheMimeTypesManager
->ReadMimeTypes(mimetypes
) ? _T("ok") : _T("ERROR"));
1730 wxPrintf(_T("WARN: mime.types file '%s' doesn't exist, not loaded.\n"),
1736 static void TestMimeFilename()
1738 wxPuts(_T("*** Testing MIME type from filename query ***\n"));
1740 static const wxChar
*filenames
[] =
1748 for ( size_t n
= 0; n
< WXSIZEOF(filenames
); n
++ )
1750 const wxString fname
= filenames
[n
];
1751 wxString ext
= fname
.AfterLast(_T('.'));
1752 wxFileType
*ft
= wxTheMimeTypesManager
->GetFileTypeFromExtension(ext
);
1755 wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext
.c_str());
1760 if ( !ft
->GetDescription(&desc
) )
1761 desc
= _T("<no description>");
1764 if ( !ft
->GetOpenCommand(&cmd
,
1765 wxFileType::MessageParameters(fname
, _T(""))) )
1766 cmd
= _T("<no command available>");
1768 wxPrintf(_T("To open %s (%s) do '%s'.\n"),
1769 fname
.c_str(), desc
.c_str(), cmd
.c_str());
1778 static void TestMimeAssociate()
1780 wxPuts(_T("*** Testing creation of filetype association ***\n"));
1782 wxFileTypeInfo
ftInfo(
1783 _T("application/x-xyz"),
1784 _T("xyzview '%s'"), // open cmd
1785 _T(""), // print cmd
1786 _T("XYZ File"), // description
1787 _T(".xyz"), // extensions
1788 NULL
// end of extensions
1790 ftInfo
.SetShortDesc(_T("XYZFile")); // used under Win32 only
1792 wxFileType
*ft
= wxTheMimeTypesManager
->Associate(ftInfo
);
1795 wxPuts(_T("ERROR: failed to create association!"));
1799 // TODO: read it back
1808 // ----------------------------------------------------------------------------
1809 // misc information functions
1810 // ----------------------------------------------------------------------------
1812 #ifdef TEST_INFO_FUNCTIONS
1814 #include "wx/utils.h"
1816 static void TestDiskInfo()
1818 wxPuts(_T("*** Testing wxGetDiskSpace() ***"));
1822 wxChar pathname
[128];
1823 wxPrintf(_T("\nEnter a directory name: "));
1824 if ( !wxFgets(pathname
, WXSIZEOF(pathname
), stdin
) )
1827 // kill the last '\n'
1828 pathname
[wxStrlen(pathname
) - 1] = 0;
1830 wxLongLong total
, free
;
1831 if ( !wxGetDiskSpace(pathname
, &total
, &free
) )
1833 wxPuts(_T("ERROR: wxGetDiskSpace failed."));
1837 wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"),
1838 (total
/ 1024).ToString().c_str(),
1839 (free
/ 1024).ToString().c_str(),
1845 static void TestOsInfo()
1847 wxPuts(_T("*** Testing OS info functions ***\n"));
1850 wxGetOsVersion(&major
, &minor
);
1851 wxPrintf(_T("Running under: %s, version %d.%d\n"),
1852 wxGetOsDescription().c_str(), major
, minor
);
1854 wxPrintf(_T("%ld free bytes of memory left.\n"), wxGetFreeMemory());
1856 wxPrintf(_T("Host name is %s (%s).\n"),
1857 wxGetHostName().c_str(), wxGetFullHostName().c_str());
1862 static void TestUserInfo()
1864 wxPuts(_T("*** Testing user info functions ***\n"));
1866 wxPrintf(_T("User id is:\t%s\n"), wxGetUserId().c_str());
1867 wxPrintf(_T("User name is:\t%s\n"), wxGetUserName().c_str());
1868 wxPrintf(_T("Home dir is:\t%s\n"), wxGetHomeDir().c_str());
1869 wxPrintf(_T("Email address:\t%s\n"), wxGetEmailAddress().c_str());
1874 #endif // TEST_INFO_FUNCTIONS
1876 // ----------------------------------------------------------------------------
1878 // ----------------------------------------------------------------------------
1880 #ifdef TEST_LONGLONG
1882 #include "wx/longlong.h"
1883 #include "wx/timer.h"
1885 // make a 64 bit number from 4 16 bit ones
1886 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
1888 // get a random 64 bit number
1889 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
1891 static const long testLongs
[] =
1902 #if wxUSE_LONGLONG_WX
1903 inline bool operator==(const wxLongLongWx
& a
, const wxLongLongNative
& b
)
1904 { return a
.GetHi() == b
.GetHi() && a
.GetLo() == b
.GetLo(); }
1905 inline bool operator==(const wxLongLongNative
& a
, const wxLongLongWx
& b
)
1906 { return a
.GetHi() == b
.GetHi() && a
.GetLo() == b
.GetLo(); }
1907 #endif // wxUSE_LONGLONG_WX
1909 static void TestSpeed()
1911 static const long max
= 100000000;
1918 for ( n
= 0; n
< max
; n
++ )
1923 wxPrintf(_T("Summing longs took %ld milliseconds.\n"), sw
.Time());
1926 #if wxUSE_LONGLONG_NATIVE
1931 for ( n
= 0; n
< max
; n
++ )
1936 wxPrintf(_T("Summing wxLongLong_t took %ld milliseconds.\n"), sw
.Time());
1938 #endif // wxUSE_LONGLONG_NATIVE
1944 for ( n
= 0; n
< max
; n
++ )
1949 wxPrintf(_T("Summing wxLongLongs took %ld milliseconds.\n"), sw
.Time());
1953 static void TestLongLongConversion()
1955 wxPuts(_T("*** Testing wxLongLong conversions ***\n"));
1959 for ( size_t n
= 0; n
< 100000; n
++ )
1963 #if wxUSE_LONGLONG_NATIVE
1964 wxLongLongNative
b(a
.GetHi(), a
.GetLo());
1966 wxASSERT_MSG( a
== b
, "conversions failure" );
1968 wxPuts(_T("Can't do it without native long long type, test skipped."));
1971 #endif // wxUSE_LONGLONG_NATIVE
1973 if ( !(nTested
% 1000) )
1982 wxPuts(_T(" done!"));
1985 static void TestMultiplication()
1987 wxPuts(_T("*** Testing wxLongLong multiplication ***\n"));
1991 for ( size_t n
= 0; n
< 100000; n
++ )
1996 #if wxUSE_LONGLONG_NATIVE
1997 wxLongLongNative
aa(a
.GetHi(), a
.GetLo());
1998 wxLongLongNative
bb(b
.GetHi(), b
.GetLo());
2000 wxASSERT_MSG( a
*b
== aa
*bb
, "multiplication failure" );
2001 #else // !wxUSE_LONGLONG_NATIVE
2002 wxPuts(_T("Can't do it without native long long type, test skipped."));
2005 #endif // wxUSE_LONGLONG_NATIVE
2007 if ( !(nTested
% 1000) )
2016 wxPuts(_T(" done!"));
2019 static void TestDivision()
2021 wxPuts(_T("*** Testing wxLongLong division ***\n"));
2025 for ( size_t n
= 0; n
< 100000; n
++ )
2027 // get a random wxLongLong (shifting by 12 the MSB ensures that the
2028 // multiplication will not overflow)
2029 wxLongLong ll
= MAKE_LL((rand() >> 12), rand(), rand(), rand());
2031 // get a random (but non null) long (not wxLongLong for now) to divide
2043 #if wxUSE_LONGLONG_NATIVE
2044 wxLongLongNative
m(ll
.GetHi(), ll
.GetLo());
2046 wxLongLongNative p
= m
/ l
, s
= m
% l
;
2047 wxASSERT_MSG( q
== p
&& r
== s
, "division failure" );
2048 #else // !wxUSE_LONGLONG_NATIVE
2049 // verify the result
2050 wxASSERT_MSG( ll
== q
*l
+ r
, "division failure" );
2051 #endif // wxUSE_LONGLONG_NATIVE
2053 if ( !(nTested
% 1000) )
2062 wxPuts(_T(" done!"));
2065 static void TestAddition()
2067 wxPuts(_T("*** Testing wxLongLong addition ***\n"));
2071 for ( size_t n
= 0; n
< 100000; n
++ )
2077 #if wxUSE_LONGLONG_NATIVE
2078 wxASSERT_MSG( c
== wxLongLongNative(a
.GetHi(), a
.GetLo()) +
2079 wxLongLongNative(b
.GetHi(), b
.GetLo()),
2080 "addition failure" );
2081 #else // !wxUSE_LONGLONG_NATIVE
2082 wxASSERT_MSG( c
- b
== a
, "addition failure" );
2083 #endif // wxUSE_LONGLONG_NATIVE
2085 if ( !(nTested
% 1000) )
2094 wxPuts(_T(" done!"));
2097 static void TestBitOperations()
2099 wxPuts(_T("*** Testing wxLongLong bit operation ***\n"));
2103 for ( size_t n
= 0; n
< 100000; n
++ )
2107 #if wxUSE_LONGLONG_NATIVE
2108 for ( size_t n
= 0; n
< 33; n
++ )
2111 #else // !wxUSE_LONGLONG_NATIVE
2112 wxPuts(_T("Can't do it without native long long type, test skipped."));
2115 #endif // wxUSE_LONGLONG_NATIVE
2117 if ( !(nTested
% 1000) )
2126 wxPuts(_T(" done!"));
2129 static void TestLongLongComparison()
2131 #if wxUSE_LONGLONG_WX
2132 wxPuts(_T("*** Testing wxLongLong comparison ***\n"));
2134 static const long ls
[2] =
2140 wxLongLongWx lls
[2];
2144 for ( size_t n
= 0; n
< WXSIZEOF(testLongs
); n
++ )
2148 for ( size_t m
= 0; m
< WXSIZEOF(lls
); m
++ )
2150 res
= lls
[m
] > testLongs
[n
];
2151 wxPrintf(_T("0x%lx > 0x%lx is %s (%s)\n"),
2152 ls
[m
], testLongs
[n
], res
? "true" : "false",
2153 res
== (ls
[m
] > testLongs
[n
]) ? "ok" : "ERROR");
2155 res
= lls
[m
] < testLongs
[n
];
2156 wxPrintf(_T("0x%lx < 0x%lx is %s (%s)\n"),
2157 ls
[m
], testLongs
[n
], res
? "true" : "false",
2158 res
== (ls
[m
] < testLongs
[n
]) ? "ok" : "ERROR");
2160 res
= lls
[m
] == testLongs
[n
];
2161 wxPrintf(_T("0x%lx == 0x%lx is %s (%s)\n"),
2162 ls
[m
], testLongs
[n
], res
? "true" : "false",
2163 res
== (ls
[m
] == testLongs
[n
]) ? "ok" : "ERROR");
2166 #endif // wxUSE_LONGLONG_WX
2169 static void TestLongLongPrint()
2171 wxPuts(_T("*** Testing wxLongLong printing ***\n"));
2173 for ( size_t n
= 0; n
< WXSIZEOF(testLongs
); n
++ )
2175 wxLongLong ll
= testLongs
[n
];
2176 wxPrintf(_T("%ld == %s\n"), testLongs
[n
], ll
.ToString().c_str());
2179 wxLongLong
ll(0x12345678, 0x87654321);
2180 wxPrintf(_T("0x1234567887654321 = %s\n"), ll
.ToString().c_str());
2183 wxPrintf(_T("-0x1234567887654321 = %s\n"), ll
.ToString().c_str());
2189 #endif // TEST_LONGLONG
2191 // ----------------------------------------------------------------------------
2193 // ----------------------------------------------------------------------------
2195 #ifdef TEST_PATHLIST
2198 #define CMD_IN_PATH _T("ls")
2200 #define CMD_IN_PATH _T("command.com")
2203 static void TestPathList()
2205 wxPuts(_T("*** Testing wxPathList ***\n"));
2207 wxPathList pathlist
;
2208 pathlist
.AddEnvList(_T("PATH"));
2209 wxString path
= pathlist
.FindValidPath(CMD_IN_PATH
);
2212 wxPrintf(_T("ERROR: command not found in the path.\n"));
2216 wxPrintf(_T("Command found in the path as '%s'.\n"), path
.c_str());
2220 #endif // TEST_PATHLIST
2222 // ----------------------------------------------------------------------------
2223 // regular expressions
2224 // ----------------------------------------------------------------------------
2228 #include "wx/regex.h"
2230 static void TestRegExCompile()
2232 wxPuts(_T("*** Testing RE compilation ***\n"));
2234 static struct RegExCompTestData
2236 const wxChar
*pattern
;
2238 } regExCompTestData
[] =
2240 { _T("foo"), TRUE
},
2241 { _T("foo("), FALSE
},
2242 { _T("foo(bar"), FALSE
},
2243 { _T("foo(bar)"), TRUE
},
2244 { _T("foo["), FALSE
},
2245 { _T("foo[bar"), FALSE
},
2246 { _T("foo[bar]"), TRUE
},
2247 { _T("foo{"), TRUE
},
2248 { _T("foo{1"), FALSE
},
2249 { _T("foo{bar"), TRUE
},
2250 { _T("foo{1}"), TRUE
},
2251 { _T("foo{1,2}"), TRUE
},
2252 { _T("foo{bar}"), TRUE
},
2253 { _T("foo*"), TRUE
},
2254 { _T("foo**"), FALSE
},
2255 { _T("foo+"), TRUE
},
2256 { _T("foo++"), FALSE
},
2257 { _T("foo?"), TRUE
},
2258 { _T("foo??"), FALSE
},
2259 { _T("foo?+"), FALSE
},
2263 for ( size_t n
= 0; n
< WXSIZEOF(regExCompTestData
); n
++ )
2265 const RegExCompTestData
& data
= regExCompTestData
[n
];
2266 bool ok
= re
.Compile(data
.pattern
);
2268 wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
2270 ok
? _T("") : _T("not "),
2271 ok
== data
.correct
? _T("ok") : _T("ERROR"));
2275 static void TestRegExMatch()
2277 wxPuts(_T("*** Testing RE matching ***\n"));
2279 static struct RegExMatchTestData
2281 const wxChar
*pattern
;
2284 } regExMatchTestData
[] =
2286 { _T("foo"), _T("bar"), FALSE
},
2287 { _T("foo"), _T("foobar"), TRUE
},
2288 { _T("^foo"), _T("foobar"), TRUE
},
2289 { _T("^foo"), _T("barfoo"), FALSE
},
2290 { _T("bar$"), _T("barbar"), TRUE
},
2291 { _T("bar$"), _T("barbar "), FALSE
},
2294 for ( size_t n
= 0; n
< WXSIZEOF(regExMatchTestData
); n
++ )
2296 const RegExMatchTestData
& data
= regExMatchTestData
[n
];
2298 wxRegEx
re(data
.pattern
);
2299 bool ok
= re
.Matches(data
.text
);
2301 wxPrintf(_T("'%s' %s %s (%s)\n"),
2303 ok
? _T("matches") : _T("doesn't match"),
2305 ok
== data
.correct
? _T("ok") : _T("ERROR"));
2309 static void TestRegExSubmatch()
2311 wxPuts(_T("*** Testing RE subexpressions ***\n"));
2313 wxRegEx
re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
2314 if ( !re
.IsValid() )
2316 wxPuts(_T("ERROR: compilation failed."));
2320 wxString text
= _T("Fri Jul 13 18:37:52 CEST 2001");
2322 if ( !re
.Matches(text
) )
2324 wxPuts(_T("ERROR: match expected."));
2328 wxPrintf(_T("Entire match: %s\n"), re
.GetMatch(text
).c_str());
2330 wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
2331 re
.GetMatch(text
, 3).c_str(),
2332 re
.GetMatch(text
, 2).c_str(),
2333 re
.GetMatch(text
, 4).c_str(),
2334 re
.GetMatch(text
, 1).c_str());
2338 static void TestRegExReplacement()
2340 wxPuts(_T("*** Testing RE replacement ***"));
2342 static struct RegExReplTestData
2346 const wxChar
*result
;
2348 } regExReplTestData
[] =
2350 { _T("foo123"), _T("bar"), _T("bar"), 1 },
2351 { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
2352 { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
2353 { _T("123foo"), _T("bar"), _T("123foo"), 0 },
2354 { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
2355 { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
2356 { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
2359 const wxChar
*pattern
= _T("([a-z]+)[^0-9]*([0-9]+)");
2360 wxRegEx
re(pattern
);
2362 wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern
);
2364 for ( size_t n
= 0; n
< WXSIZEOF(regExReplTestData
); n
++ )
2366 const RegExReplTestData
& data
= regExReplTestData
[n
];
2368 wxString text
= data
.text
;
2369 size_t nRepl
= re
.Replace(&text
, data
.repl
);
2371 wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
2372 data
.text
, data
.repl
,
2373 nRepl
, nRepl
== 1 ? _T("") : _T("es"),
2375 if ( text
== data
.result
&& nRepl
== data
.count
)
2381 wxPrintf(_T("ERROR: should be %u and '%s')\n"),
2382 data
.count
, data
.result
);
2387 static void TestRegExInteractive()
2389 wxPuts(_T("*** Testing RE interactively ***"));
2393 wxChar pattern
[128];
2394 wxPrintf(_T("\nEnter a pattern: "));
2395 if ( !wxFgets(pattern
, WXSIZEOF(pattern
), stdin
) )
2398 // kill the last '\n'
2399 pattern
[wxStrlen(pattern
) - 1] = 0;
2402 if ( !re
.Compile(pattern
) )
2410 wxPrintf(_T("Enter text to match: "));
2411 if ( !wxFgets(text
, WXSIZEOF(text
), stdin
) )
2414 // kill the last '\n'
2415 text
[wxStrlen(text
) - 1] = 0;
2417 if ( !re
.Matches(text
) )
2419 wxPrintf(_T("No match.\n"));
2423 wxPrintf(_T("Pattern matches at '%s'\n"), re
.GetMatch(text
).c_str());
2426 for ( size_t n
= 1; ; n
++ )
2428 if ( !re
.GetMatch(&start
, &len
, n
) )
2433 wxPrintf(_T("Subexpr %u matched '%s'\n"),
2434 n
, wxString(text
+ start
, len
).c_str());
2441 #endif // TEST_REGEX
2443 // ----------------------------------------------------------------------------
2445 // ----------------------------------------------------------------------------
2455 static void TestDbOpen()
2463 // ----------------------------------------------------------------------------
2464 // registry and related stuff
2465 // ----------------------------------------------------------------------------
2467 // this is for MSW only
2470 #undef TEST_REGISTRY
2475 #include "wx/confbase.h"
2476 #include "wx/msw/regconf.h"
2478 static void TestRegConfWrite()
2480 wxRegConfig
regconf(_T("console"), _T("wxwindows"));
2481 regconf
.Write(_T("Hello"), wxString(_T("world")));
2484 #endif // TEST_REGCONF
2486 #ifdef TEST_REGISTRY
2488 #include "wx/msw/registry.h"
2490 // I chose this one because I liked its name, but it probably only exists under
2492 static const wxChar
*TESTKEY
=
2493 _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2495 static void TestRegistryRead()
2497 wxPuts(_T("*** testing registry reading ***"));
2499 wxRegKey
key(TESTKEY
);
2500 wxPrintf(_T("The test key name is '%s'.\n"), key
.GetName().c_str());
2503 wxPuts(_T("ERROR: test key can't be opened, aborting test."));
2508 size_t nSubKeys
, nValues
;
2509 if ( key
.GetKeyInfo(&nSubKeys
, NULL
, &nValues
, NULL
) )
2511 wxPrintf(_T("It has %u subkeys and %u values.\n"), nSubKeys
, nValues
);
2514 wxPrintf(_T("Enumerating values:\n"));
2518 bool cont
= key
.GetFirstValue(value
, dummy
);
2521 wxPrintf(_T("Value '%s': type "), value
.c_str());
2522 switch ( key
.GetValueType(value
) )
2524 case wxRegKey::Type_None
: wxPrintf(_T("ERROR (none)")); break;
2525 case wxRegKey::Type_String
: wxPrintf(_T("SZ")); break;
2526 case wxRegKey::Type_Expand_String
: wxPrintf(_T("EXPAND_SZ")); break;
2527 case wxRegKey::Type_Binary
: wxPrintf(_T("BINARY")); break;
2528 case wxRegKey::Type_Dword
: wxPrintf(_T("DWORD")); break;
2529 case wxRegKey::Type_Multi_String
: wxPrintf(_T("MULTI_SZ")); break;
2530 default: wxPrintf(_T("other (unknown)")); break;
2533 wxPrintf(_T(", value = "));
2534 if ( key
.IsNumericValue(value
) )
2537 key
.QueryValue(value
, &val
);
2538 wxPrintf(_T("%ld"), val
);
2543 key
.QueryValue(value
, val
);
2544 wxPrintf(_T("'%s'"), val
.c_str());
2546 key
.QueryRawValue(value
, val
);
2547 wxPrintf(_T(" (raw value '%s')"), val
.c_str());
2552 cont
= key
.GetNextValue(value
, dummy
);
2556 static void TestRegistryAssociation()
2559 The second call to deleteself genertaes an error message, with a
2560 messagebox saying .flo is crucial to system operation, while the .ddf
2561 call also fails, but with no error message
2566 key
.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2568 key
= "ddxf_auto_file" ;
2569 key
.SetName("HKEY_CLASSES_ROOT\\.flo" );
2571 key
= "ddxf_auto_file" ;
2572 key
.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2575 key
.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2577 key
= "program \"%1\"" ;
2579 key
.SetName("HKEY_CLASSES_ROOT\\.ddf" );
2581 key
.SetName("HKEY_CLASSES_ROOT\\.flo" );
2583 key
.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon");
2585 key
.SetName("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command");
2589 #endif // TEST_REGISTRY
2591 // ----------------------------------------------------------------------------
2593 // ----------------------------------------------------------------------------
2597 #include "wx/socket.h"
2598 #include "wx/protocol/protocol.h"
2599 #include "wx/protocol/http.h"
2601 static void TestSocketServer()
2603 wxPuts(_T("*** Testing wxSocketServer ***\n"));
2605 static const int PORT
= 3000;
2610 wxSocketServer
*server
= new wxSocketServer(addr
);
2611 if ( !server
->Ok() )
2613 wxPuts(_T("ERROR: failed to bind"));
2620 wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT
);
2622 wxSocketBase
*socket
= server
->Accept();
2625 wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
2629 wxPuts(_T("Server: got a client."));
2631 server
->SetTimeout(60); // 1 min
2633 while ( socket
->IsConnected() )
2636 wxChar ch
= _T('\0');
2639 if ( socket
->Read(&ch
, sizeof(ch
)).Error() )
2641 // don't log error if the client just close the connection
2642 if ( socket
->IsConnected() )
2644 wxPuts(_T("ERROR: in wxSocket::Read."));
2664 wxPrintf(_T("Server: got '%s'.\n"), s
.c_str());
2665 if ( s
== _T("bye") )
2672 socket
->Write(s
.MakeUpper().c_str(), s
.length());
2673 socket
->Write("\r\n", 2);
2674 wxPrintf(_T("Server: wrote '%s'.\n"), s
.c_str());
2677 wxPuts(_T("Server: lost a client."));
2682 // same as "delete server" but is consistent with GUI programs
2686 static void TestSocketClient()
2688 wxPuts(_T("*** Testing wxSocketClient ***\n"));
2690 static const wxChar
*hostname
= _T("www.wxwindows.org");
2693 addr
.Hostname(hostname
);
2696 wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname
);
2698 wxSocketClient client
;
2699 if ( !client
.Connect(addr
) )
2701 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname
);
2705 wxPrintf(_T("--- Connected to %s:%u...\n"),
2706 addr
.Hostname().c_str(), addr
.Service());
2710 // could use simply "GET" here I suppose
2712 wxString::Format(_T("GET http://%s/\r\n"), hostname
);
2713 client
.Write(cmdGet
, cmdGet
.length());
2714 wxPrintf(_T("--- Sent command '%s' to the server\n"),
2715 MakePrintable(cmdGet
).c_str());
2716 client
.Read(buf
, WXSIZEOF(buf
));
2717 wxPrintf(_T("--- Server replied:\n%s"), buf
);
2721 #endif // TEST_SOCKETS
2723 // ----------------------------------------------------------------------------
2725 // ----------------------------------------------------------------------------
2729 #include "wx/protocol/ftp.h"
2733 #define FTP_ANONYMOUS
2735 #ifdef FTP_ANONYMOUS
2736 static const wxChar
*directory
= _T("/pub");
2737 static const wxChar
*filename
= _T("welcome.msg");
2739 static const wxChar
*directory
= _T("/etc");
2740 static const wxChar
*filename
= _T("issue");
2743 static bool TestFtpConnect()
2745 wxPuts(_T("*** Testing FTP connect ***"));
2747 #ifdef FTP_ANONYMOUS
2748 static const wxChar
*hostname
= _T("ftp.wxwindows.org");
2750 wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname
);
2751 #else // !FTP_ANONYMOUS
2752 static const wxChar
*hostname
= "localhost";
2755 wxFgets(user
, WXSIZEOF(user
), stdin
);
2756 user
[wxStrlen(user
) - 1] = '\0'; // chop off '\n'
2759 wxChar password
[256];
2760 wxPrintf(_T("Password for %s: "), password
);
2761 wxFgets(password
, WXSIZEOF(password
), stdin
);
2762 password
[wxStrlen(password
) - 1] = '\0'; // chop off '\n'
2763 ftp
.SetPassword(password
);
2765 wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname
, user
);
2766 #endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2768 if ( !ftp
.Connect(hostname
) )
2770 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname
);
2776 wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
2777 hostname
, ftp
.Pwd().c_str());
2783 // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2784 static void TestFtpWuFtpd()
2787 static const wxChar
*hostname
= _T("ftp.eudora.com");
2788 if ( !ftp
.Connect(hostname
) )
2790 wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname
);
2794 static const wxChar
*filename
= _T("eudora/pubs/draft-gellens-submit-09.txt");
2795 wxInputStream
*in
= ftp
.GetInputStream(filename
);
2798 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename
);
2802 size_t size
= in
->StreamSize();
2803 wxPrintf(_T("Reading file %s (%u bytes)..."), filename
, size
);
2805 wxChar
*data
= new wxChar
[size
];
2806 if ( !in
->Read(data
, size
) )
2808 wxPuts(_T("ERROR: read error"));
2812 wxPrintf(_T("Successfully retrieved the file.\n"));
2821 static void TestFtpList()
2823 wxPuts(_T("*** Testing wxFTP file listing ***\n"));
2826 if ( !ftp
.ChDir(directory
) )
2828 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory
);
2831 wxPrintf(_T("Current directory is '%s'\n"), ftp
.Pwd().c_str());
2833 // test NLIST and LIST
2834 wxArrayString files
;
2835 if ( !ftp
.GetFilesList(files
) )
2837 wxPuts(_T("ERROR: failed to get NLIST of files"));
2841 wxPrintf(_T("Brief list of files under '%s':\n"), ftp
.Pwd().c_str());
2842 size_t count
= files
.GetCount();
2843 for ( size_t n
= 0; n
< count
; n
++ )
2845 wxPrintf(_T("\t%s\n"), files
[n
].c_str());
2847 wxPuts(_T("End of the file list"));
2850 if ( !ftp
.GetDirList(files
) )
2852 wxPuts(_T("ERROR: failed to get LIST of files"));
2856 wxPrintf(_T("Detailed list of files under '%s':\n"), ftp
.Pwd().c_str());
2857 size_t count
= files
.GetCount();
2858 for ( size_t n
= 0; n
< count
; n
++ )
2860 wxPrintf(_T("\t%s\n"), files
[n
].c_str());
2862 wxPuts(_T("End of the file list"));
2865 if ( !ftp
.ChDir(_T("..")) )
2867 wxPuts(_T("ERROR: failed to cd to .."));
2870 wxPrintf(_T("Current directory is '%s'\n"), ftp
.Pwd().c_str());
2873 static void TestFtpDownload()
2875 wxPuts(_T("*** Testing wxFTP download ***\n"));
2878 wxInputStream
*in
= ftp
.GetInputStream(filename
);
2881 wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename
);
2885 size_t size
= in
->StreamSize();
2886 wxPrintf(_T("Reading file %s (%u bytes)..."), filename
, size
);
2889 wxChar
*data
= new wxChar
[size
];
2890 if ( !in
->Read(data
, size
) )
2892 wxPuts(_T("ERROR: read error"));
2896 wxPrintf(_T("\nContents of %s:\n%s\n"), filename
, data
);
2904 static void TestFtpFileSize()
2906 wxPuts(_T("*** Testing FTP SIZE command ***"));
2908 if ( !ftp
.ChDir(directory
) )
2910 wxPrintf(_T("ERROR: failed to cd to %s\n"), directory
);
2913 wxPrintf(_T("Current directory is '%s'\n"), ftp
.Pwd().c_str());
2915 if ( ftp
.FileExists(filename
) )
2917 int size
= ftp
.GetFileSize(filename
);
2919 wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename
);
2921 wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename
, size
);
2925 wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename
);
2929 static void TestFtpMisc()
2931 wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
2933 if ( ftp
.SendCommand("STAT") != '2' )
2935 wxPuts(_T("ERROR: STAT failed"));
2939 wxPrintf(_T("STAT returned:\n\n%s\n"), ftp
.GetLastResult().c_str());
2942 if ( ftp
.SendCommand("HELP SITE") != '2' )
2944 wxPuts(_T("ERROR: HELP SITE failed"));
2948 wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
2949 ftp
.GetLastResult().c_str());
2953 static void TestFtpInteractive()
2955 wxPuts(_T("\n*** Interactive wxFTP test ***"));
2961 wxPrintf(_T("Enter FTP command: "));
2962 if ( !wxFgets(buf
, WXSIZEOF(buf
), stdin
) )
2965 // kill the last '\n'
2966 buf
[wxStrlen(buf
) - 1] = 0;
2968 // special handling of LIST and NLST as they require data connection
2969 wxString
start(buf
, 4);
2971 if ( start
== "LIST" || start
== "NLST" )
2974 if ( wxStrlen(buf
) > 4 )
2977 wxArrayString files
;
2978 if ( !ftp
.GetList(files
, wildcard
, start
== "LIST") )
2980 wxPrintf(_T("ERROR: failed to get %s of files\n"), start
.c_str());
2984 wxPrintf(_T("--- %s of '%s' under '%s':\n"),
2985 start
.c_str(), wildcard
.c_str(), ftp
.Pwd().c_str());
2986 size_t count
= files
.GetCount();
2987 for ( size_t n
= 0; n
< count
; n
++ )
2989 wxPrintf(_T("\t%s\n"), files
[n
].c_str());
2991 wxPuts(_T("--- End of the file list"));
2996 wxChar ch
= ftp
.SendCommand(buf
);
2997 wxPrintf(_T("Command %s"), ch
? _T("succeeded") : _T("failed"));
3000 wxPrintf(_T(" (return code %c)"), ch
);
3003 wxPrintf(_T(", server reply:\n%s\n\n"), ftp
.GetLastResult().c_str());
3007 wxPuts(_T("\n*** done ***"));
3010 static void TestFtpUpload()
3012 wxPuts(_T("*** Testing wxFTP uploading ***\n"));
3015 static const wxChar
*file1
= _T("test1");
3016 static const wxChar
*file2
= _T("test2");
3017 wxOutputStream
*out
= ftp
.GetOutputStream(file1
);
3020 wxPrintf(_T("--- Uploading to %s ---\n"), file1
);
3021 out
->Write("First hello", 11);
3025 // send a command to check the remote file
3026 if ( ftp
.SendCommand(wxString("STAT ") + file1
) != '2' )
3028 wxPrintf(_T("ERROR: STAT %s failed\n"), file1
);
3032 wxPrintf(_T("STAT %s returned:\n\n%s\n"),
3033 file1
, ftp
.GetLastResult().c_str());
3036 out
= ftp
.GetOutputStream(file2
);
3039 wxPrintf(_T("--- Uploading to %s ---\n"), file1
);
3040 out
->Write("Second hello", 12);
3047 // ----------------------------------------------------------------------------
3049 // ----------------------------------------------------------------------------
3053 #include "wx/wfstream.h"
3054 #include "wx/mstream.h"
3056 static void TestFileStream()
3058 wxPuts(_T("*** Testing wxFileInputStream ***"));
3060 static const wxChar
*filename
= _T("testdata.fs");
3062 wxFileOutputStream
fsOut(filename
);
3063 fsOut
.Write("foo", 3);
3066 wxFileInputStream
fsIn(filename
);
3067 wxPrintf(_T("File stream size: %u\n"), fsIn
.GetSize());
3068 while ( !fsIn
.Eof() )
3070 putchar(fsIn
.GetC());
3073 if ( !wxRemoveFile(filename
) )
3075 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename
);
3078 wxPuts(_T("\n*** wxFileInputStream test done ***"));
3081 static void TestMemoryStream()
3083 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
3085 wxMemoryOutputStream memOutStream
;
3086 wxPrintf(_T("Initially out stream offset: %lu\n"),
3087 (unsigned long)memOutStream
.TellO());
3089 for ( const wxChar
*p
= _T("Hello, stream!"); *p
; p
++ )
3091 memOutStream
.PutC(*p
);
3094 wxPrintf(_T("Final out stream offset: %lu\n"),
3095 (unsigned long)memOutStream
.TellO());
3097 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
3100 size_t len
= memOutStream
.CopyTo(buf
, WXSIZEOF(buf
));
3102 wxMemoryInputStream
memInpStream(buf
, len
);
3103 wxPrintf(_T("Memory stream size: %u\n"), memInpStream
.GetSize());
3104 while ( !memInpStream
.Eof() )
3106 putchar(memInpStream
.GetC());
3109 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
3112 #endif // TEST_STREAMS
3114 // ----------------------------------------------------------------------------
3116 // ----------------------------------------------------------------------------
3120 #include "wx/timer.h"
3121 #include "wx/utils.h"
3123 static void TestStopWatch()
3125 wxPuts(_T("*** Testing wxStopWatch ***\n"));
3129 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
3132 wxPrintf(_T("\t%ldms\n"), sw
.Time());
3134 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
3138 wxPrintf(_T("\telapsed time: %ldms\n"), sw
.Time());
3141 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
3144 wxPrintf(_T("\telapsed time: %ldms\n"), sw
.Time());
3147 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
3150 wxPrintf(_T("\telapsed time: %ldms\n"), sw
.Time());
3153 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
3154 for ( size_t n
= 0; n
< 70; n
++ )
3158 for ( size_t m
= 0; m
< 100000; m
++ )
3160 if ( sw
.Time() < 0 || sw2
.Time() < 0 )
3162 wxPuts(_T("\ntime is negative - ERROR!"));
3170 wxPuts(_T(", ok."));
3173 #endif // TEST_TIMER
3175 // ----------------------------------------------------------------------------
3177 // ----------------------------------------------------------------------------
3181 #include "wx/vcard.h"
3183 static void DumpVObject(size_t level
, const wxVCardObject
& vcard
)
3186 wxVCardObject
*vcObj
= vcard
.GetFirstProp(&cookie
);
3189 wxPrintf(_T("%s%s"),
3190 wxString(_T('\t'), level
).c_str(),
3191 vcObj
->GetName().c_str());
3194 switch ( vcObj
->GetType() )
3196 case wxVCardObject::String
:
3197 case wxVCardObject::UString
:
3200 vcObj
->GetValue(&val
);
3201 value
<< _T('"') << val
<< _T('"');
3205 case wxVCardObject::Int
:
3208 vcObj
->GetValue(&i
);
3209 value
.Printf(_T("%u"), i
);
3213 case wxVCardObject::Long
:
3216 vcObj
->GetValue(&l
);
3217 value
.Printf(_T("%lu"), l
);
3221 case wxVCardObject::None
:
3224 case wxVCardObject::Object
:
3225 value
= _T("<node>");
3229 value
= _T("<unknown value type>");
3233 wxPrintf(_T(" = %s"), value
.c_str());
3236 DumpVObject(level
+ 1, *vcObj
);
3239 vcObj
= vcard
.GetNextProp(&cookie
);
3243 static void DumpVCardAddresses(const wxVCard
& vcard
)
3245 wxPuts(_T("\nShowing all addresses from vCard:\n"));
3249 wxVCardAddress
*addr
= vcard
.GetFirstAddress(&cookie
);
3253 int flags
= addr
->GetFlags();
3254 if ( flags
& wxVCardAddress::Domestic
)
3256 flagsStr
<< _T("domestic ");
3258 if ( flags
& wxVCardAddress::Intl
)
3260 flagsStr
<< _T("international ");
3262 if ( flags
& wxVCardAddress::Postal
)
3264 flagsStr
<< _T("postal ");
3266 if ( flags
& wxVCardAddress::Parcel
)
3268 flagsStr
<< _T("parcel ");
3270 if ( flags
& wxVCardAddress::Home
)
3272 flagsStr
<< _T("home ");
3274 if ( flags
& wxVCardAddress::Work
)
3276 flagsStr
<< _T("work ");
3279 wxPrintf(_T("Address %u:\n")
3281 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3284 addr
->GetPostOffice().c_str(),
3285 addr
->GetExtAddress().c_str(),
3286 addr
->GetStreet().c_str(),
3287 addr
->GetLocality().c_str(),
3288 addr
->GetRegion().c_str(),
3289 addr
->GetPostalCode().c_str(),
3290 addr
->GetCountry().c_str()
3294 addr
= vcard
.GetNextAddress(&cookie
);
3298 static void DumpVCardPhoneNumbers(const wxVCard
& vcard
)
3300 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
3304 wxVCardPhoneNumber
*phone
= vcard
.GetFirstPhoneNumber(&cookie
);
3308 int flags
= phone
->GetFlags();
3309 if ( flags
& wxVCardPhoneNumber::Voice
)
3311 flagsStr
<< _T("voice ");
3313 if ( flags
& wxVCardPhoneNumber::Fax
)
3315 flagsStr
<< _T("fax ");
3317 if ( flags
& wxVCardPhoneNumber::Cellular
)
3319 flagsStr
<< _T("cellular ");
3321 if ( flags
& wxVCardPhoneNumber::Modem
)
3323 flagsStr
<< _T("modem ");
3325 if ( flags
& wxVCardPhoneNumber::Home
)
3327 flagsStr
<< _T("home ");
3329 if ( flags
& wxVCardPhoneNumber::Work
)
3331 flagsStr
<< _T("work ");
3334 wxPrintf(_T("Phone number %u:\n")
3339 phone
->GetNumber().c_str()
3343 phone
= vcard
.GetNextPhoneNumber(&cookie
);
3347 static void TestVCardRead()
3349 wxPuts(_T("*** Testing wxVCard reading ***\n"));
3351 wxVCard
vcard(_T("vcard.vcf"));
3352 if ( !vcard
.IsOk() )
3354 wxPuts(_T("ERROR: couldn't load vCard."));
3358 // read individual vCard properties
3359 wxVCardObject
*vcObj
= vcard
.GetProperty("FN");
3363 vcObj
->GetValue(&value
);
3368 value
= _T("<none>");
3371 wxPrintf(_T("Full name retrieved directly: %s\n"), value
.c_str());
3374 if ( !vcard
.GetFullName(&value
) )
3376 value
= _T("<none>");
3379 wxPrintf(_T("Full name from wxVCard API: %s\n"), value
.c_str());
3381 // now show how to deal with multiply occuring properties
3382 DumpVCardAddresses(vcard
);
3383 DumpVCardPhoneNumbers(vcard
);
3385 // and finally show all
3386 wxPuts(_T("\nNow dumping the entire vCard:\n")
3387 "-----------------------------\n");
3389 DumpVObject(0, vcard
);
3393 static void TestVCardWrite()
3395 wxPuts(_T("*** Testing wxVCard writing ***\n"));
3398 if ( !vcard
.IsOk() )
3400 wxPuts(_T("ERROR: couldn't create vCard."));
3405 vcard
.SetName("Zeitlin", "Vadim");
3406 vcard
.SetFullName("Vadim Zeitlin");
3407 vcard
.SetOrganization("wxWindows", "R&D");
3409 // just dump the vCard back
3410 wxPuts(_T("Entire vCard follows:\n"));
3411 wxPuts(vcard
.Write());
3415 #endif // TEST_VCARD
3417 // ----------------------------------------------------------------------------
3419 // ----------------------------------------------------------------------------
3421 #if !defined(__WIN32__) || !wxUSE_FSVOLUME
3427 #include "wx/volume.h"
3429 static const wxChar
*volumeKinds
[] =
3435 _T("network volume"),
3439 static void TestFSVolume()
3441 wxPuts(_T("*** Testing wxFSVolume class ***"));
3443 wxArrayString volumes
= wxFSVolume::GetVolumes();
3444 size_t count
= volumes
.GetCount();
3448 wxPuts(_T("ERROR: no mounted volumes?"));
3452 wxPrintf(_T("%u mounted volumes found:\n"), count
);
3454 for ( size_t n
= 0; n
< count
; n
++ )
3456 wxFSVolume
vol(volumes
[n
]);
3459 wxPuts(_T("ERROR: couldn't create volume"));
3463 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3465 vol
.GetDisplayName().c_str(),
3466 vol
.GetName().c_str(),
3467 volumeKinds
[vol
.GetKind()],
3468 vol
.IsWritable() ? _T("rw") : _T("ro"),
3469 vol
.GetFlags() & wxFS_VOL_REMOVABLE
? _T("removable")
3474 #endif // TEST_VOLUME
3476 // ----------------------------------------------------------------------------
3477 // wide char and Unicode support
3478 // ----------------------------------------------------------------------------
3482 static void TestUnicodeToFromAscii()
3484 wxPuts(_T("Testing wxString::To/FromAscii()\n"));
3486 static const char *msg
= "Hello, world!";
3487 wxString s
= wxString::FromAscii(msg
);
3489 wxPrintf(_T("Message in Unicode: %s\n"), s
.c_str());
3490 wxPrintf(_T("Message in ASCII: %s\n"), s
.ToAscii());
3492 wxPutchar(_T('\n'));
3495 #endif // TEST_UNICODE
3499 #include "wx/strconv.h"
3500 #include "wx/fontenc.h"
3501 #include "wx/encconv.h"
3502 #include "wx/buffer.h"
3504 static const unsigned char textInUtf8_
[] =
3506 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3507 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3508 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3509 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3510 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3511 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3512 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3515 #define textInUtf8 ((const char *)textInUtf8_)
3517 static void TestUtf8()
3519 wxPuts(_T("*** Testing UTF8 support ***\n"));
3523 if ( wxConvUTF8
.MB2WC(wbuf
, textInUtf8
, WXSIZEOF(textInUtf8
)) <= 0 )
3525 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3529 wxCSConv
conv(_T("koi8-r"));
3530 if ( conv
.WC2MB(buf
, wbuf
, 0 /* not needed wcslen(wbuf) */) <= 0 )
3532 wxPuts(_T("ERROR: conversion to KOI8-R failed."));
3536 wxPrintf(_T("The resulting string (in KOI8-R): %s\n"), buf
);
3540 if ( wxConvUTF8
.WC2MB(buf
, L
"Ã la", WXSIZEOF(buf
)) <= 0 )
3542 wxPuts(_T("ERROR: conversion to UTF-8 failed."));
3546 wxPrintf(_T("The string in UTF-8: %s\n"), buf
);
3552 static void TestEncodingConverter()
3554 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3556 // using wxEncodingConverter should give the same result as above
3559 if ( wxConvUTF8
.MB2WC(wbuf
, textInUtf8
, WXSIZEOF(textInUtf8
)) <= 0 )
3561 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3565 wxEncodingConverter ec
;
3566 ec
.Init(wxFONTENCODING_UNICODE
, wxFONTENCODING_KOI8
);
3567 ec
.Convert(wbuf
, buf
);
3568 wxPrintf(_T("The same string obtained using wxEC: %s\n"), buf
);
3574 #endif // TEST_WCHAR
3576 // ----------------------------------------------------------------------------
3578 // ----------------------------------------------------------------------------
3582 #include "wx/filesys.h"
3583 #include "wx/fs_zip.h"
3584 #include "wx/zipstrm.h"
3586 static const wxChar
*TESTFILE_ZIP
= _T("testdata.zip");
3588 static void TestZipStreamRead()
3590 wxPuts(_T("*** Testing ZIP reading ***\n"));
3592 static const wxChar
*filename
= _T("foo");
3593 wxZipInputStream
istr(TESTFILE_ZIP
, filename
);
3594 wxPrintf(_T("Archive size: %u\n"), istr
.GetSize());
3596 wxPrintf(_T("Dumping the file '%s':\n"), filename
);
3597 while ( !istr
.Eof() )
3599 putchar(istr
.GetC());
3603 wxPuts(_T("\n----- done ------"));
3606 static void DumpZipDirectory(wxFileSystem
& fs
,
3607 const wxString
& dir
,
3608 const wxString
& indent
)
3610 wxString prefix
= wxString::Format(_T("%s#zip:%s"),
3611 TESTFILE_ZIP
, dir
.c_str());
3612 wxString wildcard
= prefix
+ _T("/*");
3614 wxString dirname
= fs
.FindFirst(wildcard
, wxDIR
);
3615 while ( !dirname
.empty() )
3617 if ( !dirname
.StartsWith(prefix
+ _T('/'), &dirname
) )
3619 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3624 wxPrintf(_T("%s%s\n"), indent
.c_str(), dirname
.c_str());
3626 DumpZipDirectory(fs
, dirname
,
3627 indent
+ wxString(_T(' '), 4));
3629 dirname
= fs
.FindNext();
3632 wxString filename
= fs
.FindFirst(wildcard
, wxFILE
);
3633 while ( !filename
.empty() )
3635 if ( !filename
.StartsWith(prefix
, &filename
) )
3637 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3642 wxPrintf(_T("%s%s\n"), indent
.c_str(), filename
.c_str());
3644 filename
= fs
.FindNext();
3648 static void TestZipFileSystem()
3650 wxPuts(_T("*** Testing ZIP file system ***\n"));
3652 wxFileSystem::AddHandler(new wxZipFSHandler
);
3654 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP
);
3656 DumpZipDirectory(fs
, _T(""), wxString(_T(' '), 4));
3661 // ----------------------------------------------------------------------------
3663 // ----------------------------------------------------------------------------
3667 #include "wx/zstream.h"
3668 #include "wx/wfstream.h"
3670 static const wxChar
*FILENAME_GZ
= _T("test.gz");
3671 static const wxChar
*TEST_DATA
= _T("hello and hello and hello and hello and hello");
3673 static void TestZlibStreamWrite()
3675 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3677 wxFileOutputStream
fileOutStream(FILENAME_GZ
);
3678 wxZlibOutputStream
ostr(fileOutStream
);
3679 wxPrintf(_T("Compressing the test string... "));
3680 ostr
.Write(TEST_DATA
, wxStrlen(TEST_DATA
) + 1);
3683 wxPuts(_T("(ERROR: failed)"));
3690 wxPuts(_T("\n----- done ------"));
3693 static void TestZlibStreamRead()
3695 wxPuts(_T("*** Testing Zlib stream reading ***\n"));
3697 wxFileInputStream
fileInStream(FILENAME_GZ
);
3698 wxZlibInputStream
istr(fileInStream
);
3699 wxPrintf(_T("Archive size: %u\n"), istr
.GetSize());
3701 wxPuts(_T("Dumping the file:"));
3702 while ( !istr
.Eof() )
3704 putchar(istr
.GetC());
3708 wxPuts(_T("\n----- done ------"));
3713 // ----------------------------------------------------------------------------
3715 // ----------------------------------------------------------------------------
3717 #ifdef TEST_DATETIME
3721 #include "wx/date.h"
3722 #include "wx/datetime.h"
3727 wxDateTime::wxDateTime_t day
;
3728 wxDateTime::Month month
;
3730 wxDateTime::wxDateTime_t hour
, min
, sec
;
3732 wxDateTime::WeekDay wday
;
3733 time_t gmticks
, ticks
;
3735 void Init(const wxDateTime::Tm
& tm
)
3744 gmticks
= ticks
= -1;
3747 wxDateTime
DT() const
3748 { return wxDateTime(day
, month
, year
, hour
, min
, sec
); }
3750 bool SameDay(const wxDateTime::Tm
& tm
) const
3752 return day
== tm
.mday
&& month
== tm
.mon
&& year
== tm
.year
;
3755 wxString
Format() const
3758 s
.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"),
3760 wxDateTime::GetMonthName(month
).c_str(),
3762 abs(wxDateTime::ConvertYearToBC(year
)),
3763 year
> 0 ? _T("AD") : _T("BC"));
3767 wxString
FormatDate() const
3770 s
.Printf(_T("%02d-%s-%4d%s"),
3772 wxDateTime::GetMonthName(month
, wxDateTime::Name_Abbr
).c_str(),
3773 abs(wxDateTime::ConvertYearToBC(year
)),
3774 year
> 0 ? _T("AD") : _T("BC"));
3779 static const Date testDates
[] =
3781 { 1, wxDateTime::Jan
, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu
, 0, -3600 },
3782 { 7, wxDateTime::Feb
, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu
, -1, -1 },
3783 { 8, wxDateTime::Feb
, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri
, -1, -1 },
3784 { 1, wxDateTime::Jan
, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu
, -1, -1 },
3785 { 1, wxDateTime::Jan
, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri
, -1, -1 },
3786 { 21, wxDateTime::Jan
, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon
, -1, -1 },
3787 { 29, wxDateTime::May
, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat
, 202219200, 202212000 },
3788 { 29, wxDateTime::Feb
, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun
, 194400000, 194396400 },
3789 { 1, wxDateTime::Jan
, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon
, -1, -1 },
3790 { 1, wxDateTime::Jan
, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon
, -1, -1 },
3791 { 15, wxDateTime::Oct
, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri
, -1, -1 },
3792 { 4, wxDateTime::Oct
, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon
, -1, -1 },
3793 { 1, wxDateTime::Mar
, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu
, -1, -1 },
3794 { 1, wxDateTime::Jan
, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon
, -1, -1 },
3795 { 31, wxDateTime::Dec
, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun
, -1, -1 },
3796 { 1, wxDateTime::Jan
, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat
, -1, -1 },
3797 { 12, wxDateTime::Aug
, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri
, -1, -1 },
3798 { 12, wxDateTime::Aug
, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat
, -1, -1 },
3799 { 24, wxDateTime::Nov
, -4713, 00, 00, 00, -0.5, wxDateTime::Mon
, -1, -1 },
3802 // this test miscellaneous static wxDateTime functions
3803 static void TestTimeStatic()
3805 wxPuts(_T("\n*** wxDateTime static methods test ***"));
3807 // some info about the current date
3808 int year
= wxDateTime::GetCurrentYear();
3809 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
3811 wxDateTime::IsLeapYear(year
) ? "" : "not ",
3812 wxDateTime::GetNumberOfDays(year
));
3814 wxDateTime::Month month
= wxDateTime::GetCurrentMonth();
3815 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
3816 wxDateTime::GetMonthName(month
, wxDateTime::Name_Abbr
).c_str(),
3817 wxDateTime::GetMonthName(month
).c_str(),
3818 wxDateTime::GetNumberOfDays(month
));
3821 static const size_t nYears
= 5;
3822 static const size_t years
[2][nYears
] =
3824 // first line: the years to test
3825 { 1990, 1976, 2000, 2030, 1984, },
3827 // second line: TRUE if leap, FALSE otherwise
3828 { FALSE
, TRUE
, TRUE
, FALSE
, TRUE
}
3831 for ( size_t n
= 0; n
< nYears
; n
++ )
3833 int year
= years
[0][n
];
3834 bool should
= years
[1][n
] != 0,
3835 is
= wxDateTime::IsLeapYear(year
);
3837 wxPrintf(_T("Year %d is %sa leap year (%s)\n"),
3840 should
== is
? "ok" : "ERROR");
3842 wxASSERT( should
== wxDateTime::IsLeapYear(year
) );
3846 // test constructing wxDateTime objects
3847 static void TestTimeSet()
3849 wxPuts(_T("\n*** wxDateTime construction test ***"));
3851 for ( size_t n
= 0; n
< WXSIZEOF(testDates
); n
++ )
3853 const Date
& d1
= testDates
[n
];
3854 wxDateTime dt
= d1
.DT();
3857 d2
.Init(dt
.GetTm());
3859 wxString s1
= d1
.Format(),
3862 wxPrintf(_T("Date: %s == %s (%s)\n"),
3863 s1
.c_str(), s2
.c_str(),
3864 s1
== s2
? _T("ok") : _T("ERROR"));
3868 // test time zones stuff
3869 static void TestTimeZones()
3871 wxPuts(_T("\n*** wxDateTime timezone test ***"));
3873 wxDateTime now
= wxDateTime::Now();
3875 wxPrintf(_T("Current GMT time:\t%s\n"), now
.Format(_T("%c"), wxDateTime::GMT0
).c_str());
3876 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0
).c_str());
3877 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST
).c_str());
3878 wxPrintf(_T("Current time in Paris:\t%s\n"), now
.Format(_T("%c"), wxDateTime::CET
).c_str());
3879 wxPrintf(_T(" Moscow:\t%s\n"), now
.Format(_T("%c"), wxDateTime::MSK
).c_str());
3880 wxPrintf(_T(" New York:\t%s\n"), now
.Format(_T("%c"), wxDateTime::EST
).c_str());
3882 wxDateTime::Tm tm
= now
.GetTm();
3883 if ( wxDateTime(tm
) != now
)
3885 wxPrintf(_T("ERROR: got %s instead of %s\n"),
3886 wxDateTime(tm
).Format().c_str(), now
.Format().c_str());
3890 // test some minimal support for the dates outside the standard range
3891 static void TestTimeRange()
3893 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
3895 static const wxChar
*fmt
= _T("%d-%b-%Y %H:%M:%S");
3897 wxPrintf(_T("Unix epoch:\t%s\n"),
3898 wxDateTime(2440587.5).Format(fmt
).c_str());
3899 wxPrintf(_T("Feb 29, 0: \t%s\n"),
3900 wxDateTime(29, wxDateTime::Feb
, 0).Format(fmt
).c_str());
3901 wxPrintf(_T("JDN 0: \t%s\n"),
3902 wxDateTime(0.0).Format(fmt
).c_str());
3903 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
3904 wxDateTime(1, wxDateTime::Jan
, 1).Format(fmt
).c_str());
3905 wxPrintf(_T("May 29, 2099:\t%s\n"),
3906 wxDateTime(29, wxDateTime::May
, 2099).Format(fmt
).c_str());
3909 static void TestTimeTicks()
3911 wxPuts(_T("\n*** wxDateTime ticks test ***"));
3913 for ( size_t n
= 0; n
< WXSIZEOF(testDates
); n
++ )
3915 const Date
& d
= testDates
[n
];
3916 if ( d
.ticks
== -1 )
3919 wxDateTime dt
= d
.DT();
3920 long ticks
= (dt
.GetValue() / 1000).ToLong();
3921 wxPrintf(_T("Ticks of %s:\t% 10ld"), d
.Format().c_str(), ticks
);
3922 if ( ticks
== d
.ticks
)
3924 wxPuts(_T(" (ok)"));
3928 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
3929 (long)d
.ticks
, (long)(ticks
- d
.ticks
));
3932 dt
= d
.DT().ToTimezone(wxDateTime::GMT0
);
3933 ticks
= (dt
.GetValue() / 1000).ToLong();
3934 wxPrintf(_T("GMtks of %s:\t% 10ld"), d
.Format().c_str(), ticks
);
3935 if ( ticks
== d
.gmticks
)
3937 wxPuts(_T(" (ok)"));
3941 wxPrintf(_T(" (ERROR: should be %ld, delta = %ld)\n"),
3942 (long)d
.gmticks
, (long)(ticks
- d
.gmticks
));
3949 // test conversions to JDN &c
3950 static void TestTimeJDN()
3952 wxPuts(_T("\n*** wxDateTime to JDN test ***"));
3954 for ( size_t n
= 0; n
< WXSIZEOF(testDates
); n
++ )
3956 const Date
& d
= testDates
[n
];
3957 wxDateTime
dt(d
.day
, d
.month
, d
.year
, d
.hour
, d
.min
, d
.sec
);
3958 double jdn
= dt
.GetJulianDayNumber();
3960 wxPrintf(_T("JDN of %s is:\t% 15.6f"), d
.Format().c_str(), jdn
);
3963 wxPuts(_T(" (ok)"));
3967 wxPrintf(_T(" (ERROR: should be %f, delta = %f)\n"),
3968 d
.jdn
, jdn
- d
.jdn
);
3973 // test week days computation
3974 static void TestTimeWDays()
3976 wxPuts(_T("\n*** wxDateTime weekday test ***"));
3978 // test GetWeekDay()
3980 for ( n
= 0; n
< WXSIZEOF(testDates
); n
++ )
3982 const Date
& d
= testDates
[n
];
3983 wxDateTime
dt(d
.day
, d
.month
, d
.year
, d
.hour
, d
.min
, d
.sec
);
3985 wxDateTime::WeekDay wday
= dt
.GetWeekDay();
3986 wxPrintf(_T("%s is: %s"),
3988 wxDateTime::GetWeekDayName(wday
).c_str());
3989 if ( wday
== d
.wday
)
3991 wxPuts(_T(" (ok)"));
3995 wxPrintf(_T(" (ERROR: should be %s)\n"),
3996 wxDateTime::GetWeekDayName(d
.wday
).c_str());
4002 // test SetToWeekDay()
4003 struct WeekDateTestData
4005 Date date
; // the real date (precomputed)
4006 int nWeek
; // its week index in the month
4007 wxDateTime::WeekDay wday
; // the weekday
4008 wxDateTime::Month month
; // the month
4009 int year
; // and the year
4011 wxString
Format() const
4014 switch ( nWeek
< -1 ? -nWeek
: nWeek
)
4016 case 1: which
= _T("first"); break;
4017 case 2: which
= _T("second"); break;
4018 case 3: which
= _T("third"); break;
4019 case 4: which
= _T("fourth"); break;
4020 case 5: which
= _T("fifth"); break;
4022 case -1: which
= _T("last"); break;
4027 which
+= _T(" from end");
4030 s
.Printf(_T("The %s %s of %s in %d"),
4032 wxDateTime::GetWeekDayName(wday
).c_str(),
4033 wxDateTime::GetMonthName(month
).c_str(),
4040 // the array data was generated by the following python program
4042 from DateTime import *
4043 from whrandom import *
4044 from string import *
4046 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4047 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4049 week = DateTimeDelta(7)
4052 year = randint(1900, 2100)
4053 month = randint(1, 12)
4054 day = randint(1, 28)
4055 dt = DateTime(year, month, day)
4056 wday = dt.day_of_week
4058 countFromEnd = choice([-1, 1])
4061 while dt.month is month:
4062 dt = dt - countFromEnd * week
4063 weekNum = weekNum + countFromEnd
4065 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
4067 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
4068 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
4071 static const WeekDateTestData weekDatesTestData
[] =
4073 { { 20, wxDateTime::Mar
, 2045 }, 3, wxDateTime::Mon
, wxDateTime::Mar
, 2045 },
4074 { { 5, wxDateTime::Jun
, 1985 }, -4, wxDateTime::Wed
, wxDateTime::Jun
, 1985 },
4075 { { 12, wxDateTime::Nov
, 1961 }, -3, wxDateTime::Sun
, wxDateTime::Nov
, 1961 },
4076 { { 27, wxDateTime::Feb
, 2093 }, -1, wxDateTime::Fri
, wxDateTime::Feb
, 2093 },
4077 { { 4, wxDateTime::Jul
, 2070 }, -4, wxDateTime::Fri
, wxDateTime::Jul
, 2070 },
4078 { { 2, wxDateTime::Apr
, 1906 }, -5, wxDateTime::Mon
, wxDateTime::Apr
, 1906 },
4079 { { 19, wxDateTime::Jul
, 2023 }, -2, wxDateTime::Wed
, wxDateTime::Jul
, 2023 },
4080 { { 5, wxDateTime::May
, 1958 }, -4, wxDateTime::Mon
, wxDateTime::May
, 1958 },
4081 { { 11, wxDateTime::Aug
, 1900 }, 2, wxDateTime::Sat
, wxDateTime::Aug
, 1900 },
4082 { { 14, wxDateTime::Feb
, 1945 }, 2, wxDateTime::Wed
, wxDateTime::Feb
, 1945 },
4083 { { 25, wxDateTime::Jul
, 1967 }, -1, wxDateTime::Tue
, wxDateTime::Jul
, 1967 },
4084 { { 9, wxDateTime::May
, 1916 }, -4, wxDateTime::Tue
, wxDateTime::May
, 1916 },
4085 { { 20, wxDateTime::Jun
, 1927 }, 3, wxDateTime::Mon
, wxDateTime::Jun
, 1927 },
4086 { { 2, wxDateTime::Aug
, 2000 }, 1, wxDateTime::Wed
, wxDateTime::Aug
, 2000 },
4087 { { 20, wxDateTime::Apr
, 2044 }, 3, wxDateTime::Wed
, wxDateTime::Apr
, 2044 },
4088 { { 20, wxDateTime::Feb
, 1932 }, -2, wxDateTime::Sat
, wxDateTime::Feb
, 1932 },
4089 { { 25, wxDateTime::Jul
, 2069 }, 4, wxDateTime::Thu
, wxDateTime::Jul
, 2069 },
4090 { { 3, wxDateTime::Apr
, 1925 }, 1, wxDateTime::Fri
, wxDateTime::Apr
, 1925 },
4091 { { 21, wxDateTime::Mar
, 2093 }, 3, wxDateTime::Sat
, wxDateTime::Mar
, 2093 },
4092 { { 3, wxDateTime::Dec
, 2074 }, -5, wxDateTime::Mon
, wxDateTime::Dec
, 2074 },
4095 static const wxChar
*fmt
= _T("%d-%b-%Y");
4098 for ( n
= 0; n
< WXSIZEOF(weekDatesTestData
); n
++ )
4100 const WeekDateTestData
& wd
= weekDatesTestData
[n
];
4102 dt
.SetToWeekDay(wd
.wday
, wd
.nWeek
, wd
.month
, wd
.year
);
4104 wxPrintf(_T("%s is %s"), wd
.Format().c_str(), dt
.Format(fmt
).c_str());
4106 const Date
& d
= wd
.date
;
4107 if ( d
.SameDay(dt
.GetTm()) )
4109 wxPuts(_T(" (ok)"));
4113 dt
.Set(d
.day
, d
.month
, d
.year
);
4115 wxPrintf(_T(" (ERROR: should be %s)\n"), dt
.Format(fmt
).c_str());
4120 // test the computation of (ISO) week numbers
4121 static void TestTimeWNumber()
4123 wxPuts(_T("\n*** wxDateTime week number test ***"));
4125 struct WeekNumberTestData
4127 Date date
; // the date
4128 wxDateTime::wxDateTime_t week
; // the week number in the year
4129 wxDateTime::wxDateTime_t wmon
; // the week number in the month
4130 wxDateTime::wxDateTime_t wmon2
; // same but week starts with Sun
4131 wxDateTime::wxDateTime_t dnum
; // day number in the year
4134 // data generated with the following python script:
4136 from DateTime import *
4137 from whrandom import *
4138 from string import *
4140 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
4141 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
4143 def GetMonthWeek(dt):
4144 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
4145 if weekNumMonth < 0:
4146 weekNumMonth = weekNumMonth + 53
4149 def GetLastSundayBefore(dt):
4150 if dt.iso_week[2] == 7:
4153 return dt - DateTimeDelta(dt.iso_week[2])
4156 year = randint(1900, 2100)
4157 month = randint(1, 12)
4158 day = randint(1, 28)
4159 dt = DateTime(year, month, day)
4160 dayNum = dt.day_of_year
4161 weekNum = dt.iso_week[1]
4162 weekNumMonth = GetMonthWeek(dt)
4165 dtSunday = GetLastSundayBefore(dt)
4167 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
4168 weekNumMonth2 = weekNumMonth2 + 1
4169 dtSunday = dtSunday - DateTimeDelta(7)
4171 data = { 'day': rjust(`day`, 2), \
4172 'month': monthNames[month - 1], \
4174 'weekNum': rjust(`weekNum`, 2), \
4175 'weekNumMonth': weekNumMonth, \
4176 'weekNumMonth2': weekNumMonth2, \
4177 'dayNum': rjust(`dayNum`, 3) }
4179 print " { { %(day)s, "\
4180 "wxDateTime::%(month)s, "\
4183 "%(weekNumMonth)s, "\
4184 "%(weekNumMonth2)s, "\
4185 "%(dayNum)s }," % data
4188 static const WeekNumberTestData weekNumberTestDates
[] =
4190 { { 27, wxDateTime::Dec
, 1966 }, 52, 5, 5, 361 },
4191 { { 22, wxDateTime::Jul
, 1926 }, 29, 4, 4, 203 },
4192 { { 22, wxDateTime::Oct
, 2076 }, 43, 4, 4, 296 },
4193 { { 1, wxDateTime::Jul
, 1967 }, 26, 1, 1, 182 },
4194 { { 8, wxDateTime::Nov
, 2004 }, 46, 2, 2, 313 },
4195 { { 21, wxDateTime::Mar
, 1920 }, 12, 3, 4, 81 },
4196 { { 7, wxDateTime::Jan
, 1965 }, 1, 2, 2, 7 },
4197 { { 19, wxDateTime::Oct
, 1999 }, 42, 4, 4, 292 },
4198 { { 13, wxDateTime::Aug
, 1955 }, 32, 2, 2, 225 },
4199 { { 18, wxDateTime::Jul
, 2087 }, 29, 3, 3, 199 },
4200 { { 2, wxDateTime::Sep
, 2028 }, 35, 1, 1, 246 },
4201 { { 28, wxDateTime::Jul
, 1945 }, 30, 5, 4, 209 },
4202 { { 15, wxDateTime::Jun
, 1901 }, 24, 3, 3, 166 },
4203 { { 10, wxDateTime::Oct
, 1939 }, 41, 3, 2, 283 },
4204 { { 3, wxDateTime::Dec
, 1965 }, 48, 1, 1, 337 },
4205 { { 23, wxDateTime::Feb
, 1940 }, 8, 4, 4, 54 },
4206 { { 2, wxDateTime::Jan
, 1987 }, 1, 1, 1, 2 },
4207 { { 11, wxDateTime::Aug
, 2079 }, 32, 2, 2, 223 },
4208 { { 2, wxDateTime::Feb
, 2063 }, 5, 1, 1, 33 },
4209 { { 16, wxDateTime::Oct
, 1942 }, 42, 3, 3, 289 },
4212 for ( size_t n
= 0; n
< WXSIZEOF(weekNumberTestDates
); n
++ )
4214 const WeekNumberTestData
& wn
= weekNumberTestDates
[n
];
4215 const Date
& d
= wn
.date
;
4217 wxDateTime dt
= d
.DT();
4219 wxDateTime::wxDateTime_t
4220 week
= dt
.GetWeekOfYear(wxDateTime::Monday_First
),
4221 wmon
= dt
.GetWeekOfMonth(wxDateTime::Monday_First
),
4222 wmon2
= dt
.GetWeekOfMonth(wxDateTime::Sunday_First
),
4223 dnum
= dt
.GetDayOfYear();
4225 wxPrintf(_T("%s: the day number is %d"), d
.FormatDate().c_str(), dnum
);
4226 if ( dnum
== wn
.dnum
)
4228 wxPrintf(_T(" (ok)"));
4232 wxPrintf(_T(" (ERROR: should be %d)"), wn
.dnum
);
4235 wxPrintf(_T(", week in month is %d"), wmon
);
4236 if ( wmon
== wn
.wmon
)
4238 wxPrintf(_T(" (ok)"));
4242 wxPrintf(_T(" (ERROR: should be %d)"), wn
.wmon
);
4245 wxPrintf(_T(" or %d"), wmon2
);
4246 if ( wmon2
== wn
.wmon2
)
4248 wxPrintf(_T(" (ok)"));
4252 wxPrintf(_T(" (ERROR: should be %d)"), wn
.wmon2
);
4255 wxPrintf(_T(", week in year is %d"), week
);
4256 if ( week
== wn
.week
)
4258 wxPuts(_T(" (ok)"));
4262 wxPrintf(_T(" (ERROR: should be %d)\n"), wn
.week
);
4267 // test DST calculations
4268 static void TestTimeDST()
4270 wxPuts(_T("\n*** wxDateTime DST test ***"));
4272 wxPrintf(_T("DST is%s in effect now.\n\n"),
4273 wxDateTime::Now().IsDST() ? _T("") : _T(" not"));
4275 // taken from http://www.energy.ca.gov/daylightsaving.html
4276 static const Date datesDST
[2][2004 - 1900 + 1] =
4279 { 1, wxDateTime::Apr
, 1990 },
4280 { 7, wxDateTime::Apr
, 1991 },
4281 { 5, wxDateTime::Apr
, 1992 },
4282 { 4, wxDateTime::Apr
, 1993 },
4283 { 3, wxDateTime::Apr
, 1994 },
4284 { 2, wxDateTime::Apr
, 1995 },
4285 { 7, wxDateTime::Apr
, 1996 },
4286 { 6, wxDateTime::Apr
, 1997 },
4287 { 5, wxDateTime::Apr
, 1998 },
4288 { 4, wxDateTime::Apr
, 1999 },
4289 { 2, wxDateTime::Apr
, 2000 },
4290 { 1, wxDateTime::Apr
, 2001 },
4291 { 7, wxDateTime::Apr
, 2002 },
4292 { 6, wxDateTime::Apr
, 2003 },
4293 { 4, wxDateTime::Apr
, 2004 },
4296 { 28, wxDateTime::Oct
, 1990 },
4297 { 27, wxDateTime::Oct
, 1991 },
4298 { 25, wxDateTime::Oct
, 1992 },
4299 { 31, wxDateTime::Oct
, 1993 },
4300 { 30, wxDateTime::Oct
, 1994 },
4301 { 29, wxDateTime::Oct
, 1995 },
4302 { 27, wxDateTime::Oct
, 1996 },
4303 { 26, wxDateTime::Oct
, 1997 },
4304 { 25, wxDateTime::Oct
, 1998 },
4305 { 31, wxDateTime::Oct
, 1999 },
4306 { 29, wxDateTime::Oct
, 2000 },
4307 { 28, wxDateTime::Oct
, 2001 },
4308 { 27, wxDateTime::Oct
, 2002 },
4309 { 26, wxDateTime::Oct
, 2003 },
4310 { 31, wxDateTime::Oct
, 2004 },
4315 for ( year
= 1990; year
< 2005; year
++ )
4317 wxDateTime dtBegin
= wxDateTime::GetBeginDST(year
, wxDateTime::USA
),
4318 dtEnd
= wxDateTime::GetEndDST(year
, wxDateTime::USA
);
4320 wxPrintf(_T("DST period in the US for year %d: from %s to %s"),
4321 year
, dtBegin
.Format().c_str(), dtEnd
.Format().c_str());
4323 size_t n
= year
- 1990;
4324 const Date
& dBegin
= datesDST
[0][n
];
4325 const Date
& dEnd
= datesDST
[1][n
];
4327 if ( dBegin
.SameDay(dtBegin
.GetTm()) && dEnd
.SameDay(dtEnd
.GetTm()) )
4329 wxPuts(_T(" (ok)"));
4333 wxPrintf(_T(" (ERROR: should be %s %d to %s %d)\n"),
4334 wxDateTime::GetMonthName(dBegin
.month
).c_str(), dBegin
.day
,
4335 wxDateTime::GetMonthName(dEnd
.month
).c_str(), dEnd
.day
);
4341 for ( year
= 1990; year
< 2005; year
++ )
4343 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
4345 wxDateTime::GetBeginDST(year
, wxDateTime::Country_EEC
).Format().c_str(),
4346 wxDateTime::GetEndDST(year
, wxDateTime::Country_EEC
).Format().c_str());
4350 // test wxDateTime -> text conversion
4351 static void TestTimeFormat()
4353 wxPuts(_T("\n*** wxDateTime formatting test ***"));
4355 // some information may be lost during conversion, so store what kind
4356 // of info should we recover after a round trip
4359 CompareNone
, // don't try comparing
4360 CompareBoth
, // dates and times should be identical
4361 CompareDate
, // dates only
4362 CompareTime
// time only
4367 CompareKind compareKind
;
4368 const wxChar
*format
;
4369 } formatTestFormats
[] =
4371 { CompareBoth
, _T("---> %c") },
4372 { CompareDate
, _T("Date is %A, %d of %B, in year %Y") },
4373 { CompareBoth
, _T("Date is %x, time is %X") },
4374 { CompareTime
, _T("Time is %H:%M:%S or %I:%M:%S %p") },
4375 { CompareNone
, _T("The day of year: %j, the week of year: %W") },
4376 { CompareDate
, _T("ISO date without separators: %Y%m%d") },
4379 static const Date formatTestDates
[] =
4381 { 29, wxDateTime::May
, 1976, 18, 30, 00 },
4382 { 31, wxDateTime::Dec
, 1999, 23, 30, 00 },
4384 // this test can't work for other centuries because it uses two digit
4385 // years in formats, so don't even try it
4386 { 29, wxDateTime::May
, 2076, 18, 30, 00 },
4387 { 29, wxDateTime::Feb
, 2400, 02, 15, 25 },
4388 { 01, wxDateTime::Jan
, -52, 03, 16, 47 },
4392 // an extra test (as it doesn't depend on date, don't do it in the loop)
4393 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
4395 for ( size_t d
= 0; d
< WXSIZEOF(formatTestDates
) + 1; d
++ )
4399 wxDateTime dt
= d
== 0 ? wxDateTime::Now() : formatTestDates
[d
- 1].DT();
4400 for ( size_t n
= 0; n
< WXSIZEOF(formatTestFormats
); n
++ )
4402 wxString s
= dt
.Format(formatTestFormats
[n
].format
);
4403 wxPrintf(_T("%s"), s
.c_str());
4405 // what can we recover?
4406 int kind
= formatTestFormats
[n
].compareKind
;
4410 const wxChar
*result
= dt2
.ParseFormat(s
, formatTestFormats
[n
].format
);
4413 // converion failed - should it have?
4414 if ( kind
== CompareNone
)
4415 wxPuts(_T(" (ok)"));
4417 wxPuts(_T(" (ERROR: conversion back failed)"));
4421 // should have parsed the entire string
4422 wxPuts(_T(" (ERROR: conversion back stopped too soon)"));
4426 bool equal
= FALSE
; // suppress compilaer warning
4434 equal
= dt
.IsSameDate(dt2
);
4438 equal
= dt
.IsSameTime(dt2
);
4444 wxPrintf(_T(" (ERROR: got back '%s' instead of '%s')\n"),
4445 dt2
.Format().c_str(), dt
.Format().c_str());
4449 wxPuts(_T(" (ok)"));
4456 // test text -> wxDateTime conversion
4457 static void TestTimeParse()
4459 wxPuts(_T("\n*** wxDateTime parse test ***"));
4461 struct ParseTestData
4463 const wxChar
*format
;
4468 static const ParseTestData parseTestDates
[] =
4470 { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec
, 1999, 00, 46, 40 }, TRUE
},
4471 { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec
, 1999, 03, 17, 20 }, TRUE
},
4474 for ( size_t n
= 0; n
< WXSIZEOF(parseTestDates
); n
++ )
4476 const wxChar
*format
= parseTestDates
[n
].format
;
4478 wxPrintf(_T("%s => "), format
);
4481 if ( dt
.ParseRfc822Date(format
) )
4483 wxPrintf(_T("%s "), dt
.Format().c_str());
4485 if ( parseTestDates
[n
].good
)
4487 wxDateTime dtReal
= parseTestDates
[n
].date
.DT();
4494 wxPrintf(_T("(ERROR: should be %s)\n"), dtReal
.Format().c_str());
4499 wxPuts(_T("(ERROR: bad format)"));
4504 wxPrintf(_T("bad format (%s)\n"),
4505 parseTestDates
[n
].good
? "ERROR" : "ok");
4510 static void TestDateTimeInteractive()
4512 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
4518 wxPrintf(_T("Enter a date: "));
4519 if ( !wxFgets(buf
, WXSIZEOF(buf
), stdin
) )
4522 // kill the last '\n'
4523 buf
[wxStrlen(buf
) - 1] = 0;
4526 const wxChar
*p
= dt
.ParseDate(buf
);
4529 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf
);
4535 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p
- buf
);
4538 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
4539 dt
.Format(_T("%b %d, %Y")).c_str(),
4541 dt
.GetWeekOfMonth(wxDateTime::Monday_First
),
4542 dt
.GetWeekOfMonth(wxDateTime::Sunday_First
),
4543 dt
.GetWeekOfYear(wxDateTime::Monday_First
));
4546 wxPuts(_T("\n*** done ***"));
4549 static void TestTimeMS()
4551 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
4553 wxDateTime dt1
= wxDateTime::Now(),
4554 dt2
= wxDateTime::UNow();
4556 wxPrintf(_T("Now = %s\n"), dt1
.Format(_T("%H:%M:%S:%l")).c_str());
4557 wxPrintf(_T("UNow = %s\n"), dt2
.Format(_T("%H:%M:%S:%l")).c_str());
4558 wxPrintf(_T("Dummy loop: "));
4559 for ( int i
= 0; i
< 6000; i
++ )
4561 //for ( int j = 0; j < 10; j++ )
4564 s
.Printf(_T("%g"), sqrt(i
));
4570 wxPuts(_T(", done"));
4573 dt2
= wxDateTime::UNow();
4574 wxPrintf(_T("UNow = %s\n"), dt2
.Format(_T("%H:%M:%S:%l")).c_str());
4576 wxPrintf(_T("Loop executed in %s ms\n"), (dt2
- dt1
).Format(_T("%l")).c_str());
4578 wxPuts(_T("\n*** done ***"));
4581 static void TestTimeArithmetics()
4583 wxPuts(_T("\n*** testing arithmetic operations on wxDateTime ***"));
4585 static const struct ArithmData
4587 ArithmData(const wxDateSpan
& sp
, const wxChar
*nam
)
4588 : span(sp
), name(nam
) { }
4592 } testArithmData
[] =
4594 ArithmData(wxDateSpan::Day(), _T("day")),
4595 ArithmData(wxDateSpan::Week(), _T("week")),
4596 ArithmData(wxDateSpan::Month(), _T("month")),
4597 ArithmData(wxDateSpan::Year(), _T("year")),
4598 ArithmData(wxDateSpan(1, 2, 3, 4), _T("year, 2 months, 3 weeks, 4 days")),
4601 wxDateTime
dt(29, wxDateTime::Dec
, 1999), dt1
, dt2
;
4603 for ( size_t n
= 0; n
< WXSIZEOF(testArithmData
); n
++ )
4605 wxDateSpan span
= testArithmData
[n
].span
;
4609 const wxChar
*name
= testArithmData
[n
].name
;
4610 wxPrintf(_T("%s + %s = %s, %s - %s = %s\n"),
4611 dt
.FormatISODate().c_str(), name
, dt1
.FormatISODate().c_str(),
4612 dt
.FormatISODate().c_str(), name
, dt2
.FormatISODate().c_str());
4614 wxPrintf(_T("Going back: %s"), (dt1
- span
).FormatISODate().c_str());
4615 if ( dt1
- span
== dt
)
4617 wxPuts(_T(" (ok)"));
4621 wxPrintf(_T(" (ERROR: should be %s)\n"), dt
.FormatISODate().c_str());
4624 wxPrintf(_T("Going forward: %s"), (dt2
+ span
).FormatISODate().c_str());
4625 if ( dt2
+ span
== dt
)
4627 wxPuts(_T(" (ok)"));
4631 wxPrintf(_T(" (ERROR: should be %s)\n"), dt
.FormatISODate().c_str());
4634 wxPrintf(_T("Double increment: %s"), (dt2
+ 2*span
).FormatISODate().c_str());
4635 if ( dt2
+ 2*span
== dt1
)
4637 wxPuts(_T(" (ok)"));
4641 wxPrintf(_T(" (ERROR: should be %s)\n"), dt2
.FormatISODate().c_str());
4648 static void TestTimeHolidays()
4650 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
4652 wxDateTime::Tm tm
= wxDateTime(29, wxDateTime::May
, 2000).GetTm();
4653 wxDateTime
dtStart(1, tm
.mon
, tm
.year
),
4654 dtEnd
= dtStart
.GetLastMonthDay();
4656 wxDateTimeArray hol
;
4657 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart
, dtEnd
, hol
);
4659 const wxChar
*format
= _T("%d-%b-%Y (%a)");
4661 wxPrintf(_T("All holidays between %s and %s:\n"),
4662 dtStart
.Format(format
).c_str(), dtEnd
.Format(format
).c_str());
4664 size_t count
= hol
.GetCount();
4665 for ( size_t n
= 0; n
< count
; n
++ )
4667 wxPrintf(_T("\t%s\n"), hol
[n
].Format(format
).c_str());
4673 static void TestTimeZoneBug()
4675 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
4677 wxDateTime date
= wxDateTime(1, wxDateTime::Mar
, 2000);
4678 for ( int i
= 0; i
< 31; i
++ )
4680 wxPrintf(_T("Date %s: week day %s.\n"),
4681 date
.Format(_T("%d-%m-%Y")).c_str(),
4682 date
.GetWeekDayName(date
.GetWeekDay()).c_str());
4684 date
+= wxDateSpan::Day();
4690 static void TestTimeSpanFormat()
4692 wxPuts(_T("\n*** wxTimeSpan tests ***"));
4694 static const wxChar
*formats
[] =
4696 _T("(default) %H:%M:%S"),
4697 _T("%E weeks and %D days"),
4698 _T("%l milliseconds"),
4699 _T("(with ms) %H:%M:%S:%l"),
4700 _T("100%% of minutes is %M"), // test "%%"
4701 _T("%D days and %H hours"),
4702 _T("or also %S seconds"),
4705 wxTimeSpan
ts1(1, 2, 3, 4),
4707 for ( size_t n
= 0; n
< WXSIZEOF(formats
); n
++ )
4709 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
4710 ts1
.Format(formats
[n
]).c_str(),
4711 ts2
.Format(formats
[n
]).c_str());
4719 // test compatibility with the old wxDate/wxTime classes
4720 static void TestTimeCompatibility()
4722 wxPuts(_T("\n*** wxDateTime compatibility test ***"));
4724 wxPrintf(_T("wxDate for JDN 0: %s\n"), wxDate(0l).FormatDate().c_str());
4725 wxPrintf(_T("wxDate for MJD 0: %s\n"), wxDate(2400000).FormatDate().c_str());
4727 double jdnNow
= wxDateTime::Now().GetJDN();
4728 long jdnMidnight
= (long)(jdnNow
- 0.5);
4729 wxPrintf(_T("wxDate for today: %s\n"), wxDate(jdnMidnight
).FormatDate().c_str());
4731 jdnMidnight
= wxDate().Set().GetJulianDate();
4732 wxPrintf(_T("wxDateTime for today: %s\n"),
4733 wxDateTime((double)(jdnMidnight
+ 0.5)).Format("%c", wxDateTime::GMT0
).c_str());
4735 int flags
= wxEUROPEAN
;//wxFULL;
4738 wxPrintf(_T("Today is %s\n"), date
.FormatDate(flags
).c_str());
4739 for ( int n
= 0; n
< 7; n
++ )
4741 wxPrintf(_T("Previous %s is %s\n"),
4742 wxDateTime::GetWeekDayName((wxDateTime::WeekDay
)n
),
4743 date
.Previous(n
+ 1).FormatDate(flags
).c_str());
4749 #endif // TEST_DATETIME
4751 // ----------------------------------------------------------------------------
4753 // ----------------------------------------------------------------------------
4757 #include "wx/thread.h"
4759 static size_t gs_counter
= (size_t)-1;
4760 static wxCriticalSection gs_critsect
;
4761 static wxSemaphore gs_cond
;
4763 class MyJoinableThread
: public wxThread
4766 MyJoinableThread(size_t n
) : wxThread(wxTHREAD_JOINABLE
)
4767 { m_n
= n
; Create(); }
4769 // thread execution starts here
4770 virtual ExitCode
Entry();
4776 wxThread::ExitCode
MyJoinableThread::Entry()
4778 unsigned long res
= 1;
4779 for ( size_t n
= 1; n
< m_n
; n
++ )
4783 // it's a loooong calculation :-)
4787 return (ExitCode
)res
;
4790 class MyDetachedThread
: public wxThread
4793 MyDetachedThread(size_t n
, wxChar ch
)
4797 m_cancelled
= FALSE
;
4802 // thread execution starts here
4803 virtual ExitCode
Entry();
4806 virtual void OnExit();
4809 size_t m_n
; // number of characters to write
4810 wxChar m_ch
; // character to write
4812 bool m_cancelled
; // FALSE if we exit normally
4815 wxThread::ExitCode
MyDetachedThread::Entry()
4818 wxCriticalSectionLocker
lock(gs_critsect
);
4819 if ( gs_counter
== (size_t)-1 )
4825 for ( size_t n
= 0; n
< m_n
; n
++ )
4827 if ( TestDestroy() )
4837 wxThread::Sleep(100);
4843 void MyDetachedThread::OnExit()
4845 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
4847 wxCriticalSectionLocker
lock(gs_critsect
);
4848 if ( !--gs_counter
&& !m_cancelled
)
4852 static void TestDetachedThreads()
4854 wxPuts(_T("\n*** Testing detached threads ***"));
4856 static const size_t nThreads
= 3;
4857 MyDetachedThread
*threads
[nThreads
];
4859 for ( n
= 0; n
< nThreads
; n
++ )
4861 threads
[n
] = new MyDetachedThread(10, 'A' + n
);
4864 threads
[0]->SetPriority(WXTHREAD_MIN_PRIORITY
);
4865 threads
[1]->SetPriority(WXTHREAD_MAX_PRIORITY
);
4867 for ( n
= 0; n
< nThreads
; n
++ )
4872 // wait until all threads terminate
4878 static void TestJoinableThreads()
4880 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
4882 // calc 10! in the background
4883 MyJoinableThread
thread(10);
4886 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
4887 (unsigned long)thread
.Wait());
4890 static void TestThreadSuspend()
4892 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
4894 MyDetachedThread
*thread
= new MyDetachedThread(15, 'X');
4898 // this is for this demo only, in a real life program we'd use another
4899 // condition variable which would be signaled from wxThread::Entry() to
4900 // tell us that the thread really started running - but here just wait a
4901 // bit and hope that it will be enough (the problem is, of course, that
4902 // the thread might still not run when we call Pause() which will result
4904 wxThread::Sleep(300);
4906 for ( size_t n
= 0; n
< 3; n
++ )
4910 wxPuts(_T("\nThread suspended"));
4913 // don't sleep but resume immediately the first time
4914 wxThread::Sleep(300);
4916 wxPuts(_T("Going to resume the thread"));
4921 wxPuts(_T("Waiting until it terminates now"));
4923 // wait until the thread terminates
4929 static void TestThreadDelete()
4931 // As above, using Sleep() is only for testing here - we must use some
4932 // synchronisation object instead to ensure that the thread is still
4933 // running when we delete it - deleting a detached thread which already
4934 // terminated will lead to a crash!
4936 wxPuts(_T("\n*** Testing thread delete function ***"));
4938 MyDetachedThread
*thread0
= new MyDetachedThread(30, 'W');
4942 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
4944 MyDetachedThread
*thread1
= new MyDetachedThread(30, 'Y');
4948 wxThread::Sleep(300);
4952 wxPuts(_T("\nDeleted a running thread."));
4954 MyDetachedThread
*thread2
= new MyDetachedThread(30, 'Z');
4958 wxThread::Sleep(300);
4964 wxPuts(_T("\nDeleted a sleeping thread."));
4966 MyJoinableThread
thread3(20);
4971 wxPuts(_T("\nDeleted a joinable thread."));
4973 MyJoinableThread
thread4(2);
4976 wxThread::Sleep(300);
4980 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
4985 class MyWaitingThread
: public wxThread
4988 MyWaitingThread( wxMutex
*mutex
, wxCondition
*condition
)
4991 m_condition
= condition
;
4996 virtual ExitCode
Entry()
4998 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
5003 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
5007 m_condition
->Wait();
5010 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
5018 wxCondition
*m_condition
;
5021 static void TestThreadConditions()
5024 wxCondition
condition(mutex
);
5026 // otherwise its difficult to understand which log messages pertain to
5028 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
5029 // condition.GetId(), gs_cond.GetId());
5031 // create and launch threads
5032 MyWaitingThread
*threads
[10];
5035 for ( n
= 0; n
< WXSIZEOF(threads
); n
++ )
5037 threads
[n
] = new MyWaitingThread( &mutex
, &condition
);
5040 for ( n
= 0; n
< WXSIZEOF(threads
); n
++ )
5045 // wait until all threads run
5046 wxPuts(_T("Main thread is waiting for the other threads to start"));
5049 size_t nRunning
= 0;
5050 while ( nRunning
< WXSIZEOF(threads
) )
5056 wxPrintf(_T("Main thread: %u already running\n"), nRunning
);
5060 wxPuts(_T("Main thread: all threads started up."));
5063 wxThread::Sleep(500);
5066 // now wake one of them up
5067 wxPrintf(_T("Main thread: about to signal the condition.\n"));
5072 wxThread::Sleep(200);
5074 // wake all the (remaining) threads up, so that they can exit
5075 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
5077 condition
.Broadcast();
5079 // give them time to terminate (dirty!)
5080 wxThread::Sleep(500);
5083 #include "wx/utils.h"
5085 class MyExecThread
: public wxThread
5088 MyExecThread(const wxString
& command
) : wxThread(wxTHREAD_JOINABLE
),
5094 virtual ExitCode
Entry()
5096 return (ExitCode
)wxExecute(m_command
, wxEXEC_SYNC
);
5103 static void TestThreadExec()
5105 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
5107 MyExecThread
thread(_T("true"));
5110 wxPrintf(_T("Main program exit code: %ld.\n"),
5111 wxExecute(_T("false"), wxEXEC_SYNC
));
5113 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread
.Wait());
5117 #include "wx/datetime.h"
5119 class MySemaphoreThread
: public wxThread
5122 MySemaphoreThread(int i
, wxSemaphore
*sem
)
5123 : wxThread(wxTHREAD_JOINABLE
),
5130 virtual ExitCode
Entry()
5132 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
5133 wxDateTime::Now().FormatTime().c_str(), m_i
, (long)GetId());
5137 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
5138 wxDateTime::Now().FormatTime().c_str(), m_i
, (long)GetId());
5142 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
5143 wxDateTime::Now().FormatTime().c_str(), m_i
, (long)GetId());
5155 WX_DEFINE_ARRAY(wxThread
*, ArrayThreads
);
5157 static void TestSemaphore()
5159 wxPuts(_T("*** Testing wxSemaphore class. ***"));
5161 static const int SEM_LIMIT
= 3;
5163 wxSemaphore
sem(SEM_LIMIT
, SEM_LIMIT
);
5164 ArrayThreads threads
;
5166 for ( int i
= 0; i
< 3*SEM_LIMIT
; i
++ )
5168 threads
.Add(new MySemaphoreThread(i
, &sem
));
5169 threads
.Last()->Run();
5172 for ( size_t n
= 0; n
< threads
.GetCount(); n
++ )
5179 #endif // TEST_THREADS
5181 // ----------------------------------------------------------------------------
5183 // ----------------------------------------------------------------------------
5187 #include "wx/dynarray.h"
5189 typedef unsigned short ushort
;
5191 #define DefineCompare(name, T) \
5193 int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
5195 return first - second; \
5198 int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
5200 return *first - *second; \
5203 int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
5205 return *second - *first; \
5208 DefineCompare(UShort, ushort);
5209 DefineCompare(Int
, int);
5211 // test compilation of all macros
5212 WX_DEFINE_ARRAY_SHORT(ushort
, wxArrayUShort
);
5213 WX_DEFINE_SORTED_ARRAY_SHORT(ushort
, wxSortedArrayUShortNoCmp
);
5214 WX_DEFINE_SORTED_ARRAY_CMP_SHORT(ushort
, UShortCompareValues
, wxSortedArrayUShort
);
5215 WX_DEFINE_SORTED_ARRAY_CMP_INT(int, IntCompareValues
, wxSortedArrayInt
);
5217 WX_DECLARE_OBJARRAY(Bar
, ArrayBars
);
5218 #include "wx/arrimpl.cpp"
5219 WX_DEFINE_OBJARRAY(ArrayBars
);
5221 static void PrintArray(const wxChar
* name
, const wxArrayString
& array
)
5223 wxPrintf(_T("Dump of the array '%s'\n"), name
);
5225 size_t nCount
= array
.GetCount();
5226 for ( size_t n
= 0; n
< nCount
; n
++ )
5228 wxPrintf(_T("\t%s[%u] = '%s'\n"), name
, n
, array
[n
].c_str());
5232 int wxCMPFUNC_CONV
StringLenCompare(const wxString
& first
,
5233 const wxString
& second
)
5235 return first
.length() - second
.length();
5238 #define TestArrayOf(name) \
5240 static void PrintArray(const wxChar* name, const wxSortedArray##name & array) \
5242 wxPrintf(_T("Dump of the array '%s'\n"), name); \
5244 size_t nCount = array.GetCount(); \
5245 for ( size_t n = 0; n < nCount; n++ ) \
5247 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
5251 static void PrintArray(const wxChar* name, const wxArray##name & array) \
5253 wxPrintf(_T("Dump of the array '%s'\n"), name); \
5255 size_t nCount = array.GetCount(); \
5256 for ( size_t n = 0; n < nCount; n++ ) \
5258 wxPrintf(_T("\t%s[%u] = %d\n"), name, n, array[n]); \
5262 static void TestArrayOf ## name ## s() \
5264 wxPrintf(_T("*** Testing wxArray%s ***\n"), #name); \
5272 wxPuts(_T("Initially:")); \
5273 PrintArray(_T("a"), a); \
5275 wxPuts(_T("After sort:")); \
5276 a.Sort(name ## Compare); \
5277 PrintArray(_T("a"), a); \
5279 wxPuts(_T("After reverse sort:")); \
5280 a.Sort(name ## RevCompare); \
5281 PrintArray(_T("a"), a); \
5283 wxSortedArray##name b; \
5289 wxPuts(_T("Sorted array initially:")); \
5290 PrintArray(_T("b"), b); \
5293 TestArrayOf(UShort
);
5296 static void TestArrayOfObjects()
5298 wxPuts(_T("*** Testing wxObjArray ***\n"));
5302 Bar
bar("second bar (two copies!)");
5304 wxPrintf(_T("Initially: %u objects in the array, %u objects total.\n"),
5305 bars
.GetCount(), Bar::GetNumber());
5307 bars
.Add(new Bar("first bar"));
5310 wxPrintf(_T("Now: %u objects in the array, %u objects total.\n"),
5311 bars
.GetCount(), Bar::GetNumber());
5313 bars
.RemoveAt(1, bars
.GetCount() - 1);
5315 wxPrintf(_T("After removing all but first element: %u objects in the ")
5316 _T("array, %u objects total.\n"),
5317 bars
.GetCount(), Bar::GetNumber());
5321 wxPrintf(_T("After Empty(): %u objects in the array, %u objects total.\n"),
5322 bars
.GetCount(), Bar::GetNumber());
5325 wxPrintf(_T("Finally: no more objects in the array, %u objects total.\n"),
5329 #endif // TEST_ARRAYS
5331 // ----------------------------------------------------------------------------
5333 // ----------------------------------------------------------------------------
5337 #include "wx/timer.h"
5338 #include "wx/tokenzr.h"
5340 static void TestStringConstruction()
5342 wxPuts(_T("*** Testing wxString constructores ***"));
5344 #define TEST_CTOR(args, res) \
5347 wxPrintf(_T("wxString%s = %s "), #args, s.c_str()); \
5350 wxPuts(_T("(ok)")); \
5354 wxPrintf(_T("(ERROR: should be %s)\n"), res); \
5358 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
5359 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
5360 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
5361 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
5363 static const wxChar
*s
= _T("?really!");
5364 const wxChar
*start
= wxStrchr(s
, _T('r'));
5365 const wxChar
*end
= wxStrchr(s
, _T('!'));
5366 TEST_CTOR((start
, end
), _T("really"));
5371 static void TestString()
5381 for (int i
= 0; i
< 1000000; ++i
)
5385 c
= "! How'ya doin'?";
5388 c
= "Hello world! What's up?";
5393 wxPrintf(_T("TestString elapsed time: %ld\n"), sw
.Time());
5396 static void TestPChar()
5404 for (int i
= 0; i
< 1000000; ++i
)
5406 wxStrcpy (a
, _T("Hello"));
5407 wxStrcpy (b
, _T(" world"));
5408 wxStrcpy (c
, _T("! How'ya doin'?"));
5411 wxStrcpy (c
, _T("Hello world! What's up?"));
5412 if (wxStrcmp (c
, a
) == 0)
5413 wxStrcpy (c
, _T("Doh!"));
5416 wxPrintf(_T("TestPChar elapsed time: %ld\n"), sw
.Time());
5419 static void TestStringSub()
5421 wxString
s("Hello, world!");
5423 wxPuts(_T("*** Testing wxString substring extraction ***"));
5425 wxPrintf(_T("String = '%s'\n"), s
.c_str());
5426 wxPrintf(_T("Left(5) = '%s'\n"), s
.Left(5).c_str());
5427 wxPrintf(_T("Right(6) = '%s'\n"), s
.Right(6).c_str());
5428 wxPrintf(_T("Mid(3, 5) = '%s'\n"), s(3, 5).c_str());
5429 wxPrintf(_T("Mid(3) = '%s'\n"), s
.Mid(3).c_str());
5430 wxPrintf(_T("substr(3, 5) = '%s'\n"), s
.substr(3, 5).c_str());
5431 wxPrintf(_T("substr(3) = '%s'\n"), s
.substr(3).c_str());
5433 static const wxChar
*prefixes
[] =
5437 _T("Hello, world!"),
5438 _T("Hello, world!!!"),
5444 for ( size_t n
= 0; n
< WXSIZEOF(prefixes
); n
++ )
5446 wxString prefix
= prefixes
[n
], rest
;
5447 bool rc
= s
.StartsWith(prefix
, &rest
);
5448 wxPrintf(_T("StartsWith('%s') = %s"), prefix
.c_str(), rc
? _T("TRUE") : _T("FALSE"));
5451 wxPrintf(_T(" (the rest is '%s')\n"), rest
.c_str());
5462 static void TestStringFormat()
5464 wxPuts(_T("*** Testing wxString formatting ***"));
5467 s
.Printf(_T("%03d"), 18);
5469 wxPrintf(_T("Number 18: %s\n"), wxString::Format(_T("%03d"), 18).c_str());
5470 wxPrintf(_T("Number 18: %s\n"), s
.c_str());
5475 // returns "not found" for npos, value for all others
5476 static wxString
PosToString(size_t res
)
5478 wxString s
= res
== wxString::npos
? wxString(_T("not found"))
5479 : wxString::Format(_T("%u"), res
);
5483 static void TestStringFind()
5485 wxPuts(_T("*** Testing wxString find() functions ***"));
5487 static const wxChar
*strToFind
= _T("ell");
5488 static const struct StringFindTest
5492 result
; // of searching "ell" in str
5495 { _T("Well, hello world"), 0, 1 },
5496 { _T("Well, hello world"), 6, 7 },
5497 { _T("Well, hello world"), 9, wxString::npos
},
5500 for ( size_t n
= 0; n
< WXSIZEOF(findTestData
); n
++ )
5502 const StringFindTest
& ft
= findTestData
[n
];
5503 size_t res
= wxString(ft
.str
).find(strToFind
, ft
.start
);
5505 wxPrintf(_T("Index of '%s' in '%s' starting from %u is %s "),
5506 strToFind
, ft
.str
, ft
.start
, PosToString(res
).c_str());
5508 size_t resTrue
= ft
.result
;
5509 if ( res
== resTrue
)
5515 wxPrintf(_T("(ERROR: should be %s)\n"),
5516 PosToString(resTrue
).c_str());
5523 static void TestStringTokenizer()
5525 wxPuts(_T("*** Testing wxStringTokenizer ***"));
5527 static const wxChar
*modeNames
[] =
5531 _T("return all empty"),
5536 static const struct StringTokenizerTest
5538 const wxChar
*str
; // string to tokenize
5539 const wxChar
*delims
; // delimiters to use
5540 size_t count
; // count of token
5541 wxStringTokenizerMode mode
; // how should we tokenize it
5542 } tokenizerTestData
[] =
5544 { _T(""), _T(" "), 0 },
5545 { _T("Hello, world"), _T(" "), 2 },
5546 { _T("Hello, world "), _T(" "), 2 },
5547 { _T("Hello, world"), _T(","), 2 },
5548 { _T("Hello, world!"), _T(",!"), 2 },
5549 { _T("Hello,, world!"), _T(",!"), 3 },
5550 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL
},
5551 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
5552 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS
, 4 },
5553 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS
, 6, wxTOKEN_RET_EMPTY
},
5554 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS
, 9, wxTOKEN_RET_EMPTY_ALL
},
5555 { _T("01/02/99"), _T("/-"), 3 },
5556 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS
},
5559 for ( size_t n
= 0; n
< WXSIZEOF(tokenizerTestData
); n
++ )
5561 const StringTokenizerTest
& tt
= tokenizerTestData
[n
];
5562 wxStringTokenizer
tkz(tt
.str
, tt
.delims
, tt
.mode
);
5564 size_t count
= tkz
.CountTokens();
5565 wxPrintf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
5566 MakePrintable(tt
.str
).c_str(),
5568 MakePrintable(tt
.delims
).c_str(),
5569 modeNames
[tkz
.GetMode()]);
5570 if ( count
== tt
.count
)
5576 wxPrintf(_T("(ERROR: should be %u)\n"), tt
.count
);
5581 // if we emulate strtok(), check that we do it correctly
5582 wxChar
*buf
, *s
= NULL
, *last
;
5584 if ( tkz
.GetMode() == wxTOKEN_STRTOK
)
5586 buf
= new wxChar
[wxStrlen(tt
.str
) + 1];
5587 wxStrcpy(buf
, tt
.str
);
5589 s
= wxStrtok(buf
, tt
.delims
, &last
);
5596 // now show the tokens themselves
5598 while ( tkz
.HasMoreTokens() )
5600 wxString token
= tkz
.GetNextToken();
5602 wxPrintf(_T("\ttoken %u: '%s'"),
5604 MakePrintable(token
).c_str());
5610 wxPuts(_T(" (ok)"));
5614 wxPrintf(_T(" (ERROR: should be %s)\n"), s
);
5617 s
= wxStrtok(NULL
, tt
.delims
, &last
);
5621 // nothing to compare with
5626 if ( count2
!= count
)
5628 wxPuts(_T("\tERROR: token count mismatch"));
5637 static void TestStringReplace()
5639 wxPuts(_T("*** Testing wxString::replace ***"));
5641 static const struct StringReplaceTestData
5643 const wxChar
*original
; // original test string
5644 size_t start
, len
; // the part to replace
5645 const wxChar
*replacement
; // the replacement string
5646 const wxChar
*result
; // and the expected result
5647 } stringReplaceTestData
[] =
5649 { _T("012-AWORD-XYZ"), 4, 5, _T("BWORD"), _T("012-BWORD-XYZ") },
5650 { _T("increase"), 0, 2, _T("de"), _T("decrease") },
5651 { _T("wxWindow"), 8, 0, _T("s"), _T("wxWindows") },
5652 { _T("foobar"), 3, 0, _T("-"), _T("foo-bar") },
5653 { _T("barfoo"), 0, 6, _T("foobar"), _T("foobar") },
5656 for ( size_t n
= 0; n
< WXSIZEOF(stringReplaceTestData
); n
++ )
5658 const StringReplaceTestData data
= stringReplaceTestData
[n
];
5660 wxString original
= data
.original
;
5661 original
.replace(data
.start
, data
.len
, data
.replacement
);
5663 wxPrintf(_T("wxString(\"%s\").replace(%u, %u, %s) = %s "),
5664 data
.original
, data
.start
, data
.len
, data
.replacement
,
5667 if ( original
== data
.result
)
5673 wxPrintf(_T("(ERROR: should be '%s')\n"), data
.result
);
5680 static void TestStringMatch()
5682 wxPuts(_T("*** Testing wxString::Matches() ***"));
5684 static const struct StringMatchTestData
5687 const wxChar
*wildcard
;
5689 } stringMatchTestData
[] =
5691 { _T("foobar"), _T("foo*"), 1 },
5692 { _T("foobar"), _T("*oo*"), 1 },
5693 { _T("foobar"), _T("*bar"), 1 },
5694 { _T("foobar"), _T("??????"), 1 },
5695 { _T("foobar"), _T("f??b*"), 1 },
5696 { _T("foobar"), _T("f?b*"), 0 },
5697 { _T("foobar"), _T("*goo*"), 0 },
5698 { _T("foobar"), _T("*foo"), 0 },
5699 { _T("foobarfoo"), _T("*foo"), 1 },
5700 { _T(""), _T("*"), 1 },
5701 { _T(""), _T("?"), 0 },
5704 for ( size_t n
= 0; n
< WXSIZEOF(stringMatchTestData
); n
++ )
5706 const StringMatchTestData
& data
= stringMatchTestData
[n
];
5707 bool matches
= wxString(data
.text
).Matches(data
.wildcard
);
5708 wxPrintf(_T("'%s' %s '%s' (%s)\n"),
5710 matches
? _T("matches") : _T("doesn't match"),
5712 matches
== data
.matches
? _T("ok") : _T("ERROR"));
5718 #endif // TEST_STRINGS
5720 // ----------------------------------------------------------------------------
5722 // ----------------------------------------------------------------------------
5724 #ifdef TEST_SNGLINST
5725 #include "wx/snglinst.h"
5726 #endif // TEST_SNGLINST
5728 int main(int argc
, char **argv
)
5730 wxApp::CheckBuildOptions(wxBuildOptions());
5732 wxInitializer initializer
;
5735 fprintf(stderr
, "Failed to initialize the wxWindows library, aborting.");
5740 #ifdef TEST_SNGLINST
5741 wxSingleInstanceChecker checker
;
5742 if ( checker
.Create(_T(".wxconsole.lock")) )
5744 if ( checker
.IsAnotherRunning() )
5746 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
5751 // wait some time to give time to launch another instance
5752 wxPrintf(_T("Press \"Enter\" to continue..."));
5755 else // failed to create
5757 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
5759 #endif // TEST_SNGLINST
5763 #endif // TEST_CHARSET
5766 TestCmdLineConvert();
5768 #if wxUSE_CMDLINE_PARSER
5769 static const wxCmdLineEntryDesc cmdLineDesc
[] =
5771 { wxCMD_LINE_SWITCH
, _T("h"), _T("help"), _T("show this help message"),
5772 wxCMD_LINE_VAL_NONE
, wxCMD_LINE_OPTION_HELP
},
5773 { wxCMD_LINE_SWITCH
, _T("v"), _T("verbose"), _T("be verbose") },
5774 { wxCMD_LINE_SWITCH
, _T("q"), _T("quiet"), _T("be quiet") },
5776 { wxCMD_LINE_OPTION
, _T("o"), _T("output"), _T("output file") },
5777 { wxCMD_LINE_OPTION
, _T("i"), _T("input"), _T("input dir") },
5778 { wxCMD_LINE_OPTION
, _T("s"), _T("size"), _T("output block size"),
5779 wxCMD_LINE_VAL_NUMBER
},
5780 { wxCMD_LINE_OPTION
, _T("d"), _T("date"), _T("output file date"),
5781 wxCMD_LINE_VAL_DATE
},
5783 { wxCMD_LINE_PARAM
, NULL
, NULL
, _T("input file"),
5784 wxCMD_LINE_VAL_STRING
, wxCMD_LINE_PARAM_MULTIPLE
},
5790 wxChar
**wargv
= new wxChar
*[argc
+ 1];
5793 for ( int n
= 0; n
< argc
; n
++ )
5795 wxMB2WXbuf warg
= wxConvertMB2WX(argv
[n
]);
5796 wargv
[n
] = wxStrdup(warg
);
5803 #endif // wxUSE_UNICODE
5805 wxCmdLineParser
parser(cmdLineDesc
, argc
, argv
);
5809 for ( int n
= 0; n
< argc
; n
++ )
5814 #endif // wxUSE_UNICODE
5816 parser
.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
5817 wxCMD_LINE_VAL_STRING
,
5818 wxCMD_LINE_OPTION_MANDATORY
| wxCMD_LINE_NEEDS_SEPARATOR
);
5820 switch ( parser
.Parse() )
5823 wxLogMessage(_T("Help was given, terminating."));
5827 ShowCmdLine(parser
);
5831 wxLogMessage(_T("Syntax error detected, aborting."));
5834 #endif // wxUSE_CMDLINE_PARSER
5836 #endif // TEST_CMDLINE
5844 TestStringConstruction();
5847 TestStringTokenizer();
5848 TestStringReplace();
5854 #endif // TEST_STRINGS
5860 a1
.Add(_T("tiger"));
5862 a1
.Add(_T("lion"), 3);
5864 a1
.Add(_T("human"));
5867 wxPuts(_T("*** Initially:"));
5869 PrintArray(_T("a1"), a1
);
5871 wxArrayString
a2(a1
);
5872 PrintArray(_T("a2"), a2
);
5874 wxSortedArrayString
a3(a1
);
5875 PrintArray(_T("a3"), a3
);
5877 wxPuts(_T("*** After deleting three strings from a1"));
5880 PrintArray(_T("a1"), a1
);
5881 PrintArray(_T("a2"), a2
);
5882 PrintArray(_T("a3"), a3
);
5884 wxPuts(_T("*** After reassigning a1 to a2 and a3"));
5886 PrintArray(_T("a2"), a2
);
5887 PrintArray(_T("a3"), a3
);
5889 wxPuts(_T("*** After sorting a1"));
5891 PrintArray(_T("a1"), a1
);
5893 wxPuts(_T("*** After sorting a1 in reverse order"));
5895 PrintArray(_T("a1"), a1
);
5897 wxPuts(_T("*** After sorting a1 by the string length"));
5898 a1
.Sort(StringLenCompare
);
5899 PrintArray(_T("a1"), a1
);
5901 TestArrayOfObjects();
5902 TestArrayOfUShorts();
5906 #endif // TEST_ARRAYS
5917 #ifdef TEST_DLLLOADER
5919 #endif // TEST_DLLLOADER
5923 #endif // TEST_ENVIRON
5927 #endif // TEST_EXECUTE
5929 #ifdef TEST_FILECONF
5931 #endif // TEST_FILECONF
5939 #endif // TEST_LOCALE
5943 for ( size_t n
= 0; n
< 8000; n
++ )
5945 s
<< (wxChar
)(_T('A') + (n
% 26));
5949 msg
.Printf(_T("A very very long message: '%s', the end!\n"), s
.c_str());
5951 // this one shouldn't be truncated
5954 // but this one will because log functions use fixed size buffer
5955 // (note that it doesn't need '\n' at the end neither - will be added
5957 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s
.c_str());
5969 #ifdef TEST_FILENAME
5973 fn
.Assign(_T("c:\\foo"), _T("bar.baz"));
5974 fn
.Assign(_T("/u/os9-port/Viewer/tvision/WEI2HZ-3B3-14_05-04-00MSC1.asc"));
5979 TestFileNameConstruction();
5982 TestFileNameConstruction();
5983 TestFileNameMakeRelative();
5984 TestFileNameSplit();
5987 TestFileNameComparison();
5988 TestFileNameOperations();
5990 #endif // TEST_FILENAME
5992 #ifdef TEST_FILETIME
5996 #endif // TEST_FILETIME
5999 wxLog::AddTraceMask(FTP_TRACE_MASK
);
6000 if ( TestFtpConnect() )
6011 if ( TEST_INTERACTIVE
)
6012 TestFtpInteractive();
6014 //else: connecting to the FTP server failed
6020 #ifdef TEST_LONGLONG
6021 // seed pseudo random generator
6022 srand((unsigned)time(NULL
));
6031 TestMultiplication();
6034 TestLongLongConversion();
6035 TestBitOperations();
6036 TestLongLongComparison();
6037 TestLongLongPrint();
6039 #endif // TEST_LONGLONG
6047 #endif // TEST_HASHMAP
6050 wxLog::AddTraceMask(_T("mime"));
6055 TestMimeAssociate();
6060 #ifdef TEST_INFO_FUNCTIONS
6066 if ( TEST_INTERACTIVE
)
6069 #endif // TEST_INFO_FUNCTIONS
6071 #ifdef TEST_PATHLIST
6073 #endif // TEST_PATHLIST
6081 #endif // TEST_REGCONF
6084 // TODO: write a real test using src/regex/tests file
6089 TestRegExSubmatch();
6090 TestRegExReplacement();
6092 if ( TEST_INTERACTIVE
)
6093 TestRegExInteractive();
6095 #endif // TEST_REGEX
6097 #ifdef TEST_REGISTRY
6099 TestRegistryAssociation();
6100 #endif // TEST_REGISTRY
6105 #endif // TEST_SOCKETS
6113 #endif // TEST_STREAMS
6116 int nCPUs
= wxThread::GetCPUCount();
6117 wxPrintf(_T("This system has %d CPUs\n"), nCPUs
);
6119 wxThread::SetConcurrency(nCPUs
);
6123 TestDetachedThreads();
6124 TestJoinableThreads();
6125 TestThreadSuspend();
6127 TestThreadConditions();
6132 #endif // TEST_THREADS
6136 #endif // TEST_TIMER
6138 #ifdef TEST_DATETIME
6151 TestTimeArithmetics();
6154 TestTimeSpanFormat();
6161 if ( TEST_INTERACTIVE
)
6162 TestDateTimeInteractive();
6163 #endif // TEST_DATETIME
6166 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
6168 #endif // TEST_USLEEP
6173 #endif // TEST_VCARD
6177 #endif // TEST_VOLUME
6180 TestUnicodeToFromAscii();
6181 #endif // TEST_UNICODE
6185 TestEncodingConverter();
6186 #endif // TEST_WCHAR
6189 TestZipStreamRead();
6190 TestZipFileSystem();
6194 TestZlibStreamWrite();
6195 TestZlibStreamRead();