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
MakePrintable(const wxChar * s)114 static 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 
ShowCmdLine(const wxCmdLineParser & parser)137 static 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 
TestCmdLineConvert()170 static 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 
TestDirEnumHelper(wxDir & dir,int flags=wxDIR_DEFAULT,const wxString & filespec=wxEmptyString)214 static 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 
TestDirEnum()236 static 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 
293 class DirPrintTraverser : public wxDirTraverser
294 {
295 public:
OnFile(const wxString & WXUNUSED (filename))296     virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
297     {
298         return wxDIR_CONTINUE;
299     }
300 
OnDir(const wxString & dirname)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 
TestDirTraverse()322 static 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 
TestDirExists()345 static 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 
TestDllLoad()390 static 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 
TestDllListLoaded()458 static 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 
MyGetEnv(const wxString & var)494 static 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 
TestEnvironment()505 static 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 
TestExecute()531 static 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 
TestFileRead()600 static 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 
TestTextFileRead()638 static 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 
TestFileCopy()674 static 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 
TestTempFile()723 static 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 
752 static 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 
TestFileConfRead()763 static 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
821 static 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 
TestFileNameTemp()855 static 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 
TestFileNameDirManip()893 static void TestFileNameDirManip()
894 {
895     // TODO: test AppendDir(), RemoveDir(), ...
896 }
897 
TestFileNameComparison()898 static void TestFileNameComparison()
899 {
900     // TODO!
901 }
902 
TestFileNameOperations()903 static void TestFileNameOperations()
904 {
905     // TODO!
906 }
907 
TestFileNameCwd()908 static 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 
TestFileGetTimes()924 static 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
945 static 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 
967 static wxLocale gs_localeDefault(wxLANGUAGE_ENGLISH);
968 
969 // find the name of the language from its value
GetLangName(int lang)970 static 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 
TestDefaultLang()1212 static 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 
TestMimeEnum()1261 static 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 
TestMimeOverride()1305 static 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 
TestMimeFilename()1331 static 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 
TestMimeAssociate()1375 static 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 
1413 class wxTestModule : public wxModule
1414 {
1415 protected:
OnInit()1416     virtual bool OnInit() { wxPrintf(_T("Load module: %s\n"), GetClassInfo()->GetClassName()); return true; }
OnExit()1417     virtual void OnExit() { wxPrintf(_T("Unload module: %s\n"), GetClassInfo()->GetClassName()); }
1418 };
1419 
1420 class wxTestModuleA : public wxTestModule
1421 {
1422 public:
1423     wxTestModuleA();
1424 private:
1425     DECLARE_DYNAMIC_CLASS(wxTestModuleA)
1426 };
1427 
1428 class wxTestModuleB : public wxTestModule
1429 {
1430 public:
1431     wxTestModuleB();
1432 private:
1433     DECLARE_DYNAMIC_CLASS(wxTestModuleB)
1434 };
1435 
1436 class wxTestModuleC : public wxTestModule
1437 {
1438 public:
1439     wxTestModuleC();
1440 private:
1441     DECLARE_DYNAMIC_CLASS(wxTestModuleC)
1442 };
1443 
1444 class wxTestModuleD : public wxTestModule
1445 {
1446 public:
1447     wxTestModuleD();
1448 private:
1449     DECLARE_DYNAMIC_CLASS(wxTestModuleD)
1450 };
1451 
IMPLEMENT_DYNAMIC_CLASS(wxTestModuleC,wxModule)1452 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleC, wxModule)
1453 wxTestModuleC::wxTestModuleC()
1454 {
1455     AddDependency(CLASSINFO(wxTestModuleD));
1456 }
1457 
IMPLEMENT_DYNAMIC_CLASS(wxTestModuleA,wxModule)1458 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleA, wxModule)
1459 wxTestModuleA::wxTestModuleA()
1460 {
1461     AddDependency(CLASSINFO(wxTestModuleB));
1462     AddDependency(CLASSINFO(wxTestModuleD));
1463 }
1464 
IMPLEMENT_DYNAMIC_CLASS(wxTestModuleD,wxModule)1465 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleD, wxModule)
1466 wxTestModuleD::wxTestModuleD()
1467 {
1468 }
1469 
IMPLEMENT_DYNAMIC_CLASS(wxTestModuleB,wxModule)1470 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleB, wxModule)
1471 wxTestModuleB::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
TestDiskInfo()1488 static 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 
TestOsInfo()1518 static 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 
TestPlatformInfo()1535 static 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 
TestUserInfo()1552 static 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 
TestPathList()1578 static 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 
TestRegExInteractive()1605 static 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 
TestDbOpen()1673 static 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 
1708 static void rfg1 (void);
1709 static void rfg2 (void);
1710 
1711 
1712 static void
fmtchk(const wxChar * fmt)1713 fmtchk (const wxChar *fmt)
1714 {
1715   (void) wxPrintf(_T("%s:\t`"), fmt);
1716   (void) wxPrintf(fmt, 0x12);
1717   (void) wxPrintf(_T("'\n"));
1718 }
1719 
1720 static void
fmtst1chk(const wxChar * fmt)1721 fmtst1chk (const wxChar *fmt)
1722 {
1723   (void) wxPrintf(_T("%s:\t`"), fmt);
1724   (void) wxPrintf(fmt, 4, 0x12);
1725   (void) wxPrintf(_T("'\n"));
1726 }
1727 
1728 static void
fmtst2chk(const wxChar * fmt)1729 fmtst2chk (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 
1759 wxChar *PointerNull = NULL;
1760 
1761 static void
fp_test(void)1762 fp_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 
TestPrintf()1806 static void TestPrintf()
1807 {
1808   static wxChar shortstr[] = _T("Hi, Z.");
1809   static wxChar longstr[] = _T("Good morning, Doctor Chandra.  This is Hal.  \
1810 I 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 
1987 static void
rfg1(void)1988 rfg1 (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 
2012 static void
rfg2(void)2013 rfg2 (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
2071 static 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 
TestRegConfRead()2081 static 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
2105 static const wxChar *TESTKEY =
2106     _T("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\CrashControl");
2107 
TestRegistryRead()2108 static 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 
TestRegistryAssociation()2169 static 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 
function0()2212 static void function0() { puts("function0()"); }
function1(int n)2213 static void function1(int n) { printf("function1(%d)\n", n); }
function2(double x,char c)2214 static void function2(double x, char c) { printf("function2(%g, %c)\n", x, c); }
2215 
2216 struct Object
2217 {
method0Object2218     void method0() { printf("method0()\n"); }
method1Object2219     void method1(int n) { printf("method1(%d)\n", n); }
method2Object2220     void method2(double x, char c) { printf("method2(%g, %c)\n", x, c); }
2221 };
2222 
TestScopeGuard()2223 static 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 
TestSocketServer()2250 static 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 
TestSocketClient()2349 static 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 
2394 static 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 
TestFtpConnect()2406 static 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?
TestFtpWuFtpd()2448 static 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 
TestFtpList()2485 static 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 
TestFtpDownload()2537 static 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 
TestFtpFileSize()2568 static 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 
TestFtpMisc()2593 static 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 
TestFtpInteractive()2617 static 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 
TestFtpUpload()2674 static 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 
2721 class StackDump : public wxStackWalker
2722 {
2723 public:
StackDump(const char * argv0)2724     StackDump(const char *argv0)
2725         : wxStackWalker(argv0)
2726     {
2727     }
2728 
Walk(size_t skip=1)2729     virtual void Walk(size_t skip = 1)
2730     {
2731         wxPuts(_T("Stack dump:"));
2732 
2733         wxStackWalker::Walk(skip);
2734     }
2735 
2736 protected:
OnStackFrame(const wxStackFrame & frame)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 
TestStackWalk(const char * argv0)2768 static 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 
TestStandardPaths()2788 static 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 
TestFileStream()2826 static 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 
TestMemoryStream()2853 static 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 
TestStopWatch()2895 static 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 
DumpVObject(size_t level,const wxVCardObject & vcard)2955 static 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 
DumpVCardAddresses(const wxVCard & vcard)3015 static 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 
DumpVCardPhoneNumbers(const wxVCard & vcard)3070 static 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 
TestVCardRead()3119 static 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 
TestVCardWrite()3165 static 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 
3201 static 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 
TestFSVolume()3211 static 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 
3259 static 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 
3270 static 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 
3279 static 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 
3288 static 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 
TestUtf8()3301 static 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 
TestEncodingConverter()3339 static 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 
3374 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3375 
TestZipStreamRead()3376 static 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 
DumpZipDirectory(wxFileSystem & fs,const wxString & dir,const wxString & indent)3394 static 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 
TestZipFileSystem()3436 static 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 
TestTimeStatic()3462 static 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
TestTimeZones()3481 static 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
TestTimeRange()3505 static 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
TestTimeDST()3524 static 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 
TestDateTimeInteractive()3544 static 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 
TestTimeMS()3587 static 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 
TestTimeHolidays()3619 static 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 
TestTimeZoneBug()3644 static 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 
TestTimeSpanFormat()3661 static 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 
TestTextInputStream()3701 static 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 
3740 static size_t gs_counter = (size_t)-1;
3741 static wxCriticalSection gs_critsect;
3742 static wxSemaphore gs_cond;
3743 
3744 class MyJoinableThread : public wxThread
3745 {
3746 public:
MyJoinableThread(size_t n)3747     MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3748         { m_n = n; Create(); }
3749 
3750     // thread execution starts here
3751     virtual ExitCode Entry();
3752 
3753 private:
3754     size_t m_n;
3755 };
3756 
Entry()3757 wxThread::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 
3771 class MyDetachedThread : public wxThread
3772 {
3773 public:
MyDetachedThread(size_t n,wxChar ch)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 
3789 private:
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 
Entry()3796 wxThread::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 
OnExit()3824 void 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 
TestDetachedThreads()3833 static 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 
TestJoinableThreads()3859 static 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 
TestThreadSuspend()3871 static 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 
TestThreadDelete()3910 static 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 
3966 class MyWaitingThread : public wxThread
3967 {
3968 public:
MyWaitingThread(wxMutex * mutex,wxCondition * condition)3969     MyWaitingThread( wxMutex *mutex, wxCondition *condition )
3970     {
3971         m_mutex = mutex;
3972         m_condition = condition;
3973 
3974         Create();
3975     }
3976 
Entry()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 
3997 private:
3998     wxMutex *m_mutex;
3999     wxCondition *m_condition;
4000 };
4001 
TestThreadConditions()4002 static 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 
4066 class MyExecThread : public wxThread
4067 {
4068 public:
MyExecThread(const wxString & command)4069     MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
4070                                             m_command(command)
4071     {
4072         Create();
4073     }
4074 
Entry()4075     virtual ExitCode Entry()
4076     {
4077         return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
4078     }
4079 
4080 private:
4081     wxString m_command;
4082 };
4083 
TestThreadExec()4084 static 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 
4100 class MySemaphoreThread : public wxThread
4101 {
4102 public:
MySemaphoreThread(int i,wxSemaphore * sem)4103     MySemaphoreThread(int i, wxSemaphore *sem)
4104         : wxThread(wxTHREAD_JOINABLE),
4105           m_sem(sem),
4106           m_i(i)
4107     {
4108         Create();
4109     }
4110 
Entry()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 
4131 private:
4132     wxSemaphore *m_sem;
4133     int m_i;
4134 };
4135 
4136 WX_DEFINE_ARRAY_PTR(wxThread *, ArrayThreads);
4137 
TestSemaphore()4138 static 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 
main(int argc,char ** argv)4170 int 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