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