compilation fixes for --disable-compat28
[wxWidgets.git] / samples / console / console.cpp
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$
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
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
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
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
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
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:
296 virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
297 {
298 return wxDIR_CONTINUE;
299 }
300
301 virtual wxDirTraverseResult OnDir(const wxString& dirname)
302 {
303 wxString path, name, ext;
304 wxSplitPath(dirname, &path, &name, &ext);
305
306 if ( !ext.empty() )
307 name << _T('.') << ext;
308
309 wxString indent;
310 for ( const wxChar *p = path.c_str(); *p; p++ )
311 {
312 if ( wxIsPathSeparator(*p) )
313 indent += _T(" ");
314 }
315
316 wxPrintf(_T("%s%s\n"), indent.c_str(), name.c_str());
317
318 return wxDIR_CONTINUE;
319 }
320 };
321
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
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
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
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
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
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
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
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
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
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
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
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
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
893 static void TestFileNameDirManip()
894 {
895 // TODO: test AppendDir(), RemoveDir(), ...
896 }
897
898 static void TestFileNameComparison()
899 {
900 // TODO!
901 }
902
903 static void TestFileNameOperations()
904 {
905 // TODO!
906 }
907
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
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
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
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
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
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
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
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:
1416 virtual bool OnInit() { wxPrintf(_T("Load module: %s\n"), GetClassInfo()->GetClassName()); return true; }
1417 virtual void OnExit() { wxPrintf(_T("Unload module: %s\n"), GetClassInfo()->GetClassName()); }
1418 };
1419
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
1452 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleC, wxModule)
1453 wxTestModuleC::wxTestModuleC()
1454 {
1455 AddDependency(CLASSINFO(wxTestModuleD));
1456 }
1457
1458 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleA, wxModule)
1459 wxTestModuleA::wxTestModuleA()
1460 {
1461 AddDependency(CLASSINFO(wxTestModuleB));
1462 AddDependency(CLASSINFO(wxTestModuleD));
1463 }
1464
1465 IMPLEMENT_DYNAMIC_CLASS(wxTestModuleD, wxModule)
1466 wxTestModuleD::wxTestModuleD()
1467 {
1468 }
1469
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
2212 static void function0() { puts("function0()"); }
2213 static void function1(int n) { printf("function1(%d)\n", n); }
2214 static void function2(double x, char c) { printf("function2(%g, %c)\n", x, c); }
2215
2216 struct Object
2217 {
2218 void method0() { printf("method0()\n"); }
2219 void method1(int n) { printf("method1(%d)\n", n); }
2220 void method2(double x, char c) { printf("method2(%g, %c)\n", x, c); }
2221 };
2222
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
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
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
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?
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
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
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
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
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
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
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:
2724 StackDump(const char *argv0)
2725 : wxStackWalker(argv0)
2726 {
2727 }
2728
2729 virtual void Walk(size_t skip = 1)
2730 {
2731 wxPuts(_T("Stack dump:"));
2732
2733 wxStackWalker::Walk(skip);
2734 }
2735
2736 protected:
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
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 #include "wx/wxchar.h" // wxPrintf
2788
2789 static void TestStandardPaths()
2790 {
2791 wxPuts(_T("*** Testing wxStandardPaths ***\n"));
2792
2793 wxTheApp->SetAppName(_T("console"));
2794
2795 wxStandardPathsBase& stdp = wxStandardPaths::Get();
2796 wxPrintf(_T("Config dir (sys):\t%s\n"), stdp.GetConfigDir().c_str());
2797 wxPrintf(_T("Config dir (user):\t%s\n"), stdp.GetUserConfigDir().c_str());
2798 wxPrintf(_T("Data dir (sys):\t\t%s\n"), stdp.GetDataDir().c_str());
2799 wxPrintf(_T("Data dir (sys local):\t%s\n"), stdp.GetLocalDataDir().c_str());
2800 wxPrintf(_T("Data dir (user):\t%s\n"), stdp.GetUserDataDir().c_str());
2801 wxPrintf(_T("Data dir (user local):\t%s\n"), stdp.GetUserLocalDataDir().c_str());
2802 wxPrintf(_T("Documents dir:\t\t%s\n"), stdp.GetDocumentsDir().c_str());
2803 wxPrintf(_T("Executable path:\t%s\n"), stdp.GetExecutablePath().c_str());
2804 wxPrintf(_T("Plugins dir:\t\t%s\n"), stdp.GetPluginsDir().c_str());
2805 wxPrintf(_T("Resources dir:\t\t%s\n"), stdp.GetResourcesDir().c_str());
2806 wxPrintf(_T("Localized res. dir:\t%s\n"),
2807 stdp.GetLocalizedResourcesDir(_T("fr")).c_str());
2808 wxPrintf(_T("Message catalogs dir:\t%s\n"),
2809 stdp.GetLocalizedResourcesDir
2810 (
2811 _T("fr"),
2812 wxStandardPaths::ResourceCat_Messages
2813 ).c_str());
2814 }
2815
2816 #endif // TEST_STDPATHS
2817
2818 // ----------------------------------------------------------------------------
2819 // streams
2820 // ----------------------------------------------------------------------------
2821
2822 #ifdef TEST_STREAMS
2823
2824 #include "wx/wfstream.h"
2825 #include "wx/mstream.h"
2826
2827 static void TestFileStream()
2828 {
2829 wxPuts(_T("*** Testing wxFileInputStream ***"));
2830
2831 static const wxString filename = _T("testdata.fs");
2832 {
2833 wxFileOutputStream fsOut(filename);
2834 fsOut.Write("foo", 3);
2835 }
2836
2837 {
2838 wxFileInputStream fsIn(filename);
2839 wxPrintf(_T("File stream size: %u\n"), fsIn.GetSize());
2840 while ( !fsIn.Eof() )
2841 {
2842 wxPutchar(fsIn.GetC());
2843 }
2844 }
2845
2846 if ( !wxRemoveFile(filename) )
2847 {
2848 wxPrintf(_T("ERROR: failed to remove the file '%s'.\n"), filename.c_str());
2849 }
2850
2851 wxPuts(_T("\n*** wxFileInputStream test done ***"));
2852 }
2853
2854 static void TestMemoryStream()
2855 {
2856 wxPuts(_T("*** Testing wxMemoryOutputStream ***"));
2857
2858 wxMemoryOutputStream memOutStream;
2859 wxPrintf(_T("Initially out stream offset: %lu\n"),
2860 (unsigned long)memOutStream.TellO());
2861
2862 for ( const wxChar *p = _T("Hello, stream!"); *p; p++ )
2863 {
2864 memOutStream.PutC(*p);
2865 }
2866
2867 wxPrintf(_T("Final out stream offset: %lu\n"),
2868 (unsigned long)memOutStream.TellO());
2869
2870 wxPuts(_T("*** Testing wxMemoryInputStream ***"));
2871
2872 wxChar buf[1024];
2873 size_t len = memOutStream.CopyTo(buf, WXSIZEOF(buf));
2874
2875 wxMemoryInputStream memInpStream(buf, len);
2876 wxPrintf(_T("Memory stream size: %u\n"), memInpStream.GetSize());
2877 while ( !memInpStream.Eof() )
2878 {
2879 wxPutchar(memInpStream.GetC());
2880 }
2881
2882 wxPuts(_T("\n*** wxMemoryInputStream test done ***"));
2883 }
2884
2885 #endif // TEST_STREAMS
2886
2887 // ----------------------------------------------------------------------------
2888 // timers
2889 // ----------------------------------------------------------------------------
2890
2891 #ifdef TEST_TIMER
2892
2893 #include "wx/stopwatch.h"
2894 #include "wx/utils.h"
2895
2896 static void TestStopWatch()
2897 {
2898 wxPuts(_T("*** Testing wxStopWatch ***\n"));
2899
2900 wxStopWatch sw;
2901 sw.Pause();
2902 wxPrintf(_T("Initially paused, after 2 seconds time is..."));
2903 fflush(stdout);
2904 wxSleep(2);
2905 wxPrintf(_T("\t%ldms\n"), sw.Time());
2906
2907 wxPrintf(_T("Resuming stopwatch and sleeping 3 seconds..."));
2908 fflush(stdout);
2909 sw.Resume();
2910 wxSleep(3);
2911 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2912
2913 sw.Pause();
2914 wxPrintf(_T("Pausing agan and sleeping 2 more seconds..."));
2915 fflush(stdout);
2916 wxSleep(2);
2917 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2918
2919 sw.Resume();
2920 wxPrintf(_T("Finally resuming and sleeping 2 more seconds..."));
2921 fflush(stdout);
2922 wxSleep(2);
2923 wxPrintf(_T("\telapsed time: %ldms\n"), sw.Time());
2924
2925 wxStopWatch sw2;
2926 wxPuts(_T("\nChecking for 'backwards clock' bug..."));
2927 for ( size_t n = 0; n < 70; n++ )
2928 {
2929 sw2.Start();
2930
2931 for ( size_t m = 0; m < 100000; m++ )
2932 {
2933 if ( sw.Time() < 0 || sw2.Time() < 0 )
2934 {
2935 wxPuts(_T("\ntime is negative - ERROR!"));
2936 }
2937 }
2938
2939 wxPutchar('.');
2940 fflush(stdout);
2941 }
2942
2943 wxPuts(_T(", ok."));
2944 }
2945
2946 #endif // TEST_TIMER
2947
2948 // ----------------------------------------------------------------------------
2949 // vCard support
2950 // ----------------------------------------------------------------------------
2951
2952 #ifdef TEST_VCARD
2953
2954 #include "wx/vcard.h"
2955
2956 static void DumpVObject(size_t level, const wxVCardObject& vcard)
2957 {
2958 void *cookie;
2959 wxVCardObject *vcObj = vcard.GetFirstProp(&cookie);
2960 while ( vcObj )
2961 {
2962 wxPrintf(_T("%s%s"),
2963 wxString(_T('\t'), level).c_str(),
2964 vcObj->GetName().c_str());
2965
2966 wxString value;
2967 switch ( vcObj->GetType() )
2968 {
2969 case wxVCardObject::String:
2970 case wxVCardObject::UString:
2971 {
2972 wxString val;
2973 vcObj->GetValue(&val);
2974 value << _T('"') << val << _T('"');
2975 }
2976 break;
2977
2978 case wxVCardObject::Int:
2979 {
2980 unsigned int i;
2981 vcObj->GetValue(&i);
2982 value.Printf(_T("%u"), i);
2983 }
2984 break;
2985
2986 case wxVCardObject::Long:
2987 {
2988 unsigned long l;
2989 vcObj->GetValue(&l);
2990 value.Printf(_T("%lu"), l);
2991 }
2992 break;
2993
2994 case wxVCardObject::None:
2995 break;
2996
2997 case wxVCardObject::Object:
2998 value = _T("<node>");
2999 break;
3000
3001 default:
3002 value = _T("<unknown value type>");
3003 }
3004
3005 if ( !!value )
3006 wxPrintf(_T(" = %s"), value.c_str());
3007 wxPutchar('\n');
3008
3009 DumpVObject(level + 1, *vcObj);
3010
3011 delete vcObj;
3012 vcObj = vcard.GetNextProp(&cookie);
3013 }
3014 }
3015
3016 static void DumpVCardAddresses(const wxVCard& vcard)
3017 {
3018 wxPuts(_T("\nShowing all addresses from vCard:\n"));
3019
3020 size_t nAdr = 0;
3021 void *cookie;
3022 wxVCardAddress *addr = vcard.GetFirstAddress(&cookie);
3023 while ( addr )
3024 {
3025 wxString flagsStr;
3026 int flags = addr->GetFlags();
3027 if ( flags & wxVCardAddress::Domestic )
3028 {
3029 flagsStr << _T("domestic ");
3030 }
3031 if ( flags & wxVCardAddress::Intl )
3032 {
3033 flagsStr << _T("international ");
3034 }
3035 if ( flags & wxVCardAddress::Postal )
3036 {
3037 flagsStr << _T("postal ");
3038 }
3039 if ( flags & wxVCardAddress::Parcel )
3040 {
3041 flagsStr << _T("parcel ");
3042 }
3043 if ( flags & wxVCardAddress::Home )
3044 {
3045 flagsStr << _T("home ");
3046 }
3047 if ( flags & wxVCardAddress::Work )
3048 {
3049 flagsStr << _T("work ");
3050 }
3051
3052 wxPrintf(_T("Address %u:\n")
3053 "\tflags = %s\n"
3054 "\tvalue = %s;%s;%s;%s;%s;%s;%s\n",
3055 ++nAdr,
3056 flagsStr.c_str(),
3057 addr->GetPostOffice().c_str(),
3058 addr->GetExtAddress().c_str(),
3059 addr->GetStreet().c_str(),
3060 addr->GetLocality().c_str(),
3061 addr->GetRegion().c_str(),
3062 addr->GetPostalCode().c_str(),
3063 addr->GetCountry().c_str()
3064 );
3065
3066 delete addr;
3067 addr = vcard.GetNextAddress(&cookie);
3068 }
3069 }
3070
3071 static void DumpVCardPhoneNumbers(const wxVCard& vcard)
3072 {
3073 wxPuts(_T("\nShowing all phone numbers from vCard:\n"));
3074
3075 size_t nPhone = 0;
3076 void *cookie;
3077 wxVCardPhoneNumber *phone = vcard.GetFirstPhoneNumber(&cookie);
3078 while ( phone )
3079 {
3080 wxString flagsStr;
3081 int flags = phone->GetFlags();
3082 if ( flags & wxVCardPhoneNumber::Voice )
3083 {
3084 flagsStr << _T("voice ");
3085 }
3086 if ( flags & wxVCardPhoneNumber::Fax )
3087 {
3088 flagsStr << _T("fax ");
3089 }
3090 if ( flags & wxVCardPhoneNumber::Cellular )
3091 {
3092 flagsStr << _T("cellular ");
3093 }
3094 if ( flags & wxVCardPhoneNumber::Modem )
3095 {
3096 flagsStr << _T("modem ");
3097 }
3098 if ( flags & wxVCardPhoneNumber::Home )
3099 {
3100 flagsStr << _T("home ");
3101 }
3102 if ( flags & wxVCardPhoneNumber::Work )
3103 {
3104 flagsStr << _T("work ");
3105 }
3106
3107 wxPrintf(_T("Phone number %u:\n")
3108 "\tflags = %s\n"
3109 "\tvalue = %s\n",
3110 ++nPhone,
3111 flagsStr.c_str(),
3112 phone->GetNumber().c_str()
3113 );
3114
3115 delete phone;
3116 phone = vcard.GetNextPhoneNumber(&cookie);
3117 }
3118 }
3119
3120 static void TestVCardRead()
3121 {
3122 wxPuts(_T("*** Testing wxVCard reading ***\n"));
3123
3124 wxVCard vcard(_T("vcard.vcf"));
3125 if ( !vcard.IsOk() )
3126 {
3127 wxPuts(_T("ERROR: couldn't load vCard."));
3128 }
3129 else
3130 {
3131 // read individual vCard properties
3132 wxVCardObject *vcObj = vcard.GetProperty("FN");
3133 wxString value;
3134 if ( vcObj )
3135 {
3136 vcObj->GetValue(&value);
3137 delete vcObj;
3138 }
3139 else
3140 {
3141 value = _T("<none>");
3142 }
3143
3144 wxPrintf(_T("Full name retrieved directly: %s\n"), value.c_str());
3145
3146
3147 if ( !vcard.GetFullName(&value) )
3148 {
3149 value = _T("<none>");
3150 }
3151
3152 wxPrintf(_T("Full name from wxVCard API: %s\n"), value.c_str());
3153
3154 // now show how to deal with multiply occurring properties
3155 DumpVCardAddresses(vcard);
3156 DumpVCardPhoneNumbers(vcard);
3157
3158 // and finally show all
3159 wxPuts(_T("\nNow dumping the entire vCard:\n")
3160 "-----------------------------\n");
3161
3162 DumpVObject(0, vcard);
3163 }
3164 }
3165
3166 static void TestVCardWrite()
3167 {
3168 wxPuts(_T("*** Testing wxVCard writing ***\n"));
3169
3170 wxVCard vcard;
3171 if ( !vcard.IsOk() )
3172 {
3173 wxPuts(_T("ERROR: couldn't create vCard."));
3174 }
3175 else
3176 {
3177 // set some fields
3178 vcard.SetName("Zeitlin", "Vadim");
3179 vcard.SetFullName("Vadim Zeitlin");
3180 vcard.SetOrganization("wxWidgets", "R&D");
3181
3182 // just dump the vCard back
3183 wxPuts(_T("Entire vCard follows:\n"));
3184 wxPuts(vcard.Write());
3185 }
3186 }
3187
3188 #endif // TEST_VCARD
3189
3190 // ----------------------------------------------------------------------------
3191 // wxVolume tests
3192 // ----------------------------------------------------------------------------
3193
3194 #if !defined(__WIN32__) || !wxUSE_FSVOLUME
3195 #undef TEST_VOLUME
3196 #endif
3197
3198 #ifdef TEST_VOLUME
3199
3200 #include "wx/volume.h"
3201
3202 static const wxChar *volumeKinds[] =
3203 {
3204 _T("floppy"),
3205 _T("hard disk"),
3206 _T("CD-ROM"),
3207 _T("DVD-ROM"),
3208 _T("network volume"),
3209 _T("other volume"),
3210 };
3211
3212 static void TestFSVolume()
3213 {
3214 wxPuts(_T("*** Testing wxFSVolume class ***"));
3215
3216 wxArrayString volumes = wxFSVolume::GetVolumes();
3217 size_t count = volumes.GetCount();
3218
3219 if ( !count )
3220 {
3221 wxPuts(_T("ERROR: no mounted volumes?"));
3222 return;
3223 }
3224
3225 wxPrintf(_T("%u mounted volumes found:\n"), count);
3226
3227 for ( size_t n = 0; n < count; n++ )
3228 {
3229 wxFSVolume vol(volumes[n]);
3230 if ( !vol.IsOk() )
3231 {
3232 wxPuts(_T("ERROR: couldn't create volume"));
3233 continue;
3234 }
3235
3236 wxPrintf(_T("%u: %s (%s), %s, %s, %s\n"),
3237 n + 1,
3238 vol.GetDisplayName().c_str(),
3239 vol.GetName().c_str(),
3240 volumeKinds[vol.GetKind()],
3241 vol.IsWritable() ? _T("rw") : _T("ro"),
3242 vol.GetFlags() & wxFS_VOL_REMOVABLE ? _T("removable")
3243 : _T("fixed"));
3244 }
3245 }
3246
3247 #endif // TEST_VOLUME
3248
3249 // ----------------------------------------------------------------------------
3250 // wide char and Unicode support
3251 // ----------------------------------------------------------------------------
3252
3253 #ifdef TEST_WCHAR
3254
3255 #include "wx/strconv.h"
3256 #include "wx/fontenc.h"
3257 #include "wx/encconv.h"
3258 #include "wx/buffer.h"
3259
3260 static const unsigned char utf8koi8r[] =
3261 {
3262 208, 157, 208, 181, 209, 129, 208, 186, 208, 176, 208, 183, 208, 176,
3263 208, 189, 208, 189, 208, 190, 32, 208, 191, 208, 190, 209, 128, 208,
3264 176, 208, 180, 208, 190, 208, 178, 208, 176, 208, 187, 32, 208, 188,
3265 208, 181, 208, 189, 209, 143, 32, 209, 129, 208, 178, 208, 190, 208,
3266 181, 208, 185, 32, 208, 186, 209, 128, 209, 131, 209, 130, 208, 181,
3267 208, 185, 209, 136, 208, 181, 208, 185, 32, 208, 189, 208, 190, 208,
3268 178, 208, 190, 209, 129, 209, 130, 209, 140, 209, 142, 0
3269 };
3270
3271 static const unsigned char utf8iso8859_1[] =
3272 {
3273 0x53, 0x79, 0x73, 0x74, 0xc3, 0xa8, 0x6d, 0x65, 0x73, 0x20, 0x49, 0x6e,
3274 0x74, 0xc3, 0xa9, 0x67, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x65,
3275 0x6e, 0x20, 0x4d, 0xc3, 0xa9, 0x63, 0x61, 0x6e, 0x69, 0x71, 0x75, 0x65,
3276 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x71, 0x75, 0x65, 0x20, 0x65,
3277 0x74, 0x20, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x71, 0x75, 0x65, 0
3278 };
3279
3280 static const unsigned char utf8Invalid[] =
3281 {
3282 0x3c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3e, 0x32, 0x30, 0x30,
3283 0x32, 0xe5, 0xb9, 0xb4, 0x30, 0x39, 0xe6, 0x9c, 0x88, 0x32, 0x35, 0xe6,
3284 0x97, 0xa5, 0x20, 0x30, 0x37, 0xe6, 0x99, 0x82, 0x33, 0x39, 0xe5, 0x88,
3285 0x86, 0x35, 0x37, 0xe7, 0xa7, 0x92, 0x3c, 0x2f, 0x64, 0x69, 0x73, 0x70,
3286 0x6c, 0x61, 0x79, 0
3287 };
3288
3289 static const struct Utf8Data
3290 {
3291 const unsigned char *text;
3292 size_t len;
3293 const wxChar *charset;
3294 wxFontEncoding encoding;
3295 } utf8data[] =
3296 {
3297 { utf8Invalid, WXSIZEOF(utf8Invalid), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3298 { utf8koi8r, WXSIZEOF(utf8koi8r), _T("koi8-r"), wxFONTENCODING_KOI8 },
3299 { utf8iso8859_1, WXSIZEOF(utf8iso8859_1), _T("iso8859-1"), wxFONTENCODING_ISO8859_1 },
3300 };
3301
3302 static void TestUtf8()
3303 {
3304 wxPuts(_T("*** Testing UTF8 support ***\n"));
3305
3306 char buf[1024];
3307 wchar_t wbuf[1024];
3308
3309 for ( size_t n = 0; n < WXSIZEOF(utf8data); n++ )
3310 {
3311 const Utf8Data& u8d = utf8data[n];
3312 if ( wxConvUTF8.MB2WC(wbuf, (const char *)u8d.text,
3313 WXSIZEOF(wbuf)) == (size_t)-1 )
3314 {
3315 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3316 }
3317 else
3318 {
3319 wxCSConv conv(u8d.charset);
3320 if ( conv.WC2MB(buf, wbuf, WXSIZEOF(buf)) == (size_t)-1 )
3321 {
3322 wxPrintf(_T("ERROR: conversion to %s failed.\n"), u8d.charset);
3323 }
3324 else
3325 {
3326 wxPrintf(_T("String in %s: %s\n"), u8d.charset, buf);
3327 }
3328 }
3329
3330 wxString s(wxConvUTF8.cMB2WC((const char *)u8d.text));
3331 if ( s.empty() )
3332 s = _T("<< conversion failed >>");
3333 wxPrintf(_T("String in current cset: %s\n"), s.c_str());
3334
3335 }
3336
3337 wxPuts(wxEmptyString);
3338 }
3339
3340 static void TestEncodingConverter()
3341 {
3342 wxPuts(_T("*** Testing wxEncodingConverter ***\n"));
3343
3344 // using wxEncodingConverter should give the same result as above
3345 char buf[1024];
3346 wchar_t wbuf[1024];
3347 if ( wxConvUTF8.MB2WC(wbuf, (const char *)utf8koi8r,
3348 WXSIZEOF(utf8koi8r)) == (size_t)-1 )
3349 {
3350 wxPuts(_T("ERROR: UTF-8 decoding failed."));
3351 }
3352 else
3353 {
3354 wxEncodingConverter ec;
3355 ec.Init(wxFONTENCODING_UNICODE, wxFONTENCODING_KOI8);
3356 ec.Convert(wbuf, buf);
3357 wxPrintf(_T("The same KOI8-R string using wxEC: %s\n"), buf);
3358 }
3359
3360 wxPuts(wxEmptyString);
3361 }
3362
3363 #endif // TEST_WCHAR
3364
3365 // ----------------------------------------------------------------------------
3366 // ZIP stream
3367 // ----------------------------------------------------------------------------
3368
3369 #ifdef TEST_ZIP
3370
3371 #include "wx/filesys.h"
3372 #include "wx/fs_zip.h"
3373 #include "wx/zipstrm.h"
3374
3375 static const wxChar *TESTFILE_ZIP = _T("testdata.zip");
3376
3377 static void TestZipStreamRead()
3378 {
3379 wxPuts(_T("*** Testing ZIP reading ***\n"));
3380
3381 static const wxString filename = _T("foo");
3382 wxZipInputStream istr(TESTFILE_ZIP, filename);
3383 wxPrintf(_T("Archive size: %u\n"), istr.GetSize());
3384
3385 wxPrintf(_T("Dumping the file '%s':\n"), filename.c_str());
3386 while ( !istr.Eof() )
3387 {
3388 wxPutchar(istr.GetC());
3389 fflush(stdout);
3390 }
3391
3392 wxPuts(_T("\n----- done ------"));
3393 }
3394
3395 static void DumpZipDirectory(wxFileSystem& fs,
3396 const wxString& dir,
3397 const wxString& indent)
3398 {
3399 wxString prefix = wxString::Format(_T("%s#zip:%s"),
3400 TESTFILE_ZIP, dir.c_str());
3401 wxString wildcard = prefix + _T("/*");
3402
3403 wxString dirname = fs.FindFirst(wildcard, wxDIR);
3404 while ( !dirname.empty() )
3405 {
3406 if ( !dirname.StartsWith(prefix + _T('/'), &dirname) )
3407 {
3408 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3409
3410 break;
3411 }
3412
3413 wxPrintf(_T("%s%s\n"), indent.c_str(), dirname.c_str());
3414
3415 DumpZipDirectory(fs, dirname,
3416 indent + wxString(_T(' '), 4));
3417
3418 dirname = fs.FindNext();
3419 }
3420
3421 wxString filename = fs.FindFirst(wildcard, wxFILE);
3422 while ( !filename.empty() )
3423 {
3424 if ( !filename.StartsWith(prefix, &filename) )
3425 {
3426 wxPrintf(_T("ERROR: unexpected wxFileSystem::FindNext result\n"));
3427
3428 break;
3429 }
3430
3431 wxPrintf(_T("%s%s\n"), indent.c_str(), filename.c_str());
3432
3433 filename = fs.FindNext();
3434 }
3435 }
3436
3437 static void TestZipFileSystem()
3438 {
3439 wxPuts(_T("*** Testing ZIP file system ***\n"));
3440
3441 wxFileSystem::AddHandler(new wxZipFSHandler);
3442 wxFileSystem fs;
3443 wxPrintf(_T("Dumping all files in the archive %s:\n"), TESTFILE_ZIP);
3444
3445 DumpZipDirectory(fs, _T(""), wxString(_T(' '), 4));
3446 }
3447
3448 #endif // TEST_ZIP
3449
3450 // ----------------------------------------------------------------------------
3451 // date time
3452 // ----------------------------------------------------------------------------
3453
3454 #ifdef TEST_DATETIME
3455
3456 #include "wx/math.h"
3457 #include "wx/datetime.h"
3458
3459 // this test miscellaneous static wxDateTime functions
3460
3461 #if TEST_ALL
3462
3463 static void TestTimeStatic()
3464 {
3465 wxPuts(_T("\n*** wxDateTime static methods test ***"));
3466
3467 // some info about the current date
3468 int year = wxDateTime::GetCurrentYear();
3469 wxPrintf(_T("Current year %d is %sa leap one and has %d days.\n"),
3470 year,
3471 wxDateTime::IsLeapYear(year) ? "" : "not ",
3472 wxDateTime::GetNumberOfDays(year));
3473
3474 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
3475 wxPrintf(_T("Current month is '%s' ('%s') and it has %d days\n"),
3476 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
3477 wxDateTime::GetMonthName(month).c_str(),
3478 wxDateTime::GetNumberOfDays(month));
3479 }
3480
3481 // test time zones stuff
3482 static void TestTimeZones()
3483 {
3484 wxPuts(_T("\n*** wxDateTime timezone test ***"));
3485
3486 wxDateTime now = wxDateTime::Now();
3487
3488 wxPrintf(_T("Current GMT time:\t%s\n"), now.Format(_T("%c"), wxDateTime::GMT0).c_str());
3489 wxPrintf(_T("Unix epoch (GMT):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::GMT0).c_str());
3490 wxPrintf(_T("Unix epoch (EST):\t%s\n"), wxDateTime((time_t)0).Format(_T("%c"), wxDateTime::EST).c_str());
3491 wxPrintf(_T("Current time in Paris:\t%s\n"), now.Format(_T("%c"), wxDateTime::CET).c_str());
3492 wxPrintf(_T(" Moscow:\t%s\n"), now.Format(_T("%c"), wxDateTime::MSK).c_str());
3493 wxPrintf(_T(" New York:\t%s\n"), now.Format(_T("%c"), wxDateTime::EST).c_str());
3494
3495 wxPrintf(_T("%s\n"), wxDateTime::Now().Format(_T("Our timezone is %Z")).c_str());
3496
3497 wxDateTime::Tm tm = now.GetTm();
3498 if ( wxDateTime(tm) != now )
3499 {
3500 wxPrintf(_T("ERROR: got %s instead of %s\n"),
3501 wxDateTime(tm).Format().c_str(), now.Format().c_str());
3502 }
3503 }
3504
3505 // test some minimal support for the dates outside the standard range
3506 static void TestTimeRange()
3507 {
3508 wxPuts(_T("\n*** wxDateTime out-of-standard-range dates test ***"));
3509
3510 static const wxChar *fmt = _T("%d-%b-%Y %H:%M:%S");
3511
3512 wxPrintf(_T("Unix epoch:\t%s\n"),
3513 wxDateTime(2440587.5).Format(fmt).c_str());
3514 wxPrintf(_T("Feb 29, 0: \t%s\n"),
3515 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
3516 wxPrintf(_T("JDN 0: \t%s\n"),
3517 wxDateTime(0.0).Format(fmt).c_str());
3518 wxPrintf(_T("Jan 1, 1AD:\t%s\n"),
3519 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
3520 wxPrintf(_T("May 29, 2099:\t%s\n"),
3521 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
3522 }
3523
3524 // test DST calculations
3525 static void TestTimeDST()
3526 {
3527 wxPuts(_T("\n*** wxDateTime DST test ***"));
3528
3529 wxPrintf(_T("DST is%s in effect now.\n\n"),
3530 wxDateTime::Now().IsDST() ? wxEmptyString : _T(" not"));
3531
3532 for ( int year = 1990; year < 2005; year++ )
3533 {
3534 wxPrintf(_T("DST period in Europe for year %d: from %s to %s\n"),
3535 year,
3536 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
3537 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
3538 }
3539 }
3540
3541 #endif // TEST_ALL
3542
3543 #if TEST_INTERACTIVE
3544
3545 static void TestDateTimeInteractive()
3546 {
3547 wxPuts(_T("\n*** interactive wxDateTime tests ***"));
3548
3549 wxChar buf[128];
3550
3551 for ( ;; )
3552 {
3553 wxPrintf(_T("Enter a date: "));
3554 if ( !wxFgets(buf, WXSIZEOF(buf), stdin) )
3555 break;
3556
3557 // kill the last '\n'
3558 buf[wxStrlen(buf) - 1] = 0;
3559
3560 wxDateTime dt;
3561 const wxChar *p = dt.ParseDate(buf);
3562 if ( !p )
3563 {
3564 wxPrintf(_T("ERROR: failed to parse the date '%s'.\n"), buf);
3565
3566 continue;
3567 }
3568 else if ( *p )
3569 {
3570 wxPrintf(_T("WARNING: parsed only first %u characters.\n"), p - buf);
3571 }
3572
3573 wxPrintf(_T("%s: day %u, week of month %u/%u, week of year %u\n"),
3574 dt.Format(_T("%b %d, %Y")).c_str(),
3575 dt.GetDayOfYear(),
3576 dt.GetWeekOfMonth(wxDateTime::Monday_First),
3577 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
3578 dt.GetWeekOfYear(wxDateTime::Monday_First));
3579 }
3580
3581 wxPuts(_T("\n*** done ***"));
3582 }
3583
3584 #endif // TEST_INTERACTIVE
3585
3586 #if TEST_ALL
3587
3588 static void TestTimeMS()
3589 {
3590 wxPuts(_T("*** testing millisecond-resolution support in wxDateTime ***"));
3591
3592 wxDateTime dt1 = wxDateTime::Now(),
3593 dt2 = wxDateTime::UNow();
3594
3595 wxPrintf(_T("Now = %s\n"), dt1.Format(_T("%H:%M:%S:%l")).c_str());
3596 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3597 wxPrintf(_T("Dummy loop: "));
3598 for ( int i = 0; i < 6000; i++ )
3599 {
3600 //for ( int j = 0; j < 10; j++ )
3601 {
3602 wxString s;
3603 s.Printf(_T("%g"), sqrt((float)i));
3604 }
3605
3606 if ( !(i % 100) )
3607 wxPutchar('.');
3608 }
3609 wxPuts(_T(", done"));
3610
3611 dt1 = dt2;
3612 dt2 = wxDateTime::UNow();
3613 wxPrintf(_T("UNow = %s\n"), dt2.Format(_T("%H:%M:%S:%l")).c_str());
3614
3615 wxPrintf(_T("Loop executed in %s ms\n"), (dt2 - dt1).Format(_T("%l")).c_str());
3616
3617 wxPuts(_T("\n*** done ***"));
3618 }
3619
3620 static void TestTimeHolidays()
3621 {
3622 wxPuts(_T("\n*** testing wxDateTimeHolidayAuthority ***\n"));
3623
3624 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
3625 wxDateTime dtStart(1, tm.mon, tm.year),
3626 dtEnd = dtStart.GetLastMonthDay();
3627
3628 wxDateTimeArray hol;
3629 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
3630
3631 const wxChar *format = _T("%d-%b-%Y (%a)");
3632
3633 wxPrintf(_T("All holidays between %s and %s:\n"),
3634 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
3635
3636 size_t count = hol.GetCount();
3637 for ( size_t n = 0; n < count; n++ )
3638 {
3639 wxPrintf(_T("\t%s\n"), hol[n].Format(format).c_str());
3640 }
3641
3642 wxPuts(wxEmptyString);
3643 }
3644
3645 static void TestTimeZoneBug()
3646 {
3647 wxPuts(_T("\n*** testing for DST/timezone bug ***\n"));
3648
3649 wxDateTime date = wxDateTime(1, wxDateTime::Mar, 2000);
3650 for ( int i = 0; i < 31; i++ )
3651 {
3652 wxPrintf(_T("Date %s: week day %s.\n"),
3653 date.Format(_T("%d-%m-%Y")).c_str(),
3654 date.GetWeekDayName(date.GetWeekDay()).c_str());
3655
3656 date += wxDateSpan::Day();
3657 }
3658
3659 wxPuts(wxEmptyString);
3660 }
3661
3662 static void TestTimeSpanFormat()
3663 {
3664 wxPuts(_T("\n*** wxTimeSpan tests ***"));
3665
3666 static const wxChar *formats[] =
3667 {
3668 _T("(default) %H:%M:%S"),
3669 _T("%E weeks and %D days"),
3670 _T("%l milliseconds"),
3671 _T("(with ms) %H:%M:%S:%l"),
3672 _T("100%% of minutes is %M"), // test "%%"
3673 _T("%D days and %H hours"),
3674 _T("or also %S seconds"),
3675 };
3676
3677 wxTimeSpan ts1(1, 2, 3, 4),
3678 ts2(111, 222, 333);
3679 for ( size_t n = 0; n < WXSIZEOF(formats); n++ )
3680 {
3681 wxPrintf(_T("ts1 = %s\tts2 = %s\n"),
3682 ts1.Format(formats[n]).c_str(),
3683 ts2.Format(formats[n]).c_str());
3684 }
3685
3686 wxPuts(wxEmptyString);
3687 }
3688
3689 #endif // TEST_ALL
3690
3691 #endif // TEST_DATETIME
3692
3693 // ----------------------------------------------------------------------------
3694 // wxTextInput/OutputStream
3695 // ----------------------------------------------------------------------------
3696
3697 #ifdef TEST_TEXTSTREAM
3698
3699 #include "wx/txtstrm.h"
3700 #include "wx/wfstream.h"
3701
3702 static void TestTextInputStream()
3703 {
3704 wxPuts(_T("\n*** wxTextInputStream test ***"));
3705
3706 wxString filename = _T("testdata.fc");
3707 wxFileInputStream fsIn(filename);
3708 if ( !fsIn.Ok() )
3709 {
3710 wxPuts(_T("ERROR: couldn't open file."));
3711 }
3712 else
3713 {
3714 wxTextInputStream tis(fsIn);
3715
3716 size_t line = 1;
3717 for ( ;; )
3718 {
3719 const wxString s = tis.ReadLine();
3720
3721 // line could be non empty if the last line of the file isn't
3722 // terminated with EOL
3723 if ( fsIn.Eof() && s.empty() )
3724 break;
3725
3726 wxPrintf(_T("Line %d: %s\n"), line++, s.c_str());
3727 }
3728 }
3729 }
3730
3731 #endif // TEST_TEXTSTREAM
3732
3733 // ----------------------------------------------------------------------------
3734 // threads
3735 // ----------------------------------------------------------------------------
3736
3737 #ifdef TEST_THREADS
3738
3739 #include "wx/thread.h"
3740
3741 static size_t gs_counter = (size_t)-1;
3742 static wxCriticalSection gs_critsect;
3743 static wxSemaphore gs_cond;
3744
3745 class MyJoinableThread : public wxThread
3746 {
3747 public:
3748 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
3749 { m_n = n; Create(); }
3750
3751 // thread execution starts here
3752 virtual ExitCode Entry();
3753
3754 private:
3755 size_t m_n;
3756 };
3757
3758 wxThread::ExitCode MyJoinableThread::Entry()
3759 {
3760 unsigned long res = 1;
3761 for ( size_t n = 1; n < m_n; n++ )
3762 {
3763 res *= n;
3764
3765 // it's a loooong calculation :-)
3766 Sleep(100);
3767 }
3768
3769 return (ExitCode)res;
3770 }
3771
3772 class MyDetachedThread : public wxThread
3773 {
3774 public:
3775 MyDetachedThread(size_t n, wxChar ch)
3776 {
3777 m_n = n;
3778 m_ch = ch;
3779 m_cancelled = false;
3780
3781 Create();
3782 }
3783
3784 // thread execution starts here
3785 virtual ExitCode Entry();
3786
3787 // and stops here
3788 virtual void OnExit();
3789
3790 private:
3791 size_t m_n; // number of characters to write
3792 wxChar m_ch; // character to write
3793
3794 bool m_cancelled; // false if we exit normally
3795 };
3796
3797 wxThread::ExitCode MyDetachedThread::Entry()
3798 {
3799 {
3800 wxCriticalSectionLocker lock(gs_critsect);
3801 if ( gs_counter == (size_t)-1 )
3802 gs_counter = 1;
3803 else
3804 gs_counter++;
3805 }
3806
3807 for ( size_t n = 0; n < m_n; n++ )
3808 {
3809 if ( TestDestroy() )
3810 {
3811 m_cancelled = true;
3812
3813 break;
3814 }
3815
3816 wxPutchar(m_ch);
3817 fflush(stdout);
3818
3819 wxThread::Sleep(100);
3820 }
3821
3822 return 0;
3823 }
3824
3825 void MyDetachedThread::OnExit()
3826 {
3827 wxLogTrace(_T("thread"), _T("Thread %ld is in OnExit"), GetId());
3828
3829 wxCriticalSectionLocker lock(gs_critsect);
3830 if ( !--gs_counter && !m_cancelled )
3831 gs_cond.Post();
3832 }
3833
3834 static void TestDetachedThreads()
3835 {
3836 wxPuts(_T("\n*** Testing detached threads ***"));
3837
3838 static const size_t nThreads = 3;
3839 MyDetachedThread *threads[nThreads];
3840 size_t n;
3841 for ( n = 0; n < nThreads; n++ )
3842 {
3843 threads[n] = new MyDetachedThread(10, 'A' + n);
3844 }
3845
3846 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
3847 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
3848
3849 for ( n = 0; n < nThreads; n++ )
3850 {
3851 threads[n]->Run();
3852 }
3853
3854 // wait until all threads terminate
3855 gs_cond.Wait();
3856
3857 wxPuts(wxEmptyString);
3858 }
3859
3860 static void TestJoinableThreads()
3861 {
3862 wxPuts(_T("\n*** Testing a joinable thread (a loooong calculation...) ***"));
3863
3864 // calc 10! in the background
3865 MyJoinableThread thread(10);
3866 thread.Run();
3867
3868 wxPrintf(_T("\nThread terminated with exit code %lu.\n"),
3869 (unsigned long)thread.Wait());
3870 }
3871
3872 static void TestThreadSuspend()
3873 {
3874 wxPuts(_T("\n*** Testing thread suspend/resume functions ***"));
3875
3876 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
3877
3878 thread->Run();
3879
3880 // this is for this demo only, in a real life program we'd use another
3881 // condition variable which would be signaled from wxThread::Entry() to
3882 // tell us that the thread really started running - but here just wait a
3883 // bit and hope that it will be enough (the problem is, of course, that
3884 // the thread might still not run when we call Pause() which will result
3885 // in an error)
3886 wxThread::Sleep(300);
3887
3888 for ( size_t n = 0; n < 3; n++ )
3889 {
3890 thread->Pause();
3891
3892 wxPuts(_T("\nThread suspended"));
3893 if ( n > 0 )
3894 {
3895 // don't sleep but resume immediately the first time
3896 wxThread::Sleep(300);
3897 }
3898 wxPuts(_T("Going to resume the thread"));
3899
3900 thread->Resume();
3901 }
3902
3903 wxPuts(_T("Waiting until it terminates now"));
3904
3905 // wait until the thread terminates
3906 gs_cond.Wait();
3907
3908 wxPuts(wxEmptyString);
3909 }
3910
3911 static void TestThreadDelete()
3912 {
3913 // As above, using Sleep() is only for testing here - we must use some
3914 // synchronisation object instead to ensure that the thread is still
3915 // running when we delete it - deleting a detached thread which already
3916 // terminated will lead to a crash!
3917
3918 wxPuts(_T("\n*** Testing thread delete function ***"));
3919
3920 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
3921
3922 thread0->Delete();
3923
3924 wxPuts(_T("\nDeleted a thread which didn't start to run yet."));
3925
3926 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
3927
3928 thread1->Run();
3929
3930 wxThread::Sleep(300);
3931
3932 thread1->Delete();
3933
3934 wxPuts(_T("\nDeleted a running thread."));
3935
3936 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
3937
3938 thread2->Run();
3939
3940 wxThread::Sleep(300);
3941
3942 thread2->Pause();
3943
3944 thread2->Delete();
3945
3946 wxPuts(_T("\nDeleted a sleeping thread."));
3947
3948 MyJoinableThread thread3(20);
3949 thread3.Run();
3950
3951 thread3.Delete();
3952
3953 wxPuts(_T("\nDeleted a joinable thread."));
3954
3955 MyJoinableThread thread4(2);
3956 thread4.Run();
3957
3958 wxThread::Sleep(300);
3959
3960 thread4.Delete();
3961
3962 wxPuts(_T("\nDeleted a joinable thread which already terminated."));
3963
3964 wxPuts(wxEmptyString);
3965 }
3966
3967 class MyWaitingThread : public wxThread
3968 {
3969 public:
3970 MyWaitingThread( wxMutex *mutex, wxCondition *condition )
3971 {
3972 m_mutex = mutex;
3973 m_condition = condition;
3974
3975 Create();
3976 }
3977
3978 virtual ExitCode Entry()
3979 {
3980 wxPrintf(_T("Thread %lu has started running.\n"), GetId());
3981 fflush(stdout);
3982
3983 gs_cond.Post();
3984
3985 wxPrintf(_T("Thread %lu starts to wait...\n"), GetId());
3986 fflush(stdout);
3987
3988 m_mutex->Lock();
3989 m_condition->Wait();
3990 m_mutex->Unlock();
3991
3992 wxPrintf(_T("Thread %lu finished to wait, exiting.\n"), GetId());
3993 fflush(stdout);
3994
3995 return 0;
3996 }
3997
3998 private:
3999 wxMutex *m_mutex;
4000 wxCondition *m_condition;
4001 };
4002
4003 static void TestThreadConditions()
4004 {
4005 wxMutex mutex;
4006 wxCondition condition(mutex);
4007
4008 // otherwise its difficult to understand which log messages pertain to
4009 // which condition
4010 //wxLogTrace(_T("thread"), _T("Local condition var is %08x, gs_cond = %08x"),
4011 // condition.GetId(), gs_cond.GetId());
4012
4013 // create and launch threads
4014 MyWaitingThread *threads[10];
4015
4016 size_t n;
4017 for ( n = 0; n < WXSIZEOF(threads); n++ )
4018 {
4019 threads[n] = new MyWaitingThread( &mutex, &condition );
4020 }
4021
4022 for ( n = 0; n < WXSIZEOF(threads); n++ )
4023 {
4024 threads[n]->Run();
4025 }
4026
4027 // wait until all threads run
4028 wxPuts(_T("Main thread is waiting for the other threads to start"));
4029 fflush(stdout);
4030
4031 size_t nRunning = 0;
4032 while ( nRunning < WXSIZEOF(threads) )
4033 {
4034 gs_cond.Wait();
4035
4036 nRunning++;
4037
4038 wxPrintf(_T("Main thread: %u already running\n"), nRunning);
4039 fflush(stdout);
4040 }
4041
4042 wxPuts(_T("Main thread: all threads started up."));
4043 fflush(stdout);
4044
4045 wxThread::Sleep(500);
4046
4047 #if 1
4048 // now wake one of them up
4049 wxPrintf(_T("Main thread: about to signal the condition.\n"));
4050 fflush(stdout);
4051 condition.Signal();
4052 #endif
4053
4054 wxThread::Sleep(200);
4055
4056 // wake all the (remaining) threads up, so that they can exit
4057 wxPrintf(_T("Main thread: about to broadcast the condition.\n"));
4058 fflush(stdout);
4059 condition.Broadcast();
4060
4061 // give them time to terminate (dirty!)
4062 wxThread::Sleep(500);
4063 }
4064
4065 #include "wx/utils.h"
4066
4067 class MyExecThread : public wxThread
4068 {
4069 public:
4070 MyExecThread(const wxString& command) : wxThread(wxTHREAD_JOINABLE),
4071 m_command(command)
4072 {
4073 Create();
4074 }
4075
4076 virtual ExitCode Entry()
4077 {
4078 return (ExitCode)wxExecute(m_command, wxEXEC_SYNC);
4079 }
4080
4081 private:
4082 wxString m_command;
4083 };
4084
4085 static void TestThreadExec()
4086 {
4087 wxPuts(_T("*** Testing wxExecute interaction with threads ***\n"));
4088
4089 MyExecThread thread(_T("true"));
4090 thread.Run();
4091
4092 wxPrintf(_T("Main program exit code: %ld.\n"),
4093 wxExecute(_T("false"), wxEXEC_SYNC));
4094
4095 wxPrintf(_T("Thread exit code: %ld.\n"), (long)thread.Wait());
4096 }
4097
4098 // semaphore tests
4099 #include "wx/datetime.h"
4100
4101 class MySemaphoreThread : public wxThread
4102 {
4103 public:
4104 MySemaphoreThread(int i, wxSemaphore *sem)
4105 : wxThread(wxTHREAD_JOINABLE),
4106 m_sem(sem),
4107 m_i(i)
4108 {
4109 Create();
4110 }
4111
4112 virtual ExitCode Entry()
4113 {
4114 wxPrintf(_T("%s: Thread #%d (%ld) starting to wait for semaphore...\n"),
4115 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4116
4117 m_sem->Wait();
4118
4119 wxPrintf(_T("%s: Thread #%d (%ld) acquired the semaphore.\n"),
4120 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4121
4122 Sleep(1000);
4123
4124 wxPrintf(_T("%s: Thread #%d (%ld) releasing the semaphore.\n"),
4125 wxDateTime::Now().FormatTime().c_str(), m_i, (long)GetId());
4126
4127 m_sem->Post();
4128
4129 return 0;
4130 }
4131
4132 private:
4133 wxSemaphore *m_sem;
4134 int m_i;
4135 };
4136
4137 WX_DEFINE_ARRAY_PTR(wxThread *, ArrayThreads);
4138
4139 static void TestSemaphore()
4140 {
4141 wxPuts(_T("*** Testing wxSemaphore class. ***"));
4142
4143 static const int SEM_LIMIT = 3;
4144
4145 wxSemaphore sem(SEM_LIMIT, SEM_LIMIT);
4146 ArrayThreads threads;
4147
4148 for ( int i = 0; i < 3*SEM_LIMIT; i++ )
4149 {
4150 threads.Add(new MySemaphoreThread(i, &sem));
4151 threads.Last()->Run();
4152 }
4153
4154 for ( size_t n = 0; n < threads.GetCount(); n++ )
4155 {
4156 threads[n]->Wait();
4157 delete threads[n];
4158 }
4159 }
4160
4161 #endif // TEST_THREADS
4162
4163 // ----------------------------------------------------------------------------
4164 // entry point
4165 // ----------------------------------------------------------------------------
4166
4167 #ifdef TEST_SNGLINST
4168 #include "wx/snglinst.h"
4169 #endif // TEST_SNGLINST
4170
4171 int main(int argc, char **argv)
4172 {
4173 #if wxUSE_UNICODE
4174 wxChar **wxArgv = new wxChar *[argc + 1];
4175
4176 {
4177 int n;
4178
4179 for (n = 0; n < argc; n++ )
4180 {
4181 wxMB2WXbuf warg = wxConvertMB2WX(argv[n]);
4182 wxArgv[n] = wxStrdup(warg);
4183 }
4184
4185 wxArgv[n] = NULL;
4186 }
4187 #else // !wxUSE_UNICODE
4188 #define wxArgv argv
4189 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
4190
4191 wxApp::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, "program");
4192
4193 wxInitializer initializer;
4194 if ( !initializer )
4195 {
4196 fprintf(stderr, "Failed to initialize the wxWidgets library, aborting.");
4197
4198 return -1;
4199 }
4200
4201 #ifdef TEST_SNGLINST
4202 wxSingleInstanceChecker checker;
4203 if ( checker.Create(_T(".wxconsole.lock")) )
4204 {
4205 if ( checker.IsAnotherRunning() )
4206 {
4207 wxPrintf(_T("Another instance of the program is running, exiting.\n"));
4208
4209 return 1;
4210 }
4211
4212 // wait some time to give time to launch another instance
4213 wxPrintf(_T("Press \"Enter\" to continue..."));
4214 wxFgetc(stdin);
4215 }
4216 else // failed to create
4217 {
4218 wxPrintf(_T("Failed to init wxSingleInstanceChecker.\n"));
4219 }
4220 #endif // TEST_SNGLINST
4221
4222 #ifdef TEST_CMDLINE
4223 TestCmdLineConvert();
4224
4225 #if wxUSE_CMDLINE_PARSER
4226 static const wxCmdLineEntryDesc cmdLineDesc[] =
4227 {
4228 { wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("show this help message"),
4229 wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP },
4230 { wxCMD_LINE_SWITCH, _T("v"), _T("verbose"), _T("be verbose") },
4231 { wxCMD_LINE_SWITCH, _T("q"), _T("quiet"), _T("be quiet") },
4232
4233 { wxCMD_LINE_OPTION, _T("o"), _T("output"), _T("output file") },
4234 { wxCMD_LINE_OPTION, _T("i"), _T("input"), _T("input dir") },
4235 { wxCMD_LINE_OPTION, _T("s"), _T("size"), _T("output block size"),
4236 wxCMD_LINE_VAL_NUMBER },
4237 { wxCMD_LINE_OPTION, _T("d"), _T("date"), _T("output file date"),
4238 wxCMD_LINE_VAL_DATE },
4239
4240 { wxCMD_LINE_PARAM, NULL, NULL, _T("input file"),
4241 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
4242
4243 { wxCMD_LINE_NONE }
4244 };
4245
4246 wxCmdLineParser parser(cmdLineDesc, argc, wxArgv);
4247
4248 parser.AddOption(_T("project_name"), _T(""), _T("full path to project file"),
4249 wxCMD_LINE_VAL_STRING,
4250 wxCMD_LINE_OPTION_MANDATORY | wxCMD_LINE_NEEDS_SEPARATOR);
4251
4252 switch ( parser.Parse() )
4253 {
4254 case -1:
4255 wxLogMessage(_T("Help was given, terminating."));
4256 break;
4257
4258 case 0:
4259 ShowCmdLine(parser);
4260 break;
4261
4262 default:
4263 wxLogMessage(_T("Syntax error detected, aborting."));
4264 break;
4265 }
4266 #endif // wxUSE_CMDLINE_PARSER
4267
4268 #endif // TEST_CMDLINE
4269
4270 #ifdef TEST_DIR
4271 #if TEST_ALL
4272 TestDirExists();
4273 TestDirEnum();
4274 #endif
4275 TestDirTraverse();
4276 #endif // TEST_DIR
4277
4278 #ifdef TEST_DYNLIB
4279 TestDllLoad();
4280 TestDllListLoaded();
4281 #endif // TEST_DYNLIB
4282
4283 #ifdef TEST_ENVIRON
4284 TestEnvironment();
4285 #endif // TEST_ENVIRON
4286
4287 #ifdef TEST_EXECUTE
4288 TestExecute();
4289 #endif // TEST_EXECUTE
4290
4291 #ifdef TEST_FILECONF
4292 TestFileConfRead();
4293 #endif // TEST_FILECONF
4294
4295 #ifdef TEST_LOCALE
4296 TestDefaultLang();
4297 #endif // TEST_LOCALE
4298
4299 #ifdef TEST_LOG
4300 wxPuts(_T("*** Testing wxLog ***"));
4301
4302 wxString s;
4303 for ( size_t n = 0; n < 8000; n++ )
4304 {
4305 s << (wxChar)(_T('A') + (n % 26));
4306 }
4307
4308 wxLogWarning(_T("The length of the string is %lu"),
4309 (unsigned long)s.length());
4310
4311 wxString msg;
4312 msg.Printf(_T("A very very long message: '%s', the end!\n"), s.c_str());
4313
4314 // this one shouldn't be truncated
4315 wxPrintf(msg);
4316
4317 // but this one will because log functions use fixed size buffer
4318 // (note that it doesn't need '\n' at the end neither - will be added
4319 // by wxLog anyhow)
4320 wxLogMessage(_T("A very very long message 2: '%s', the end!"), s.c_str());
4321 #endif // TEST_LOG
4322
4323 #ifdef TEST_FILE
4324 TestFileRead();
4325 TestTextFileRead();
4326 TestFileCopy();
4327 TestTempFile();
4328 #endif // TEST_FILE
4329
4330 #ifdef TEST_FILENAME
4331 TestFileNameTemp();
4332 TestFileNameCwd();
4333 TestFileNameDirManip();
4334 TestFileNameComparison();
4335 TestFileNameOperations();
4336 #endif // TEST_FILENAME
4337
4338 #ifdef TEST_FILETIME
4339 TestFileGetTimes();
4340 #if 0
4341 TestFileSetTimes();
4342 #endif
4343 #endif // TEST_FILETIME
4344
4345 #ifdef TEST_FTP
4346 wxLog::AddTraceMask(FTP_TRACE_MASK);
4347 if ( TestFtpConnect() )
4348 {
4349 #if TEST_ALL
4350 TestFtpList();
4351 TestFtpDownload();
4352 TestFtpMisc();
4353 TestFtpFileSize();
4354 TestFtpUpload();
4355 #endif // TEST_ALL
4356
4357 #if TEST_INTERACTIVE
4358 TestFtpInteractive();
4359 #endif
4360 }
4361 //else: connecting to the FTP server failed
4362
4363 #if 0
4364 TestFtpWuFtpd();
4365 #endif
4366 #endif // TEST_FTP
4367
4368 #ifdef TEST_MIME
4369 wxLog::AddTraceMask(_T("mime"));
4370 #if TEST_ALL
4371 TestMimeEnum();
4372 #endif
4373 TestMimeOverride();
4374 TestMimeAssociate();
4375 TestMimeFilename();
4376 #endif // TEST_MIME
4377
4378 #ifdef TEST_INFO_FUNCTIONS
4379 TestOsInfo();
4380 TestPlatformInfo();
4381 TestUserInfo();
4382
4383 #if TEST_INTERACTIVE
4384 TestDiskInfo();
4385 #endif
4386 #endif // TEST_INFO_FUNCTIONS
4387
4388 #ifdef TEST_PATHLIST
4389 TestPathList();
4390 #endif // TEST_PATHLIST
4391
4392 #ifdef TEST_ODBC
4393 TestDbOpen();
4394 #endif // TEST_ODBC
4395
4396 #ifdef TEST_PRINTF
4397 TestPrintf();
4398 #endif // TEST_PRINTF
4399
4400 #ifdef TEST_REGCONF
4401 #if 0
4402 TestRegConfWrite();
4403 #endif
4404 TestRegConfRead();
4405 #endif // TEST_REGCONF
4406
4407 #if defined TEST_REGEX && TEST_INTERACTIVE
4408 TestRegExInteractive();
4409 #endif // defined TEST_REGEX && TEST_INTERACTIVE
4410
4411 #ifdef TEST_REGISTRY
4412 TestRegistryRead();
4413 TestRegistryAssociation();
4414 #endif // TEST_REGISTRY
4415
4416 #ifdef TEST_SOCKETS
4417 TestSocketServer();
4418 TestSocketClient();
4419 #endif // TEST_SOCKETS
4420
4421 #ifdef TEST_STREAMS
4422 #if TEST_ALL
4423 TestFileStream();
4424 #endif
4425 TestMemoryStream();
4426 #endif // TEST_STREAMS
4427
4428 #ifdef TEST_TEXTSTREAM
4429 TestTextInputStream();
4430 #endif // TEST_TEXTSTREAM
4431
4432 #ifdef TEST_THREADS
4433 int nCPUs = wxThread::GetCPUCount();
4434 wxPrintf(_T("This system has %d CPUs\n"), nCPUs);
4435 if ( nCPUs != -1 )
4436 wxThread::SetConcurrency(nCPUs);
4437
4438 TestJoinableThreads();
4439
4440 #if TEST_ALL
4441 TestJoinableThreads();
4442 TestDetachedThreads();
4443 TestThreadSuspend();
4444 TestThreadDelete();
4445 TestThreadConditions();
4446 TestThreadExec();
4447 TestSemaphore();
4448 #endif
4449 #endif // TEST_THREADS
4450
4451 #ifdef TEST_TIMER
4452 TestStopWatch();
4453 #endif // TEST_TIMER
4454
4455 #ifdef TEST_DATETIME
4456 #if TEST_ALL
4457 TestTimeStatic();
4458 TestTimeRange();
4459 TestTimeZones();
4460 TestTimeDST();
4461 TestTimeHolidays();
4462 TestTimeSpanFormat();
4463 TestTimeMS();
4464
4465 TestTimeZoneBug();
4466 #endif
4467
4468 #if TEST_INTERACTIVE
4469 TestDateTimeInteractive();
4470 #endif
4471 #endif // TEST_DATETIME
4472
4473 #ifdef TEST_SCOPEGUARD
4474 TestScopeGuard();
4475 #endif
4476
4477 #ifdef TEST_STACKWALKER
4478 #if wxUSE_STACKWALKER
4479 TestStackWalk(argv[0]);
4480 #endif
4481 #endif // TEST_STACKWALKER
4482
4483 #ifdef TEST_STDPATHS
4484 TestStandardPaths();
4485 #endif
4486
4487 #ifdef TEST_USLEEP
4488 wxPuts(_T("Sleeping for 3 seconds... z-z-z-z-z..."));
4489 wxUsleep(3000);
4490 #endif // TEST_USLEEP
4491
4492 #ifdef TEST_VCARD
4493 TestVCardRead();
4494 TestVCardWrite();
4495 #endif // TEST_VCARD
4496
4497 #ifdef TEST_VOLUME
4498 TestFSVolume();
4499 #endif // TEST_VOLUME
4500
4501 #ifdef TEST_WCHAR
4502 TestUtf8();
4503 TestEncodingConverter();
4504 #endif // TEST_WCHAR
4505
4506 #ifdef TEST_ZIP
4507 TestZipStreamRead();
4508 TestZipFileSystem();
4509 #endif // TEST_ZIP
4510
4511 #if wxUSE_UNICODE
4512 {
4513 for ( int n = 0; n < argc; n++ )
4514 free(wxArgv[n]);
4515
4516 delete [] wxArgv;
4517 }
4518 #endif // wxUSE_UNICODE
4519
4520 wxUnusedVar(argc);
4521 wxUnusedVar(argv);
4522 return 0;
4523 }