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