X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9fc3ad34c5326856aeebf02335244ae315cef688..9fb35cf18009442686df164132c451479c98d536:/samples/console/console.cpp diff --git a/samples/console/console.cpp b/samples/console/console.cpp index f72458ddd5..a60440aae9 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -30,9 +30,11 @@ // what to test? //#define TEST_ARRAYS +#define TEST_DIR //#define TEST_LOG +//#define TEST_MIME //#define TEST_STRINGS -#define TEST_THREADS +//#define TEST_THREADS //#define TEST_TIME //#define TEST_LONGLONG @@ -40,6 +42,133 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// wxDir +// ---------------------------------------------------------------------------- + +#ifdef TEST_DIR + +#include + +static void TestDirEnumHelper(wxDir& dir, + int flags = wxDIR_DEFAULT, + const wxString& filespec = wxEmptyString) +{ + wxString filename; + + if ( !dir.IsOpened() ) + return; + + bool cont = dir.GetFirst(&filename, filespec, flags); + while ( cont ) + { + printf("\t%s\n", filename.c_str()); + + cont = dir.GetNext(&filename); + } + + puts(""); +} + +static void TestDirEnum() +{ + wxDir dir(wxGetCwd()); + + puts("Enumerating everything in current directory:"); + TestDirEnumHelper(dir); + + puts("Enumerating really everything in current directory:"); + TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT); + + puts("Enumerating object files in current directory:"); + TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o"); + + puts("Enumerating directories in current directory:"); + TestDirEnumHelper(dir, wxDIR_DIRS); + + puts("Enumerating files in current directory:"); + TestDirEnumHelper(dir, wxDIR_FILES); + + 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 + + puts("Enumerating everything in root directory:"); + TestDirEnumHelper(dir, wxDIR_DEFAULT); + + puts("Enumerating directories in root directory:"); + TestDirEnumHelper(dir, wxDIR_DIRS); + + puts("Enumerating files in root directory:"); + TestDirEnumHelper(dir, wxDIR_FILES); + + puts("Enumerating files including hidden in root directory:"); + TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN); + + puts("Enumerating files in non existing directory:"); + wxDir dirNo("nosuchdir"); + TestDirEnumHelper(dirNo); +} + +#endif // TEST_DIR + +// ---------------------------------------------------------------------------- +// MIME types +// ---------------------------------------------------------------------------- + +#ifdef TEST_MIME + +#include + +static void TestMimeEnum() +{ + wxMimeTypesManager mimeTM; + wxArrayString mimetypes; + + size_t count = mimeTM.EnumAllFileTypes(mimetypes); + + printf("*** All %u known filetypes: ***\n", count); + + wxArrayString exts; + wxString desc; + + for ( size_t n = 0; n < count; n++ ) + { + wxFileType *filetype = mimeTM.GetFileTypeFromMimeType(mimetypes[n]); + if ( !filetype ) + { + printf("nothing known about the filetype '%s'!\n", + mimetypes[n].c_str()); + continue; + } + + filetype->GetDescription(&desc); + filetype->GetExtensions(exts); + + filetype->GetIcon(NULL); + + wxString extsAll; + for ( size_t e = 0; e < exts.GetCount(); e++ ) + { + if ( e > 0 ) + extsAll << _T(", "); + extsAll += exts[e]; + } + + printf("\t%s: %s (%s)\n", + mimetypes[n].c_str(), desc.c_str(), extsAll.c_str()); + } +} + +#endif // TEST_MIME + // ---------------------------------------------------------------------------- // long long // ---------------------------------------------------------------------------- @@ -93,9 +222,26 @@ static void TestSpeed() static void TestDivision() { - wxLongLong ll = 0x38417388; // some number < LONG_MAX + #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3) + + // seed pseudo random generator + //srand((unsigned)time(NULL)); + + size_t nTested = 0; + for ( size_t n = 0; n < 10000; n++ ) + { + // get a random wxLongLong (shifting by 12 the MSB ensures that the + // multiplication will not overflow) + wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand()); + + wxASSERT( (ll * 1000l)/1000l == ll ); + + nTested++; + } + + printf("\n*** Tested %u divisions/multiplications: ok\n", nTested); - wxASSERT( (ll / 1000l)*1000l == ll ); + #undef MAKE_LL } #endif // TEST_LONGLONG @@ -108,6 +254,224 @@ static void TestDivision() #include +// the test data +struct Date +{ + wxDateTime::wxDateTime_t day; + wxDateTime::Month month; + int year; + wxDateTime::wxDateTime_t hour, min, sec; + double jdn; + time_t gmticks, ticks; + + void Init(const wxDateTime::Tm& tm) + { + day = tm.mday; + month = tm.mon; + year = tm.year; + hour = tm.hour; + min = tm.min; + sec = tm.sec; + jdn = 0.0; + gmticks = ticks = -1; + } + + wxDateTime DT() const + { return wxDateTime(day, month, year, hour, min, sec); } + + wxString Format() const + { + wxString s; + s.Printf("%02d:%02d:%02d %10s %02d, %4d%s", + hour, min, sec, + wxDateTime::GetMonthName(month).c_str(), + day, + abs(wxDateTime::ConvertYearToBC(year)), + year > 0 ? "AD" : "BC"); + return s; + } +}; + +static const Date testDates[] = +{ + { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, 0, -3600 }, + { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, -1, -1 }, + { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, 202219200, 202212000 }, + { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, 194400000, 194396400 }, + { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, -1, -1 }, + { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, -1, -1 }, + { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, -1, -1 }, + { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, -1, -1 }, + { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, -1, -1 }, + { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, -1, -1 }, + { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, -1, -1 }, + { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, -1, -1 }, + { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, -1, -1 }, + { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, -1, -1 }, + { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, -1, -1 }, +}; + +// this test miscellaneous static wxDateTime functions +static void TestTimeStatic() +{ + puts("\n*** wxDateTime static methods test ***"); + + // some info about the current date + int year = wxDateTime::GetCurrentYear(); + printf("Current year %d is %sa leap one and has %d days.\n", + year, + wxDateTime::IsLeapYear(year) ? "" : "not ", + wxDateTime::GetNumberOfDays(year)); + + wxDateTime::Month month = wxDateTime::GetCurrentMonth(); + printf("Current month is '%s' ('%s') and it has %d days\n", + wxDateTime::GetMonthName(month, TRUE).c_str(), + wxDateTime::GetMonthName(month).c_str(), + wxDateTime::GetNumberOfDays(month)); + + // leap year logic + static const size_t nYears = 5; + static const size_t years[2][nYears] = + { + // first line: the years to test + { 1990, 1976, 2000, 2030, 1984, }, + + // second line: TRUE if leap, FALSE otherwise + { FALSE, TRUE, TRUE, FALSE, TRUE } + }; + + for ( size_t n = 0; n < nYears; n++ ) + { + int year = years[0][n]; + bool should = years[1][n] != 0; + + printf("Year %d is %sa leap year (should be: %s)\n", + year, + wxDateTime::IsLeapYear(year) ? "" : "not ", + should ? "yes" : "no"); + + wxASSERT( should == wxDateTime::IsLeapYear(year) ); + } +} + +// test constructing wxDateTime objects +static void TestTimeSet() +{ + puts("\n*** wxDateTime construction test ***"); + + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d1 = testDates[n]; + wxDateTime dt = d1.DT(); + + Date d2; + d2.Init(dt.GetTm()); + + wxString s1 = d1.Format(), + s2 = d2.Format(); + + printf("Date: %s == %s (%s)\n", + s1.c_str(), s2.c_str(), + s1 == s2 ? "ok" : "ERROR"); + } +} + +// test time zones stuff +static void TestTimeZones() +{ + puts("\n*** wxDateTime timezone test ***"); + + wxDateTime now = wxDateTime::Now(); + + printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str()); + printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str()); + printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str()); + printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str()); + printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str()); + printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str()); +} + +// test some minimal support for the dates outside the standard range +static void TestTimeRange() +{ + puts("\n*** wxDateTime out-of-standard-range dates test ***"); + + printf("Unix epoch:\t%s\n", + wxDateTime(2440587.5).Format().c_str()); + printf("Feb 29, 0: \t%s\n", + wxDateTime(29, wxDateTime::Feb, 0).Format().c_str()); + printf("JDN 0: \t%s\n", + wxDateTime(0.0).Format().c_str()); + printf("Jan 1, 1AD:\t%s\n", + wxDateTime(1, wxDateTime::Jan, 1).Format().c_str()); + printf("May 29, 2099:\t%s\n", + wxDateTime(29, wxDateTime::May, 2099).Format().c_str()); +} + +static void TestTimeTicks() +{ + puts("\n*** wxDateTime ticks test ***"); + + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d = testDates[n]; + if ( d.ticks == -1 ) + continue; + + wxDateTime dt = d.DT(); + long ticks = (dt.GetValue() / 1000).ToLong(); + printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks); + if ( ticks == d.ticks ) + { + puts(" (ok)"); + } + else + { + printf(" (ERROR: should be %ld, delta = %ld)\n", + d.ticks, ticks - d.ticks); + } + + dt = d.DT().ToTimezone(wxDateTime::GMT0); + ticks = (dt.GetValue() / 1000).ToLong(); + printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks); + if ( ticks == d.gmticks ) + { + puts(" (ok)"); + } + else + { + printf(" (ERROR: should be %ld, delta = %ld)\n", + d.gmticks, ticks - d.gmticks); + } + } + + puts(""); +} + +// test conversions to JDN &c +static void TestTimeJDN() +{ + puts("\n*** wxDateTime to JDN test ***"); + + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d = testDates[n]; + wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec); + double jdn = dt.GetJulianDayNumber(); + + printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn); + if ( jdn == d.jdn ) + { + puts(" (ok)"); + } + else + { + printf(" (ERROR: should be %f, delta = %f)\n", + d.jdn, jdn - d.jdn); + } + } +} + #endif // TEST_TIME // ---------------------------------------------------------------------------- @@ -152,7 +516,14 @@ wxThread::ExitCode MyJoinableThread::Entry() class MyDetachedThread : public wxThread { public: - MyDetachedThread(size_t n, char ch) { m_n = n; m_ch = ch; Create(); } + MyDetachedThread(size_t n, char ch) + { + m_n = n; + m_ch = ch; + m_cancelled = FALSE; + + Create(); + } // thread execution starts here virtual ExitCode Entry(); @@ -163,6 +534,8 @@ public: private: size_t m_n; // number of characters to write char m_ch; // character to write + + bool m_cancelled; // FALSE if we exit normally }; wxThread::ExitCode MyDetachedThread::Entry() @@ -178,7 +551,11 @@ wxThread::ExitCode MyDetachedThread::Entry() for ( size_t n = 0; n < m_n; n++ ) { if ( TestDestroy() ) + { + m_cancelled = TRUE; + break; + } putchar(m_ch); fflush(stdout); @@ -194,13 +571,13 @@ void MyDetachedThread::OnExit() wxLogTrace("thread", "Thread %ld is in OnExit", GetId()); wxCriticalSectionLocker lock(gs_critsect); - if ( !--gs_counter ) + if ( !--gs_counter && !m_cancelled ) gs_cond.Signal(); } void TestDetachedThreads() { - puts("*** Testing detached threads ***"); + puts("\n*** Testing detached threads ***"); static const size_t nThreads = 3; MyDetachedThread *threads[nThreads]; @@ -226,7 +603,7 @@ void TestDetachedThreads() void TestJoinableThreads() { - puts("*** Testing a joinable thread (a loooong calculation...) ***"); + puts("\n*** Testing a joinable thread (a loooong calculation...) ***"); // calc 10! in the background MyJoinableThread thread(10); @@ -238,7 +615,9 @@ void TestJoinableThreads() void TestThreadSuspend() { - MyDetachedThread *thread = new MyDetachedThread(30, 'X'); + puts("\n*** Testing thread suspend/resume functions ***"); + + MyDetachedThread *thread = new MyDetachedThread(15, 'X'); thread->Run(); @@ -265,12 +644,70 @@ void TestThreadSuspend() thread->Resume(); } + puts("Waiting until it terminates now"); + // wait until the thread terminates gs_cond.Wait(); puts(""); } +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 + // running when we delete it - deleting a detached thread which already + // terminated will lead to a crash! + + puts("\n*** Testing thread delete function ***"); + + MyDetachedThread *thread0 = new MyDetachedThread(30, 'W'); + + thread0->Delete(); + + puts("\nDeleted a thread which didn't start to run yet."); + + MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y'); + + thread1->Run(); + + wxThread::Sleep(300); + + thread1->Delete(); + + puts("\nDeleted a running thread."); + + MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z'); + + thread2->Run(); + + wxThread::Sleep(300); + + thread2->Pause(); + + thread2->Delete(); + + puts("\nDeleted a sleeping thread."); + + MyJoinableThread thread3(20); + thread3.Run(); + + thread3.Delete(); + + puts("\nDeleted a joinable thread."); + + MyJoinableThread thread4(2); + thread4.Run(); + + wxThread::Sleep(300); + + thread4.Delete(); + + puts("\nDeleted a joinable thread which already terminated."); + + puts(""); +} + #endif // TEST_THREADS // ---------------------------------------------------------------------------- @@ -300,7 +737,7 @@ void PrintArray(const char* name, const wxArrayString& array) #include "wx/timer.h" -void TestString() +static void TestString() { wxStopWatch sw; @@ -325,7 +762,7 @@ void TestString() printf ("TestString elapsed time: %ld\n", sw.Time()); } -void TestPChar() +static void TestPChar() { wxStopWatch sw; @@ -348,6 +785,23 @@ void TestPChar() printf ("TestPChar elapsed time: %ld\n", sw.Time()); } +static void TestStringSub() +{ + wxString s("Hello, world!"); + + puts("*** Testing wxString substring extraction ***"); + + printf("String = '%s'\n", s.c_str()); + printf("Left(5) = '%s'\n", s.Left(5).c_str()); + printf("Right(6) = '%s'\n", s.Right(6).c_str()); + printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str()); + printf("Mid(3) = '%s'\n", s.Mid(3).c_str()); + printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str()); + printf("substr(3) = '%s'\n", s.substr(3).c_str()); + + puts(""); +} + #endif // TEST_STRINGS // ---------------------------------------------------------------------------- @@ -362,8 +816,12 @@ int main(int argc, char **argv) } #ifdef TEST_STRINGS - TestPChar(); - TestString(); + if ( 0 ) + { + TestPChar(); + TestString(); + } + TestStringSub(); #endif // TEST_STRINGS #ifdef TEST_ARRAYS @@ -398,6 +856,10 @@ int main(int argc, char **argv) PrintArray("a3", a3); #endif // TEST_ARRAYS +#ifdef TEST_DIR + TestDirEnum(); +#endif // TEST_DIR + #ifdef TEST_LOG wxString s; for ( size_t n = 0; n < 8000; n++ ) @@ -418,15 +880,23 @@ int main(int argc, char **argv) #endif // TEST_LOG #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"); - TestThreadSuspend(); - if ( 0 ) - { - TestDetachedThreads(); - TestJoinableThreads(); - } + if ( 1 ) + TestDetachedThreads(); + if ( 1 ) + TestJoinableThreads(); + if ( 1 ) + TestThreadSuspend(); + if ( 1 ) + TestThreadDelete(); + #endif // TEST_THREADS #ifdef TEST_LONGLONG @@ -436,12 +906,20 @@ int main(int argc, char **argv) TestDivision(); #endif // TEST_LONGLONG +#ifdef TEST_MIME + TestMimeEnum(); +#endif // TEST_MIME + #ifdef TEST_TIME - wxDateTime time = wxDateTime::Now(); - printf("Current time: '%s', current year %u is %sa leap one", - time.Format().c_str(), - time.GetYear(), - wxDateTime::IsLeapYear(time.GetYear()) ? "" : "not"); + TestTimeSet(); + if ( 0 ) + { + TestTimeStatic(); + TestTimeZones(); + TestTimeRange(); + TestTimeTicks(); + } + TestTimeJDN(); #endif // TEST_TIME wxUninitialize();