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