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