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