1/////////////////////////////////////////////////////////////////////////////
2// Name:        samples/console/console.cpp
3// Purpose:     A sample console (as opposed to GUI) program using wxWidgets
4// Author:      Vadim Zeitlin
5// Modified by:
6// Created:     04.10.99
7// RCS-ID:      $Id: console.cpp 43361 2006-11-12 19:55:19Z VZ $
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#include <stdio.h>
23
24#include "wx/string.h"
25#include "wx/file.h"
26#include "wx/app.h"
27#include "wx/log.h"
28#include "wx/apptrait.h"
29#include "wx/platinfo.h"
30
31// without this pragma, the stupid compiler precompiles #defines below so that
32// changing them doesn't "take place" later!
33#ifdef __VISUALC__
34    #pragma hdrstop
35#endif
36
37// ----------------------------------------------------------------------------
38// conditional compilation
39// ----------------------------------------------------------------------------
40
41/*
42   A note about all these conditional compilation macros: this file is used
43   both as a test suite for various non-GUI wxWidgets classes and as a
44   scratchpad for quick tests. So there are two compilation modes: if you
45   define TEST_ALL all tests are run, otherwise you may enable the individual
46   tests individually in the "#else" branch below.
47 */
48
49// what to test (in alphabetic order)? Define TEST_ALL to 0 to do a single
50// test, define it to 1 to do all tests.
51#define TEST_ALL 0
52
53
54#if TEST_ALL
55    #define TEST_CMDLINE
56    #define TEST_DATETIME
57    #define TEST_DIR
58    #define TEST_DYNLIB
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  --FIXME! (RN)
66    #define TEST_INFO_FUNCTIONS
67    #define TEST_LOCALE
68    #define TEST_LOG
69    #define TEST_MIME
70    #define TEST_MODULE
71    #define TEST_PATHLIST
72    #define TEST_ODBC
73    #define TEST_PRINTF
74    #define TEST_REGCONF
75    #define TEST_REGEX
76    #define TEST_REGISTRY
77    #define TEST_SCOPEGUARD
78    #define TEST_SNGLINST
79//    #define TEST_SOCKETS  --FIXME! (RN)
80    #define TEST_STACKWALKER
81    #define TEST_STDPATHS
82    #define TEST_STREAMS
83    #define TEST_TEXTSTREAM
84    #define TEST_THREADS
85    #define TEST_TIMER
86    // #define TEST_VCARD            -- don't enable this (VZ)
87//    #define TEST_VOLUME   --FIXME! (RN)
88    #define TEST_WCHAR
89    #define TEST_ZIP
90#else // #if TEST_ALL
91    #define TEST_STDPATHS
92#endif
93
94// some tests are interactive, define this to run them
95#ifdef TEST_INTERACTIVE
96    #undef TEST_INTERACTIVE
97
98    #define TEST_INTERACTIVE 1
99#else
100    #define TEST_INTERACTIVE 0
101#endif
102
103// ============================================================================
104// implementation
105// ============================================================================
106
107// ----------------------------------------------------------------------------
108// helper functions
109// ----------------------------------------------------------------------------
110
111#if defined(TEST_SOCKETS)
112
113// replace TABs with \t and CRs with \n
114static wxString MakePrintable(const wxChar *s)
115{
116    wxString str(s);
117    (void)str.Replace(_T("\t"), _T("\\t"));
118    (void)str.Replace(_T("\n"), _T("\\n"));
119    (void)str.Replace(_T("\r"), _T("\\r"));
120
121    return str;
122}
123
124#endif // MakePrintable() is used
125
126// ----------------------------------------------------------------------------
127// wxCmdLineParser
128// ----------------------------------------------------------------------------
129
130#ifdef TEST_CMDLINE
131
132#include "wx/cmdline.h"
133#include "wx/datetime.h"
134
135#if wxUSE_CMDLINE_PARSER
136
137static void ShowCmdLine(const wxCmdLineParser& parser)
138{
139    wxString s = _T("Command line parsed successfully:\nInput files: ");
140
141    size_t count = parser.GetParamCount();
142    for ( size_t param = 0; param < count; param++ )
143    {
144        s << parser.GetParam(param) << ' ';
145    }
146
147    s << '\n'
148      << _T("Verbose:\t") << (parser.Found(_T("v")) ? _T("yes") : _T("no")) << '\n'
149      << _T("Quiet:\t") << (parser.Found(_T("q")) ? _T("yes") : _T("no")) << '\n';
150
151    wxString strVal;
152    long lVal;
153    wxDateTime dt;
154    if ( parser.Found(_T("o"), &strVal) )
155        s << _T("Output file:\t") << strVal << '\n';
156    if ( parser.Found(_T("i"), &strVal) )
157        s << _T("Input dir:\t") << strVal << '\n';
158    if ( parser.Found(_T("s"), &lVal) )
159        s << _T("Size:\t") << lVal << '\n';
160    if ( parser.Found(_T("d"), &dt) )
161        s << _T("Date:\t") << dt.FormatISODate() << '\n';
162    if ( parser.Found(_T("project_name"), &strVal) )
163        s << _T("Project:\t") << strVal << '\n';
164
165    wxLogMessage(s);
166}
167
168#endif // wxUSE_CMDLINE_PARSER
169
170static void TestCmdLineConvert()
171{
172    static const wxChar *cmdlines[] =
173    {
174        _T("arg1 arg2"),
175        _T("-a \"-bstring 1\" -c\"string 2\" \"string 3\""),
176        _T("literal \\\" and \"\""),
177    };
178
179    for ( size_t n = 0; n < WXSIZEOF(cmdlines); n++ )
180    {
181        const wxChar *cmdline = cmdlines[n];
182        wxPrintf(_T("Parsing: %s\n"), cmdline);
183        wxArrayString args = wxCmdLineParser::ConvertStringToArgs(cmdline);
184
185        size_t count = args.GetCount();
186        wxPrintf(_T("\targc = %u\n"), count);
187        for ( size_t arg = 0; arg < count; arg++ )
188        {
189            wxPrintf(_T("\targv[%u] = %s\n"), arg, args[arg].c_str());
190        }
191    }
192}
193
194#endif // TEST_CMDLINE
195
196// ----------------------------------------------------------------------------
197// wxDir
198// ----------------------------------------------------------------------------
199
200#ifdef TEST_DIR
201
202#include "wx/dir.h"
203
204#ifdef __UNIX__
205    static const wxChar *ROOTDIR = _T("/");
206    static const wxChar *TESTDIR = _T("/usr/local/share");
207#elif defined(__WXMSW__) || defined(__DOS__) || defined(__OS2__)
208    static const wxChar *ROOTDIR = _T("c:\\");
209    static const wxChar *TESTDIR = _T("d:\\");
210#else
211    #error "don't know where the root directory is"
212#endif
213
214static void TestDirEnumHelper(wxDir& dir,
215                              int flags = wxDIR_DEFAULT,
216                              const wxString& filespec = wxEmptyString)
217{
218    wxString filename;
219
220    if ( !dir.IsOpened() )
221        return;
222
223    bool cont = dir.GetFirst(&filename, filespec, flags);
224    while ( cont )
225    {
226        wxPrintf(_T("\t%s\n"), filename.c_str());
227
228        cont = dir.GetNext(&filename);
229    }
230
231    wxPuts(wxEmptyString);
232}
233
234#if TEST_ALL
235
236static void TestDirEnum()
237{
238    wxPuts(_T("*** Testing wxDir::GetFirst/GetNext ***"));
239
240    wxString cwd = wxGetCwd();
241    if ( !wxDir::Exists(cwd) )
242    {
243        wxPrintf(_T("ERROR: current directory '%s' doesn't exist?\n"), cwd.c_str());
244        return;
245    }
246
247    wxDir dir(cwd);
248    if ( !dir.IsOpened() )
249    {
250        wxPrintf(_T("ERROR: failed to open current directory '%s'.\n"), cwd.c_str());
251        return;
252    }
253
254    wxPuts(_T("Enumerating everything in current directory:"));
255    TestDirEnumHelper(dir);
256
257    wxPuts(_T("Enumerating really everything in current directory:"));
258    TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
259
260    wxPuts(_T("Enumerating object files in current directory:"));
261    TestDirEnumHelper(dir, wxDIR_DEFAULT, _T("*.o*"));
262
263    wxPuts(_T("Enumerating directories in current directory:"));
264    TestDirEnumHelper(dir, wxDIR_DIRS);
265
266    wxPuts(_T("Enumerating files in current directory:"));
267    TestDirEnumHelper(dir, wxDIR_FILES);
268
269    wxPuts(_T("Enumerating files including hidden in current directory:"));
270    TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
271
272    dir.Open(ROOTDIR);
273
274    wxPuts(_T("Enumerating everything in root directory:"));
275    TestDirEnumHelper(dir, wxDIR_DEFAULT);
276
277    wxPuts(_T("Enumerating directories in root directory:"));
278    TestDirEnumHelper(dir, wxDIR_DIRS);
279
280    wxPuts(_T("Enumerating files in root directory:"));
281    TestDirEnumHelper(dir, wxDIR_FILES);
282
283    wxPuts(_T("Enumerating files including hidden in root directory:"));
284    TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
285
286    wxPuts(_T("Enumerating files in non existing directory:"));
287    wxDir dirNo(_T("nosuchdir"));
288    TestDirEnumHelper(dirNo);
289}
290
291#endif // TEST_ALL
292
293class DirPrintTraverser : public wxDirTraverser
294{
295public:
296    virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
297    {
298        return wxDIR_CONTINUE;
299    }
300
301    virtual wxDirTraverseResult OnDir(const wxString& dirname)
302    {
303        wxString path, name, ext;
304        wxSplitPath(dirname, &path, &name, &ext);
305
306        if ( !ext.empty() )
307            name << _T('.') << ext;
308
309        wxString indent;
310        for ( const wxChar *p = path.c_str(); *p; p++ )
311        {
312            if ( wxIsPathSeparator(*p) )
313                indent += _T("    ");
314        }
315
316        wxPrintf(_T("%s%s\n"), indent.c_str(), name.c_str());
317
318        return wxDIR_CONTINUE;
319    }
320};
321
322static void TestDirTraverse()
323{
324    wxPuts(_T("*** Testing wxDir::Traverse() ***"));
325
326    // enum all files
327    wxArrayString files;
328    size_t n = wxDir::GetAllFiles(TESTDIR, &files);
329    wxPrintf(_T("There are %u files under '%s'\n"), n, TESTDIR);
330    if ( n > 1 )
331    {
332        wxPrintf(_T("First one is '%s'\n"), files[0u].c_str());
333        wxPrintf(_T(" last one is '%s'\n"), files[n - 1].c_str());
334    }
335
336    // enum again with custom traverser
337    wxPuts(_T("Now enumerating directories:"));
338    wxDir dir(TESTDIR);
339    DirPrintTraverser traverser;
340    dir.Traverse(traverser, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN);
341}
342
343#if TEST_ALL
344
345static void TestDirExists()
346{
347    wxPuts(_T("*** Testing wxDir::Exists() ***"));
348
349    static const wxChar *dirnames[] =
350    {
351        _T("."),
352#if defined(__WXMSW__)
353        _T("c:"),
354        _T("c:\\"),
355        _T("\\\\share\\file"),
356        _T("c:\\dos"),
357        _T("c:\\dos\\"),
358        _T("c:\\dos\\\\"),
359        _T("c:\\autoexec.bat"),
360#elif defined(__UNIX__)
361        _T("/"),
362        _T("//"),
363        _T("/usr/bin"),
364        _T("/usr//bin"),
365        _T("/usr///bin"),
366#endif
367    };
368
369    for ( size_t n = 0; n < WXSIZEOF(dirnames); n++ )
370    {
371        wxPrintf(_T("%-40s: %s\n"),
372                 dirnames[n],
373                 wxDir::Exists(dirnames[n]) ? _T("exists")
374                                            : _T("doesn't exist"));
375    }
376}
377
378#endif // TEST_ALL
379
380#endif // TEST_DIR
381
382// ----------------------------------------------------------------------------
383// wxDllLoader
384// ----------------------------------------------------------------------------
385
386#ifdef TEST_DYNLIB
387
388#include "wx/dynlib.h"
389
390static void TestDllLoad()
391{
392#if defined(__WXMSW__)
393    static const wxChar *LIB_NAME = _T("kernel32.dll");
394    static const wxChar *FUNC_NAME = _T("lstrlenA");
395#elif defined(__UNIX__)
396    // weird: using just libc.so does *not* work!
397    static const wxChar *LIB_NAME = _T("/lib/libc.so.6");
398    static const wxChar *FUNC_NAME = _T("strlen");
399#else
400    #error "don't know how to test wxDllLoader on this platform"
401#endif
402
403    wxPuts(_T("*** testing basic wxDynamicLibrary functions ***\n"));
404
405    wxDynamicLibrary lib(LIB_NAME);
406    if ( !lib.IsLoaded() )
407    {
408        wxPrintf(_T("ERROR: failed to load '%s'.\n"), LIB_NAME);
409    }
410    else
411    {
412        typedef int (wxSTDCALL *wxStrlenType)(const char *);
413        wxStrlenType pfnStrlen = (wxStrlenType)lib.GetSymbol(FUNC_NAME);
414        if ( !pfnStrlen )
415        {
416            wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
417                     FUNC_NAME, LIB_NAME);
418        }
419        else
420        {
421            wxPrintf(_T("Calling %s dynamically loaded from %s "),
422                     FUNC_NAME, LIB_NAME);
423
424            if ( pfnStrlen("foo") != 3 )
425            {
426                wxPrintf(_T("ERROR: loaded function is not wxStrlen()!\n"));
427            }
428            else
429            {
430                wxPuts(_T("... ok"));
431            }
432        }
433
434#ifdef __WXMSW__
435        static const wxChar *FUNC_NAME_AW = _T("lstrlen");
436
437        typedef int (wxSTDCALL *wxStrlenTypeAorW)(const wxChar *);
438        wxStrlenTypeAorW
439            pfnStrlenAorW = (wxStrlenTypeAorW)lib.GetSymbolAorW(FUNC_NAME_AW);
440        if ( !pfnStrlenAorW )
441        {
442            wxPrintf(_T("ERROR: function '%s' wasn't found in '%s'.\n"),
443                     FUNC_NAME_AW, LIB_NAME);
444        }
445        else
446        {
447            if ( pfnStrlenAorW(_T("foobar")) != 6 )
448            {
449                wxPrintf(_T("ERROR: loaded function is not wxStrlen()!\n"));
450            }
451        }
452#endif // __WXMSW__
453    }
454}
455
456#if defined(__WXMSW__) || defined(__UNIX__)
457
458static void TestDllListLoaded()
459{
460    wxPuts(_T("*** testing wxDynamicLibrary::ListLoaded() ***\n"));
461
462    puts("\nLoaded modules:");
463    wxDynamicLibraryDetailsArray dlls = wxDynamicLibrary::ListLoaded();
464    const size_t count = dlls.GetCount();
465    for ( size_t n = 0; n < count; ++n )
466    {
467        const wxDynamicLibraryDetails& details = dlls[n];
468        printf("%-45s", details.GetPath().mb_str());
469
470        void *addr;
471        size_t len;
472        if ( details.GetAddress(&addr, &len) )
473        {
474            printf(" %08lx:%08lx",
475                   (unsigned long)addr, (unsigned long)((char *)addr + len));
476        }
477
478        printf(" %s\n", details.GetVersion().mb_str());
479    }
480}
481
482#endif
483
484#endif // TEST_DYNLIB
485
486// ----------------------------------------------------------------------------
487// wxGet/SetEnv
488// ----------------------------------------------------------------------------
489
490#ifdef TEST_ENVIRON
491
492#include "wx/utils.h"
493
494static wxString MyGetEnv(const wxString& var)
495{
496    wxString val;
497    if ( !wxGetEnv(var, &val) )
498        val = _T("<empty>");
499    else
500        val = wxString(_T('\'')) + val + _T('\'');
501
502    return val;
503}
504
505static void TestEnvironment()
506{
507    const wxChar *var = _T("wxTestVar");
508
509    wxPuts(_T("*** testing environment access functions ***"));
510
511    wxPrintf(_T("Initially getenv(%s) = %s\n"), var, MyGetEnv(var).c_str());
512    wxSetEnv(var, _T("value for wxTestVar"));
513    wxPrintf(_T("After wxSetEnv: getenv(%s) = %s\n"),  var, MyGetEnv(var).c_str());
514    wxSetEnv(var, _T("another value"));
515    wxPrintf(_T("After 2nd wxSetEnv: getenv(%s) = %s\n"),  var, MyGetEnv(var).c_str());
516    wxUnsetEnv(var);
517    wxPrintf(_T("After wxUnsetEnv: getenv(%s) = %s\n"),  var, MyGetEnv(var).c_str());
518    wxPrintf(_T("PATH = %s\n"),  MyGetEnv(_T("PATH")).c_str());
519}
520
521#endif // TEST_ENVIRON
522
523// ----------------------------------------------------------------------------
524// wxExecute
525// ----------------------------------------------------------------------------
526
527#ifdef TEST_EXECUTE
528
529#include "wx/utils.h"
530
531static void TestExecute()
532{
533    wxPuts(_T("*** testing wxExecute ***"));
534
535#ifdef __UNIX__
536    #define COMMAND "cat -n ../../Makefile" // "echo hi"
537    #define SHELL_COMMAND "echo hi from shell"
538    #define REDIRECT_COMMAND COMMAND // "date"
539#elif defined(__WXMSW__)
540    #define COMMAND "command.com /c echo hi"
541    #define SHELL_COMMAND "echo hi"
542    #define REDIRECT_COMMAND COMMAND
543#else
544    #error "no command to exec"
545#endif // OS
546
547    wxPrintf(_T("Testing wxShell: "));
548    fflush(stdout);
549    if ( wxShell(_T(SHELL_COMMAND)) )
550        wxPuts(_T("Ok."));
551    else
552        wxPuts(_T("ERROR."));
553
554    wxPrintf(_T("Testing wxExecute: "));
555    fflush(stdout);
556    if ( wxExecute(_T(COMMAND), true /* sync */) == 0 )
557        wxPuts(_T("Ok."));
558    else
559        wxPuts(_T("ERROR."));
560
561#if 0 // no, it doesn't work (yet?)
562    wxPrintf(_T("Testing async wxExecute: "));
563    fflush(stdout);
564    if ( wxExecute(COMMAND) != 0 )
565        wxPuts(_T("Ok (command launched)."));
566    else
567        wxPuts(_T("ERROR."));
568#endif // 0
569
570    wxPrintf(_T("Testing wxExecute with redirection:\n"));
571    wxArrayString output;
572    if ( wxExecute(_T(REDIRECT_COMMAND), output) != 0 )
573    {
574        wxPuts(_T("ERROR."));
575    }
576    else
577    {
578        size_t count = output.GetCount();
579        for ( size_t n = 0; n < count; n++ )
580        {
581            wxPrintf(_T("\t%s\n"), output[n].c_str());
582        }
583
584        wxPuts(_T("Ok."));
585    }
586}
587
588#endif // TEST_EXECUTE
589
590// ----------------------------------------------------------------------------
591// file
592// ----------------------------------------------------------------------------
593
594#ifdef TEST_FILE
595
596#include "wx/file.h"
597#include "wx/ffile.h"
598#include "wx/textfile.h"
599
600static void TestFileRead()
601{
602    wxPuts(_T("*** wxFile read test ***"));
603
604    wxFile file(_T("testdata.fc"));
605    if ( file.IsOpened() )
606    {
607        wxPrintf(_T("File length: %lu\n"), file.Length());
608
609        wxPuts(_T("File dump:\n----------"));
610
611        static const size_t len = 1024;
612        wxChar buf[len];
613        for ( ;; )
614        {
615            size_t nRead = file.Read(buf, len);
616            if ( nRead == (size_t)wxInvalidOffset )
617            {
618                wxPrintf(_T("Failed to read the file."));
619                break;
620            }
621
622            fwrite(buf, nRead, 1, stdout);
623
624            if ( nRead < len )
625                break;
626        }
627
628        wxPuts(_T("----------"));
629    }
630    else
631    {
632        wxPrintf(_T("ERROR: can't open test file.\n"));
633    }
634
635    wxPuts(wxEmptyString);
636}
637
638static void TestTextFileRead()
639{
640    wxPuts(_T("*** wxTextFile read test ***"));
641
642    wxTextFile file(_T("testdata.fc"));
643    if ( file.Open() )
644    {
645        wxPrintf(_T("Number of lines: %u\n"), file.GetLineCount());
646        wxPrintf(_T("Last line: '%s'\n"), file.GetLastLine().c_str());
647
648        wxString s;
649
650        wxPuts(_T("\nDumping the entire file:"));
651        for ( s = file.GetFirstLine(); !file.Eof(); s = file.GetNextLine() )
652        {
653            wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
654        }
655        wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
656
657        wxPuts(_T("\nAnd now backwards:"));
658        for ( s = file.GetLastLine();
659              file.GetCurrentLine() != 0;
660              s = file.GetPrevLine() )
661        {
662            wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
663        }
664        wxPrintf(_T("%6u: %s\n"), file.GetCurrentLine() + 1, s.c_str());
665    }
666    else
667    {
668        wxPrintf(_T("ERROR: can't open '%s'\n"), file.GetName());
669    }
670
671    wxPuts(wxEmptyString);
672}
673
674static void TestFileCopy()
675{
676    wxPuts(_T("*** Testing wxCopyFile ***"));
677
678    static const wxChar *filename1 = _T("testdata.fc");
679    static const wxChar *filename2 = _T("test2");
680    if ( !wxCopyFile(filename1, filename2) )
681    {
682        wxPuts(_T("ERROR: failed to copy file"));
683    }
684    else
685    {
686        wxFFile f1(filename1, _T("rb")),
687                f2(filename2, _T("rb"));
688
689        if ( !f1.IsOpened() || !f2.IsOpened() )
690        {
691            wxPuts(_T("ERROR: failed to open file(s)"));
692        }
693        else
694        {
695            wxString s1, s2;
696            if ( !f1.ReadAll(&s1) || !f2.ReadAll(&s2) )
697            {
698                wxPuts(_T("ERROR: failed to read file(s)"));
699            }
700            else
701            {
702                if ( (s1.length() != s2.length()) ||
703                     (memcmp(s1.c_str(), s2.c_str(), s1.length()) != 0) )
704                {
705                    wxPuts(_T("ERROR: copy error!"));
706                }
707                else
708                {
709                    wxPuts(_T("File was copied ok."));
710                }
711            }
712        }
713    }
714
715    if ( !wxRemoveFile(filename2) )
716    {
717        wxPuts(_T("ERROR: failed to remove the file"));
718    }
719
720    wxPuts(wxEmptyString);
721}
722
723static void TestTempFile()
724{
725    wxPuts(_T("*** wxTempFile test ***"));
726
727    wxTempFile tmpFile;
728    if ( tmpFile.Open(_T("test2")) && tmpFile.Write(_T("the answer is 42")) )
729    {
730        if ( tmpFile.Commit() )
731            wxPuts(_T("File committed."));
732        else
733            wxPuts(_T("ERROR: could't commit temp file."));
734
735        wxRemoveFile(_T("test2"));
736    }
737
738    wxPuts(wxEmptyString);
739}
740
741#endif // TEST_FILE
742
743// ----------------------------------------------------------------------------
744// wxFileConfig
745// ----------------------------------------------------------------------------
746
747#ifdef TEST_FILECONF
748
749#include "wx/confbase.h"
750#include "wx/fileconf.h"
751
752static const struct FileConfTestData
753{
754    const wxChar *name;      // value name
755    const wxChar *value;     // the value from the file
756} fcTestData[] =
757{
758    { _T("value1"),                       _T("one") },
759    { _T("value2"),                       _T("two") },
760    { _T("novalue"),                      _T("default") },
761};
762
763static void TestFileConfRead()
764{
765    wxPuts(_T("*** testing wxFileConfig loading/reading ***"));
766
767    wxFileConfig fileconf(_T("test"), wxEmptyString,
768                          _T("testdata.fc"), wxEmptyString,
769                          wxCONFIG_USE_RELATIVE_PATH);
770
771    // test simple reading
772    wxPuts(_T("\nReading config file:"));
773    wxString defValue(_T("default")), value;
774    for ( size_t n = 0; n < WXSIZEOF(fcTestData); n++ )
775    {
776        const FileConfTestData& data = fcTestData[n];
777        value = fileconf.Read(data.name, defValue);
778        wxPrintf(_T("\t%s = %s "), data.name, value.c_str());
779        if ( value == data.value )
780        {
781            wxPuts(_T("(ok)"));
782        }
783        else
784        {
785            wxPrintf(_T("(ERROR: should be %s)\n"), data.value);
786        }
787    }
788
789    // test enumerating the entries
790    wxPuts(_T("\nEnumerating all root entries:"));
791    long dummy;
792    wxString name;
793    bool cont = fileconf.GetFirstEntry(name, dummy);
794    while ( cont )
795    {
796        wxPrintf(_T("\t%s = %s\n"),
797               name.c_str(),
798               fileconf.Read(name.c_str(), _T("ERROR")).c_str());
799
800        cont = fileconf.GetNextEntry(name, dummy);
801    }
802
803    static const wxChar *testEntry = _T("TestEntry");
804    wxPrintf(_T("\nTesting deletion of newly created \"Test\" entry: "));
805    fileconf.Write(testEntry, _T("A value"));
806    fileconf.DeleteEntry(testEntry);
807    wxPrintf(fileconf.HasEntry(testEntry) ? _T("ERROR\n") : _T("ok\n"));
808}
809
810#endif // TEST_FILECONF
811
812// ----------------------------------------------------------------------------
813// wxFileName
814// ----------------------------------------------------------------------------
815
816#ifdef TEST_FILENAME
817
818#include "wx/filename.h"
819
820#if 0
821static void DumpFileName(const wxChar *desc, const wxFileName& fn)
822{
823    wxPuts(desc);
824
825    wxString full = fn.GetFullPath();
826
827    wxString vol, path, name, ext;
828    wxFileName::SplitPath(full, &vol, &path, &name, &ext);
829
830    wxPrintf(_T("'%s'-> vol '%s', path '%s', name '%s', ext '%s'\n"),
831             full.c_str(), vol.c_str(), path.c_str(), name.c_str(), ext.c_str());
832
833    wxFileName::SplitPath(full, &path, &name, &ext);
834    wxPrintf(_T("or\t\t-> path '%s', name '%s', ext '%s'\n"),
835             path.c_str(), name.c_str(), ext.c_str());
836
837    wxPrintf(_T("path is also:\t'%s'\n"), fn.GetPath().c_str());
838    wxPrintf(_T("with volume: \t'%s'\n"),
839             fn.GetPath(wxPATH_GET_VOLUME).c_str());
840    wxPrintf(_T("with separator:\t'%s'\n"),
841             fn.GetPath(wxPATH_GET_SEPARATOR).c_str());
842    wxPrintf(_T("with both:   \t'%s'\n"),
843             fn.GetPath(wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME).c_str());
844
845    wxPuts(_T("The directories in the path are:"));
846    wxArrayString dirs = fn.GetDirs();
847    size_t count = dirs.GetCount();
848    for ( size_t n = 0; n < count; n++ )
849    {
850        wxPrintf(_T("\t%u: %s\n"), n, dirs[n].c_str());
851    }
852}
853#endif
854
855static void TestFileNameTemp()
856{
857    wxPuts(_T("*** testing wxFileName temp file creation ***"));
858
859    static const wxChar *tmpprefixes[] =
860    {
861        _T(""),
862        _T("foo"),
863        _T(".."),
864        _T("../bar"),
865#ifdef __UNIX__
866        _T("/tmp/foo"),
867        _T("/tmp/foo/bar"), // this one must be an error
868#endif // __UNIX__
869    };
870
871    for ( size_t n = 0; n < WXSIZEOF(tmpprefixes); n++ )
872    {
873        wxString path = wxFileName::CreateTempFileName(tmpprefixes[n]);
874        if ( path.empty() )
875        {
876            // "error" is not in upper case because it may be ok
877            wxPrintf(_T("Prefix '%s'\t-> error\n"), tmpprefixes[n]);
878        }
879        else
880        {
881            wxPrintf(_T("Prefix '%s'\t-> temp file '%s'\n"),
882                   tmpprefixes[n], path.c_str());
883
884            if ( !wxRemoveFile(path) )
885            {
886                wxLogWarning(_T("Failed to remove temp file '%s'"),
887                             path.c_str());
888            }
889        }
890    }
891}
892
893static void TestFileNameDirManip()
894{
895    // TODO: test AppendDir(), RemoveDir(), ...
896}
897
898static void TestFileNameComparison()
899{
900    // TODO!
901}
902
903static void TestFileNameOperations()
904{
905    // TODO!
906}
907
908static void TestFileNameCwd()
909{
910    // TODO!
911}
912
913#endif // TEST_FILENAME
914
915// ----------------------------------------------------------------------------
916// wxFileName time functions
917// ----------------------------------------------------------------------------
918
919#ifdef TEST_FILETIME
920
921#include "wx/filename.h"
922#include "wx/datetime.h"
923
924static void TestFileGetTimes()
925{
926    wxFileName fn(_T("testdata.fc"));
927
928    wxDateTime dtAccess, dtMod, dtCreate;
929    if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) )
930    {
931        wxPrintf(_T("ERROR: GetTimes() failed.\n"));
932    }
933    else
934    {
935        static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S");
936
937        wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str());
938        wxPrintf(_T("Creation:    \t%s\n"), dtCreate.Format(fmt).c_str());
939        wxPrintf(_T("Last read:   \t%s\n"), dtAccess.Format(fmt).c_str());
940        wxPrintf(_T("Last write:  \t%s\n"), dtMod.Format(fmt).c_str());
941    }
942}
943
944#if 0
945static void TestFileSetTimes()
946{
947    wxFileName fn(_T("testdata.fc"));
948
949    if ( !fn.Touch() )
950    {
951        wxPrintf(_T("ERROR: Touch() failed.\n"));
952    }
953}
954#endif
955
956#endif // TEST_FILETIME
957
958// ----------------------------------------------------------------------------
959// wxLocale
960// ----------------------------------------------------------------------------
961
962#ifdef TEST_LOCALE
963
964#include "wx/intl.h"
965#include "wx/utils.h"   // for wxSetEnv
966
967static wxLocale gs_localeDefault(wxLANGUAGE_ENGLISH);
968
969// find the name of the language from its value
970static const wxChar *GetLangName(int lang)
971{
972    static const wxChar *languageNames[] =
973    {
974        _T("DEFAULT"),
975        _T("UNKNOWN"),
976        _T("ABKHAZIAN"),
977        _T("AFAR"),
978        _T("AFRIKAANS"),
979        _T("ALBANIAN"),
980        _T("AMHARIC"),
981        _T("ARABIC"),
982        _T("ARABIC_ALGERIA"),
983        _T("ARABIC_BAHRAIN"),
984        _T("ARABIC_EGYPT"),
985        _T("ARABIC_IRAQ"),
986        _T("ARABIC_JORDAN"),
987        _T("ARABIC_KUWAIT"),
988        _T("ARABIC_LEBANON"),
989        _T("ARABIC_LIBYA"),
990        _T("ARABIC_MOROCCO"),
991        _T("ARABIC_OMAN"),
992        _T("ARABIC_QATAR"),
993        _T("ARABIC_SAUDI_ARABIA"),
994        _T("ARABIC_SUDAN"),
995        _T("ARABIC_SYRIA"),
996        _T("ARABIC_TUNISIA"),
997        _T("ARABIC_UAE"),
998        _T("ARABIC_YEMEN"),
999        _T("ARMENIAN"),
1000        _T("ASSAMESE"),
1001        _T("AYMARA"),
1002        _T("AZERI"),
1003        _T("AZERI_CYRILLIC"),
1004        _T("AZERI_LATIN"),
1005        _T("BASHKIR"),
1006        _T("BASQUE"),
1007        _T("BELARUSIAN"),
1008        _T("BENGALI"),
1009        _T("BHUTANI"),
1010        _T("BIHARI"),
1011        _T("BISLAMA"),
1012        _T("BRETON"),
1013        _T("BULGARIAN"),
1014        _T("BURMESE"),
1015        _T("CAMBODIAN"),
1016        _T("CATALAN"),
1017        _T("CHINESE"),
1018        _T("CHINESE_SIMPLIFIED"),
1019        _T("CHINESE_TRADITIONAL"),
1020        _T("CHINESE_HONGKONG"),
1021        _T("CHINESE_MACAU"),
1022        _T("CHINESE_SINGAPORE"),
1023        _T("CHINESE_TAIWAN"),
1024        _T("CORSICAN"),
1025        _T("CROATIAN"),
1026        _T("CZECH"),
1027        _T("DANISH"),
1028        _T("DUTCH"),
1029        _T("DUTCH_BELGIAN"),
1030        _T("ENGLISH"),
1031        _T("ENGLISH_UK"),
1032        _T("ENGLISH_US"),
1033        _T("ENGLISH_AUSTRALIA"),
1034        _T("ENGLISH_BELIZE"),
1035        _T("ENGLISH_BOTSWANA"),
1036        _T("ENGLISH_CANADA"),
1037        _T("ENGLISH_CARIBBEAN"),
1038        _T("ENGLISH_DENMARK"),
1039        _T("ENGLISH_EIRE"),
1040        _T("ENGLISH_JAMAICA"),
1041        _T("ENGLISH_NEW_ZEALAND"),
1042        _T("ENGLISH_PHILIPPINES"),
1043        _T("ENGLISH_SOUTH_AFRICA"),
1044        _T("ENGLISH_TRINIDAD"),
1045        _T("ENGLISH_ZIMBABWE"),
1046        _T("ESPERANTO"),
1047        _T("ESTONIAN"),
1048        _T("FAEROESE"),
1049        _T("FARSI"),
1050        _T("FIJI"),
1051        _T("FINNISH"),
1052        _T("FRENCH"),
1053        _T("FRENCH_BELGIAN"),
1054        _T("FRENCH_CANADIAN"),
1055        _T("FRENCH_LUXEMBOURG"),
1056        _T("FRENCH_MONACO"),
1057        _T("FRENCH_SWISS"),
1058        _T("FRISIAN"),
1059        _T("GALICIAN"),
1060        _T("GEORGIAN"),
1061        _T("GERMAN"),
1062        _T("GERMAN_AUSTRIAN"),
1063        _T("GERMAN_BELGIUM"),
1064        _T("GERMAN_LIECHTENSTEIN"),
1065        _T("GERMAN_LUXEMBOURG"),
1066        _T("GERMAN_SWISS"),
1067        _T("GREEK"),
1068        _T("GREENLANDIC"),
1069        _T("GUARANI"),
1070        _T("GUJARATI"),
1071        _T("HAUSA"),
1072        _T("HEBREW"),
1073        _T("HINDI"),
1074        _T("HUNGARIAN"),
1075        _T("ICELANDIC"),
1076        _T("INDONESIAN"),
1077        _T("INTERLINGUA"),
1078        _T("INTERLINGUE"),
1079        _T("INUKTITUT"),
1080        _T("INUPIAK"),
1081        _T("IRISH"),
1082        _T("ITALIAN"),
1083        _T("ITALIAN_SWISS"),
1084        _T("JAPANESE"),
1085        _T("JAVANESE"),
1086        _T("KANNADA"),
1087        _T("KASHMIRI"),
1088        _T("KASHMIRI_INDIA"),
1089        _T("KAZAKH"),
1090        _T("KERNEWEK"),
1091        _T("KINYARWANDA"),
1092        _T("KIRGHIZ"),
1093        _T("KIRUNDI"),
1094        _T("KONKANI"),
1095        _T("KOREAN"),
1096        _T("KURDISH"),
1097        _T("LAOTHIAN"),
1098        _T("LATIN"),
1099        _T("LATVIAN"),
1100        _T("LINGALA"),
1101        _T("LITHUANIAN"),
1102        _T("MACEDONIAN"),
1103        _T("MALAGASY"),
1104        _T("MALAY"),
1105        _T("MALAYALAM"),
1106        _T("MALAY_BRUNEI_DARUSSALAM"),
1107        _T("MALAY_MALAYSIA"),
1108        _T("MALTESE"),
1109        _T("MANIPURI"),
1110        _T("MAORI"),
1111        _T("MARATHI"),
1112        _T("MOLDAVIAN"),
1113        _T("MONGOLIAN"),
1114        _T("NAURU"),
1115        _T("NEPALI"),
1116        _T("NEPALI_INDIA"),
1117        _T("NORWEGIAN_BOKMAL"),
1118        _T("NORWEGIAN_NYNORSK"),
1119        _T("OCCITAN"),
1120        _T("ORIYA"),
1121        _T("OROMO"),
1122        _T("PASHTO"),
1123        _T("POLISH"),
1124        _T("PORTUGUESE"),
1125        _T("PORTUGUESE_BRAZILIAN"),
1126        _T("PUNJABI"),
1127        _T("QUECHUA"),
1128        _T("RHAETO_ROMANCE"),
1129        _T("ROMANIAN"),
1130        _T("RUSSIAN"),
1131        _T("RUSSIAN_UKRAINE"),
1132        _T("SAMOAN"),
1133        _T("SANGHO"),
1134        _T("SANSKRIT"),
1135        _T("SCOTS_GAELIC"),
1136        _T("SERBIAN"),
1137        _T("SERBIAN_CYRILLIC"),
1138        _T("SERBIAN_LATIN"),
1139        _T("SERBO_CROATIAN"),
1140        _T("SESOTHO"),
1141        _T("SETSWANA"),
1142        _T("SHONA"),
1143        _T("SINDHI"),
1144        _T("SINHALESE"),
1145        _T("SISWATI"),
1146        _T("SLOVAK"),
1147        _T("SLOVENIAN"),
1148        _T("SOMALI"),
1149        _T("SPANISH"),
1150        _T("SPANISH_ARGENTINA"),
1151        _T("SPANISH_BOLIVIA"),
1152        _T("SPANISH_CHILE"),
1153        _T("SPANISH_COLOMBIA"),
1154        _T("SPANISH_COSTA_RICA"),
1155        _T("SPANISH_DOMINICAN_REPUBLIC"),
1156        _T("SPANISH_ECUADOR"),
1157        _T("SPANISH_EL_SALVADOR"),
1158        _T("SPANISH_GUATEMALA"),
1159        _T("SPANISH_HONDURAS"),
1160        _T("SPANISH_MEXICAN"),
1161        _T("SPANISH_MODERN"),
1162        _T("SPANISH_NICARAGUA"),
1163        _T("SPANISH_PANAMA"),
1164        _T("SPANISH_PARAGUAY"),
1165        _T("SPANISH_PERU"),
1166        _T("SPANISH_PUERTO_RICO"),
1167        _T("SPANISH_URUGUAY"),
1168        _T("SPANISH_US"),
1169        _T("SPANISH_VENEZUELA"),
1170        _T("SUNDANESE"),
1171        _T("SWAHILI"),
1172        _T("SWEDISH"),
1173        _T("SWEDISH_FINLAND"),
1174        _T("TAGALOG"),
1175        _T("TAJIK"),
1176        _T("TAMIL"),
1177        _T("TATAR"),
1178        _T("TELUGU"),
1179        _T("THAI"),
1180        _T("TIBETAN"),
1181        _T("TIGRINYA"),
1182        _T("TONGA"),
1183        _T("TSONGA"),
1184        _T("TURKISH"),
1185        _T("TURKMEN"),
1186        _T("TWI"),
1187        _T("UIGHUR"),
1188        _T("UKRAINIAN"),
1189        _T("URDU"),
1190        _T("URDU_INDIA"),
1191        _T("URDU_PAKISTAN"),
1192        _T("UZBEK"),
1193        _T("UZBEK_CYRILLIC"),
1194        _T("UZBEK_LATIN"),
1195        _T("VIETNAMESE"),
1196        _T("VOLAPUK"),
1197        _T("WELSH"),
1198        _T("WOLOF"),
1199        _T("XHOSA"),
1200        _T("YIDDISH"),
1201        _T("YORUBA"),
1202        _T("ZHUANG"),
1203        _T("ZULU"),
1204    };
1205
1206    if ( (size_t)lang < WXSIZEOF(languageNames) )
1207        return languageNames[lang];
1208    else
1209        return _T("INVALID");
1210}
1211
1212static void TestDefaultLang()
1213{
1214    wxPuts(_T("*** Testing wxLocale::GetSystemLanguage ***"));
1215
1216    static const wxChar *langStrings[] =
1217    {
1218        NULL,               // system default
1219        _T("C"),
1220        _T("fr"),
1221        _T("fr_FR"),
1222        _T("en"),
1223        _T("en_GB"),
1224        _T("en_US"),
1225        _T("de_DE.iso88591"),
1226        _T("german"),
1227        _T("?"),            // invalid lang spec
1228        _T("klingonese"),   // I bet on some systems it does exist...
1229    };
1230
1231    wxPrintf(_T("The default system encoding is %s (%d)\n"),
1232             wxLocale::GetSystemEncodingName().c_str(),
1233             wxLocale::GetSystemEncoding());
1234
1235    for ( size_t n = 0; n < WXSIZEOF(langStrings); n++ )
1236    {
1237        const wxChar *langStr = langStrings[n];
1238        if ( langStr )
1239        {
1240            // FIXME: this doesn't do anything at all under Windows, we need
1241            //        to create a new wxLocale!
1242            wxSetEnv(_T("LC_ALL"), langStr);
1243        }
1244
1245        int lang = gs_localeDefault.GetSystemLanguage();
1246        wxPrintf(_T("Locale for '%s' is %s.\n"),
1247                 langStr ? langStr : _T("system default"), GetLangName(lang));
1248    }
1249}
1250
1251#endif // TEST_LOCALE
1252
1253// ----------------------------------------------------------------------------
1254// MIME types
1255// ----------------------------------------------------------------------------
1256
1257#ifdef TEST_MIME
1258
1259#include "wx/mimetype.h"
1260
1261static void TestMimeEnum()
1262{
1263    wxPuts(_T("*** Testing wxMimeTypesManager::EnumAllFileTypes() ***\n"));
1264
1265    wxArrayString mimetypes;
1266
1267    size_t count = wxTheMimeTypesManager->EnumAllFileTypes(mimetypes);
1268
1269    wxPrintf(_T("*** All %u known filetypes: ***\n"), count);
1270
1271    wxArrayString exts;
1272    wxString desc;
1273
1274    for ( size_t n = 0; n < count; n++ )
1275    {
1276        wxFileType *filetype =
1277            wxTheMimeTypesManager->GetFileTypeFromMimeType(mimetypes[n]);
1278        if ( !filetype )
1279        {
1280            wxPrintf(_T("nothing known about the filetype '%s'!\n"),
1281                   mimetypes[n].c_str());
1282            continue;
1283        }
1284
1285        filetype->GetDescription(&desc);
1286        filetype->GetExtensions(exts);
1287
1288        filetype->GetIcon(NULL);
1289
1290        wxString extsAll;
1291        for ( size_t e = 0; e < exts.GetCount(); e++ )
1292        {
1293            if ( e > 0 )
1294                extsAll << _T(", ");
1295            extsAll += exts[e];
1296        }
1297
1298        wxPrintf(_T("\t%s: %s (%s)\n"),
1299               mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
1300    }
1301
1302    wxPuts(wxEmptyString);
1303}
1304
1305static void TestMimeOverride()
1306{
1307    wxPuts(_T("*** Testing wxMimeTypesManager additional files loading ***\n"));
1308
1309    static const wxChar *mailcap = _T("/tmp/mailcap");
1310    static const wxChar *mimetypes = _T("/tmp/mime.types");
1311
1312    if ( wxFile::Exists(mailcap) )
1313        wxPrintf(_T("Loading mailcap from '%s': %s\n"),
1314                 mailcap,
1315                 wxTheMimeTypesManager->ReadMailcap(mailcap) ? _T("ok") : _T("ERROR"));
1316    else
1317        wxPrintf(_T("WARN: mailcap file '%s' doesn't exist, not loaded.\n"),
1318                 mailcap);
1319
1320    if ( wxFile::Exists(mimetypes) )
1321        wxPrintf(_T("Loading mime.types from '%s': %s\n"),
1322                 mimetypes,
1323                 wxTheMimeTypesManager->ReadMimeTypes(mimetypes) ? _T("ok") : _T("ERROR"));
1324    else
1325        wxPrintf(_T("WARN: mime.types file '%s' doesn't exist, not loaded.\n"),
1326                 mimetypes);
1327
1328    wxPuts(wxEmptyString);
1329}
1330
1331static void TestMimeFilename()
1332{
1333    wxPuts(_T("*** Testing MIME type from filename query ***\n"));
1334
1335    static const wxChar *filenames[] =
1336    {
1337        _T("readme.txt"),
1338        _T("document.pdf"),
1339        _T("image.gif"),
1340        _T("picture.jpeg"),
1341    };
1342
1343    for ( size_t n = 0; n < WXSIZEOF(filenames); n++ )
1344    {
1345        const wxString fname = filenames[n];
1346        wxString ext = fname.AfterLast(_T('.'));
1347        wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension(ext);
1348        if ( !ft )
1349        {
1350            wxPrintf(_T("WARNING: extension '%s' is unknown.\n"), ext.c_str());
1351        }
1352        else
1353        {
1354            wxString desc;
1355            if ( !ft->GetDescription(&desc) )
1356                desc = _T("<no description>");
1357
1358            wxString cmd;
1359            if ( !ft->GetOpenCommand(&cmd,
1360                                     wxFileType::MessageParameters(fname, wxEmptyString)) )
1361                cmd = _T("<no command available>");
1362            else
1363                cmd = wxString(_T('"')) + cmd + _T('"');
1364
1365            wxPrintf(_T("To open %s (%s) do %s.\n"),
1366                     fname.c_str(), desc.c_str(), cmd.c_str());
1367
1368            delete ft;
1369        }
1370    }
1371
1372    wxPuts(wxEmptyString);
1373}
1374
1375static void TestMimeAssociate()
1376{
1377    wxPuts(_T("*** Testing creation of filetype association ***\n"));
1378
1379    wxFileTypeInfo ftInfo(
1380                            _T("application/x-xyz"),
1381                            _T("xyzview '%s'"), // open cmd
1382                            _T(""),             // print cmd
1383                            _T("XYZ File"),     // description
1384                            _T(".xyz"),         // extensions
1385                            NULL                // end of extensions
1386                         );
1387    ftInfo.SetShortDesc(_T("XYZFile")); // used under Win32 only
1388
1389    wxFileType *ft = wxTheMimeTypesManager->Associate(ftInfo);
1390    if ( !ft )
1391    {
1392        wxPuts(_T("ERROR: failed to create association!"));
1393    }
1394    else
1395    {
1396        // TODO: read it back
1397        delete ft;
1398    }
1399
1400    wxPuts(wxEmptyString);
1401}
1402
1403#endif // TEST_MIME
1404
1405// ----------------------------------------------------------------------------
1406// module dependencies feature
1407// ----------------------------------------------------------------------------
1408
1409#ifdef TEST_MODULE
1410
1411#include "wx/module.h"
1412
1413class wxTestModule : public wxModule
1414{
1415protected:
1416    virtual bool OnInit() { wxPrintf(_T("Load module: %s\n"), GetClassInfo()->GetClassName()); return true; }
1417    virtual void OnExit() { wxPrintf(_T("Unload module: %s\n"), GetClassInfo()->GetClassName()); }
1418};
1419
1420class wxTestModuleA : public wxTestModule
1421{
1422public:
1423    wxTestModuleA();
1424private:
1425    DECLARE_DYNAMIC_CLASS(wxTestModuleA)
1426};
1427
1428class wxTestModuleB : public wxTestModule
1429{
1430public:
1431    wxTestModuleB();
1432private:
1433    DECLARE_DYNAMIC_CLASS(wxTestModuleB)
1434};
1435
1436class wxTestModuleC : public wxTestModule
1437{
1438public:
1439    wxTestModuleC();
1440private:
1441    DECLARE_DYNAMIC_CLASS(wxTestModuleC)
1442};
1443
1444class wxTestModuleD : public wxTestModule
1445{
1446public:
1447    wxTestModuleD();
1448private:
1449    DECLARE_DYNAMIC_CLASS(wxTestModuleD)
1450};
1451
1452IMPLEMENT_DYNAMIC_CLASS(wxTestModuleC, wxModule)
1453wxTestModuleC::wxTestModuleC()
1454{
1455    AddDependency(CLASSINFO(wxTestModuleD));
1456}
1457
1458IMPLEMENT_DYNAMIC_CLASS(wxTestModuleA, wxModule)
1459wxTestModuleA::wxTestModuleA()
1460{
1461    AddDependency(CLASSINFO(wxTestModuleB));
1462    AddDependency(CLASSINFO(wxTestModuleD));
1463}
1464
1465IMPLEMENT_DYNAMIC_CLASS(wxTestModuleD, wxModule)
1466wxTestModuleD::wxTestModuleD()
1467{
1468}
1469
1470IMPLEMENT_DYNAMIC_CLASS(wxTestModuleB, wxModule)
1471wxTestModuleB::wxTestModuleB()
1472{
1473    AddDependency(CLASSINFO(wxTestModuleD));
1474    AddDependency(CLASSINFO(wxTestModuleC));
1475}
1476
1477#endif // TEST_MODULE
1478
1479// ----------------------------------------------------------------------------
1480// misc information functions
1481// ----------------------------------------------------------------------------
1482
1483#ifdef TEST_INFO_FUNCTIONS
1484
1485#include "wx/utils.h"
1486
1487#if TEST_INTERACTIVE
1488static void TestDiskInfo()
1489{
1490    wxPuts(_T("*** Testing wxGetDiskSpace() ***"));
1491
1492    for ( ;; )
1493    {
1494        wxChar pathname[128];
1495        wxPrintf(_T("\nEnter a directory name: "));
1496        if ( !wxFgets(pathname, WXSIZEOF(pathname), stdin) )
1497            break;
1498
1499        // kill the last '\n'
1500        pathname[wxStrlen(pathname) - 1] = 0;
1501
1502        wxLongLong total, free;
1503        if ( !wxGetDiskSpace(pathname, &total, &free) )
1504        {
1505            wxPuts(_T("ERROR: wxGetDiskSpace failed."));
1506        }
1507        else
1508        {
1509            wxPrintf(_T("%sKb total, %sKb free on '%s'.\n"),
1510                    (total / 1024).ToString().c_str(),
1511                    (free / 1024).ToString().c_str(),
1512                    pathname);
1513        }
1514    }
1515}
1516#endif // TEST_INTERACTIVE
1517
1518static void TestOsInfo()
1519{
1520    wxPuts(_T("*** Testing OS info functions ***\n"));
1521
1522    int major, minor;
1523    wxGetOsVersion(&major, &minor);
1524    wxPrintf(_T("Running under: %s, version %d.%d\n"),
1525            wxGetOsDescription().c_str(), major, minor);
1526
1527    wxPrintf(_T("%ld free bytes of memory left.\n"), wxGetFreeMemory().ToLong());
1528
1529    wxPrintf(_T("Host name is %s (%s).\n"),
1530           wxGetHostName().c_str(), wxGetFullHostName().c_str());
1531
1532    wxPuts(wxEmptyString);
1533}
1534
1535static void TestPlatformInfo()
1536{
1537    wxPuts(_T("*** Testing wxPlatformInfo functions ***\n"));
1538
1539    // get this platform
1540    wxPlatformInfo plat;
1541
1542    wxPrintf(_T("Operating system family name is: %s\n"), plat.GetOperatingSystemFamilyName().c_str());
1543    wxPrintf(_T("Operating system name is: %s\n"), plat.GetOperatingSystemIdName().c_str());
1544    wxPrintf(_T("Port ID name is: %s\n"), plat.GetPortIdName().c_str());
1545    wxPrintf(_T("Port ID short name is: %s\n"), plat.GetPortIdShortName().c_str());
1546    wxPrintf(_T("Architecture is: %s\n"), plat.GetArchName().c_str());
1547    wxPrintf(_T("Endianness is: %s\n"), plat.GetEndiannessName().c_str());
1548
1549    wxPuts(wxEmptyString);
1550}
1551
1552static void TestUserInfo()
1553{
1554    wxPuts(_T("*** Testing user info functions ***\n"));
1555
1556    wxPrintf(_T("User id is:\t%s\n"), wxGetUserId().c_str());
1557    wxPrintf(_T("User name is:\t%s\n"), wxGetUserName().c_str());
1558    wxPrintf(_T("Home dir is:\t%s\n"), wxGetHomeDir().c_str());
1559    wxPrintf(_T("Email address:\t%s\n"), wxGetEmailAddress().c_str());
1560
1561    wxPuts(wxEmptyString);
1562}
1563
1564#endif // TEST_INFO_FUNCTIONS
1565
1566// ----------------------------------------------------------------------------
1567// path list
1568// ----------------------------------------------------------------------------
1569
1570#ifdef TEST_PATHLIST
1571
1572#ifdef __UNIX__
1573    #define CMD_IN_PATH _T("ls")
1574#else
1575    #define CMD_IN_PATH _T("command.com")
1576#endif
1577
1578static void TestPathList()
1579{
1580    wxPuts(_T("*** Testing wxPathList ***\n"));
1581
1582    wxPathList pathlist;
1583    pathlist.AddEnvList(_T("PATH"));
1584    wxString path = pathlist.FindValidPath(CMD_IN_PATH);
1585    if ( path.empty() )
1586    {
1587        wxPrintf(_T("ERROR: command not found in the path.\n"));
1588    }
1589    else
1590    {
1591        wxPrintf(_T("Command found in the path as '%s'.\n"), path.c_str());
1592    }
1593}
1594
1595#endif // TEST_PATHLIST
1596
1597// ----------------------------------------------------------------------------
1598// regular expressions
1599// ----------------------------------------------------------------------------
1600
1601#ifdef TEST_REGEX
1602
1603#include "wx/regex.h"
1604
1605static void TestRegExInteractive()
1606{
1607    wxPuts(_T("*** Testing RE interactively ***"));
1608
1609    for ( ;; )
1610    {
1611        wxChar pattern[128];
1612        wxPrintf(_T("\nEnter a pattern: "));
1613        if ( !wxFgets(pattern, WXSIZEOF(pattern), stdin) )
1614            break;
1615
1616        // kill the last '\n'
1617        pattern[wxStrlen(pattern) - 1] = 0;
1618
1619        wxRegEx re;
1620        if ( !re.Compile(pattern) )
1621        {
1622            continue;
1623        }
1624
1625        wxChar text[128];
1626        for ( ;; )
1627        {
1628            wxPrintf(_T("Enter text to match: "));
1629            if ( !wxFgets(text, WXSIZEOF(text), stdin) )
1630                break;
1631
1632            // kill the last '\n'
1633            text[wxStrlen(text) - 1] = 0;
1634
1635            if ( !re.Matches(text) )
1636            {
1637                wxPrintf(_T("No match.\n"));
1638            }
1639            else
1640            {
1641                wxPrintf(_T("Pattern matches at '%s'\n"), re.GetMatch(text).c_str());
1642
1643                size_t start, len;
1644                for ( size_t n = 1; ; n++ )
1645                {
1646                    if ( !re.GetMatch(&start, &len, n) )
1647                    {
1648                        break;
1649                    }
1650
1651                    wxPrintf(_T("Subexpr %u matched '%s'\n"),
1652                             n, wxString(text + start, len).c_str());
1653                }
1654            }
1655        }
1656    }
1657}
1658
1659#endif // TEST_REGEX
1660
1661// ----------------------------------------------------------------------------
1662// database
1663// ----------------------------------------------------------------------------
1664
1665#if !wxUSE_ODBC
1666    #undef TEST_ODBC
1667#endif
1668
1669#ifdef TEST_ODBC
1670
1671#include "wx/db.h"
1672
1673static void TestDbOpen()
1674{
1675    HENV henv;
1676    wxDb db(henv);
1677}
1678
1679#endif // TEST_ODBC
1680
1681// ----------------------------------------------------------------------------
1682// printf() tests
1683// ----------------------------------------------------------------------------
1684
1685/*
1686   NB: this stuff was taken from the glibc test suite and modified to build
1687       in wxWidgets: if I read the copyright below properly, this shouldn't
1688       be a problem
1689 */
1690
1691#ifdef TEST_PRINTF
1692
1693#ifdef wxTEST_PRINTF
1694    // use our functions from wxchar.cpp
1695    #undef wxPrintf
1696    #undef wxSprintf
1697
1698    // NB: do _not_ use ATTRIBUTE_PRINTF here, we have some invalid formats
1699    //     in the tests below
1700    int wxPrintf( const wxChar *format, ... );
1701    int wxSprintf( wxChar *str, const wxChar *format, ... );
1702#endif
1703
1704#include "wx/longlong.h"
1705
1706#include <float.h>
1707
1708static void rfg1 (void);
1709static void rfg2 (void);
1710
1711
1712static void
1713fmtchk (const wxChar *fmt)
1714{
1715  (void) wxPrintf(_T("%s:\t`"), fmt);
1716  (void) wxPrintf(fmt, 0x12);
1717  (void) wxPrintf(_T("'\n"));
1718}
1719
1720static void
1721fmtst1chk (const wxChar *fmt)
1722{
1723  (void) wxPrintf(_T("%s:\t`"), fmt);
1724  (void) wxPrintf(fmt, 4, 0x12);
1725  (void) wxPrintf(_T("'\n"));
1726}
1727
1728static void
1729fmtst2chk (const wxChar *fmt)
1730{
1731  (void) wxPrintf(_T("%s:\t`"), fmt);
1732  (void) wxPrintf(fmt, 4, 4, 0x12);
1733  (void) wxPrintf(_T("'\n"));
1734}
1735
1736/* This page is covered by the following copyright: */
1737
1738/* (C) Copyright C E Chew
1739 *
1740 * Feel free to copy, use and distribute this software provided:
1741 *
1742 *        1. you do not pretend that you wrote it
1743 *        2. you leave this copyright notice intact.
1744 */
1745
1746/*
1747 * Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
1748 */
1749
1750#define DEC -123
1751#define INT 255
1752#define UNS (~0)
1753
1754/* Formatted Output Test
1755 *
1756 * This exercises the output formatting code.
1757 */
1758
1759wxChar *PointerNull = NULL;
1760
1761static void
1762fp_test (void)
1763{
1764  int i, j, k, l;
1765  wxChar buf[7];
1766  wxChar *prefix = buf;
1767  wxChar tp[20];
1768
1769  wxPuts(_T("\nFormatted output test"));
1770  wxPrintf(_T("prefix  6d      6o      6x      6X      6u\n"));
1771  wxStrcpy(prefix, _T("%"));
1772  for (i = 0; i < 2; i++) {
1773    for (j = 0; j < 2; j++) {
1774      for (k = 0; k < 2; k++) {
1775        for (l = 0; l < 2; l++) {
1776          wxStrcpy(prefix, _T("%"));
1777          if (i == 0) wxStrcat(prefix, _T("-"));
1778          if (j == 0) wxStrcat(prefix, _T("+"));
1779          if (k == 0) wxStrcat(prefix, _T("#"));
1780          if (l == 0) wxStrcat(prefix, _T("0"));
1781          wxPrintf(_T("%5s |"), prefix);
1782          wxStrcpy(tp, prefix);
1783          wxStrcat(tp, _T("6d |"));
1784          wxPrintf(tp, DEC);
1785          wxStrcpy(tp, prefix);
1786          wxStrcat(tp, _T("6o |"));
1787          wxPrintf(tp, INT);
1788          wxStrcpy(tp, prefix);
1789          wxStrcat(tp, _T("6x |"));
1790          wxPrintf(tp, INT);
1791          wxStrcpy(tp, prefix);
1792          wxStrcat(tp, _T("6X |"));
1793          wxPrintf(tp, INT);
1794          wxStrcpy(tp, prefix);
1795          wxStrcat(tp, _T("6u |"));
1796          wxPrintf(tp, UNS);
1797          wxPrintf(_T("\n"));
1798        }
1799      }
1800    }
1801  }
1802  wxPrintf(_T("%10s\n"), PointerNull);
1803  wxPrintf(_T("%-10s\n"), PointerNull);
1804}
1805
1806static void TestPrintf()
1807{
1808  static wxChar shortstr[] = _T("Hi, Z.");
1809  static wxChar longstr[] = _T("Good morning, Doctor Chandra.  This is Hal.  \
1810I am ready for my first lesson today.");
1811  int result = 0;
1812  wxString test_format;
1813
1814  fmtchk(_T("%.4x"));
1815  fmtchk(_T("%04x"));
1816  fmtchk(_T("%4.4x"));
1817  fmtchk(_T("%04.4x"));
1818  fmtchk(_T("%4.3x"));
1819  fmtchk(_T("%04.3x"));
1820
1821  fmtst1chk(_T("%.*x"));
1822  fmtst1chk(_T("%0*x"));
1823  fmtst2chk(_T("%*.*x"));
1824  fmtst2chk(_T("%0*.*x"));
1825
1826  wxString bad_format = _T("bad format:\t\"%b\"\n");
1827  wxPrintf(bad_format.c_str());
1828  wxPrintf(_T("nil pointer (padded):\t\"%10p\"\n"), (void *) NULL);
1829
1830  wxPrintf(_T("decimal negative:\t\"%d\"\n"), -2345);
1831  wxPrintf(_T("octal negative:\t\"%o\"\n"), -2345);
1832  wxPrintf(_T("hex negative:\t\"%x\"\n"), -2345);
1833  wxPrintf(_T("long decimal number:\t\"%ld\"\n"), -123456L);
1834  wxPrintf(_T("long octal negative:\t\"%lo\"\n"), -2345L);
1835  wxPrintf(_T("long unsigned decimal number:\t\"%lu\"\n"), -123456L);
1836  wxPrintf(_T("zero-padded LDN:\t\"%010ld\"\n"), -123456L);
1837  test_format = _T("left-adjusted ZLDN:\t\"%-010ld\"\n");
1838  wxPrintf(test_format.c_str(), -123456);
1839  wxPrintf(_T("space-padded LDN:\t\"%10ld\"\n"), -123456L);
1840  wxPrintf(_T("left-adjusted SLDN:\t\"%-10ld\"\n"), -123456L);
1841
1842  test_format = _T("zero-padded string:\t\"%010s\"\n");
1843  wxPrintf(test_format.c_str(), shortstr);
1844  test_format = _T("left-adjusted Z string:\t\"%-010s\"\n");
1845  wxPrintf(test_format.c_str(), shortstr);
1846  wxPrintf(_T("space-padded string:\t\"%10s\"\n"), shortstr);
1847  wxPrintf(_T("left-adjusted S string:\t\"%-10s\"\n"), shortstr);
1848  wxPrintf(_T("null string:\t\"%s\"\n"), PointerNull);
1849  wxPrintf(_T("limited string:\t\"%.22s\"\n"), longstr);
1850
1851  wxPrintf(_T("e-style >= 1:\t\"%e\"\n"), 12.34);
1852  wxPrintf(_T("e-style >= .1:\t\"%e\"\n"), 0.1234);
1853  wxPrintf(_T("e-style < .1:\t\"%e\"\n"), 0.001234);
1854  wxPrintf(_T("e-style big:\t\"%.60e\"\n"), 1e20);
1855  wxPrintf(_T("e-style == .1:\t\"%e\"\n"), 0.1);
1856  wxPrintf(_T("f-style >= 1:\t\"%f\"\n"), 12.34);
1857  wxPrintf(_T("f-style >= .1:\t\"%f\"\n"), 0.1234);
1858  wxPrintf(_T("f-style < .1:\t\"%f\"\n"), 0.001234);
1859  wxPrintf(_T("g-style >= 1:\t\"%g\"\n"), 12.34);
1860  wxPrintf(_T("g-style >= .1:\t\"%g\"\n"), 0.1234);
1861  wxPrintf(_T("g-style < .1:\t\"%g\"\n"), 0.001234);
1862  wxPrintf(_T("g-style big:\t\"%.60g\"\n"), 1e20);
1863
1864  wxPrintf (_T(" %6.5f\n"), .099999999860301614);
1865  wxPrintf (_T(" %6.5f\n"), .1);
1866  wxPrintf (_T("x%5.4fx\n"), .5);
1867
1868  wxPrintf (_T("%#03x\n"), 1);
1869
1870  //wxPrintf (_T("something really insane: %.10000f\n"), 1.0);
1871
1872  {
1873    double d = FLT_MIN;
1874    int niter = 17;
1875
1876    while (niter-- != 0)
1877      wxPrintf (_T("%.17e\n"), d / 2);
1878    fflush (stdout);
1879  }
1880
1881#ifndef __WATCOMC__
1882  // Open Watcom cause compiler error here
1883  // Error! E173: col(24) floating-point constant too small to represent
1884  wxPrintf (_T("%15.5e\n"), 4.9406564584124654e-324);
1885#endif
1886
1887#define FORMAT _T("|%12.4f|%12.4e|%12.4g|\n")
1888  wxPrintf (FORMAT, 0.0, 0.0, 0.0);
1889  wxPrintf (FORMAT, 1.0, 1.0, 1.0);
1890  wxPrintf (FORMAT, -1.0, -1.0, -1.0);
1891  wxPrintf (FORMAT, 100.0, 100.0, 100.0);
1892  wxPrintf (FORMAT, 1000.0, 1000.0, 1000.0);
1893  wxPrintf (FORMAT, 10000.0, 10000.0, 10000.0);
1894  wxPrintf (FORMAT, 12345.0, 12345.0, 12345.0);
1895  wxPrintf (FORMAT, 100000.0, 100000.0, 100000.0);
1896  wxPrintf (FORMAT, 123456.0, 123456.0, 123456.0);
1897#undef        FORMAT
1898
1899  {
1900    wxChar buf[20];
1901    int rc = wxSnprintf (buf, WXSIZEOF(buf), _T("%30s"), _T("foo"));
1902
1903    wxPrintf(_T("snprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n"),
1904             rc, WXSIZEOF(buf), buf);
1905#if 0
1906    wxChar buf2[512];
1907    wxPrintf ("snprintf (\"%%.999999u\", 10)\n",
1908            wxSnprintf(buf2, WXSIZEOFbuf2), "%.999999u", 10));
1909#endif
1910  }
1911
1912  fp_test ();
1913
1914  wxPrintf (_T("%e should be 1.234568e+06\n"), 1234567.8);
1915  wxPrintf (_T("%f should be 1234567.800000\n"), 1234567.8);
1916  wxPrintf (_T("%g should be 1.23457e+06\n"), 1234567.8);
1917  wxPrintf (_T("%g should be 123.456\n"), 123.456);
1918  wxPrintf (_T("%g should be 1e+06\n"), 1000000.0);
1919  wxPrintf (_T("%g should be 10\n"), 10.0);
1920  wxPrintf (_T("%g should be 0.02\n"), 0.02);
1921
1922  {
1923    double x=1.0;
1924    wxPrintf(_T("%.17f\n"),(1.0/x/10.0+1.0)*x-x);
1925  }
1926
1927  {
1928    wxChar buf[200];
1929
1930    wxSprintf(buf,_T("%*s%*s%*s"),-1,_T("one"),-20,_T("two"),-30,_T("three"));
1931
1932    result |= wxStrcmp (buf,
1933                      _T("onetwo                 three                         "));
1934
1935    wxPuts (result != 0 ? _T("Test failed!") : _T("Test ok."));
1936  }
1937
1938#ifdef wxLongLong_t
1939  {
1940      wxChar buf[200];
1941
1942      wxSprintf(buf, _T("%07") wxLongLongFmtSpec _T("o"), wxLL(040000000000));
1943      #if 0
1944        // for some reason below line fails under Borland
1945      wxPrintf (_T("sprintf (buf, \"%%07Lo\", 040000000000ll) = %s"), buf);
1946      #endif
1947
1948      if (wxStrcmp (buf, _T("40000000000")) != 0)
1949      {
1950          result = 1;
1951          wxPuts (_T("\tFAILED"));
1952      }
1953      wxUnusedVar(result);
1954      wxPuts (wxEmptyString);
1955  }
1956#endif // wxLongLong_t
1957
1958  wxPrintf (_T("printf (\"%%hhu\", %u) = %hhu\n"), UCHAR_MAX + 2, UCHAR_MAX + 2);
1959  wxPrintf (_T("printf (\"%%hu\", %u) = %hu\n"), USHRT_MAX + 2, USHRT_MAX + 2);
1960
1961  wxPuts (_T("--- Should be no further output. ---"));
1962  rfg1 ();
1963  rfg2 ();
1964
1965#if 0
1966  {
1967    wxChar bytes[7];
1968    wxChar buf[20];
1969
1970    memset (bytes, '\xff', sizeof bytes);
1971    wxSprintf (buf, _T("foo%hhn\n"), &bytes[3]);
1972    if (bytes[0] != '\xff' || bytes[1] != '\xff' || bytes[2] != '\xff'
1973        || bytes[4] != '\xff' || bytes[5] != '\xff' || bytes[6] != '\xff')
1974      {
1975        wxPuts (_T("%hhn overwrite more bytes"));
1976        result = 1;
1977      }
1978    if (bytes[3] != 3)
1979      {
1980        wxPuts (_T("%hhn wrote incorrect value"));
1981        result = 1;
1982      }
1983  }
1984#endif
1985}
1986
1987static void
1988rfg1 (void)
1989{
1990  wxChar buf[100];
1991
1992  wxSprintf (buf, _T("%5.s"), _T("xyz"));
1993  if (wxStrcmp (buf, _T("     ")) != 0)
1994    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("     "));
1995  wxSprintf (buf, _T("%5.f"), 33.3);
1996  if (wxStrcmp (buf, _T("   33")) != 0)
1997    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("   33"));
1998  wxSprintf (buf, _T("%8.e"), 33.3e7);
1999  if (wxStrcmp (buf, _T("   3e+08")) != 0)
2000    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("   3e+08"));
2001  wxSprintf (buf, _T("%8.E"), 33.3e7);
2002  if (wxStrcmp (buf, _T("   3E+08")) != 0)
2003    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("   3E+08"));
2004  wxSprintf (buf, _T("%.g"), 33.3);
2005  if (wxStrcmp (buf, _T("3e+01")) != 0)
2006    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3e+01"));
2007  wxSprintf (buf, _T("%.G"), 33.3);
2008  if (wxStrcmp (buf, _T("3E+01")) != 0)
2009    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3E+01"));
2010}
2011
2012static void
2013rfg2 (void)
2014{
2015  int prec;
2016  wxChar buf[100];
2017  wxString test_format;
2018
2019  prec = 0;
2020  wxSprintf (buf, _T("%.*g"), prec, 3.3);
2021  if (wxStrcmp (buf, _T("3")) != 0)
2022    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2023  prec = 0;
2024  wxSprintf (buf, _T("%.*G"), prec, 3.3);
2025  if (wxStrcmp (buf, _T("3")) != 0)
2026    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("3"));
2027  prec = 0;
2028  wxSprintf (buf, _T("%7.*G"), prec, 3.33);
2029  if (wxStrcmp (buf, _T("      3")) != 0)
2030    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("      3"));
2031  prec = 3;
2032  test_format = _T("%04.*o");
2033  wxSprintf (buf, test_format.c_str(), prec, 33);
2034  if (wxStrcmp (buf, _T(" 041")) != 0)
2035    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 041"));
2036  prec = 7;
2037  test_format = _T("%09.*u");
2038  wxSprintf (buf, test_format.c_str(), prec, 33);
2039  if (wxStrcmp (buf, _T("  0000033")) != 0)
2040    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T("  0000033"));
2041  prec = 3;
2042  test_format = _T("%04.*x");
2043  wxSprintf (buf, test_format.c_str(), prec, 33);
2044  if (wxStrcmp (buf, _T(" 021")) != 0)
2045    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2046  prec = 3;
2047  test_format = _T("%04.*X");
2048  wxSprintf (buf, test_format.c_str(), prec, 33);
2049  if (wxStrcmp (buf, _T(" 021")) != 0)
2050    wxPrintf (_T("got: '%s', expected: '%s'\n"), buf, _T(" 021"));
2051}
2052
2053#endif // TEST_PRINTF
2054
2055// ----------------------------------------------------------------------------
2056// registry and related stuff
2057// ----------------------------------------------------------------------------
2058
2059// this is for MSW only
2060#ifndef __WXMSW__
2061    #undef TEST_REGCONF
2062    #undef TEST_REGISTRY
2063#endif
2064
2065#ifdef TEST_REGCONF
2066
2067#include "wx/confbase.h"
2068#include "wx/msw/regconf.h"
2069
2070#if 0
2071static void TestRegConfWrite()
2072{
2073    wxConfig *config = new wxConfig(_T("myapp"));
2074    config->SetPath(_T("/group1"));
2075    config->Write(_T("entry1"), _T("foo"));
2076    config->SetPath(_T("/group2"));
2077    config->Write(_T("entry1"), _T("bar"));
2078}
2079#endif
2080
2081static void TestRegConfRead()
2082{
2083    wxConfig *config = new wxConfig(_T("myapp"));
2084
2085    wxString str;
2086    long dummy;
2087    config->SetPath(_T("/"));
2088    wxPuts(_T("Enumerating / subgroups:"));
2089    bool bCont = config->GetFirstGroup(str, dummy);
2090    while(bCont)
2091    {
2092        wxPuts(str);
2093        bCont = config->GetNextGroup(str, dummy);
2094    }
2095}
2096
2097#endif // TEST_REGCONF
2098
2099#ifdef TEST_REGISTRY
2100
2101#include "wx/msw/registry.h"
2102
2103// I chose this one because I liked its name, but it probably only exists under
2104// NT
2105static const wxChar *TESTKEY =
2106    _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2107
2108static void TestRegistryRead()
2109{
2110    wxPuts(_T("*** testing registry reading ***"));
2111
2112    wxRegKey key(TESTKEY);
2113    wxPrintf(_T("The test key name is '%s'.\n"), key.GetName().c_str());
2114    if ( !key.Open() )
2115    {
2116        wxPuts(_T("ERROR: test key can't be opened, aborting test."));
2117
2118        return;
2119    }
2120
2121    size_t nSubKeys, nValues;
2122    if ( key.GetKeyInfo(&nSubKeys, NULL, &nValues, NULL) )
2123    {
2124        wxPrintf(_T("It has %u subkeys and %u values.\n"), nSubKeys, nValues);
2125    }
2126
2127    wxPrintf(_T("Enumerating values:\n"));
2128
2129    long dummy;
2130    wxString value;
2131    bool cont = key.GetFirstValue(value, dummy);
2132    while ( cont )
2133    {
2134        wxPrintf(_T("Value '%s': type "), value.c_str());
2135        switch ( key.GetValueType(value) )
2136        {
2137            case wxRegKey::Type_None:   wxPrintf(_T("ERROR (none)")); break;
2138            case wxRegKey::Type_String: wxPrintf(_T("SZ")); break;
2139            case wxRegKey::Type_Expand_String: wxPrintf(_T("EXPAND_SZ")); break;
2140            case wxRegKey::Type_Binary: wxPrintf(_T("BINARY")); break;
2141            case wxRegKey::Type_Dword: wxPrintf(_T("DWORD")); break;
2142            case wxRegKey::Type_Multi_String: wxPrintf(_T("MULTI_SZ")); break;
2143            default: wxPrintf(_T("other (unknown)")); break;
2144        }
2145
2146        wxPrintf(_T(", value = "));
2147        if ( key.IsNumericValue(value) )
2148        {
2149            long val;
2150            key.QueryValue(value, &val);
2151            wxPrintf(_T("%ld"), val);
2152        }
2153        else // string
2154        {
2155            wxString val;
2156            key.QueryValue(value, val);
2157            wxPrintf(_T("'%s'"), val.c_str());
2158
2159            key.QueryRawValue(value, val);
2160            wxPrintf(_T(" (raw value '%s')"), val.c_str());
2161        }
2162
2163        wxPutchar('\n');
2164
2165        cont = key.GetNextValue(value, dummy);
2166    }
2167}
2168
2169static void TestRegistryAssociation()
2170{
2171    /*
2172       The second call to deleteself genertaes an error message, with a
2173       messagebox saying .flo is crucial to system operation, while the .ddf
2174       call also fails, but with no error message
2175    */
2176
2177    wxRegKey key;
2178
2179    key.SetName(_T("HKEY_CLASSES_ROOT\\.ddf") );
2180    key.Create();
2181    key = _T("ddxf_auto_file") ;
2182    key.SetName(_T("HKEY_CLASSES_ROOT\\.flo") );
2183    key.Create();
2184    key = _T("ddxf_auto_file") ;
2185    key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"));
2186    key.Create();
2187    key = _T("program,0") ;
2188    key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"));
2189    key.Create();
2190    key = _T("program \"%1\"") ;
2191
2192    key.SetName(_T("HKEY_CLASSES_ROOT\\.ddf") );
2193    key.DeleteSelf();
2194    key.SetName(_T("HKEY_CLASSES_ROOT\\.flo") );
2195    key.DeleteSelf();
2196    key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\DefaultIcon"));
2197    key.DeleteSelf();
2198    key.SetName(_T("HKEY_CLASSES_ROOT\\ddxf_auto_file\\shell\\open\\command"));
2199    key.DeleteSelf();
2200}
2201
2202#endif // TEST_REGISTRY
2203
2204// ----------------------------------------------------------------------------
2205// scope guard
2206// ----------------------------------------------------------------------------
2207
2208#ifdef TEST_SCOPEGUARD
2209
2210#include "wx/scopeguard.h"
2211
2212static void function0() { puts("function0()"); }
2213static void function1(int n) { printf("function1(%d)\n", n); }
2214static void function2(double x, char c) { printf("function2(%g, %c)\n", x, c); }
2215
2216struct Object
2217{
2218    void method0() { printf("method0()\n"); }
2219    void method1(int n) { printf("method1(%d)\n", n); }
2220    void method2(double x, char c) { printf("method2(%g, %c)\n", x, c); }
2221};
2222
2223static void TestScopeGuard()
2224{
2225    wxON_BLOCK_EXIT0(function0);
2226    wxON_BLOCK_EXIT1(function1, 17);
2227    wxON_BLOCK_EXIT2(function2, 3.14, 'p');
2228
2229    Object obj;
2230    wxON_BLOCK_EXIT_OBJ0(obj, Object::method0);
2231    wxON_BLOCK_EXIT_OBJ1(obj, Object::method1, 7);
2232    wxON_BLOCK_EXIT_OBJ2(obj, Object::method2, 2.71, 'e');
2233
2234    wxScopeGuard dismissed = wxMakeGuard(function0);
2235    dismissed.Dismiss();
2236}
2237
2238#endif
2239
2240// ----------------------------------------------------------------------------
2241// sockets
2242// ----------------------------------------------------------------------------
2243
2244#ifdef TEST_SOCKETS
2245
2246#include "wx/socket.h"
2247#include "wx/protocol/protocol.h"
2248#include "wx/protocol/http.h"
2249
2250static void TestSocketServer()
2251{
2252    wxPuts(_T("*** Testing wxSocketServer ***\n"));
2253
2254    static const int PORT = 3000;
2255
2256    wxIPV4address addr;
2257    addr.Service(PORT);
2258
2259    wxSocketServer *server = new wxSocketServer(addr);
2260    if ( !server->Ok() )
2261    {
2262        wxPuts(_T("ERROR: failed to bind"));
2263
2264        return;
2265    }
2266
2267    bool quit = false;
2268    while ( !quit )
2269    {
2270        wxPrintf(_T("Server: waiting for connection on port %d...\n"), PORT);
2271
2272        wxSocketBase *socket = server->Accept();
2273        if ( !socket )
2274        {
2275            wxPuts(_T("ERROR: wxSocketServer::Accept() failed."));
2276            break;
2277        }
2278
2279        wxPuts(_T("Server: got a client."));
2280
2281        server->SetTimeout(60); // 1 min
2282
2283        bool close = false;
2284        while ( !close && socket->IsConnected() )
2285        {
2286            wxString s;
2287            wxChar ch = _T('\0');
2288            for ( ;; )
2289            {
2290                if ( socket->Read(&ch, sizeof(ch)).Error() )
2291                {
2292                    // don't log error if the client just close the connection
2293                    if ( socket->IsConnected() )
2294                    {
2295                        wxPuts(_T("ERROR: in wxSocket::Read."));
2296                    }
2297
2298                    break;
2299                }
2300
2301                if ( ch == '\r' )
2302                    continue;
2303
2304                if ( ch == '\n' )
2305                    break;
2306
2307                s += ch;
2308            }
2309
2310            if ( ch != '\n' )
2311            {
2312                break;
2313            }
2314
2315            wxPrintf(_T("Server: got '%s'.\n"), s.c_str());
2316            if ( s == _T("close") )
2317            {
2318                wxPuts(_T("Closing connection"));
2319
2320                close = true;
2321            }
2322            else if ( s == _T("quit") )
2323            {
2324                close =
2325                quit = true;
2326
2327                wxPuts(_T("Shutting down the server"));
2328            }
2329            else // not a special command
2330            {
2331                socket->Write(s.MakeUpper().c_str(), s.length());
2332                socket->Write("\r\n", 2);
2333                wxPrintf(_T("Server: wrote '%s'.\n"), s.c_str());
2334            }
2335        }
2336
2337        if ( !close )
2338        {
2339            wxPuts(_T("Server: lost a client unexpectedly."));
2340        }
2341
2342        socket->Destroy();
2343    }
2344
2345    // same as "delete server" but is consistent with GUI programs
2346    server->Destroy();
2347}
2348
2349static void TestSocketClient()
2350{
2351    wxPuts(_T("*** Testing wxSocketClient ***\n"));
2352
2353    static const wxChar *hostname = _T("www.wxwidgets.org");
2354
2355    wxIPV4address addr;
2356    addr.Hostname(hostname);
2357    addr.Service(80);
2358
2359    wxPrintf(_T("--- Attempting to connect to %s:80...\n"), hostname);
2360
2361    wxSocketClient client;
2362    if ( !client.Connect(addr) )
2363    {
2364        wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2365    }
2366    else
2367    {
2368        wxPrintf(_T("--- Connected to %s:%u...\n"),
2369               addr.Hostname().c_str(), addr.Service());
2370
2371        wxChar buf[8192];
2372
2373        // could use simply "GET" here I suppose
2374        wxString cmdGet =
2375            wxString::Format(_T("GET http://%s/\r\n"), hostname);
2376        client.Write(cmdGet, cmdGet.length());
2377        wxPrintf(_T("--- Sent command '%s' to the server\n"),
2378               MakePrintable(cmdGet).c_str());
2379        client.Read(buf, WXSIZEOF(buf));
2380        wxPrintf(_T("--- Server replied:\n%s"), buf);
2381    }
2382}
2383
2384#endif // TEST_SOCKETS
2385
2386// ----------------------------------------------------------------------------
2387// FTP
2388// ----------------------------------------------------------------------------
2389
2390#ifdef TEST_FTP
2391
2392#include "wx/protocol/ftp.h"
2393
2394static wxFTP ftp;
2395
2396#define FTP_ANONYMOUS
2397
2398#ifdef FTP_ANONYMOUS
2399    static const wxChar *directory = _T("/pub");
2400    static const wxChar *filename = _T("welcome.msg");
2401#else
2402    static const wxChar *directory = _T("/etc");
2403    static const wxChar *filename = _T("issue");
2404#endif
2405
2406static bool TestFtpConnect()
2407{
2408    wxPuts(_T("*** Testing FTP connect ***"));
2409
2410#ifdef FTP_ANONYMOUS
2411    static const wxChar *hostname = _T("ftp.wxwidgets.org");
2412
2413    wxPrintf(_T("--- Attempting to connect to %s:21 anonymously...\n"), hostname);
2414#else // !FTP_ANONYMOUS
2415    static const wxChar *hostname = "localhost";
2416
2417    wxChar user[256];
2418    wxFgets(user, WXSIZEOF(user), stdin);
2419    user[wxStrlen(user) - 1] = '\0'; // chop off '\n'
2420    ftp.SetUser(user);
2421
2422    wxChar password[256];
2423    wxPrintf(_T("Password for %s: "), password);
2424    wxFgets(password, WXSIZEOF(password), stdin);
2425    password[wxStrlen(password) - 1] = '\0'; // chop off '\n'
2426    ftp.SetPassword(password);
2427
2428    wxPrintf(_T("--- Attempting to connect to %s:21 as %s...\n"), hostname, user);
2429#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
2430
2431    if ( !ftp.Connect(hostname) )
2432    {
2433        wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2434
2435        return false;
2436    }
2437    else
2438    {
2439        wxPrintf(_T("--- Connected to %s, current directory is '%s'\n"),
2440                 hostname, ftp.Pwd().c_str());
2441        ftp.Close();
2442    }
2443
2444    return true;
2445}
2446
2447// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
2448static void TestFtpWuFtpd()
2449{
2450    wxFTP ftp;
2451    static const wxChar *hostname = _T("ftp.eudora.com");
2452    if ( !ftp.Connect(hostname) )
2453    {
2454        wxPrintf(_T("ERROR: failed to connect to %s\n"), hostname);
2455    }
2456    else
2457    {
2458        static const wxChar *filename = _T("eudora/pubs/draft-gellens-submit-09.txt");
2459        wxInputStream *in = ftp.GetInputStream(filename);
2460        if ( !in )
2461        {
2462            wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
2463        }
2464        else
2465        {
2466            size_t size = in->GetSize();
2467            wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
2468
2469            wxChar *data = new wxChar[size];
2470            if ( !in->Read(data, size) )
2471            {
2472                wxPuts(_T("ERROR: read error"));
2473            }
2474            else
2475            {
2476                wxPrintf(_T("Successfully retrieved the file.\n"));
2477            }
2478
2479            delete [] data;
2480            delete in;
2481        }
2482    }
2483}
2484
2485static void TestFtpList()
2486{
2487    wxPuts(_T("*** Testing wxFTP file listing ***\n"));
2488
2489    // test CWD
2490    if ( !ftp.ChDir(directory) )
2491    {
2492        wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
2493    }
2494
2495    wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2496
2497    // test NLIST and LIST
2498    wxArrayString files;
2499    if ( !ftp.GetFilesList(files) )
2500    {
2501        wxPuts(_T("ERROR: failed to get NLIST of files"));
2502    }
2503    else
2504    {
2505        wxPrintf(_T("Brief list of files under '%s':\n"), ftp.Pwd().c_str());
2506        size_t count = files.GetCount();
2507        for ( size_t n = 0; n < count; n++ )
2508        {
2509            wxPrintf(_T("\t%s\n"), files[n].c_str());
2510        }
2511        wxPuts(_T("End of the file list"));
2512    }
2513
2514    if ( !ftp.GetDirList(files) )
2515    {
2516        wxPuts(_T("ERROR: failed to get LIST of files"));
2517    }
2518    else
2519    {
2520        wxPrintf(_T("Detailed list of files under '%s':\n"), ftp.Pwd().c_str());
2521        size_t count = files.GetCount();
2522        for ( size_t n = 0; n < count; n++ )
2523        {
2524            wxPrintf(_T("\t%s\n"), files[n].c_str());
2525        }
2526        wxPuts(_T("End of the file list"));
2527    }
2528
2529    if ( !ftp.ChDir(_T("..")) )
2530    {
2531        wxPuts(_T("ERROR: failed to cd to .."));
2532    }
2533
2534    wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2535}
2536
2537static void TestFtpDownload()
2538{
2539    wxPuts(_T("*** Testing wxFTP download ***\n"));
2540
2541    // test RETR
2542    wxInputStream *in = ftp.GetInputStream(filename);
2543    if ( !in )
2544    {
2545        wxPrintf(_T("ERROR: couldn't get input stream for %s\n"), filename);
2546    }
2547    else
2548    {
2549        size_t size = in->GetSize();
2550        wxPrintf(_T("Reading file %s (%u bytes)..."), filename, size);
2551        fflush(stdout);
2552
2553        wxChar *data = new wxChar[size];
2554        if ( !in->Read(data, size) )
2555        {
2556            wxPuts(_T("ERROR: read error"));
2557        }
2558        else
2559        {
2560            wxPrintf(_T("\nContents of %s:\n%s\n"), filename, data);
2561        }
2562
2563        delete [] data;
2564        delete in;
2565    }
2566}
2567
2568static void TestFtpFileSize()
2569{
2570    wxPuts(_T("*** Testing FTP SIZE command ***"));
2571
2572    if ( !ftp.ChDir(directory) )
2573    {
2574        wxPrintf(_T("ERROR: failed to cd to %s\n"), directory);
2575    }
2576
2577    wxPrintf(_T("Current directory is '%s'\n"), ftp.Pwd().c_str());
2578
2579    if ( ftp.FileExists(filename) )
2580    {
2581        int size = ftp.GetFileSize(filename);
2582        if ( size == -1 )
2583            wxPrintf(_T("ERROR: couldn't get size of '%s'\n"), filename);
2584        else
2585            wxPrintf(_T("Size of '%s' is %d bytes.\n"), filename, size);
2586    }
2587    else
2588    {
2589        wxPrintf(_T("ERROR: '%s' doesn't exist\n"), filename);
2590    }
2591}
2592
2593static void TestFtpMisc()
2594{
2595    wxPuts(_T("*** Testing miscellaneous wxFTP functions ***"));
2596
2597    if ( ftp.SendCommand(_T("STAT")) != '2' )
2598    {
2599        wxPuts(_T("ERROR: STAT failed"));
2600    }
2601    else
2602    {
2603        wxPrintf(_T("STAT returned:\n\n%s\n"), ftp.GetLastResult().c_str());
2604    }
2605
2606    if ( ftp.SendCommand(_T("HELP SITE")) != '2' )
2607    {
2608        wxPuts(_T("ERROR: HELP SITE failed"));
2609    }
2610    else
2611    {
2612        wxPrintf(_T("The list of site-specific commands:\n\n%s\n"),
2613               ftp.GetLastResult().c_str());
2614    }
2615}
2616
2617static void TestFtpInteractive()
2618{
2619    wxPuts(_T("\n*** Interactive wxFTP test ***"));
2620
2621    wxChar buf[128];
2622
2623    for ( ;; )
2624    {
2625        wxPrintf(_T("Enter FTP command: "));
2626        if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
2627            break;
2628
2629        // kill the last '\n'
2630        buf[wxStrlen(buf) - 1] = 0;
2631
2632        // special handling of LIST and NLST as they require data connection
2633        wxString start(buf, 4);
2634        start.MakeUpper();
2635        if ( start == _T("LIST") || start == _T("NLST") )
2636        {
2637            wxString wildcard;
2638            if ( wxStrlen(buf) > 4 )
2639                wildcard = buf + 5;
2640
2641            wxArrayString files;
2642            if ( !ftp.GetList(files, wildcard, start == _T("LIST")) )
2643            {
2644                wxPrintf(_T("ERROR: failed to get %s of files\n"), start.c_str());
2645            }
2646            else
2647            {
2648                wxPrintf(_T("--- %s of '%s' under '%s':\n"),
2649                       start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
2650                size_t count = files.GetCount();
2651                for ( size_t n = 0; n < count; n++ )
2652                {
2653                    wxPrintf(_T("\t%s\n"), files[n].c_str());
2654                }
2655                wxPuts(_T("--- End of the file list"));
2656            }
2657        }
2658        else // !list
2659        {
2660            wxChar ch = ftp.SendCommand(buf);
2661            wxPrintf(_T("Command %s"), ch ? _T("succeeded") : _T("failed"));
2662            if ( ch )
2663            {
2664                wxPrintf(_T(" (return code %c)"), ch);
2665            }
2666
2667            wxPrintf(_T(", server reply:\n%s\n\n"), ftp.GetLastResult().c_str());
2668        }
2669    }
2670
2671    wxPuts(_T("\n*** done ***"));
2672}
2673
2674static void TestFtpUpload()
2675{
2676    wxPuts(_T("*** Testing wxFTP uploading ***\n"));
2677
2678    // upload a file
2679    static const wxChar *file1 = _T("test1");
2680    static const wxChar *file2 = _T("test2");
2681    wxOutputStream *out = ftp.GetOutputStream(file1);
2682    if ( out )
2683    {
2684        wxPrintf(_T("--- Uploading to %s ---\n"), file1);
2685        out->Write("First hello", 11);
2686        delete out;
2687    }
2688
2689    // send a command to check the remote file
2690    if ( ftp.SendCommand(wxString(_T("STAT ")) + file1) != '2' )
2691    {
2692        wxPrintf(_T("ERROR: STAT %s failed\n"), file1);
2693    }
2694    else
2695    {
2696        wxPrintf(_T("STAT %s returned:\n\n%s\n"),
2697               file1, ftp.GetLastResult().c_str());
2698    }
2699
2700    out = ftp.GetOutputStream(file2);
2701    if ( out )
2702    {
2703        wxPrintf(_T("--- Uploading to %s ---\n"), file1);
2704        out->Write("Second hello", 12);
2705        delete out;
2706    }
2707}
2708
2709#endif // TEST_FTP
2710
2711// ----------------------------------------------------------------------------
2712// stack backtrace
2713// ----------------------------------------------------------------------------
2714
2715#ifdef TEST_STACKWALKER
2716
2717#if wxUSE_STACKWALKER
2718
2719#include "wx/stackwalk.h"
2720
2721class StackDump : public wxStackWalker
2722{
2723public:
2724    StackDump(const char *argv0)
2725        : wxStackWalker(argv0)
2726    {
2727    }
2728
2729    virtual void Walk(size_t skip = 1)
2730    {
2731        wxPuts(_T("Stack dump:"));
2732
2733        wxStackWalker::Walk(skip);
2734    }
2735
2736protected:
2737    virtual void OnStackFrame(const wxStackFrame& frame)
2738    {
2739        printf("[%2d] ", frame.GetLevel());
2740
2741        wxString name = frame.GetName();
2742        if ( !name.empty() )
2743        {
2744            printf("%-20.40s", name.mb_str());
2745        }
2746        else
2747        {
2748            printf("0x%08lx", (unsigned long)frame.GetAddress());
2749        }
2750
2751        if ( frame.HasSourceLocation() )
2752        {
2753            printf("\t%s:%d",
2754                   frame.GetFileName().mb_str(),
2755                   frame.GetLine());
2756        }
2757
2758        puts("");
2759
2760        wxString type, val;
2761        for ( size_t n = 0; frame.GetParam(n, &type, &name, &val); n++ )
2762        {
2763            printf("\t%s %s = %s\n", type.mb_str(), name.mb_str(), val.mb_str());
2764        }
2765    }
2766};
2767
2768static void TestStackWalk(const char *argv0)
2769{
2770    wxPuts(_T("*** Testing wxStackWalker ***\n"));
2771
2772    StackDump dump(argv0);
2773    dump.Walk();
2774}
2775
2776#endif // wxUSE_STACKWALKER
2777
2778#endif // TEST_STACKWALKER
2779
2780// ----------------------------------------------------------------------------
2781// standard paths
2782// ----------------------------------------------------------------------------
2783
2784#ifdef TEST_STDPATHS
2785
2786#include "wx/stdpaths.h"
2787
2788static void TestStandardPaths()
2789{
2790    wxPuts(_T("*** Testing wxStandardPaths ***\n"));
2791
2792    wxTheApp->SetAppName(_T("console"));
2793
2794    wxStandardPathsBase& stdp = wxStandardPaths::Get();
2795    wxPrintf(_T("Config dir (sys):\t%s\n"), stdp.GetConfigDir().c_str());
2796    wxPrintf(_T("Config dir (user):\t%s\n"), stdp.GetUserConfigDir().c_str());
2797    wxPrintf(_T("Data dir (sys):\t\t%s\n"), stdp.GetDataDir().c_str());
2798    wxPrintf(_T("Data dir (sys local):\t%s\n"), stdp.GetLocalDataDir().c_str());
2799    wxPrintf(_T("Data dir (user):\t%s\n"), stdp.GetUserDataDir().c_str());
2800    wxPrintf(_T("Data dir (user local):\t%s\n"), stdp.GetUserLocalDataDir().c_str());
2801    wxPrintf(_T("Documents dir:\t\t%s\n"), stdp.GetDocumentsDir().c_str());
2802    wxPrintf(_T("Executable path:\t%s\n"), stdp.GetExecutablePath().c_str());
2803    wxPrintf(_T("Plugins dir:\t\t%s\n"), stdp.GetPluginsDir().c_str());
2804    wxPrintf(_T("Resources dir:\t\t%s\n"), stdp.GetResourcesDir().c_str());
2805    wxPrintf(_T("Localized res. dir:\t%s\n"),
2806             stdp.GetLocalizedResourcesDir(_T("fr")).c_str());
2807    wxPrintf(_T("Message catalogs dir:\t%s\n"),
2808             stdp.GetLocalizedResourcesDir
2809                  (
2810                    _T("fr"),
2811                    wxStandardPaths::ResourceCat_Messages
2812                  ).c_str());
2813}
2814
2815#endif // TEST_STDPATHS
2816
2817// ----------------------------------------------------------------------------
2818// streams
2819// ----------------------------------------------------------------------------
2820
2821#ifdef TEST_STREAMS
2822
2823#include "wx/wfstream.h"
2824#include "wx/mstream.h"
2825
2826static void TestFileStream()
2827{
2828    wxPuts(_T("*** Testing wxFileInputStream ***"));
2829
2830    static const wxString filename = _T("testdata.fs");
2831    {
2832        wxFileOutputStream fsOut(filename);
2833        fsOut.Write("foo", 3);
2834    }
2835
2836    {
2837        wxFileInputStream fsIn(filename);
2838        wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
2839        while ( !fsIn.Eof() )
2840        {
2841            wxPutchar(fsIn.GetC());
2842        }
2843    }
2844
2845    if ( !wxRemoveFile(filename) )
2846    {
2847        wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename.c_str());
2848    }
2849
2850    wxPuts(_T("\n*** wxFileInputStream test done ***"));
2851}
2852
2853static void TestMemoryStream()
2854{
2855    wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
2856
2857    wxMemoryOutputStream memOutStream;
2858    wxPrintf(_T("Initially out stream offset: %lu\n"),
2859             (unsigned long)memOutStream.TellO());
2860
2861    for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
2862    {
2863        memOutStream.PutC(*p);
2864    }
2865
2866    wxPrintf(_T("Final out stream offset: %lu\n"),
2867             (unsigned long)memOutStream.TellO());
2868
2869    wxPuts(_T("*** Testing wxMemoryInputStream ***"));
2870
2871    wxChar buf[1024];
2872    size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
2873
2874    wxMemoryInputStream memInpStream(buf, len);
2875    wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2876    while ( !memInpStream.Eof() )
2877    {
2878        wxPutchar(memInpStream.GetC());
2879    }
2880
2881    wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
2882}
2883
2884#endif // TEST_STREAMS
2885
2886// ----------------------------------------------------------------------------
2887// timers
2888// ----------------------------------------------------------------------------
2889
2890#ifdef TEST_TIMER
2891
2892#include "wx/stopwatch.h"
2893#include "wx/utils.h"
2894
2895static void TestStopWatch()
2896{
2897    wxPuts(_T("*** Testing wxStopWatch ***\n"));
2898
2899    wxStopWatch sw;
2900    sw.Pause();
2901    wxPrintf(_T("Initially paused, after 2 seconds time is..."));
2902    fflush(stdout);
2903    wxSleep(2);
2904    wxPrintf(_T("\t%ldms\n"), sw.Time());
2905
2906    wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
2907    fflush(stdout);
2908    sw.Resume();
2909    wxSleep(3);
2910    wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2911
2912    sw.Pause();
2913    wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
2914    fflush(stdout);
2915    wxSleep(2);
2916    wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2917
2918    sw.Resume();
2919    wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
2920    fflush(stdout);
2921    wxSleep(2);
2922    wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2923
2924    wxStopWatch sw2;
2925    wxPuts(_T("\nChecking for 'backwards clock' bug..."));
2926    for ( size_t n = 0; n < 70; n++ )
2927    {
2928        sw2.Start();
2929
2930        for ( size_t m = 0; m < 100000; m++ )
2931        {
2932            if ( sw.Time() < 0 || sw2.Time() < 0 )
2933            {
2934                wxPuts(_T("\ntime is negative - ERROR!"));
2935            }
2936        }
2937
2938        wxPutchar('.');
2939        fflush(stdout);
2940    }
2941
2942    wxPuts(_T(", ok."));
2943}
2944
2945#endif // TEST_TIMER
2946
2947// ----------------------------------------------------------------------------
2948// vCard support
2949// ----------------------------------------------------------------------------
2950
2951#ifdef TEST_VCARD
2952
2953#include "wx/vcard.h"
2954
2955static void DumpVObject(size_t level, const wxVCardObject& vcard)
2956{
2957    void *cookie;
2958    wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2959    while ( vcObj )
2960    {
2961        wxPrintf(_T("%s%s"),
2962               wxString(_T('\t'), level).c_str(),
2963               vcObj->GetName().c_str());
2964
2965        wxString value;
2966        switch ( vcObj->GetType() )
2967        {
2968            case wxVCardObject::String:
2969            case wxVCardObject::UString:
2970                {
2971                    wxString val;
2972                    vcObj->GetValue(&val);
2973                    value << _T('"') << val << _T('"');
2974                }
2975                break;
2976
2977            case wxVCardObject::Int:
2978                {
2979                    unsigned int i;
2980                    vcObj->GetValue(&i);
2981                    value.Printf(_T("%u"), i);
2982                }
2983                break;
2984
2985            case wxVCardObject::Long:
2986                {
2987                    unsigned long l;
2988                    vcObj->GetValue(&l);
2989                    value.Printf(_T("%lu"), l);
2990                }
2991                break;
2992
2993            case wxVCardObject::None:
2994                break;
2995
2996            case wxVCardObject::Object:
2997                value = _T("<node>");
2998                break;
2999
3000            default:
3001                value = _T("<unknown value type>");
3002        }
3003
3004        if ( !!value )
3005            wxPrintf(_T(" = %s"), value.c_str());
3006        wxPutchar('\n');
3007
3008        DumpVObject(level + 1, *vcObj);
3009
3010        delete vcObj;
3011        vcObj = vcard.GetNextProp(&cookie);
3012    }
3013}
3014
3015static void DumpVCardAddresses(const wxVCard& vcard)
3016{
3017    wxPuts(_T("\nShowing all addresses from vCard:\n"));
3018
3019    size_t nAdr = 0;
3020    void *cookie;
3021    wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3022    while ( addr )
3023    {
3024        wxString flagsStr;
3025        int flags = addr->GetFlags();
3026        if ( flags & wxVCardAddress::Domestic )
3027        {
3028            flagsStr << _T("domestic ");
3029        }
3030        if ( flags & wxVCardAddress::Intl )
3031        {
3032            flagsStr << _T("international ");
3033        }
3034        if ( flags & wxVCardAddress::Postal )
3035        {
3036            flagsStr << _T("postal ");
3037        }
3038        if ( flags & wxVCardAddress::Parcel )
3039        {
3040            flagsStr << _T("parcel ");
3041        }
3042        if ( flags & wxVCardAddress::Home )
3043        {
3044            flagsStr << _T("home ");
3045        }
3046        if ( flags & wxVCardAddress::Work )
3047        {
3048            flagsStr << _T("work ");
3049        }
3050
3051        wxPrintf(_T("Address %u:\n")
3052               "\tflags = %s\n"
3053               "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3054               ++nAdr,
3055               flagsStr.c_str(),
3056               addr->GetPostOffice().c_str(),
3057               addr->GetExtAddress().c_str(),
3058               addr->GetStreet().c_str(),
3059               addr->GetLocality().c_str(),
3060               addr->GetRegion().c_str(),
3061               addr->GetPostalCode().c_str(),
3062               addr->GetCountry().c_str()
3063               );
3064
3065        delete addr;
3066        addr = vcard.GetNextAddress(&cookie);
3067    }
3068}
3069
3070static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3071{
3072    wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
3073
3074    size_t nPhone = 0;
3075    void *cookie;
3076    wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3077    while ( phone )
3078    {
3079        wxString flagsStr;
3080        int flags = phone->GetFlags();
3081        if ( flags & wxVCardPhoneNumber::Voice )
3082        {
3083            flagsStr << _T("voice ");
3084        }
3085        if ( flags & wxVCardPhoneNumber::Fax )
3086        {
3087            flagsStr << _T("fax ");
3088        }
3089        if ( flags & wxVCardPhoneNumber::Cellular )
3090        {
3091            flagsStr << _T("cellular ");
3092        }
3093        if ( flags & wxVCardPhoneNumber::Modem )
3094        {
3095            flagsStr << _T("modem ");
3096        }
3097        if ( flags & wxVCardPhoneNumber::Home )
3098        {
3099            flagsStr << _T("home ");
3100        }
3101        if ( flags & wxVCardPhoneNumber::Work )
3102        {
3103            flagsStr << _T("work ");
3104        }
3105
3106        wxPrintf(_T("Phone number %u:\n")
3107               "\tflags = %s\n"
3108               "\tvalue = %s\n",
3109               ++nPhone,
3110               flagsStr.c_str(),
3111               phone->GetNumber().c_str()
3112               );
3113
3114        delete phone;
3115        phone = vcard.GetNextPhoneNumber(&cookie);
3116    }
3117}
3118
3119static void TestVCardRead()
3120{
3121    wxPuts(_T("*** Testing wxVCard reading ***\n"));
3122
3123    wxVCard vcard(_T("vcard.vcf"));
3124    if ( !vcard.IsOk() )
3125    {
3126        wxPuts(_T("ERROR: couldn't load vCard."));
3127    }
3128    else
3129    {
3130        // read individual vCard properties
3131        wxVCardObject *vcObj = vcard.GetProperty("FN");
3132        wxString value;
3133        if ( vcObj )
3134        {
3135            vcObj->GetValue(&value);
3136            delete vcObj;
3137        }
3138        else
3139        {
3140            value = _T("<none>");
3141        }
3142
3143        wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
3144
3145
3146        if ( !vcard.GetFullName(&value) )
3147        {
3148            value = _T("<none>");
3149        }
3150
3151        wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
3152
3153        // now show how to deal with multiply occurring properties
3154        DumpVCardAddresses(vcard);
3155        DumpVCardPhoneNumbers(vcard);
3156
3157        // and finally show all
3158        wxPuts(_T("\nNow dumping the entire vCard:\n")
3159             "-----------------------------\n");
3160
3161        DumpVObject(0, vcard);
3162    }
3163}
3164
3165static void TestVCardWrite()
3166{
3167    wxPuts(_T("*** Testing wxVCard writing ***\n"));
3168
3169    wxVCard vcard;
3170    if ( !vcard.IsOk() )
3171    {
3172        wxPuts(_T("ERROR: couldn't create vCard."));
3173    }
3174    else
3175    {
3176        // set some fields
3177        vcard.SetName("Zeitlin", "Vadim");
3178        vcard.SetFullName("Vadim Zeitlin");
3179        vcard.SetOrganization("wxWidgets", "R&D");
3180
3181        // just dump the vCard back
3182        wxPuts(_T("Entire vCard follows:\n"));
3183        wxPuts(vcard.Write());
3184    }
3185}
3186
3187#endif // TEST_VCARD
3188
3189// ----------------------------------------------------------------------------
3190// wxVolume tests
3191// ----------------------------------------------------------------------------
3192
3193#if !defined(__WIN32__) || !wxUSE_FSVOLUME
3194    #undef TEST_VOLUME
3195#endif
3196
3197#ifdef TEST_VOLUME
3198
3199#include "wx/volume.h"
3200
3201static const wxChar *volumeKinds[] =
3202{
3203    _T("floppy"),
3204    _T("hard disk"),
3205    _T("CD-ROM"),
3206    _T("DVD-ROM"),
3207    _T("network volume"),
3208    _T("other volume"),
3209};
3210
3211static void TestFSVolume()
3212{
3213    wxPuts(_T("*** Testing wxFSVolume class ***"));
3214
3215    wxArrayString volumes = wxFSVolume::GetVolumes();
3216    size_t count = volumes.GetCount();
3217
3218    if ( !count )
3219    {
3220        wxPuts(_T("ERROR: no mounted volumes?"));
3221        return;
3222    }
3223
3224    wxPrintf(_T("%u mounted volumes found:\n"), count);
3225
3226    for ( size_t n = 0; n < count; n++ )
3227    {
3228        wxFSVolume vol(volumes[n]);
3229        if ( !vol.IsOk() )
3230        {
3231            wxPuts(_T("ERROR: couldn't create volume"));
3232            continue;
3233        }
3234
3235        wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3236                 n + 1,
3237                 vol.GetDisplayName().c_str(),
3238                 vol.GetName().c_str(),
3239                 volumeKinds[vol.GetKind()],
3240                 vol.IsWritable() ? _T("rw") : _T("ro"),
3241                 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3242                                                     : _T("fixed"));
3243    }
3244}
3245
3246#endif // TEST_VOLUME
3247
3248// ----------------------------------------------------------------------------
3249// wide char and Unicode support
3250// ----------------------------------------------------------------------------
3251
3252#ifdef TEST_WCHAR
3253
3254#include "wx/strconv.h"
3255#include "wx/fontenc.h"
3256#include "wx/encconv.h"
3257#include "wx/buffer.h"
3258
3259static const unsigned char utf8koi8r[] =
3260{
3261    208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3262    208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3263    176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3264    208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3265    181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3266    208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3267    178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3268};
3269
3270static const unsigned char utf8iso8859_1[] =
3271{
3272    0x53, 0x79, 0x73, 0x74, 0xc3, 0xa8, 0x6d, 0x65, 0x73, 0x20, 0x49, 0x6e,
3273    0x74, 0xc3, 0xa9, 0x67, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x65,
3274    0x6e, 0x20, 0x4d, 0xc3, 0xa9, 0x63, 0x61, 0x6e, 0x69, 0x71, 0x75, 0x65,
3275    0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x71, 0x75, 0x65, 0x20, 0x65,
3276    0x74, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x71, 0x75, 0x65, 0
3277};
3278
3279static const unsigned char utf8Invalid[] =
3280{
3281    0x3c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3e, 0x32, 0x30, 0x30,
3282    0x32, 0xe5, 0xb9, 0xb4, 0x30, 0x39, 0xe6, 0x9c, 0x88, 0x32, 0x35, 0xe6,
3283    0x97, 0xa5, 0x20, 0x30, 0x37, 0xe6, 0x99, 0x82, 0x33, 0x39, 0xe5, 0x88,
3284    0x86, 0x35, 0x37, 0xe7, 0xa7, 0x92, 0x3c, 0x2f, 0x64, 0x69, 0x73, 0x70,
3285    0x6c, 0x61, 0x79, 0
3286};
3287
3288static const struct Utf8Data
3289{
3290    const unsigned char *text;
3291    size_t len;
3292    const wxChar *charset;
3293    wxFontEncoding encoding;
3294} utf8data[] =
3295{
3296    { utf8Invalid, WXSIZEOF(utf8Invalid), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3297    { utf8koi8r, WXSIZEOF(utf8koi8r), _T("koi8-r"), wxFONTENCODING_KOI8 },
3298    { utf8iso8859_1, WXSIZEOF(utf8iso8859_1), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3299};
3300
3301static void TestUtf8()
3302{
3303    wxPuts(_T("*** Testing UTF8 support ***\n"));
3304
3305    char buf[1024];
3306    wchar_t wbuf[1024];
3307
3308    for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
3309    {
3310        const Utf8Data& u8d = utf8data[n];
3311        if ( wxConvUTF8.MB2WC(wbuf, (const char *)u8d.text,
3312                              WXSIZEOF(wbuf)) == (size_t)-1 )
3313        {
3314            wxPuts(_T("ERROR: UTF-8 decoding failed."));
3315        }
3316        else
3317        {
3318            wxCSConv conv(u8d.charset);
3319            if ( conv.WC2MB(buf, wbuf, WXSIZEOF(buf)) == (size_t)-1 )
3320            {
3321                wxPrintf(_T("ERROR: conversion to %s failed.\n"), u8d.charset);
3322            }
3323            else
3324            {
3325                wxPrintf(_T("String in %s: %s\n"), u8d.charset, buf);
3326            }
3327        }
3328
3329        wxString s(wxConvUTF8.cMB2WC((const char *)u8d.text));
3330        if ( s.empty() )
3331            s = _T("<< conversion failed >>");
3332        wxPrintf(_T("String in current cset: %s\n"), s.c_str());
3333
3334    }
3335
3336    wxPuts(wxEmptyString);
3337}
3338
3339static void TestEncodingConverter()
3340{
3341    wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3342
3343    // using wxEncodingConverter should give the same result as above
3344    char buf[1024];
3345    wchar_t wbuf[1024];
3346    if ( wxConvUTF8.MB2WC(wbuf, (const char *)utf8koi8r,
3347                          WXSIZEOF(utf8koi8r)) == (size_t)-1 )
3348    {
3349        wxPuts(_T("ERROR: UTF-8 decoding failed."));
3350    }
3351    else
3352    {
3353        wxEncodingConverter ec;
3354        ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3355        ec.Convert(wbuf, buf);
3356        wxPrintf(_T("The same KOI8-R string using wxEC: %s\n"), buf);
3357    }
3358
3359    wxPuts(wxEmptyString);
3360}
3361
3362#endif // TEST_WCHAR
3363
3364// ----------------------------------------------------------------------------
3365// ZIP stream
3366// ----------------------------------------------------------------------------
3367
3368#ifdef TEST_ZIP
3369
3370#include "wx/filesys.h"
3371#include "wx/fs_zip.h"
3372#include "wx/zipstrm.h"
3373
3374static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3375
3376static void TestZipStreamRead()
3377{
3378    wxPuts(_T("*** Testing ZIP reading ***\n"));
3379
3380    static const wxString filename = _T("foo");
3381    wxZipInputStream istr(TESTFILE_ZIP, filename);
3382    wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3383
3384    wxPrintf(_T("Dumping the file '%s':\n"), filename.c_str());
3385    while ( !istr.Eof() )
3386    {
3387        wxPutchar(istr.GetC());
3388        fflush(stdout);
3389    }
3390
3391    wxPuts(_T("\n----- done ------"));
3392}
3393
3394static void DumpZipDirectory(wxFileSystem& fs,
3395                             const wxString& dir,
3396                             const wxString& indent)
3397{
3398    wxString prefix = wxString::Format(_T("%s#zip:%s"),
3399                                         TESTFILE_ZIP, dir.c_str());
3400    wxString wildcard = prefix + _T("/*");
3401
3402    wxString dirname = fs.FindFirst(wildcard, wxDIR);
3403    while ( !dirname.empty() )
3404    {
3405        if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3406        {
3407            wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3408
3409            break;
3410        }
3411
3412        wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3413
3414        DumpZipDirectory(fs, dirname,
3415                         indent + wxString(_T(' '), 4));
3416
3417        dirname = fs.FindNext();
3418    }
3419
3420    wxString filename = fs.FindFirst(wildcard, wxFILE);
3421    while ( !filename.empty() )
3422    {
3423        if ( !filename.StartsWith(prefix, &filename) )
3424        {
3425            wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3426
3427            break;
3428        }
3429
3430        wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3431
3432        filename = fs.FindNext();
3433    }
3434}
3435
3436static void TestZipFileSystem()
3437{
3438    wxPuts(_T("*** Testing ZIP file system ***\n"));
3439
3440    wxFileSystem::AddHandler(new wxZipFSHandler);
3441    wxFileSystem fs;
3442    wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3443
3444    DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3445}
3446
3447#endif // TEST_ZIP
3448
3449// ----------------------------------------------------------------------------
3450// date time
3451// ----------------------------------------------------------------------------
3452
3453#ifdef TEST_DATETIME
3454
3455#include "wx/math.h"
3456#include "wx/datetime.h"
3457
3458// this test miscellaneous static wxDateTime functions
3459
3460#if TEST_ALL
3461
3462static void TestTimeStatic()
3463{
3464    wxPuts(_T("\n*** wxDateTime static methods test ***"));
3465
3466    // some info about the current date
3467    int year = wxDateTime::GetCurrentYear();
3468    wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
3469           year,
3470           wxDateTime::IsLeapYear(year) ? "" : "not ",
3471           wxDateTime::GetNumberOfDays(year));
3472
3473    wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3474    wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
3475           wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3476           wxDateTime::GetMonthName(month).c_str(),
3477           wxDateTime::GetNumberOfDays(month));
3478}
3479
3480// test time zones stuff
3481static void TestTimeZones()
3482{
3483    wxPuts(_T("\n*** wxDateTime timezone test ***"));
3484
3485    wxDateTime now = wxDateTime::Now();
3486
3487    wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
3488    wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
3489    wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
3490    wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
3491    wxPrintf(_T("               Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
3492    wxPrintf(_T("             New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
3493
3494    wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
3495
3496    wxDateTime::Tm tm = now.GetTm();
3497    if ( wxDateTime(tm) != now )
3498    {
3499        wxPrintf(_T("ERROR: got %s instead of %s\n"),
3500                 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3501    }
3502}
3503
3504// test some minimal support for the dates outside the standard range
3505static void TestTimeRange()
3506{
3507    wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
3508
3509    static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
3510
3511    wxPrintf(_T("Unix epoch:\t%s\n"),
3512             wxDateTime(2440587.5).Format(fmt).c_str());
3513    wxPrintf(_T("Feb 29, 0: \t%s\n"),
3514             wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3515    wxPrintf(_T("JDN 0:     \t%s\n"),
3516             wxDateTime(0.0).Format(fmt).c_str());
3517    wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
3518             wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3519    wxPrintf(_T("May 29, 2099:\t%s\n"),
3520             wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3521}
3522
3523// test DST calculations
3524static void TestTimeDST()
3525{
3526    wxPuts(_T("\n*** wxDateTime DST test ***"));
3527
3528    wxPrintf(_T("DST is%s in effect now.\n\n"),
3529             wxDateTime::Now().IsDST() ? wxEmptyString : _T(" not"));
3530
3531    for ( int year = 1990; year < 2005; year++ )
3532    {
3533        wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
3534                 year,
3535                 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3536                 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3537    }
3538}
3539
3540#endif // TEST_ALL
3541
3542#if TEST_INTERACTIVE
3543
3544static void TestDateTimeInteractive()
3545{
3546    wxPuts(_T("\n*** interactive wxDateTime tests ***"));
3547
3548    wxChar buf[128];
3549
3550    for ( ;; )
3551    {
3552        wxPrintf(_T("Enter a date: "));
3553        if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
3554            break;
3555
3556        // kill the last '\n'
3557        buf[wxStrlen(buf) - 1] = 0;
3558
3559        wxDateTime dt;
3560        const wxChar *p = dt.ParseDate(buf);
3561        if ( !p )
3562        {
3563            wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
3564
3565            continue;
3566        }
3567        else if ( *p )
3568        {
3569            wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
3570        }
3571
3572        wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
3573                 dt.Format(_T("%b %d, %Y")).c_str(),
3574                 dt.GetDayOfYear(),
3575                 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3576                 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3577                 dt.GetWeekOfYear(wxDateTime::Monday_First));
3578    }
3579
3580    wxPuts(_T("\n*** done ***"));
3581}
3582
3583#endif // TEST_INTERACTIVE
3584
3585#if TEST_ALL
3586
3587static void TestTimeMS()
3588{
3589    wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
3590
3591    wxDateTime dt1 = wxDateTime::Now(),
3592               dt2 = wxDateTime::UNow();
3593
3594    wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
3595    wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3596    wxPrintf(_T("Dummy loop: "));
3597    for ( int i = 0; i < 6000; i++ )
3598    {
3599        //for ( int j = 0; j < 10; j++ )
3600        {
3601            wxString s;
3602            s.Printf(_T("%g"), sqrt((float)i));
3603        }
3604
3605        if ( !(i % 100) )
3606            wxPutchar('.');
3607    }
3608    wxPuts(_T(", done"));
3609
3610    dt1 = dt2;
3611    dt2 = wxDateTime::UNow();
3612    wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3613
3614    wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
3615
3616    wxPuts(_T("\n*** done ***"));
3617}
3618
3619static void TestTimeHolidays()
3620{
3621    wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
3622
3623    wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3624    wxDateTime dtStart(1, tm.mon, tm.year),
3625               dtEnd = dtStart.GetLastMonthDay();
3626
3627    wxDateTimeArray hol;
3628    wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3629
3630    const wxChar *format = _T("%d-%b-%Y (%a)");
3631
3632    wxPrintf(_T("All holidays between %s and %s:\n"),
3633           dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
3634
3635    size_t count = hol.GetCount();
3636    for ( size_t n = 0; n < count; n++ )
3637    {
3638        wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
3639    }
3640
3641    wxPuts(wxEmptyString);
3642}
3643
3644static void TestTimeZoneBug()
3645{
3646    wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
3647
3648    wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
3649    for ( int i = 0; i < 31; i++ )
3650    {
3651        wxPrintf(_T("Date %s: week day %s.\n"),
3652               date.Format(_T("%d-%m-%Y")).c_str(),
3653               date.GetWeekDayName(date.GetWeekDay()).c_str());
3654
3655        date += wxDateSpan::Day();
3656    }
3657
3658    wxPuts(wxEmptyString);
3659}
3660
3661static void TestTimeSpanFormat()
3662{
3663    wxPuts(_T("\n*** wxTimeSpan tests ***"));
3664
3665    static const wxChar *formats[] =
3666    {
3667        _T("(default) %H:%M:%S"),
3668        _T("%E weeks and %D days"),
3669        _T("%l milliseconds"),
3670        _T("(with ms) %H:%M:%S:%l"),
3671        _T("100%% of minutes is %M"),       // test "%%"
3672        _T("%D days and %H hours"),
3673        _T("or also %S seconds"),
3674    };
3675
3676    wxTimeSpan ts1(1, 2, 3, 4),
3677                ts2(111, 222, 333);
3678    for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
3679    {
3680        wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
3681               ts1.Format(formats[n]).c_str(),
3682               ts2.Format(formats[n]).c_str());
3683    }
3684
3685    wxPuts(wxEmptyString);
3686}
3687
3688#endif // TEST_ALL
3689
3690#endif // TEST_DATETIME
3691
3692// ----------------------------------------------------------------------------
3693// wxTextInput/OutputStream
3694// ----------------------------------------------------------------------------
3695
3696#ifdef TEST_TEXTSTREAM
3697
3698#include "wx/txtstrm.h"
3699#include "wx/wfstream.h"
3700
3701static void TestTextInputStream()
3702{
3703    wxPuts(_T("\n*** wxTextInputStream test ***"));
3704
3705    wxString filename = _T("testdata.fc");
3706    wxFileInputStream fsIn(filename);
3707    if ( !fsIn.Ok() )
3708    {
3709        wxPuts(_T("ERROR: couldn't open file."));
3710    }
3711    else
3712    {
3713        wxTextInputStream tis(fsIn);
3714
3715        size_t line = 1;
3716        for ( ;; )
3717        {
3718            const wxString s = tis.ReadLine();
3719
3720            // line could be non empty if the last line of the file isn't
3721            // terminated with EOL
3722            if ( fsIn.Eof() && s.empty() )
3723                break;
3724
3725            wxPrintf(_T("Line %d: %s\n"), line++, s.c_str());
3726        }
3727    }
3728}
3729
3730#endif // TEST_TEXTSTREAM
3731
3732// ----------------------------------------------------------------------------
3733// threads
3734// ----------------------------------------------------------------------------
3735
3736#ifdef TEST_THREADS
3737
3738#include "wx/thread.h"
3739
3740static size_t gs_counter = (size_t)-1;
3741static wxCriticalSection gs_critsect;
3742static wxSemaphore gs_cond;
3743
3744class MyJoinableThread : public wxThread
3745{
3746public:
3747    MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3748        { m_n = n; Create(); }
3749
3750    // thread execution starts here
3751    virtual ExitCode Entry();
3752
3753private:
3754    size_t m_n;
3755};
3756
3757wxThread::ExitCode MyJoinableThread::Entry()
3758{
3759    unsigned long res = 1;
3760    for ( size_t n = 1; n < m_n; n++ )
3761    {
3762        res *= n;
3763
3764        // it's a loooong calculation :-)
3765        Sleep(100);
3766    }
3767
3768    return (ExitCode)res;
3769}
3770
3771class MyDetachedThread : public wxThread
3772{
3773public:
3774    MyDetachedThread(size_t n, wxChar ch)
3775    {
3776        m_n = n;
3777        m_ch = ch;
3778        m_cancelled = false;
3779
3780        Create();
3781    }
3782
3783    // thread execution starts here
3784    virtual ExitCode Entry();
3785
3786    // and stops here
3787    virtual void OnExit();
3788
3789private:
3790    size_t m_n; // number of characters to write
3791    wxChar m_ch;  // character to write
3792
3793    bool m_cancelled;   // false if we exit normally
3794};
3795
3796wxThread::ExitCode MyDetachedThread::Entry()
3797{
3798    {
3799        wxCriticalSectionLocker lock(gs_critsect);
3800        if ( gs_counter == (size_t)-1 )
3801            gs_counter = 1;
3802        else
3803            gs_counter++;
3804    }
3805
3806    for ( size_t n = 0; n < m_n; n++ )
3807    {
3808        if ( TestDestroy() )
3809        {
3810            m_cancelled = true;
3811
3812            break;
3813        }
3814
3815        wxPutchar(m_ch);
3816        fflush(stdout);
3817
3818        wxThread::Sleep(100);
3819    }
3820
3821    return 0;
3822}
3823
3824void MyDetachedThread::OnExit()
3825{
3826    wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
3827
3828    wxCriticalSectionLocker lock(gs_critsect);
3829    if ( !--gs_counter && !m_cancelled )
3830        gs_cond.Post();
3831}
3832
3833static void TestDetachedThreads()
3834{
3835    wxPuts(_T("\n*** Testing detached threads ***"));
3836
3837    static const size_t nThreads = 3;
3838    MyDetachedThread *threads[nThreads];
3839    size_t n;
3840    for ( n = 0; n < nThreads; n++ )
3841    {
3842        threads[n] = new MyDetachedThread(10, 'A' + n);
3843    }
3844
3845    threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3846    threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3847
3848    for ( n = 0; n < nThreads; n++ )
3849    {
3850        threads[n]->Run();
3851    }
3852
3853    // wait until all threads terminate
3854    gs_cond.Wait();
3855
3856    wxPuts(wxEmptyString);
3857}
3858
3859static void TestJoinableThreads()
3860{
3861    wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
3862
3863    // calc 10! in the background
3864    MyJoinableThread thread(10);
3865    thread.Run();
3866
3867    wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
3868             (unsigned long)thread.Wait());
3869}
3870
3871static void TestThreadSuspend()
3872{
3873    wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
3874
3875    MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3876
3877    thread->Run();
3878
3879    // this is for this demo only, in a real life program we'd use another
3880    // condition variable which would be signaled from wxThread::Entry() to
3881    // tell us that the thread really started running - but here just wait a
3882    // bit and hope that it will be enough (the problem is, of course, that
3883    // the thread might still not run when we call Pause() which will result
3884    // in an error)
3885    wxThread::Sleep(300);
3886
3887    for ( size_t n = 0; n < 3; n++ )
3888    {
3889        thread->Pause();
3890
3891        wxPuts(_T("\nThread suspended"));
3892        if ( n > 0 )
3893        {
3894            // don't sleep but resume immediately the first time
3895            wxThread::Sleep(300);
3896        }
3897        wxPuts(_T("Going to resume the thread"));
3898
3899        thread->Resume();
3900    }
3901
3902    wxPuts(_T("Waiting until it terminates now"));
3903
3904    // wait until the thread terminates
3905    gs_cond.Wait();
3906
3907    wxPuts(wxEmptyString);
3908}
3909
3910static void TestThreadDelete()
3911{
3912    // As above, using Sleep() is only for testing here - we must use some
3913    // synchronisation object instead to ensure that the thread is still
3914    // running when we delete it - deleting a detached thread which already
3915    // terminated will lead to a crash!
3916
3917    wxPuts(_T("\n*** Testing thread delete function ***"));
3918
3919    MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
3920
3921    thread0->Delete();
3922
3923    wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
3924
3925    MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
3926
3927    thread1->Run();
3928
3929    wxThread::Sleep(300);
3930
3931    thread1->Delete();
3932
3933    wxPuts(_T("\nDeleted a running thread."));
3934
3935    MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
3936
3937    thread2->Run();
3938
3939    wxThread::Sleep(300);
3940
3941    thread2->Pause();
3942
3943    thread2->Delete();
3944
3945    wxPuts(_T("\nDeleted a sleeping thread."));
3946
3947    MyJoinableThread thread3(20);
3948    thread3.Run();
3949
3950    thread3.Delete();
3951
3952    wxPuts(_T("\nDeleted a joinable thread."));
3953
3954    MyJoinableThread thread4(2);
3955    thread4.Run();
3956
3957    wxThread::Sleep(300);
3958
3959    thread4.Delete();
3960
3961    wxPuts(_T("\nDeleted a joinable thread which already terminated."));
3962
3963    wxPuts(wxEmptyString);
3964}
3965
3966class MyWaitingThread : public wxThread
3967{
3968public:
3969    MyWaitingThread( wxMutex *mutex, wxCondition *condition )
3970    {
3971        m_mutex = mutex;
3972        m_condition = condition;
3973
3974        Create();
3975    }
3976
3977    virtual ExitCode Entry()
3978    {
3979        wxPrintf(_T("Thread %lu has started running.\n"), GetId());
3980        fflush(stdout);
3981
3982        gs_cond.Post();
3983
3984        wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
3985        fflush(stdout);
3986
3987        m_mutex->Lock();
3988        m_condition->Wait();
3989        m_mutex->Unlock();
3990
3991        wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
3992        fflush(stdout);
3993
3994        return 0;
3995    }
3996
3997private:
3998    wxMutex *m_mutex;
3999    wxCondition *m_condition;
4000};
4001
4002static void TestThreadConditions()
4003{
4004    wxMutex mutex;
4005    wxCondition condition(mutex);
4006
4007    // otherwise its difficult to understand which log messages pertain to
4008    // which condition
4009    //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
4010    //           condition.GetId(), gs_cond.GetId());
4011
4012    // create and launch threads
4013    MyWaitingThread *threads[10];
4014
4015    size_t n;
4016    for ( n = 0; n < WXSIZEOF(threads); n++ )
4017    {
4018        threads[n] = new MyWaitingThread( &mutex, &condition );
4019    }
4020
4021    for ( n = 0; n < WXSIZEOF(threads); n++ )
4022    {
4023        threads[n]->Run();
4024    }
4025
4026    // wait until all threads run
4027    wxPuts(_T("Main thread is waiting for the other threads to start"));
4028    fflush(stdout);
4029
4030    size_t nRunning = 0;
4031    while ( nRunning < WXSIZEOF(threads) )
4032    {
4033        gs_cond.Wait();
4034
4035        nRunning++;
4036
4037        wxPrintf(_T("Main thread: %u already running\n"), nRunning);
4038        fflush(stdout);
4039    }
4040
4041    wxPuts(_T("Main thread: all threads started up."));
4042    fflush(stdout);
4043
4044    wxThread::Sleep(500);
4045
4046#if 1
4047    // now wake one of them up
4048    wxPrintf(_T("Main thread: about to signal the condition.\n"));
4049    fflush(stdout);
4050    condition.Signal();
4051#endif
4052
4053    wxThread::Sleep(200);
4054
4055    // wake all the (remaining) threads up, so that they can exit
4056    wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
4057    fflush(stdout);
4058    condition.Broadcast();
4059
4060    // give them time to terminate (dirty!)
4061    wxThread::Sleep(500);
4062}
4063
4064#include "wx/utils.h"
4065
4066class MyExecThread : public wxThread
4067{
4068public:
4069    MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
4070                                            m_command(command)
4071    {
4072        Create();
4073    }
4074
4075    virtual ExitCode Entry()
4076    {
4077        return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
4078    }
4079
4080private:
4081    wxString m_command;
4082};
4083
4084static void TestThreadExec()
4085{
4086    wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
4087
4088    MyExecThread thread(_T("true"));
4089    thread.Run();
4090
4091    wxPrintf(_T("Main program exit code: %ld.\n"),
4092             wxExecute(_T("false"), wxEXEC_SYNC));
4093
4094    wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
4095}
4096
4097// semaphore tests
4098#include "wx/datetime.h"
4099
4100class MySemaphoreThread : public wxThread
4101{
4102public:
4103    MySemaphoreThread(int i, wxSemaphore *sem)
4104        : wxThread(wxTHREAD_JOINABLE),
4105          m_sem(sem),
4106          m_i(i)
4107    {
4108        Create();
4109    }
4110
4111    virtual ExitCode Entry()
4112    {
4113        wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
4114                 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4115
4116        m_sem->Wait();
4117
4118        wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
4119                 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4120
4121        Sleep(1000);
4122
4123        wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
4124                 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4125
4126        m_sem->Post();
4127
4128        return 0;
4129    }
4130
4131private:
4132    wxSemaphore *m_sem;
4133    int m_i;
4134};
4135
4136WX_DEFINE_ARRAY_PTR(wxThread *, ArrayThreads);
4137
4138static void TestSemaphore()
4139{
4140    wxPuts(_T("*** Testing wxSemaphore class. ***"));
4141
4142    static const int SEM_LIMIT = 3;
4143
4144    wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
4145    ArrayThreads threads;
4146
4147    for ( int i = 0; i < 3*SEM_LIMIT; i++ )
4148    {
4149        threads.Add(new MySemaphoreThread(i, &sem));
4150        threads.Last()->Run();
4151    }
4152
4153    for ( size_t n = 0; n < threads.GetCount(); n++ )
4154    {
4155        threads[n]->Wait();
4156        delete threads[n];
4157    }
4158}
4159
4160#endif // TEST_THREADS
4161
4162// ----------------------------------------------------------------------------
4163// entry point
4164// ----------------------------------------------------------------------------
4165
4166#ifdef TEST_SNGLINST
4167    #include "wx/snglinst.h"
4168#endif // TEST_SNGLINST
4169
4170int main(int argc, char **argv)
4171{
4172#if wxUSE_UNICODE
4173    wxChar **wxArgv = new wxChar *[argc + 1];
4174
4175    {
4176        int n;
4177
4178        for (n = 0; n < argc; n++ )
4179        {
4180            wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
4181            wxArgv[n] = wxStrdup(warg);
4182        }
4183
4184        wxArgv[n] = NULL;
4185    }
4186#else // !wxUSE_UNICODE
4187    #define wxArgv argv
4188#endif // wxUSE_UNICODE/!wxUSE_UNICODE
4189
4190    wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");
4191
4192    wxInitializer initializer;
4193    if ( !initializer )
4194    {
4195        fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.");
4196
4197        return -1;
4198    }
4199
4200#ifdef TEST_SNGLINST
4201    wxSingleInstanceChecker checker;
4202    if ( checker.Create(_T(".wxconsole.lock")) )
4203    {
4204        if ( checker.IsAnotherRunning() )
4205        {
4206            wxPrintf(_T("Another instance of the program is running, exiting.\n"));
4207
4208            return 1;
4209        }
4210
4211        // wait some time to give time to launch another instance
4212        wxPrintf(_T("Press \"Enter\" to continue..."));
4213        wxFgetc(stdin);
4214    }
4215    else // failed to create
4216    {
4217        wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4218    }
4219#endif // TEST_SNGLINST
4220
4221#ifdef TEST_CMDLINE
4222    TestCmdLineConvert();
4223
4224#if wxUSE_CMDLINE_PARSER
4225    static const wxCmdLineEntryDesc cmdLineDesc[] =
4226    {
4227        { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
4228            wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
4229        { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
4230        { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"),   _T("be quiet") },
4231
4232        { wxCMD_LINE_OPTION, _T("o"), _T("output"),  _T("output file") },
4233        { wxCMD_LINE_OPTION, _T("i"), _T("input"),   _T("input dir") },
4234        { wxCMD_LINE_OPTION, _T("s"), _T("size"),    _T("output block size"),
4235            wxCMD_LINE_VAL_NUMBER },
4236        { wxCMD_LINE_OPTION, _T("d"), _T("date"),    _T("output file date"),
4237            wxCMD_LINE_VAL_DATE },
4238
4239        { wxCMD_LINE_PARAM,  NULL, NULL, _T("input file"),
4240            wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4241
4242        { wxCMD_LINE_NONE }
4243    };
4244
4245    wxCmdLineParser parser(cmdLineDesc, argc, wxArgv);
4246
4247    parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
4248                     wxCMD_LINE_VAL_STRING,
4249                     wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4250
4251    switch ( parser.Parse() )
4252    {
4253        case -1:
4254            wxLogMessage(_T("Help was given, terminating."));
4255            break;
4256
4257        case 0:
4258            ShowCmdLine(parser);
4259            break;
4260
4261        default:
4262            wxLogMessage(_T("Syntax error detected, aborting."));
4263            break;
4264    }
4265#endif // wxUSE_CMDLINE_PARSER
4266
4267#endif // TEST_CMDLINE
4268
4269#ifdef TEST_DIR
4270    #if TEST_ALL
4271        TestDirExists();
4272        TestDirEnum();
4273    #endif
4274    TestDirTraverse();
4275#endif // TEST_DIR
4276
4277#ifdef TEST_DYNLIB
4278    TestDllLoad();
4279    TestDllListLoaded();
4280#endif // TEST_DYNLIB
4281
4282#ifdef TEST_ENVIRON
4283    TestEnvironment();
4284#endif // TEST_ENVIRON
4285
4286#ifdef TEST_EXECUTE
4287    TestExecute();
4288#endif // TEST_EXECUTE
4289
4290#ifdef TEST_FILECONF
4291    TestFileConfRead();
4292#endif // TEST_FILECONF
4293
4294#ifdef TEST_LOCALE
4295    TestDefaultLang();
4296#endif // TEST_LOCALE
4297
4298#ifdef TEST_LOG
4299    wxPuts(_T("*** Testing wxLog ***"));
4300
4301    wxString s;
4302    for ( size_t n = 0; n < 8000; n++ )
4303    {
4304        s << (wxChar)(_T('A') + (n % 26));
4305    }
4306
4307    wxLogWarning(_T("The length of the string is %lu"),
4308                 (unsigned long)s.length());
4309
4310    wxString msg;
4311    msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
4312
4313    // this one shouldn't be truncated
4314    wxPrintf(msg);
4315
4316    // but this one will because log functions use fixed size buffer
4317    // (note that it doesn't need '\n' at the end neither - will be added
4318    //  by wxLog anyhow)
4319    wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
4320#endif // TEST_LOG
4321
4322#ifdef TEST_FILE
4323    TestFileRead();
4324    TestTextFileRead();
4325    TestFileCopy();
4326    TestTempFile();
4327#endif // TEST_FILE
4328
4329#ifdef TEST_FILENAME
4330    TestFileNameTemp();
4331    TestFileNameCwd();
4332    TestFileNameDirManip();
4333    TestFileNameComparison();
4334    TestFileNameOperations();
4335#endif // TEST_FILENAME
4336
4337#ifdef TEST_FILETIME
4338    TestFileGetTimes();
4339    #if 0
4340    TestFileSetTimes();
4341    #endif
4342#endif // TEST_FILETIME
4343
4344#ifdef TEST_FTP
4345    wxLog::AddTraceMask(FTP_TRACE_MASK);
4346    if ( TestFtpConnect() )
4347    {
4348        #if TEST_ALL
4349            TestFtpList();
4350            TestFtpDownload();
4351            TestFtpMisc();
4352            TestFtpFileSize();
4353            TestFtpUpload();
4354        #endif // TEST_ALL
4355
4356        #if TEST_INTERACTIVE
4357            TestFtpInteractive();
4358        #endif
4359    }
4360    //else: connecting to the FTP server failed
4361
4362    #if 0
4363        TestFtpWuFtpd();
4364    #endif
4365#endif // TEST_FTP
4366
4367#ifdef TEST_MIME
4368    wxLog::AddTraceMask(_T("mime"));
4369    #if TEST_ALL
4370        TestMimeEnum();
4371    #endif
4372        TestMimeOverride();
4373        TestMimeAssociate();
4374    TestMimeFilename();
4375#endif // TEST_MIME
4376
4377#ifdef TEST_INFO_FUNCTIONS
4378    TestOsInfo();
4379    TestPlatformInfo();
4380    TestUserInfo();
4381
4382    #if TEST_INTERACTIVE
4383        TestDiskInfo();
4384    #endif
4385#endif // TEST_INFO_FUNCTIONS
4386
4387#ifdef TEST_PATHLIST
4388    TestPathList();
4389#endif // TEST_PATHLIST
4390
4391#ifdef TEST_ODBC
4392    TestDbOpen();
4393#endif // TEST_ODBC
4394
4395#ifdef TEST_PRINTF
4396    TestPrintf();
4397#endif // TEST_PRINTF
4398
4399#ifdef TEST_REGCONF
4400    #if 0
4401    TestRegConfWrite();
4402    #endif
4403    TestRegConfRead();
4404#endif // TEST_REGCONF
4405
4406#if defined TEST_REGEX && TEST_INTERACTIVE
4407    TestRegExInteractive();
4408#endif // defined TEST_REGEX && TEST_INTERACTIVE
4409
4410#ifdef TEST_REGISTRY
4411    TestRegistryRead();
4412    TestRegistryAssociation();
4413#endif // TEST_REGISTRY
4414
4415#ifdef TEST_SOCKETS
4416    TestSocketServer();
4417    TestSocketClient();
4418#endif // TEST_SOCKETS
4419
4420#ifdef TEST_STREAMS
4421    #if TEST_ALL
4422        TestFileStream();
4423    #endif
4424        TestMemoryStream();
4425#endif // TEST_STREAMS
4426
4427#ifdef TEST_TEXTSTREAM
4428    TestTextInputStream();
4429#endif // TEST_TEXTSTREAM
4430
4431#ifdef TEST_THREADS
4432    int nCPUs = wxThread::GetCPUCount();
4433    wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
4434    if ( nCPUs != -1 )
4435        wxThread::SetConcurrency(nCPUs);
4436
4437        TestJoinableThreads();
4438
4439    #if TEST_ALL
4440        TestJoinableThreads();
4441        TestDetachedThreads();
4442        TestThreadSuspend();
4443        TestThreadDelete();
4444        TestThreadConditions();
4445        TestThreadExec();
4446        TestSemaphore();
4447    #endif
4448#endif // TEST_THREADS
4449
4450#ifdef TEST_TIMER
4451    TestStopWatch();
4452#endif // TEST_TIMER
4453
4454#ifdef TEST_DATETIME
4455    #if TEST_ALL
4456        TestTimeStatic();
4457        TestTimeRange();
4458        TestTimeZones();
4459        TestTimeDST();
4460        TestTimeHolidays();
4461        TestTimeSpanFormat();
4462        TestTimeMS();
4463
4464        TestTimeZoneBug();
4465    #endif
4466
4467    #if TEST_INTERACTIVE
4468        TestDateTimeInteractive();
4469    #endif
4470#endif // TEST_DATETIME
4471
4472#ifdef TEST_SCOPEGUARD
4473    TestScopeGuard();
4474#endif
4475
4476#ifdef TEST_STACKWALKER
4477#if wxUSE_STACKWALKER
4478    TestStackWalk(argv[0]);
4479#endif
4480#endif // TEST_STACKWALKER
4481
4482#ifdef TEST_STDPATHS
4483    TestStandardPaths();
4484#endif
4485
4486#ifdef TEST_USLEEP
4487    wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
4488    wxUsleep(3000);
4489#endif // TEST_USLEEP
4490
4491#ifdef TEST_VCARD
4492    TestVCardRead();
4493    TestVCardWrite();
4494#endif // TEST_VCARD
4495
4496#ifdef TEST_VOLUME
4497    TestFSVolume();
4498#endif // TEST_VOLUME
4499
4500#ifdef TEST_WCHAR
4501    TestUtf8();
4502    TestEncodingConverter();
4503#endif // TEST_WCHAR
4504
4505#ifdef TEST_ZIP
4506    TestZipStreamRead();
4507    TestZipFileSystem();
4508#endif // TEST_ZIP
4509
4510#if wxUSE_UNICODE
4511    {
4512        for ( int n = 0; n < argc; n++ )
4513            free(wxArgv[n]);
4514
4515        delete [] wxArgv;
4516    }
4517#endif // wxUSE_UNICODE
4518
4519    wxUnusedVar(argc);
4520    wxUnusedVar(argv);
4521    return 0;
4522}
4523