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