home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / samples / console / console.cpp next >
C/C++ Source or Header  |  2002-09-08  |  178KB  |  6,194 lines

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