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