// headers
// ----------------------------------------------------------------------------
+#include "wx/defs.h"
+
+#if wxUSE_GUI
+ #error "This sample can't be compiled in GUI mode."
+#endif // wxUSE_GUI
+
#include <stdio.h>
-#include <wx/string.h>
-#include <wx/file.h>
-#include <wx/app.h>
+#include "wx/string.h"
+#include "wx/file.h"
+#include "wx/app.h"
// without this pragma, the stupid compiler precompiles #defines below so that
// changing them doesn't "take place" later!
// conditional compilation
// ----------------------------------------------------------------------------
-// what to test (in alphabetic order)?
-
-//#define TEST_ARRAYS
-#define TEST_CHARSET
-//#define TEST_CMDLINE
-//#define TEST_DATETIME
-//#define TEST_DIR
-//#define TEST_DLLLOADER
-//#define TEST_ENVIRON
-//#define TEST_EXECUTE
-//#define TEST_FILE
-//#define TEST_FILECONF
-//#define TEST_FILENAME
-//#define TEST_FTP
-//#define TEST_HASH
-//#define TEST_INFO_FUNCTIONS
-//#define TEST_LIST
-//#define TEST_LOCALE
-//#define TEST_LOG
-//#define TEST_LONGLONG
-//#define TEST_MIME
-//#define TEST_PATHLIST
-//#define TEST_REGCONF
-//#define TEST_REGISTRY
-//#define TEST_SOCKETS
-//#define TEST_STREAMS
-//#define TEST_STRINGS
-//#define TEST_THREADS
-//#define TEST_TIMER
-//#define TEST_VCARD -- don't enable this (VZ)
-//#define TEST_WCHAR
-//#define TEST_ZIP
-//#define TEST_ZLIB
+/*
+ A note about all these conditional compilation macros: this file is used
+ both as a test suite for various non-GUI wxWindows classes and as a
+ scratchpad for quick tests. So there are two compilation modes: if you
+ define TEST_ALL all tests are run, otherwise you may enable the individual
+ tests individually in the "#else" branch below.
+ */
+
+// what to test (in alphabetic order)? uncomment the line below to do all tests
+// #define TEST_ALL
+#ifdef TEST_ALL
+ #define TEST_ARRAYS
+ #define TEST_CHARSET
+ #define TEST_CMDLINE
+ #define TEST_DATETIME
+ #define TEST_DIR
+ #define TEST_DLLLOADER
+ #define TEST_ENVIRON
+ #define TEST_EXECUTE
+ #define TEST_FILE
+ #define TEST_FILECONF
+ #define TEST_FILENAME
+ #define TEST_FILETIME
+ #define TEST_FTP
+ #define TEST_HASH
+ #define TEST_HASHMAP
+ #define TEST_INFO_FUNCTIONS
+ #define TEST_LIST
+ #define TEST_LOCALE
+ #define TEST_LOG
+ #define TEST_LONGLONG
+ #define TEST_MIME
+ #define TEST_PATHLIST
+ #define TEST_ODBC
+ #define TEST_REGCONF
+ #define TEST_REGEX
+ #define TEST_REGISTRY
+ #define TEST_SNGLINST
+ #define TEST_SOCKETS
+ #define TEST_STREAMS
+ #define TEST_STRINGS
+ #define TEST_THREADS
+ #define TEST_TIMER
+ // #define TEST_VCARD -- don't enable this (VZ)
+ #define TEST_VOLUME
+ #define TEST_WCHAR
+ #define TEST_ZIP
+ #define TEST_ZLIB
+
+ #undef TEST_ALL
+ static const bool TEST_ALL = TRUE;
+#else
+ #define TEST_FILENAME
+
+ static const bool TEST_ALL = FALSE;
+#endif
+
+// some tests are interactive, define this to run them
+#ifdef TEST_INTERACTIVE
+ #undef TEST_INTERACTIVE
+
+ static const bool TEST_INTERACTIVE = TRUE;
+#else
+ static const bool TEST_INTERACTIVE = FALSE;
+#endif
// ----------------------------------------------------------------------------
// test class for container objects
#ifdef TEST_CHARSET
-#include <wx/fontmap.h>
+#include "wx/fontmap.h"
static void TestCharset()
{
for ( size_t n = 0; n < WXSIZEOF(charsets); n++ )
{
- wxFontEncoding enc = wxTheFontMapper->CharsetToEncoding(charsets[n]);
+ wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charsets[n]);
wxPrintf(_T("Charset: %s\tEncoding: %s (%s)\n"),
charsets[n],
- wxTheFontMapper->GetEncodingName(enc).c_str(),
- wxTheFontMapper->GetEncodingDescription(enc).c_str());
+ wxFontMapper::Get()->GetEncodingName(enc).c_str(),
+ wxFontMapper::Get()->GetEncodingDescription(enc).c_str());
}
}
#ifdef TEST_CMDLINE
-#include <wx/cmdline.h>
-#include <wx/datetime.h>
+#include "wx/cmdline.h"
+#include "wx/datetime.h"
+
+#if wxUSE_CMDLINE_PARSER
static void ShowCmdLine(const wxCmdLineParser& parser)
{
wxLogMessage(s);
}
+#endif // wxUSE_CMDLINE_PARSER
+
+static void TestCmdLineConvert()
+{
+ static const char *cmdlines[] =
+ {
+ "arg1 arg2",
+ "-a \"-bstring 1\" -c\"string 2\" \"string 3\"",
+ "literal \\\" and \"\"",
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(cmdlines); n++ )
+ {
+ const char *cmdline = cmdlines[n];
+ printf("Parsing: %s\n", cmdline);
+ wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdline);
+
+ size_t count = args.GetCount();
+ printf("\targc = %u\n", count);
+ for ( size_t arg = 0; arg < count; arg++ )
+ {
+ printf("\targv[%u] = %s\n", arg, args[arg].c_str());
+ }
+ }
+}
+
#endif // TEST_CMDLINE
// ----------------------------------------------------------------------------
#ifdef TEST_DIR
-#include <wx/dir.h>
+#include "wx/dir.h"
+
+#ifdef __UNIX__
+ static const wxChar *ROOTDIR = _T("/");
+ static const wxChar *TESTDIR = _T("/usr");
+#elif defined(__WXMSW__)
+ static const wxChar *ROOTDIR = _T("c:\\");
+ static const wxChar *TESTDIR = _T("d:\\");
+#else
+ #error "don't know where the root directory is"
+#endif
static void TestDirEnumHelper(wxDir& dir,
int flags = wxDIR_DEFAULT,
static void TestDirEnum()
{
+ puts("*** Testing wxDir::GetFirst/GetNext ***");
+
wxDir dir(wxGetCwd());
puts("Enumerating everything in current directory:");
puts("Enumerating files including hidden in current directory:");
TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
-#ifdef __UNIX__
- dir.Open("/");
-#elif defined(__WXMSW__)
- dir.Open("c:\\");
-#else
- #error "don't know where the root directory is"
-#endif
+ dir.Open(ROOTDIR);
puts("Enumerating everything in root directory:");
TestDirEnumHelper(dir, wxDIR_DEFAULT);
TestDirEnumHelper(dirNo);
}
+class DirPrintTraverser : public wxDirTraverser
+{
+public:
+ virtual wxDirTraverseResult OnFile(const wxString& filename)
+ {
+ return wxDIR_CONTINUE;
+ }
+
+ virtual wxDirTraverseResult OnDir(const wxString& dirname)
+ {
+ wxString path, name, ext;
+ wxSplitPath(dirname, &path, &name, &ext);
+
+ if ( !ext.empty() )
+ name << _T('.') << ext;
+
+ wxString indent;
+ for ( const wxChar *p = path.c_str(); *p; p++ )
+ {
+ if ( wxIsPathSeparator(*p) )
+ indent += _T(" ");
+ }
+
+ printf("%s%s\n", indent.c_str(), name.c_str());
+
+ return wxDIR_CONTINUE;
+ }
+};
+
+static void TestDirTraverse()
+{
+ puts("*** Testing wxDir::Traverse() ***");
+
+ // enum all files
+ wxArrayString files;
+ size_t n = wxDir::GetAllFiles(TESTDIR, &files);
+ printf("There are %u files under '%s'\n", n, TESTDIR);
+ if ( n > 1 )
+ {
+ printf("First one is '%s'\n", files[0u].c_str());
+ printf(" last one is '%s'\n", files[n - 1].c_str());
+ }
+
+ // enum again with custom traverser
+ wxDir dir(TESTDIR);
+ DirPrintTraverser traverser;
+ dir.Traverse(traverser, _T(""), wxDIR_DIRS | wxDIR_HIDDEN);
+}
+
#endif // TEST_DIR
// ----------------------------------------------------------------------------
#ifdef TEST_DLLLOADER
-#include <wx/dynlib.h>
+#include "wx/dynlib.h"
static void TestDllLoad()
{
}
else
{
- typedef int (*strlenType)(char *);
+ typedef int (*strlenType)(const char *);
strlenType pfnStrlen = (strlenType)wxDllLoader::GetSymbol(dllHandle, FUNC_NAME);
if ( !pfnStrlen )
{
#ifdef TEST_ENVIRON
-#include <wx/utils.h>
+#include "wx/utils.h"
static wxString MyGetEnv(const wxString& var)
{
printf("After 2nd wxSetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
wxUnsetEnv(var);
printf("After wxUnsetEnv: getenv(%s) = %s\n", var, MyGetEnv(var).c_str());
- printf("PATH = %s\n", MyGetEnv(_T("PATH")));
+ printf("PATH = %s\n", MyGetEnv(_T("PATH")).c_str());
}
#endif // TEST_ENVIRON
#ifdef TEST_EXECUTE
-#include <wx/utils.h>
+#include "wx/utils.h"
static void TestExecute()
{
#ifdef TEST_FILE
-#include <wx/file.h>
-#include <wx/ffile.h>
-#include <wx/textfile.h>
+#include "wx/file.h"
+#include "wx/ffile.h"
+#include "wx/textfile.h"
static void TestFileRead()
{
#ifdef TEST_FILECONF
-#include <wx/confbase.h>
-#include <wx/fileconf.h>
+#include "wx/confbase.h"
+#include "wx/fileconf.h"
static const struct FileConfTestData
{
#ifdef TEST_FILENAME
-#include <wx/filename.h>
+#include "wx/filename.h"
+
+static void DumpFileName(const wxFileName& fn)
+{
+ wxString full = fn.GetFullPath();
+
+ wxString vol, path, name, ext;
+ wxFileName::SplitPath(full, &vol, &path, &name, &ext);
+
+ wxPrintf(_T("Filename '%s' -> vol '%s', path '%s', name '%s', ext '%s'\n"),
+ full.c_str(), vol.c_str(), path.c_str(), name.c_str(), ext.c_str());
+}
static struct FileNameInfo
{
const wxChar *fullname;
+ const wxChar *volume;
const wxChar *path;
const wxChar *name;
const wxChar *ext;
+ bool isAbsolute;
+ wxPathFormat format;
} filenames[] =
{
- { _T("/usr/bin/ls"), _T("/usr/bin"), _T("ls"), _T("") },
- { _T("/usr/bin/"), _T("/usr/bin"), _T(""), _T("") },
- { _T("~/.zshrc"), _T("~"), _T(".zshrc"), _T("") },
- { _T("../../foo"), _T("../.."), _T("foo"), _T("") },
- { _T("foo.bar"), _T(""), _T("foo"), _T("bar") },
- { _T("~/foo.bar"), _T("~"), _T("foo"), _T("bar") },
- { _T("Mahogany-0.60/foo.bar"), _T("Mahogany-0.60"), _T("foo"), _T("bar") },
- { _T("/tmp/wxwin.tar.bz"), _T("/tmp"), _T("wxwin.tar"), _T("bz") },
+ // Unix file names
+ { _T("/usr/bin/ls"), _T(""), _T("/usr/bin"), _T("ls"), _T(""), TRUE, wxPATH_UNIX },
+ { _T("/usr/bin/"), _T(""), _T("/usr/bin"), _T(""), _T(""), TRUE, wxPATH_UNIX },
+ { _T("~/.zshrc"), _T(""), _T("~"), _T(".zshrc"), _T(""), TRUE, wxPATH_UNIX },
+ { _T("../../foo"), _T(""), _T("../.."), _T("foo"), _T(""), FALSE, wxPATH_UNIX },
+ { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), FALSE, wxPATH_UNIX },
+ { _T("~/foo.bar"), _T(""), _T("~"), _T("foo"), _T("bar"), TRUE, wxPATH_UNIX },
+ { _T("/foo"), _T(""), _T("/"), _T("foo"), _T(""), TRUE, wxPATH_UNIX },
+ { _T("Mahogany-0.60/foo.bar"), _T(""), _T("Mahogany-0.60"), _T("foo"), _T("bar"), FALSE, wxPATH_UNIX },
+ { _T("/tmp/wxwin.tar.bz"), _T(""), _T("/tmp"), _T("wxwin.tar"), _T("bz"), TRUE, wxPATH_UNIX },
+
+ // Windows file names
+ { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), FALSE, wxPATH_DOS },
+ { _T("\\foo.bar"), _T(""), _T("\\"), _T("foo"), _T("bar"), FALSE, wxPATH_DOS },
+ { _T("c:foo.bar"), _T("c"), _T(""), _T("foo"), _T("bar"), FALSE, wxPATH_DOS },
+ { _T("c:\\foo.bar"), _T("c"), _T("\\"), _T("foo"), _T("bar"), TRUE, wxPATH_DOS },
+ { _T("c:\\Windows\\command.com"), _T("c"), _T("\\Windows"), _T("command"), _T("com"), TRUE, wxPATH_DOS },
+ { _T("\\\\server\\foo.bar"), _T("server"), _T("\\"), _T("foo"), _T("bar"), TRUE, wxPATH_DOS },
+
+ // wxFileName support for Mac file names is broken currently
+#if 0
+ // Mac file names
+ { _T("Volume:Dir:File"), _T("Volume"), _T("Dir"), _T("File"), _T(""), TRUE, wxPATH_MAC },
+ { _T("Volume:Dir:Subdir:File"), _T("Volume"), _T("Dir:Subdir"), _T("File"), _T(""), TRUE, wxPATH_MAC },
+ { _T("Volume:"), _T("Volume"), _T(""), _T(""), _T(""), TRUE, wxPATH_MAC },
+ { _T(":Dir:File"), _T(""), _T("Dir"), _T("File"), _T(""), FALSE, wxPATH_MAC },
+ { _T(":File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), FALSE, wxPATH_MAC },
+ { _T("File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), FALSE, wxPATH_MAC },
+#endif // 0
+
+ // VMS file names
+ { _T("device:[dir1.dir2.dir3]file.txt"), _T("device"), _T("dir1.dir2.dir3"), _T("file"), _T("txt"), TRUE, wxPATH_VMS },
+ { _T("file.txt"), _T(""), _T(""), _T("file"), _T("txt"), FALSE, wxPATH_VMS },
};
static void TestFileNameConstruction()
for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
{
- wxFileName fn(filenames[n].fullname, wxPATH_UNIX);
+ const FileNameInfo& fni = filenames[n];
+
+ wxFileName fn(fni.fullname, fni.format);
- printf("Filename: '%s'\t", fn.GetFullPath().c_str());
- if ( !fn.Normalize(wxPATH_NORM_ALL, _T(""), wxPATH_UNIX) )
+ wxString fullname = fn.GetFullPath(fni.format);
+ if ( fullname != fni.fullname )
+ {
+ printf("ERROR: fullname should be '%s'\n", fni.fullname);
+ }
+
+ bool isAbsolute = fn.IsAbsolute(fni.format);
+ printf("'%s' is %s (%s)\n\t",
+ fullname.c_str(),
+ isAbsolute ? "absolute" : "relative",
+ isAbsolute == fni.isAbsolute ? "ok" : "ERROR");
+
+ if ( !fn.Normalize(wxPATH_NORM_ALL, _T(""), fni.format) )
{
puts("ERROR (couldn't be normalized)");
}
else
{
- printf("normalized: '%s'\n", fn.GetFullPath().c_str());
+ printf("normalized: '%s'\n", fn.GetFullPath(fni.format).c_str());
}
}
for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
{
- const FileNameInfo &fni = filenames[n];
- wxString path, name, ext;
- wxFileName::SplitPath(fni.fullname, &path, &name, &ext);
+ const FileNameInfo& fni = filenames[n];
+ wxString volume, path, name, ext;
+ wxFileName::SplitPath(fni.fullname,
+ &volume, &path, &name, &ext, fni.format);
+
+ printf("%s -> volume = '%s', path = '%s', name = '%s', ext = '%s'",
+ fni.fullname,
+ volume.c_str(), path.c_str(), name.c_str(), ext.c_str());
- printf("%s -> path = '%s', name = '%s', ext = '%s'",
- fni.fullname, path.c_str(), name.c_str(), ext.c_str());
+ if ( volume != fni.volume )
+ printf(" (ERROR: volume = '%s')", fni.volume);
if ( path != fni.path )
printf(" (ERROR: path = '%s')", fni.path);
if ( name != fni.name )
printf(" (ERROR: name = '%s')", fni.name);
if ( ext != fni.ext )
printf(" (ERROR: ext = '%s')", fni.ext);
+
puts("");
}
+}
- puts("");
+static void TestFileNameTemp()
+{
+ puts("*** testing wxFileName temp file creation ***");
+
+ static const char *tmpprefixes[] =
+ {
+ "",
+ "foo",
+ "..",
+ "../bar",
+#ifdef __UNIX__
+ "/tmp/foo",
+ "/tmp/foo/bar", // this one must be an error
+#endif // __UNIX__
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(tmpprefixes); n++ )
+ {
+ wxString path = wxFileName::CreateTempFileName(tmpprefixes[n]);
+ if ( path.empty() )
+ {
+ // "error" is not in upper case because it may be ok
+ printf("Prefix '%s'\t-> error\n", tmpprefixes[n]);
+ }
+ else
+ {
+ printf("Prefix '%s'\t-> temp file '%s'\n",
+ tmpprefixes[n], path.c_str());
+
+ if ( !wxRemoveFile(path) )
+ {
+ wxLogWarning("Failed to remove temp file '%s'", path.c_str());
+ }
+ }
+ }
+}
+
+static void TestFileNameMakeRelative()
+{
+ puts("*** testing wxFileName::MakeRelativeTo() ***");
+
+ for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
+ {
+ const FileNameInfo& fni = filenames[n];
+
+ wxFileName fn(fni.fullname, fni.format);
+
+ // choose the base dir of the same format
+ wxString base;
+ switch ( fni.format )
+ {
+ case wxPATH_UNIX:
+ base = "/usr/bin/";
+ break;
+
+ case wxPATH_DOS:
+ base = "c:\\";
+ break;
+
+ case wxPATH_MAC:
+ case wxPATH_VMS:
+ // TODO: I don't know how this is supposed to work there
+ continue;
+
+ case wxPATH_NATIVE: // make gcc happy
+ default:
+ wxFAIL_MSG( "unexpected path format" );
+ }
+
+ printf("'%s' relative to '%s': ",
+ fn.GetFullPath(fni.format).c_str(), base.c_str());
+
+ if ( !fn.MakeRelativeTo(base, fni.format) )
+ {
+ puts("unchanged");
+ }
+ else
+ {
+ printf("'%s'\n", fn.GetFullPath(fni.format).c_str());
+ }
+ }
}
static void TestFileNameComparison()
#endif // TEST_FILENAME
+// ----------------------------------------------------------------------------
+// wxFileName time functions
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_FILETIME
+
+#include <wx/filename.h>
+#include <wx/datetime.h>
+
+static void TestFileGetTimes()
+{
+ wxFileName fn(_T("testdata.fc"));
+
+ wxDateTime dtAccess, dtMod, dtCreate;
+ if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) )
+ {
+ wxPrintf(_T("ERROR: GetTimes() failed.\n"));
+ }
+ else
+ {
+ static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S");
+
+ wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str());
+ wxPrintf(_T("Creation: \t%s\n"), dtCreate.Format(fmt).c_str());
+ wxPrintf(_T("Last read: \t%s\n"), dtAccess.Format(fmt).c_str());
+ wxPrintf(_T("Last write: \t%s\n"), dtMod.Format(fmt).c_str());
+ }
+}
+
+static void TestFileSetTimes()
+{
+ wxFileName fn(_T("testdata.fc"));
+
+ if ( !fn.Touch() )
+ {
+ wxPrintf(_T("ERROR: Touch() failed.\n"));
+ }
+}
+
+#endif // TEST_FILETIME
+
// ----------------------------------------------------------------------------
// wxHashTable
// ----------------------------------------------------------------------------
#ifdef TEST_HASH
-#include <wx/hash.h>
+#include "wx/hash.h"
struct Foo
{
WX_DECLARE_LIST(Foo, wxListFoos);
WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
-#include <wx/listimpl.cpp>
+#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListFoos);
#endif // TEST_HASH
+// ----------------------------------------------------------------------------
+// wxHashMap
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_HASHMAP
+
+#include "wx/hashmap.h"
+
+// test compilation of basic map types
+WX_DECLARE_HASH_MAP( int*, int*, wxPointerHash, wxPointerEqual, myPtrHashMap );
+WX_DECLARE_HASH_MAP( long, long, wxIntegerHash, wxIntegerEqual, myLongHashMap );
+WX_DECLARE_HASH_MAP( unsigned long, unsigned, wxIntegerHash, wxIntegerEqual,
+ myUnsignedHashMap );
+WX_DECLARE_HASH_MAP( unsigned int, unsigned, wxIntegerHash, wxIntegerEqual,
+ myTestHashMap1 );
+WX_DECLARE_HASH_MAP( int, unsigned, wxIntegerHash, wxIntegerEqual,
+ myTestHashMap2 );
+WX_DECLARE_HASH_MAP( short, unsigned, wxIntegerHash, wxIntegerEqual,
+ myTestHashMap3 );
+WX_DECLARE_HASH_MAP( unsigned short, unsigned, wxIntegerHash, wxIntegerEqual,
+ myTestHashMap4 );
+
+// same as:
+// WX_DECLARE_HASH_MAP( wxString, wxString, wxStringHash, wxStringEqual,
+// myStringHashMap );
+WX_DECLARE_STRING_HASH_MAP(wxString, myStringHashMap);
+
+typedef myStringHashMap::iterator Itor;
+
+static void TestHashMap()
+{
+ puts("*** Testing wxHashMap ***\n");
+ myStringHashMap sh(0); // as small as possible
+ wxString buf;
+ size_t i;
+ const size_t count = 10000;
+
+ // init with some data
+ for( i = 0; i < count; ++i )
+ {
+ buf.Printf(wxT("%d"), i );
+ sh[buf] = wxT("A") + buf + wxT("C");
+ }
+
+ // test that insertion worked
+ if( sh.size() != count )
+ {
+ printf("*** ERROR: %u ELEMENTS, SHOULD BE %u ***\n", sh.size(), count);
+ }
+
+ for( i = 0; i < count; ++i )
+ {
+ buf.Printf(wxT("%d"), i );
+ if( sh[buf] != wxT("A") + buf + wxT("C") )
+ {
+ printf("*** ERROR INSERTION BROKEN! STOPPING NOW! ***\n");
+ return;
+ }
+ }
+
+ // check that iterators work
+ Itor it;
+ for( i = 0, it = sh.begin(); it != sh.end(); ++it, ++i )
+ {
+ if( i == count )
+ {
+ printf("*** ERROR ITERATORS DO NOT TERMINATE! STOPPING NOW! ***\n");
+ return;
+ }
+
+ if( it->second != sh[it->first] )
+ {
+ printf("*** ERROR ITERATORS BROKEN! STOPPING NOW! ***\n");
+ return;
+ }
+ }
+
+ if( sh.size() != i )
+ {
+ printf("*** ERROR: %u ELEMENTS ITERATED, SHOULD BE %u ***\n", i, count);
+ }
+
+ // test copy ctor, assignment operator
+ myStringHashMap h1( sh ), h2( 0 );
+ h2 = sh;
+
+ for( i = 0, it = sh.begin(); it != sh.end(); ++it, ++i )
+ {
+ if( h1[it->first] != it->second )
+ {
+ printf("*** ERROR: COPY CTOR BROKEN %s ***\n", it->first.c_str());
+ }
+
+ if( h2[it->first] != it->second )
+ {
+ printf("*** ERROR: OPERATOR= BROKEN %s ***\n", it->first.c_str());
+ }
+ }
+
+ // other tests
+ for( i = 0; i < count; ++i )
+ {
+ buf.Printf(wxT("%d"), i );
+ size_t sz = sh.size();
+
+ // test find() and erase(it)
+ if( i < 100 )
+ {
+ it = sh.find( buf );
+ if( it != sh.end() )
+ {
+ sh.erase( it );
+
+ if( sh.find( buf ) != sh.end() )
+ {
+ printf("*** ERROR: FOUND DELETED ELEMENT %u ***\n", i);
+ }
+ }
+ else
+ printf("*** ERROR: CANT FIND ELEMENT %u ***\n", i);
+ }
+ else
+ // test erase(key)
+ {
+ size_t c = sh.erase( buf );
+ if( c != 1 )
+ printf("*** ERROR: SHOULD RETURN 1 ***\n");
+
+ if( sh.find( buf ) != sh.end() )
+ {
+ printf("*** ERROR: FOUND DELETED ELEMENT %u ***\n", i);
+ }
+ }
+
+ // count should decrease
+ if( sh.size() != sz - 1 )
+ {
+ printf("*** ERROR: COUNT DID NOT DECREASE ***\n");
+ }
+ }
+
+ printf("*** Finished testing wxHashMap ***\n");
+}
+
+#endif // TEST_HASHMAP
+
// ----------------------------------------------------------------------------
// wxList
// ----------------------------------------------------------------------------
#ifdef TEST_LIST
-#include <wx/list.h>
+#include "wx/list.h"
WX_DECLARE_LIST(Bar, wxListBars);
-#include <wx/listimpl.cpp>
+#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListBars);
static void TestListCtor()
{
static const char *languageNames[] =
{
- "DEFAULT",
- "UNKNOWN",
+ "DEFAULT",
+ "UNKNOWN",
"ABKHAZIAN",
"AFAR",
"AFRIKAANS",
_T("klingonese"), // I bet on some systems it does exist...
};
+ wxPrintf(_T("The default system encoding is %s (%d)\n"),
+ wxLocale::GetSystemEncodingName().c_str(),
+ wxLocale::GetSystemEncoding());
+
for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ )
{
const char *langStr = langStrings[n];
if ( langStr )
+ {
+ // FIXME: this doesn't do anything at all under Windows, we need
+ // to create a new wxLocale!
wxSetEnv(_T("LC_ALL"), langStr);
+ }
int lang = gs_localeDefault.GetSystemLanguage();
printf("Locale for '%s' is %s.\n",
#ifdef TEST_MIME
-#include <wx/mimetype.h>
+#include "wx/mimetype.h"
static void TestMimeEnum()
{
_T("application/x-xyz"),
_T("xyzview '%s'"), // open cmd
_T(""), // print cmd
- _T("XYZ File") // description
- _T(".xyz"), // extensions
- NULL // end of extensions
+ _T("XYZ File"), // description
+ _T(".xyz"), // extensions
+ NULL // end of extensions
);
ftInfo.SetShortDesc(_T("XYZFile")); // used under Win32 only
#ifdef TEST_INFO_FUNCTIONS
-#include <wx/utils.h>
+#include "wx/utils.h"
+
+static void TestDiskInfo()
+{
+ puts("*** Testing wxGetDiskSpace() ***");
+
+ for ( ;; )
+ {
+ char pathname[128];
+ printf("\nEnter a directory name: ");
+ if ( !fgets(pathname, WXSIZEOF(pathname), stdin) )
+ break;
+
+ // kill the last '\n'
+ pathname[strlen(pathname) - 1] = 0;
+
+ wxLongLong total, free;
+ if ( !wxGetDiskSpace(pathname, &total, &free) )
+ {
+ wxPuts(_T("ERROR: wxGetDiskSpace failed."));
+ }
+ else
+ {
+ wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"),
+ (total / 1024).ToString().c_str(),
+ (free / 1024).ToString().c_str(),
+ pathname);
+ }
+ }
+}
static void TestOsInfo()
{
#ifdef TEST_LONGLONG
-#include <wx/longlong.h>
-#include <wx/timer.h>
+#include "wx/longlong.h"
+#include "wx/timer.h"
// make a 64 bit number from 4 16 bit ones
#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
// get a random 64 bit number
#define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
+static const long testLongs[] =
+{
+ 0,
+ 1,
+ -1,
+ LONG_MAX,
+ LONG_MIN,
+ 0x1234,
+ -0x1234
+};
+
#if wxUSE_LONGLONG_WX
inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
{ return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
// multiplication will not overflow)
wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
- // get a random long (not wxLongLong for now) to divide it with
- long l = rand();
+ // get a random (but non null) long (not wxLongLong for now) to divide
+ // it with
+ long l;
+ do
+ {
+ l = rand();
+ }
+ while ( !l );
+
q = ll / l;
r = ll % l;
static void TestLongLongComparison()
{
+#if wxUSE_LONGLONG_WX
puts("*** Testing wxLongLong comparison ***\n");
- static const long testLongs[] =
- {
- 0,
- 1,
- -1,
- LONG_MAX,
- LONG_MIN,
- 0x1234,
- -0x1234
- };
-
static const long ls[2] =
{
0x1234,
wxLongLongWx lls[2];
lls[0] = ls[0];
- lls[1] = ls[1];
+ lls[1] = ls[1];
for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
{
res == (ls[m] == testLongs[n]) ? "ok" : "ERROR");
}
}
+#endif // wxUSE_LONGLONG_WX
+}
+
+static void TestLongLongPrint()
+{
+ wxPuts(_T("*** Testing wxLongLong printing ***\n"));
+
+ for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ )
+ {
+ wxLongLong ll = testLongs[n];
+ wxPrintf(_T("%ld == %s\n"), testLongs[n], ll.ToString().c_str());
+ }
+
+ wxLongLong ll(0x12345678, 0x87654321);
+ wxPrintf(_T("0x1234567887654321 = %s\n"), ll.ToString().c_str());
+
+ ll.Negate();
+ wxPrintf(_T("-0x1234567887654321 = %s\n"), ll.ToString().c_str());
}
#undef MAKE_LL
#endif // TEST_PATHLIST
+// ----------------------------------------------------------------------------
+// regular expressions
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_REGEX
+
+#include "wx/regex.h"
+
+static void TestRegExCompile()
+{
+ wxPuts(_T("*** Testing RE compilation ***\n"));
+
+ static struct RegExCompTestData
+ {
+ const wxChar *pattern;
+ bool correct;
+ } regExCompTestData[] =
+ {
+ { _T("foo"), TRUE },
+ { _T("foo("), FALSE },
+ { _T("foo(bar"), FALSE },
+ { _T("foo(bar)"), TRUE },
+ { _T("foo["), FALSE },
+ { _T("foo[bar"), FALSE },
+ { _T("foo[bar]"), TRUE },
+ { _T("foo{"), TRUE },
+ { _T("foo{1"), FALSE },
+ { _T("foo{bar"), TRUE },
+ { _T("foo{1}"), TRUE },
+ { _T("foo{1,2}"), TRUE },
+ { _T("foo{bar}"), TRUE },
+ { _T("foo*"), TRUE },
+ { _T("foo**"), FALSE },
+ { _T("foo+"), TRUE },
+ { _T("foo++"), FALSE },
+ { _T("foo?"), TRUE },
+ { _T("foo??"), FALSE },
+ { _T("foo?+"), FALSE },
+ };
+
+ wxRegEx re;
+ for ( size_t n = 0; n < WXSIZEOF(regExCompTestData); n++ )
+ {
+ const RegExCompTestData& data = regExCompTestData[n];
+ bool ok = re.Compile(data.pattern);
+
+ wxPrintf(_T("'%s' is %sa valid RE (%s)\n"),
+ data.pattern,
+ ok ? _T("") : _T("not "),
+ ok == data.correct ? _T("ok") : _T("ERROR"));
+ }
+}
+
+static void TestRegExMatch()
+{
+ wxPuts(_T("*** Testing RE matching ***\n"));
+
+ static struct RegExMatchTestData
+ {
+ const wxChar *pattern;
+ const wxChar *text;
+ bool correct;
+ } regExMatchTestData[] =
+ {
+ { _T("foo"), _T("bar"), FALSE },
+ { _T("foo"), _T("foobar"), TRUE },
+ { _T("^foo"), _T("foobar"), TRUE },
+ { _T("^foo"), _T("barfoo"), FALSE },
+ { _T("bar$"), _T("barbar"), TRUE },
+ { _T("bar$"), _T("barbar "), FALSE },
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(regExMatchTestData); n++ )
+ {
+ const RegExMatchTestData& data = regExMatchTestData[n];
+
+ wxRegEx re(data.pattern);
+ bool ok = re.Matches(data.text);
+
+ wxPrintf(_T("'%s' %s %s (%s)\n"),
+ data.pattern,
+ ok ? _T("matches") : _T("doesn't match"),
+ data.text,
+ ok == data.correct ? _T("ok") : _T("ERROR"));
+ }
+}
+
+static void TestRegExSubmatch()
+{
+ wxPuts(_T("*** Testing RE subexpressions ***\n"));
+
+ wxRegEx re(_T("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).*([[:digit:]]+)$"));
+ if ( !re.IsValid() )
+ {
+ wxPuts(_T("ERROR: compilation failed."));
+ return;
+ }
+
+ wxString text = _T("Fri Jul 13 18:37:52 CEST 2001");
+
+ if ( !re.Matches(text) )
+ {
+ wxPuts(_T("ERROR: match expected."));
+ }
+ else
+ {
+ wxPrintf(_T("Entire match: %s\n"), re.GetMatch(text).c_str());
+
+ wxPrintf(_T("Date: %s/%s/%s, wday: %s\n"),
+ re.GetMatch(text, 3).c_str(),
+ re.GetMatch(text, 2).c_str(),
+ re.GetMatch(text, 4).c_str(),
+ re.GetMatch(text, 1).c_str());
+ }
+}
+
+static void TestRegExReplacement()
+{
+ wxPuts(_T("*** Testing RE replacement ***"));
+
+ static struct RegExReplTestData
+ {
+ const wxChar *text;
+ const wxChar *repl;
+ const wxChar *result;
+ size_t count;
+ } regExReplTestData[] =
+ {
+ { _T("foo123"), _T("bar"), _T("bar"), 1 },
+ { _T("foo123"), _T("\\2\\1"), _T("123foo"), 1 },
+ { _T("foo_123"), _T("\\2\\1"), _T("123foo"), 1 },
+ { _T("123foo"), _T("bar"), _T("123foo"), 0 },
+ { _T("123foo456foo"), _T("&&"), _T("123foo456foo456foo"), 1 },
+ { _T("foo123foo123"), _T("bar"), _T("barbar"), 2 },
+ { _T("foo123_foo456_foo789"), _T("bar"), _T("bar_bar_bar"), 3 },
+ };
+
+ const wxChar *pattern = _T("([a-z]+)[^0-9]*([0-9]+)");
+ wxRegEx re(pattern);
+
+ wxPrintf(_T("Using pattern '%s' for replacement.\n"), pattern);
+
+ for ( size_t n = 0; n < WXSIZEOF(regExReplTestData); n++ )
+ {
+ const RegExReplTestData& data = regExReplTestData[n];
+
+ wxString text = data.text;
+ size_t nRepl = re.Replace(&text, data.repl);
+
+ wxPrintf(_T("%s =~ s/RE/%s/g: %u match%s, result = '%s' ("),
+ data.text, data.repl,
+ nRepl, nRepl == 1 ? _T("") : _T("es"),
+ text.c_str());
+ if ( text == data.result && nRepl == data.count )
+ {
+ wxPuts(_T("ok)"));
+ }
+ else
+ {
+ wxPrintf(_T("ERROR: should be %u and '%s')\n"),
+ data.count, data.result);
+ }
+ }
+}
+
+static void TestRegExInteractive()
+{
+ wxPuts(_T("*** Testing RE interactively ***"));
+
+ for ( ;; )
+ {
+ char pattern[128];
+ printf("\nEnter a pattern: ");
+ if ( !fgets(pattern, WXSIZEOF(pattern), stdin) )
+ break;
+
+ // kill the last '\n'
+ pattern[strlen(pattern) - 1] = 0;
+
+ wxRegEx re;
+ if ( !re.Compile(pattern) )
+ {
+ continue;
+ }
+
+ char text[128];
+ for ( ;; )
+ {
+ printf("Enter text to match: ");
+ if ( !fgets(text, WXSIZEOF(text), stdin) )
+ break;
+
+ // kill the last '\n'
+ text[strlen(text) - 1] = 0;
+
+ if ( !re.Matches(text) )
+ {
+ printf("No match.\n");
+ }
+ else
+ {
+ printf("Pattern matches at '%s'\n", re.GetMatch(text).c_str());
+
+ size_t start, len;
+ for ( size_t n = 1; ; n++ )
+ {
+ if ( !re.GetMatch(&start, &len, n) )
+ {
+ break;
+ }
+
+ printf("Subexpr %u matched '%s'\n",
+ n, wxString(text + start, len).c_str());
+ }
+ }
+ }
+ }
+}
+
+#endif // TEST_REGEX
+
+// ----------------------------------------------------------------------------
+// database
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_ODBC
+
+#include <wx/db.h>
+
+static void TestDbOpen()
+{
+ HENV henv;
+ wxDb db(henv);
+}
+
+#endif // TEST_ODBC
+
// ----------------------------------------------------------------------------
// registry and related stuff
// ----------------------------------------------------------------------------
#ifdef TEST_REGCONF
-#include <wx/confbase.h>
-#include <wx/msw/regconf.h>
+#include "wx/confbase.h"
+#include "wx/msw/regconf.h"
static void TestRegConfWrite()
{
#ifdef TEST_REGISTRY
-#include <wx/msw/registry.h>
+#include "wx/msw/registry.h"
// I chose this one because I liked its name, but it probably only exists under
// NT
#ifdef TEST_SOCKETS
-#include <wx/socket.h>
-#include <wx/protocol/protocol.h>
-#include <wx/protocol/http.h>
+#include "wx/socket.h"
+#include "wx/protocol/protocol.h"
+#include "wx/protocol/http.h"
static void TestSocketServer()
{
#ifdef TEST_FTP
-#include <wx/protocol/ftp.h>
+#include "wx/protocol/ftp.h"
static wxFTP ftp;
#ifdef TEST_STREAMS
-#include <wx/wfstream.h>
-#include <wx/mstream.h>
+#include "wx/wfstream.h"
+#include "wx/mstream.h"
static void TestFileStream()
{
#ifdef TEST_TIMER
-#include <wx/timer.h>
-#include <wx/utils.h>
+#include "wx/timer.h"
+#include "wx/utils.h"
static void TestStopWatch()
{
#ifdef TEST_VCARD
-#include <wx/vcard.h>
+#include "wx/vcard.h"
static void DumpVObject(size_t level, const wxVCardObject& vcard)
{
#endif // TEST_VCARD
+// ----------------------------------------------------------------------------
+// wxVolume tests
+// ----------------------------------------------------------------------------
+
+#if !wxUSE_FSVOLUME
+ #undef TEST_VOLUME
+#endif
+
+#ifdef TEST_VOLUME
+
+#include "wx/volume.h"
+
+static const wxChar *volumeKinds[] =
+{
+ _T("floppy"),
+ _T("hard disk"),
+ _T("CD-ROM"),
+ _T("DVD-ROM"),
+ _T("network volume"),
+ _T("other volume"),
+};
+
+static void TestFSVolume()
+{
+ wxPuts(_T("*** Testing wxFSVolume class ***"));
+
+ wxArrayString volumes = wxFSVolume::GetVolumes();
+ size_t count = volumes.GetCount();
+
+ if ( !count )
+ {
+ wxPuts(_T("ERROR: no mounted volumes?"));
+ return;
+ }
+
+ wxPrintf(_T("%u mounted volumes found:\n"), count);
+
+ for ( size_t n = 0; n < count; n++ )
+ {
+ wxFSVolume vol(volumes[n]);
+ if ( !vol.IsOk() )
+ {
+ wxPuts(_T("ERROR: couldn't create volume"));
+ continue;
+ }
+
+ wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
+ n + 1,
+ vol.GetDisplayName().c_str(),
+ vol.GetName().c_str(),
+ volumeKinds[vol.GetKind()],
+ vol.IsWritable() ? _T("rw") : _T("ro"),
+ vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
+ : _T("fixed"));
+ }
+}
+
+#endif // TEST_VOLUME
+
// ----------------------------------------------------------------------------
// wide char (Unicode) support
// ----------------------------------------------------------------------------
#ifdef TEST_WCHAR
-#include <wx/strconv.h>
-#include <wx/fontenc.h>
-#include <wx/encconv.h>
-#include <wx/buffer.h>
+#include "wx/strconv.h"
+#include "wx/fontenc.h"
+#include "wx/encconv.h"
+#include "wx/buffer.h"
+
+static const char textInUtf8[] =
+{
+ 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
+ 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
+ 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
+ 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
+ 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
+ 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
+ 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
+};
static void TestUtf8()
{
puts("*** Testing UTF8 support ***\n");
- static const char textInUtf8[] =
- {
- 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
- 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
- 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
- 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
- 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
- 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
- 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
- };
-
char buf[1024];
wchar_t wbuf[1024];
if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
}
else
{
- // using wxEncodingConverter
-#if 0
- wxEncodingConverter ec;
- ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
- ec.Convert(wbuf, buf);
-#else // using wxCSConv
wxCSConv conv(_T("koi8-r"));
if ( conv.WC2MB(buf, wbuf, 0 /* not needed wcslen(wbuf) */) <= 0 )
{
puts("ERROR: conversion to KOI8-R failed.");
}
else
-#endif
+ {
+ printf("The resulting string (in KOI8-R): %s\n", buf);
+ }
+ }
- printf("The resulting string (in koi8-r): %s\n", buf);
+ if ( wxConvUTF8.WC2MB(buf, L"Ã la", WXSIZEOF(buf)) <= 0 )
+ {
+ puts("ERROR: conversion to UTF-8 failed.");
}
+ else
+ {
+ printf("The string in UTF-8: %s\n", buf);
+ }
+
+ puts("");
+}
+
+static void TestEncodingConverter()
+{
+ wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
+
+ // using wxEncodingConverter should give the same result as above
+ char buf[1024];
+ wchar_t wbuf[1024];
+ if ( wxConvUTF8.MB2WC(wbuf, textInUtf8, WXSIZEOF(textInUtf8)) <= 0 )
+ {
+ puts("ERROR: UTF-8 decoding failed.");
+ }
+ else
+ {
+ wxEncodingConverter ec;
+ ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
+ ec.Convert(wbuf, buf);
+ printf("The same string obtained using wxEC: %s\n", buf);
+ }
+
+ puts("");
}
#endif // TEST_WCHAR
#ifdef TEST_ZLIB
-#include <wx/zstream.h>
-#include <wx/wfstream.h>
+#include "wx/zstream.h"
+#include "wx/wfstream.h"
static const wxChar *FILENAME_GZ = _T("test.gz");
static const char *TEST_DATA = "hello and hello again";
#include <math.h>
-#include <wx/date.h>
-
-#include <wx/datetime.h>
+#include "wx/date.h"
+#include "wx/datetime.h"
// the test data
struct Date
_T("(with ms) %H:%M:%S:%l"),
_T("100%% of minutes is %M"), // test "%%"
_T("%D days and %H hours"),
+ _T("or also %S seconds"),
};
wxTimeSpan ts1(1, 2, 3, 4),
#ifdef TEST_THREADS
-#include <wx/thread.h>
+#include "wx/thread.h"
static size_t gs_counter = (size_t)-1;
static wxCriticalSection gs_critsect;
-static wxCondition gs_cond;
+static wxSemaphore gs_cond;
class MyJoinableThread : public wxThread
{
wxCriticalSectionLocker lock(gs_critsect);
if ( !--gs_counter && !m_cancelled )
- gs_cond.Signal();
+ gs_cond.Post();
}
-void TestDetachedThreads()
+static void TestDetachedThreads()
{
puts("\n*** Testing detached threads ***");
puts("");
}
-void TestJoinableThreads()
+static void TestJoinableThreads()
{
puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
(unsigned long)thread.Wait());
}
-void TestThreadSuspend()
+static void TestThreadSuspend()
{
puts("\n*** Testing thread suspend/resume functions ***");
puts("");
}
-void TestThreadDelete()
+static void TestThreadDelete()
{
// As above, using Sleep() is only for testing here - we must use some
// synchronisation object instead to ensure that the thread is still
puts("");
}
-#endif // TEST_THREADS
+class MyWaitingThread : public wxThread
+{
+public:
+ MyWaitingThread( wxMutex *mutex, wxCondition *condition )
+ {
+ m_mutex = mutex;
+ m_condition = condition;
-// ----------------------------------------------------------------------------
-// arrays
-// ----------------------------------------------------------------------------
+ Create();
+ }
-#ifdef TEST_ARRAYS
+ virtual ExitCode Entry()
+ {
+ printf("Thread %lu has started running.\n", GetId());
+ fflush(stdout);
-static void PrintArray(const char* name, const wxArrayString& array)
+ gs_cond.Post();
+
+ printf("Thread %lu starts to wait...\n", GetId());
+ fflush(stdout);
+
+ m_mutex->Lock();
+ m_condition->Wait();
+ m_mutex->Unlock();
+
+ printf("Thread %lu finished to wait, exiting.\n", GetId());
+ fflush(stdout);
+
+ return 0;
+ }
+
+private:
+ wxMutex *m_mutex;
+ wxCondition *m_condition;
+};
+
+static void TestThreadConditions()
{
- printf("Dump of the array '%s'\n", name);
+ wxMutex mutex;
+ wxCondition condition(mutex);
- size_t nCount = array.GetCount();
- for ( size_t n = 0; n < nCount; n++ )
+ // otherwise its difficult to understand which log messages pertain to
+ // which condition
+ //wxLogTrace("thread", "Local condition var is %08x, gs_cond = %08x",
+ // condition.GetId(), gs_cond.GetId());
+
+ // create and launch threads
+ MyWaitingThread *threads[10];
+
+ size_t n;
+ for ( n = 0; n < WXSIZEOF(threads); n++ )
{
- printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
+ threads[n] = new MyWaitingThread( &mutex, &condition );
}
-}
-static void PrintArray(const char* name, const wxArrayInt& array)
-{
- printf("Dump of the array '%s'\n", name);
+ for ( n = 0; n < WXSIZEOF(threads); n++ )
+ {
+ threads[n]->Run();
+ }
- size_t nCount = array.GetCount();
- for ( size_t n = 0; n < nCount; n++ )
+ // wait until all threads run
+ puts("Main thread is waiting for the other threads to start");
+ fflush(stdout);
+
+ size_t nRunning = 0;
+ while ( nRunning < WXSIZEOF(threads) )
{
- printf("\t%s[%u] = %d\n", name, n, array[n]);
+ gs_cond.Wait();
+
+ nRunning++;
+
+ printf("Main thread: %u already running\n", nRunning);
+ fflush(stdout);
}
+
+ puts("Main thread: all threads started up.");
+ fflush(stdout);
+
+ wxThread::Sleep(500);
+
+#if 1
+ // now wake one of them up
+ printf("Main thread: about to signal the condition.\n");
+ fflush(stdout);
+ condition.Signal();
+#endif
+
+ wxThread::Sleep(200);
+
+ // wake all the (remaining) threads up, so that they can exit
+ printf("Main thread: about to broadcast the condition.\n");
+ fflush(stdout);
+ condition.Broadcast();
+
+ // give them time to terminate (dirty!)
+ wxThread::Sleep(500);
}
-int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
- const wxString& second)
+#include "wx/utils.h"
+
+class MyExecThread : public wxThread
{
- return first.length() - second.length();
-}
+public:
+ MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
+ m_command(command)
+ {
+ Create();
+ }
+
+ virtual ExitCode Entry()
+ {
+ return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
+ }
+
+private:
+ wxString m_command;
+};
-int wxCMPFUNC_CONV IntCompare(int *first,
- int *second)
+static void TestThreadExec()
{
- return *first - *second;
+ wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
+
+ MyExecThread thread(_T("true"));
+ thread.Run();
+
+ wxPrintf(_T("Main program exit code: %ld.\n"),
+ wxExecute(_T("false"), wxEXEC_SYNC));
+
+ wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
}
-int wxCMPFUNC_CONV IntRevCompare(int *first,
- int *second)
+// semaphore tests
+#include "wx/datetime.h"
+
+class MySemaphoreThread : public wxThread
{
- return *second - *first;
-}
+public:
+ MySemaphoreThread(int i, wxSemaphore *sem)
+ : wxThread(wxTHREAD_JOINABLE),
+ m_sem(sem),
+ m_i(i)
+ {
+ Create();
+ }
+
+ virtual ExitCode Entry()
+ {
+ wxPrintf(_T("%s: Thread %d starting to wait for semaphore...\n"),
+ wxDateTime::Now().FormatTime().c_str(), m_i);
+
+ m_sem->Wait();
+
+ wxPrintf(_T("%s: Thread %d acquired the semaphore.\n"),
+ wxDateTime::Now().FormatTime().c_str(), m_i);
+
+ Sleep(1000);
+
+ wxPrintf(_T("%s: Thread %d releasing the semaphore.\n"),
+ wxDateTime::Now().FormatTime().c_str(), m_i);
-static void TestArrayOfInts()
+ m_sem->Post();
+
+ return 0;
+ }
+
+private:
+ wxSemaphore *m_sem;
+ int m_i;
+};
+
+WX_DEFINE_ARRAY(wxThread *, ArrayThreads);
+
+static void TestSemaphore()
{
- puts("*** Testing wxArrayInt ***\n");
+ wxPuts(_T("*** Testing wxSemaphore class. ***"));
- wxArrayInt a;
- a.Add(1);
- a.Add(17);
- a.Add(5);
- a.Add(3);
+ static const int SEM_LIMIT = 3;
- puts("Initially:");
- PrintArray("a", a);
+ wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
+ ArrayThreads threads;
- puts("After sort:");
- a.Sort(IntCompare);
- PrintArray("a", a);
+ for ( int i = 0; i < 3*SEM_LIMIT; i++ )
+ {
+ threads.Add(new MySemaphoreThread(i, &sem));
+ threads.Last()->Run();
+ }
- puts("After reverse sort:");
- a.Sort(IntRevCompare);
- PrintArray("a", a);
+ for ( size_t n = 0; n < threads.GetCount(); n++ )
+ {
+ threads[n]->Wait();
+ delete threads[n];
+ }
}
+#endif // TEST_THREADS
+
+// ----------------------------------------------------------------------------
+// arrays
+// ----------------------------------------------------------------------------
+
+#ifdef TEST_ARRAYS
+
#include "wx/dynarray.h"
+#define DefineCompare(name, T) \
+ \
+int wxCMPFUNC_CONV name ## CompareValues(T first, T second) \
+{ \
+ return first - second; \
+} \
+ \
+int wxCMPFUNC_CONV name ## Compare(T* first, T* second) \
+{ \
+ return *first - *second; \
+} \
+ \
+int wxCMPFUNC_CONV name ## RevCompare(T* first, T* second) \
+{ \
+ return *second - *first; \
+} \
+
+DefineCompare(Short, short);
+DefineCompare(Int, int);
+
+// test compilation of all macros
+WX_DEFINE_ARRAY(short, wxArrayShort);
+WX_DEFINE_SORTED_ARRAY(short, wxSortedArrayShortNoCmp);
+WX_DEFINE_SORTED_ARRAY_CMP(short, ShortCompareValues, wxSortedArrayShort);
+WX_DEFINE_SORTED_ARRAY_CMP(int, IntCompareValues, wxSortedArrayInt);
+
WX_DECLARE_OBJARRAY(Bar, ArrayBars);
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(ArrayBars);
+static void PrintArray(const char* name, const wxArrayString& array)
+{
+ printf("Dump of the array '%s'\n", name);
+
+ size_t nCount = array.GetCount();
+ for ( size_t n = 0; n < nCount; n++ )
+ {
+ printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
+ }
+}
+
+int wxCMPFUNC_CONV StringLenCompare(const wxString& first,
+ const wxString& second)
+{
+ return first.length() - second.length();
+}
+
+#define TestArrayOf(name) \
+ \
+static void PrintArray(const char* name, const wxSortedArray##name & array) \
+{ \
+ printf("Dump of the array '%s'\n", name); \
+ \
+ size_t nCount = array.GetCount(); \
+ for ( size_t n = 0; n < nCount; n++ ) \
+ { \
+ printf("\t%s[%u] = %d\n", name, n, array[n]); \
+ } \
+} \
+ \
+static void PrintArray(const char* name, const wxArray##name & array) \
+{ \
+ printf("Dump of the array '%s'\n", name); \
+ \
+ size_t nCount = array.GetCount(); \
+ for ( size_t n = 0; n < nCount; n++ ) \
+ { \
+ printf("\t%s[%u] = %d\n", name, n, array[n]); \
+ } \
+} \
+ \
+static void TestArrayOf ## name ## s() \
+{ \
+ printf("*** Testing wxArray%s ***\n", #name); \
+ \
+ wxArray##name a; \
+ a.Add(1); \
+ a.Add(17); \
+ a.Add(5); \
+ a.Add(3); \
+ \
+ puts("Initially:"); \
+ PrintArray("a", a); \
+ \
+ puts("After sort:"); \
+ a.Sort(name ## Compare); \
+ PrintArray("a", a); \
+ \
+ puts("After reverse sort:"); \
+ a.Sort(name ## RevCompare); \
+ PrintArray("a", a); \
+ \
+ wxSortedArray##name b; \
+ b.Add(1); \
+ b.Add(17); \
+ b.Add(5); \
+ b.Add(3); \
+ \
+ puts("Sorted array initially:"); \
+ PrintArray("b", b); \
+}
+
+TestArrayOf(Short);
+TestArrayOf(Int);
+
static void TestArrayOfObjects()
{
puts("*** Testing wxObjArray ***\n");
puts("");
}
+static void TestStringMatch()
+{
+ wxPuts(_T("*** Testing wxString::Matches() ***"));
+
+ static const struct StringMatchTestData
+ {
+ const wxChar *text;
+ const wxChar *wildcard;
+ bool matches;
+ } stringMatchTestData[] =
+ {
+ { _T("foobar"), _T("foo*"), 1 },
+ { _T("foobar"), _T("*oo*"), 1 },
+ { _T("foobar"), _T("*bar"), 1 },
+ { _T("foobar"), _T("??????"), 1 },
+ { _T("foobar"), _T("f??b*"), 1 },
+ { _T("foobar"), _T("f?b*"), 0 },
+ { _T("foobar"), _T("*goo*"), 0 },
+ { _T("foobar"), _T("*foo"), 0 },
+ { _T("foobarfoo"), _T("*foo"), 1 },
+ { _T(""), _T("*"), 1 },
+ { _T(""), _T("?"), 0 },
+ };
+
+ for ( size_t n = 0; n < WXSIZEOF(stringMatchTestData); n++ )
+ {
+ const StringMatchTestData& data = stringMatchTestData[n];
+ bool matches = wxString(data.text).Matches(data.wildcard);
+ wxPrintf(_T("'%s' %s '%s' (%s)\n"),
+ data.wildcard,
+ matches ? _T("matches") : _T("doesn't match"),
+ data.text,
+ matches == data.matches ? _T("ok") : _T("ERROR"));
+ }
+
+ wxPuts(_T(""));
+}
+
#endif // TEST_STRINGS
// ----------------------------------------------------------------------------
// entry point
// ----------------------------------------------------------------------------
+#ifdef TEST_SNGLINST
+ #include "wx/snglinst.h"
+#endif // TEST_SNGLINST
+
int main(int argc, char **argv)
{
- if ( !wxInitialize() )
+ wxInitializer initializer;
+ if ( !initializer )
{
fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
+
+ return -1;
+ }
+
+#ifdef TEST_SNGLINST
+ wxSingleInstanceChecker checker;
+ if ( checker.Create(_T(".wxconsole.lock")) )
+ {
+ if ( checker.IsAnotherRunning() )
+ {
+ wxPrintf(_T("Another instance of the program is running, exiting.\n"));
+
+ return 1;
+ }
+
+ // wait some time to give time to launch another instance
+ wxPrintf(_T("Press \"Enter\" to continue..."));
+ wxFgetc(stdin);
+ }
+ else // failed to create
+ {
+ wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
}
+#endif // TEST_SNGLINST
#ifdef TEST_CHARSET
TestCharset();
#endif // TEST_CHARSET
#ifdef TEST_CMDLINE
+ TestCmdLineConvert();
+
+#if wxUSE_CMDLINE_PARSER
static const wxCmdLineEntryDesc cmdLineDesc[] =
{
+ { wxCMD_LINE_SWITCH, _T("h"), _T("help"), "show this help message",
+ wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
{ wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
{ wxCMD_LINE_OPTION, "o", "output", "output file" },
{ wxCMD_LINE_OPTION, "i", "input", "input dir" },
- { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
- { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
+ { wxCMD_LINE_OPTION, "s", "size", "output block size",
+ wxCMD_LINE_VAL_NUMBER },
+ { wxCMD_LINE_OPTION, "d", "date", "output file date",
+ wxCMD_LINE_VAL_DATE },
{ wxCMD_LINE_PARAM, NULL, NULL, "input file",
wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
wxLogMessage("Syntax error detected, aborting.");
break;
}
+#endif // wxUSE_CMDLINE_PARSER
+
#endif // TEST_CMDLINE
#ifdef TEST_STRINGS
- if ( 0 )
+ if ( TEST_ALL )
{
TestPChar();
TestString();
- }
TestStringSub();
- if ( 0 )
- {
TestStringConstruction();
TestStringFormat();
TestStringFind();
TestStringTokenizer();
TestStringReplace();
}
+ else
+ {
+ TestStringMatch();
+ }
#endif // TEST_STRINGS
#ifdef TEST_ARRAYS
- if ( 0 )
+ if ( TEST_ALL )
{
- wxArrayString a1;
- a1.Add("tiger");
- a1.Add("cat");
- a1.Add("lion");
- a1.Add("dog");
- a1.Add("human");
- a1.Add("ape");
+ wxArrayString a1;
+ a1.Add("tiger");
+ a1.Add("cat");
+ a1.Add("lion");
+ a1.Add("dog");
+ a1.Add("human");
+ a1.Add("ape");
- puts("*** Initially:");
+ puts("*** Initially:");
- PrintArray("a1", a1);
+ PrintArray("a1", a1);
- wxArrayString a2(a1);
- PrintArray("a2", a2);
+ wxArrayString a2(a1);
+ PrintArray("a2", a2);
- wxSortedArrayString a3(a1);
- PrintArray("a3", a3);
+ wxSortedArrayString a3(a1);
+ PrintArray("a3", a3);
- puts("*** After deleting a string from a1");
- a1.Remove(2);
+ puts("*** After deleting a string from a1");
+ a1.Remove(2);
- PrintArray("a1", a1);
- PrintArray("a2", a2);
- PrintArray("a3", a3);
+ PrintArray("a1", a1);
+ PrintArray("a2", a2);
+ PrintArray("a3", a3);
- puts("*** After reassigning a1 to a2 and a3");
- a3 = a2 = a1;
- PrintArray("a2", a2);
- PrintArray("a3", a3);
+ puts("*** After reassigning a1 to a2 and a3");
+ a3 = a2 = a1;
+ PrintArray("a2", a2);
+ PrintArray("a3", a3);
- puts("*** After sorting a1");
- a1.Sort();
- PrintArray("a1", a1);
+ puts("*** After sorting a1");
+ a1.Sort();
+ PrintArray("a1", a1);
- puts("*** After sorting a1 in reverse order");
- a1.Sort(TRUE);
- PrintArray("a1", a1);
+ puts("*** After sorting a1 in reverse order");
+ a1.Sort(TRUE);
+ PrintArray("a1", a1);
- puts("*** After sorting a1 by the string length");
- a1.Sort(StringLenCompare);
- PrintArray("a1", a1);
+ puts("*** After sorting a1 by the string length");
+ a1.Sort(StringLenCompare);
+ PrintArray("a1", a1);
- TestArrayOfObjects();
+ TestArrayOfObjects();
+ TestArrayOfShorts();
}
+
TestArrayOfInts();
#endif // TEST_ARRAYS
#ifdef TEST_DIR
- TestDirEnum();
+ if ( TEST_ALL )
+ {
+ TestDirEnum();
+ TestDirTraverse();
+ }
#endif // TEST_DIR
#ifdef TEST_DLLLOADER
#endif // TEST_LOG
#ifdef TEST_FILE
- if ( 0 )
+ if ( TEST_ALL )
{
TestFileRead();
TestTextFileRead();
+ TestFileCopy();
}
- TestFileCopy();
#endif // TEST_FILE
#ifdef TEST_FILENAME
- TestFileNameSplit();
if ( 0 )
+ {
+ wxFileName fn;
+ fn.Assign("c:\\foo", "bar.baz");
+
+ DumpFileName(fn);
+ }
+
+ if ( 1 )
{
TestFileNameConstruction();
+ TestFileNameMakeRelative();
+ TestFileNameSplit();
+ TestFileNameTemp();
TestFileNameCwd();
TestFileNameComparison();
TestFileNameOperations();
}
#endif // TEST_FILENAME
-#ifdef TEST_THREADS
- int nCPUs = wxThread::GetCPUCount();
- printf("This system has %d CPUs\n", nCPUs);
- if ( nCPUs != -1 )
- wxThread::SetConcurrency(nCPUs);
+#ifdef TEST_FILETIME
+ TestFileGetTimes();
+ TestFileSetTimes();
+#endif // TEST_FILETIME
- if ( argc > 1 && argv[1][0] == 't' )
- wxLog::AddTraceMask("thread");
+#ifdef TEST_FTP
+ wxLog::AddTraceMask(FTP_TRACE_MASK);
+ if ( TestFtpConnect() )
+ {
+ if ( TEST_ALL )
+ {
+ TestFtpList();
+ TestFtpDownload();
+ TestFtpMisc();
+ TestFtpFileSize();
+ TestFtpUpload();
+ }
- if ( 1 )
- TestDetachedThreads();
- if ( 1 )
- TestJoinableThreads();
- if ( 1 )
- TestThreadSuspend();
- if ( 1 )
- TestThreadDelete();
+ if ( TEST_INTERACTIVE )
+ TestFtpInteractive();
+ }
+ //else: connecting to the FTP server failed
-#endif // TEST_THREADS
+ if ( 0 )
+ TestFtpWuFtpd();
+#endif // TEST_FTP
#ifdef TEST_LONGLONG
// seed pseudo random generator
{
TestSpeed();
}
- if ( 0 )
+
+ if ( TEST_ALL )
{
TestMultiplication();
TestDivision();
TestAddition();
TestLongLongConversion();
TestBitOperations();
+ TestLongLongComparison();
+ TestLongLongPrint();
}
- TestLongLongComparison();
#endif // TEST_LONGLONG
#ifdef TEST_HASH
TestHash();
#endif // TEST_HASH
+#ifdef TEST_HASHMAP
+ TestHashMap();
+#endif // TEST_HASHMAP
+
#ifdef TEST_MIME
wxLog::AddTraceMask(_T("mime"));
- if ( 1 )
+ if ( TEST_ALL )
{
TestMimeEnum();
TestMimeOverride();
TestMimeFilename();
}
- else
- TestMimeAssociate();
+
+ TestMimeAssociate();
#endif // TEST_MIME
#ifdef TEST_INFO_FUNCTIONS
- TestOsInfo();
- TestUserInfo();
+ if ( TEST_ALL )
+ {
+ TestOsInfo();
+ TestUserInfo();
+
+ if ( TEST_INTERACTIVE )
+ TestDiskInfo();
+ }
#endif // TEST_INFO_FUNCTIONS
#ifdef TEST_PATHLIST
TestPathList();
#endif // TEST_PATHLIST
+#ifdef TEST_ODBC
+ TestDbOpen();
+#endif // TEST_ODBC
+
#ifdef TEST_REGCONF
TestRegConfWrite();
#endif // TEST_REGCONF
+#ifdef TEST_REGEX
+ // TODO: write a real test using src/regex/tests file
+ if ( TEST_ALL )
+ {
+ TestRegExCompile();
+ TestRegExMatch();
+ TestRegExSubmatch();
+ TestRegExReplacement();
+
+ if ( TEST_INTERACTIVE )
+ TestRegExInteractive();
+ }
+#endif // TEST_REGEX
+
#ifdef TEST_REGISTRY
- if ( 0 )
- TestRegistryRead();
+ TestRegistryRead();
TestRegistryAssociation();
#endif // TEST_REGISTRY
#ifdef TEST_SOCKETS
- if ( 0 )
- {
- TestSocketServer();
- }
- TestSocketClient();
+ TestSocketServer();
+ TestSocketClient();
#endif // TEST_SOCKETS
-#ifdef TEST_FTP
- wxLog::AddTraceMask(FTP_TRACE_MASK);
- if ( TestFtpConnect() )
- {
- TestFtpFileSize();
- if ( 0 )
- {
- TestFtpList();
- TestFtpDownload();
- TestFtpMisc();
- TestFtpUpload();
- }
- if ( 0 )
- TestFtpInteractive();
- }
- //else: connecting to the FTP server failed
-
- if ( 0 )
- TestFtpWuFtpd();
-#endif // TEST_FTP
-
#ifdef TEST_STREAMS
- if ( 0 )
TestFileStream();
TestMemoryStream();
#endif // TEST_STREAMS
+#ifdef TEST_THREADS
+ int nCPUs = wxThread::GetCPUCount();
+ printf("This system has %d CPUs\n", nCPUs);
+ if ( nCPUs != -1 )
+ wxThread::SetConcurrency(nCPUs);
+
+ if ( TEST_ALL )
+ {
+ TestDetachedThreads();
+ TestJoinableThreads();
+ TestThreadSuspend();
+ TestThreadDelete();
+ TestThreadConditions();
+ TestThreadExec();
+ }
+
+ TestSemaphore();
+#endif // TEST_THREADS
+
#ifdef TEST_TIMER
TestStopWatch();
#endif // TEST_TIMER
#ifdef TEST_DATETIME
- if ( 0 )
+ if ( TEST_ALL )
{
TestTimeSet();
TestTimeStatic();
TestTimeArithmetics();
TestTimeHolidays();
TestTimeFormat();
+ TestTimeSpanFormat();
TestTimeMS();
TestTimeZoneBug();
}
- TestTimeSpanFormat();
- if ( 0 )
+
+ if ( TEST_INTERACTIVE )
TestDateTimeInteractive();
#endif // TEST_DATETIME
#endif // TEST_USLEEP
#ifdef TEST_VCARD
- if ( 0 )
TestVCardRead();
TestVCardWrite();
#endif // TEST_VCARD
+#ifdef TEST_VOLUME
+ TestFSVolume();
+#endif // TEST_VOLUME
+
#ifdef TEST_WCHAR
TestUtf8();
+ TestEncodingConverter();
#endif // TEST_WCHAR
#ifdef TEST_ZIP
- if ( 0 )
- TestZipStreamRead();
+ TestZipStreamRead();
TestZipFileSystem();
#endif // TEST_ZIP
#ifdef TEST_ZLIB
- if ( 0 )
TestZlibStreamWrite();
TestZlibStreamRead();
#endif // TEST_ZLIB
- wxUninitialize();
-
return 0;
}