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