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