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