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