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