X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/353f41cb3b49d4b49adaa6ee173a71bf75c17015..a2d541ca9c552d1a30ba75970968a7a220f4955a:/samples/console/console.cpp?ds=sidebyside diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 052ab5a0ee..edac5f6bf2 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -64,6 +64,7 @@ #define TEST_FILETIME #define TEST_FTP #define TEST_HASH + #define TEST_HASHMAP #define TEST_INFO_FUNCTIONS #define TEST_LIST #define TEST_LOCALE @@ -71,6 +72,7 @@ #define TEST_LONGLONG #define TEST_MIME #define TEST_PATHLIST + #define TEST_ODBC #define TEST_REGCONF #define TEST_REGEX #define TEST_REGISTRY @@ -81,6 +83,7 @@ #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 @@ -97,7 +100,7 @@ #ifdef TEST_INTERACTIVE #undef TEST_INTERACTIVE - static const bool TEST_INTERACTIVE = FALSE; + static const bool TEST_INTERACTIVE = TRUE; #else static const bool TEST_INTERACTIVE = FALSE; #endif @@ -181,11 +184,11 @@ 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()); } } @@ -765,8 +768,20 @@ static void DumpFileName(const wxFileName& fn) 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"), + wxPrintf(_T("'%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()); + + wxFileName::SplitPath(full, &path, &name, &ext); + wxPrintf(_T("or\t\t-> path '%s', name '%s', ext '%s'\n"), + path.c_str(), name.c_str(), ext.c_str()); + + wxPrintf(_T("path is also:\t'%s'\n"), fn.GetPath().c_str()); + wxPrintf(_T("with volume: \t'%s'\n"), + fn.GetPath(wxPATH_GET_VOLUME).c_str()); + wxPrintf(_T("with separator:\t'%s'\n"), + fn.GetPath(wxPATH_GET_SEPARATOR).c_str()); + wxPrintf(_T("with both: \t'%s'\n"), + fn.GetPath(wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME).c_str()); } static struct FileNameInfo @@ -799,6 +814,8 @@ static struct FileNameInfo { _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 }, @@ -806,6 +823,7 @@ static struct FileNameInfo { _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 }, @@ -828,7 +846,7 @@ static void TestFileNameConstruction() printf("ERROR: fullname should be '%s'\n", fni.fullname); } - bool isAbsolute = fn.IsAbsolute(); + bool isAbsolute = fn.IsAbsolute(fni.format); printf("'%s' is %s (%s)\n\t", fullname.c_str(), isAbsolute ? "absolute" : "relative", @@ -881,17 +899,25 @@ static void TestFileNameTemp() static const char *tmpprefixes[] = { + "", "foo", - "/tmp/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() ) + 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()); @@ -980,8 +1006,8 @@ static void TestFileGetTimes() { wxFileName fn(_T("testdata.fc")); - wxDateTime dtAccess, dtMod, dtChange; - if ( !fn.GetTimes(&dtAccess, &dtMod, &dtChange) ) + wxDateTime dtAccess, dtMod, dtCreate; + if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) ) { wxPrintf(_T("ERROR: GetTimes() failed.\n")); } @@ -990,9 +1016,9 @@ static void TestFileGetTimes() static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S"); wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str()); - wxPrintf(_T("Access: \t%s\n"), dtAccess.Format(fmt).c_str()); - wxPrintf(_T("Mod/creation:\t%s\n"), dtMod.Format(fmt).c_str()); - wxPrintf(_T("Change: \t%s\n"), dtChange.Format(fmt).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()); } } @@ -1094,6 +1120,152 @@ static void TestHash() #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 // ---------------------------------------------------------------------------- @@ -1554,9 +1726,9 @@ static void TestMimeAssociate() _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 @@ -1799,8 +1971,15 @@ static void TestDivision() // 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; @@ -2198,6 +2377,22 @@ static void TestRegExInteractive() #endif // TEST_REGEX +// ---------------------------------------------------------------------------- +// database +// ---------------------------------------------------------------------------- + +#ifdef TEST_ODBC + +#include + +static void TestDbOpen() +{ + HENV henv; + wxDb db(henv); +} + +#endif // TEST_ODBC + // ---------------------------------------------------------------------------- // registry and related stuff // ---------------------------------------------------------------------------- @@ -2849,18 +3044,28 @@ static void TestStopWatch() puts("*** Testing wxStopWatch ***\n"); wxStopWatch sw; - printf("Sleeping 3 seconds..."); + sw.Pause(); + printf("Initially paused, after 2 seconds time is..."); + fflush(stdout); + wxSleep(2); + printf("\t%ldms\n", sw.Time()); + + printf("Resuming stopwatch and sleeping 3 seconds..."); + fflush(stdout); + sw.Resume(); wxSleep(3); printf("\telapsed time: %ldms\n", sw.Time()); sw.Pause(); - printf("Sleeping 2 more seconds..."); + printf("Pausing agan and sleeping 2 more seconds..."); + fflush(stdout); wxSleep(2); printf("\telapsed time: %ldms\n", sw.Time()); sw.Resume(); - printf("And 3 more seconds..."); - wxSleep(3); + printf("Finally resuming and sleeping 2 more seconds..."); + fflush(stdout); + wxSleep(2); printf("\telapsed time: %ldms\n", sw.Time()); wxStopWatch sw2; @@ -2878,6 +3083,7 @@ static void TestStopWatch() } putchar('.'); + fflush(stdout); } puts(", ok."); @@ -3127,6 +3333,65 @@ static void TestVCardWrite() #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 // ---------------------------------------------------------------------------- @@ -3138,21 +3403,21 @@ static void TestVCardWrite() #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 ) @@ -3161,22 +3426,49 @@ static void TestUtf8() } 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 @@ -4363,7 +4655,7 @@ static void TestTimeCompatibility() static size_t gs_counter = (size_t)-1; static wxCriticalSection gs_critsect; -static wxCondition gs_cond; +static wxSemaphore gs_cond; class MyJoinableThread : public wxThread { @@ -4451,10 +4743,10 @@ void MyDetachedThread::OnExit() 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 ***"); @@ -4480,7 +4772,7 @@ void TestDetachedThreads() puts(""); } -void TestJoinableThreads() +static void TestJoinableThreads() { puts("\n*** Testing a joinable thread (a loooong calculation...) ***"); @@ -4492,7 +4784,7 @@ void TestJoinableThreads() (unsigned long)thread.Wait()); } -void TestThreadSuspend() +static void TestThreadSuspend() { puts("\n*** Testing thread suspend/resume functions ***"); @@ -4531,7 +4823,7 @@ void TestThreadSuspend() 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 @@ -4587,82 +4879,315 @@ void TestThreadDelete() 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"); @@ -5236,11 +5761,10 @@ int main(int argc, char **argv) PrintArray("a1", a1); TestArrayOfObjects(); + TestArrayOfShorts(); } - else - { - TestArrayOfInts(); - } + + TestArrayOfInts(); #endif // TEST_ARRAYS #ifdef TEST_DIR @@ -5304,7 +5828,7 @@ int main(int argc, char **argv) #endif // TEST_FILE #ifdef TEST_FILENAME - if ( 1 ) + if ( 0 ) { wxFileName fn; fn.Assign("c:\\foo", "bar.baz"); @@ -5351,26 +5875,6 @@ int main(int argc, char **argv) TestFtpWuFtpd(); #endif // TEST_FTP -#ifdef TEST_THREADS - int nCPUs = wxThread::GetCPUCount(); - printf("This system has %d CPUs\n", nCPUs); - if ( nCPUs != -1 ) - wxThread::SetConcurrency(nCPUs); - - if ( argc > 1 && argv[1][0] == 't' ) - wxLog::AddTraceMask("thread"); - - if ( 1 ) - TestDetachedThreads(); - if ( 1 ) - TestJoinableThreads(); - if ( 1 ) - TestThreadSuspend(); - if ( 1 ) - TestThreadDelete(); - -#endif // TEST_THREADS - #ifdef TEST_LONGLONG // seed pseudo random generator srand((unsigned)time(NULL)); @@ -5396,16 +5900,20 @@ int main(int argc, char **argv) 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 @@ -5413,7 +5921,9 @@ int main(int argc, char **argv) { TestOsInfo(); TestUserInfo(); - TestDiskInfo(); + + if ( TEST_INTERACTIVE ) + TestDiskInfo(); } #endif // TEST_INFO_FUNCTIONS @@ -5421,6 +5931,10 @@ int main(int argc, char **argv) TestPathList(); #endif // TEST_PATHLIST +#ifdef TEST_ODBC + TestDbOpen(); +#endif // TEST_ODBC + #ifdef TEST_REGCONF TestRegConfWrite(); #endif // TEST_REGCONF @@ -5454,6 +5968,25 @@ int main(int argc, char **argv) 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 @@ -5494,8 +6027,13 @@ int main(int argc, char **argv) TestVCardWrite(); #endif // TEST_VCARD +#ifdef TEST_VOLUME + TestFSVolume(); +#endif // TEST_VOLUME + #ifdef TEST_WCHAR TestUtf8(); + TestEncodingConverter(); #endif // TEST_WCHAR #ifdef TEST_ZIP