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