]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
1. corrected HAVE_PW_GECOS detection in configure (which never worked)
[wxWidgets.git] / samples / console / console.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/console/console.cpp
3 // Purpose: a sample console (as opposed to GUI) progam using wxWindows
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 04.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include <stdio.h>
21
22 #include <wx/string.h>
23 #include <wx/file.h>
24 #include <wx/app.h>
25
26 // without this pragma, the stupid compiler precompiles #defines below so that
27 // changing them doesn't "take place" later!
28 #ifdef __VISUALC__
29 #pragma hdrstop
30 #endif
31
32 // ----------------------------------------------------------------------------
33 // conditional compilation
34 // ----------------------------------------------------------------------------
35
36 // what to test (in alphabetic order)?
37
38 //#define TEST_ARRAYS
39 //#define TEST_CMDLINE
40 //#define TEST_DATETIME
41 //#define TEST_DIR
42 //#define TEST_EXECUTE
43 //#define TEST_FILECONF
44 //#define TEST_HASH
45 //#define TEST_LOG
46 //#define TEST_LONGLONG
47 //#define TEST_MIME
48 #define TEST_INFO_FUNCTIONS
49 //#define TEST_SOCKETS
50 //#define TEST_STRINGS
51 //#define TEST_THREADS
52 //#define TEST_TIMER
53
54 // ============================================================================
55 // implementation
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // helper functions
60 // ----------------------------------------------------------------------------
61
62 #if defined(TEST_STRINGS) || defined(TEST_SOCKETS)
63
64 // replace TABs with \t and CRs with \n
65 static wxString MakePrintable(const wxChar *s)
66 {
67 wxString str(s);
68 (void)str.Replace(_T("\t"), _T("\\t"));
69 (void)str.Replace(_T("\n"), _T("\\n"));
70 (void)str.Replace(_T("\r"), _T("\\r"));
71
72 return str;
73 }
74
75 #endif // MakePrintable() is used
76
77 // ----------------------------------------------------------------------------
78 // wxCmdLineParser
79 // ----------------------------------------------------------------------------
80
81 #ifdef TEST_CMDLINE
82
83 #include <wx/cmdline.h>
84 #include <wx/datetime.h>
85
86 static void ShowCmdLine(const wxCmdLineParser& parser)
87 {
88 wxString s = "Input files: ";
89
90 size_t count = parser.GetParamCount();
91 for ( size_t param = 0; param < count; param++ )
92 {
93 s << parser.GetParam(param) << ' ';
94 }
95
96 s << '\n'
97 << "Verbose:\t" << (parser.Found("v") ? "yes" : "no") << '\n'
98 << "Quiet:\t" << (parser.Found("q") ? "yes" : "no") << '\n';
99
100 wxString strVal;
101 long lVal;
102 wxDateTime dt;
103 if ( parser.Found("o", &strVal) )
104 s << "Output file:\t" << strVal << '\n';
105 if ( parser.Found("i", &strVal) )
106 s << "Input dir:\t" << strVal << '\n';
107 if ( parser.Found("s", &lVal) )
108 s << "Size:\t" << lVal << '\n';
109 if ( parser.Found("d", &dt) )
110 s << "Date:\t" << dt.FormatISODate() << '\n';
111
112 wxLogMessage(s);
113 }
114
115 #endif // TEST_CMDLINE
116
117 // ----------------------------------------------------------------------------
118 // wxDir
119 // ----------------------------------------------------------------------------
120
121 #ifdef TEST_DIR
122
123 #include <wx/dir.h>
124
125 static void TestDirEnumHelper(wxDir& dir,
126 int flags = wxDIR_DEFAULT,
127 const wxString& filespec = wxEmptyString)
128 {
129 wxString filename;
130
131 if ( !dir.IsOpened() )
132 return;
133
134 bool cont = dir.GetFirst(&filename, filespec, flags);
135 while ( cont )
136 {
137 printf("\t%s\n", filename.c_str());
138
139 cont = dir.GetNext(&filename);
140 }
141
142 puts("");
143 }
144
145 static void TestDirEnum()
146 {
147 wxDir dir(wxGetCwd());
148
149 puts("Enumerating everything in current directory:");
150 TestDirEnumHelper(dir);
151
152 puts("Enumerating really everything in current directory:");
153 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
154
155 puts("Enumerating object files in current directory:");
156 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
157
158 puts("Enumerating directories in current directory:");
159 TestDirEnumHelper(dir, wxDIR_DIRS);
160
161 puts("Enumerating files in current directory:");
162 TestDirEnumHelper(dir, wxDIR_FILES);
163
164 puts("Enumerating files including hidden in current directory:");
165 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
166
167 #ifdef __UNIX__
168 dir.Open("/");
169 #elif defined(__WXMSW__)
170 dir.Open("c:\\");
171 #else
172 #error "don't know where the root directory is"
173 #endif
174
175 puts("Enumerating everything in root directory:");
176 TestDirEnumHelper(dir, wxDIR_DEFAULT);
177
178 puts("Enumerating directories in root directory:");
179 TestDirEnumHelper(dir, wxDIR_DIRS);
180
181 puts("Enumerating files in root directory:");
182 TestDirEnumHelper(dir, wxDIR_FILES);
183
184 puts("Enumerating files including hidden in root directory:");
185 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
186
187 puts("Enumerating files in non existing directory:");
188 wxDir dirNo("nosuchdir");
189 TestDirEnumHelper(dirNo);
190 }
191
192 #endif // TEST_DIR
193
194 // ----------------------------------------------------------------------------
195 // wxExecute
196 // ----------------------------------------------------------------------------
197
198 #ifdef TEST_EXECUTE
199
200 #include <wx/utils.h>
201
202 static void TestExecute()
203 {
204 puts("*** testing wxExecute ***");
205
206 #ifdef __UNIX__
207 #define COMMAND "echo hi"
208 #define SHELL_COMMAND "echo hi from shell"
209 #define REDIRECT_COMMAND "date"
210 #elif defined(__WXMSW__)
211 #define COMMAND "command.com -c 'echo hi'"
212 #define SHELL_COMMAND "echo hi"
213 #define REDIRECT_COMMAND COMMAND
214 #else
215 #error "no command to exec"
216 #endif // OS
217
218 printf("Testing wxShell: ");
219 fflush(stdout);
220 if ( wxShell(SHELL_COMMAND) )
221 puts("Ok.");
222 else
223 puts("ERROR.");
224
225 printf("Testing wxExecute: ");
226 fflush(stdout);
227 if ( wxExecute(COMMAND, TRUE /* sync */) == 0 )
228 puts("Ok.");
229 else
230 puts("ERROR.");
231
232 #if 0 // no, it doesn't work (yet?)
233 printf("Testing async wxExecute: ");
234 fflush(stdout);
235 if ( wxExecute(COMMAND) != 0 )
236 puts("Ok (command launched).");
237 else
238 puts("ERROR.");
239 #endif // 0
240
241 printf("Testing wxExecute with redirection:\n");
242 wxArrayString output;
243 if ( wxExecute(REDIRECT_COMMAND, output) != 0 )
244 {
245 puts("ERROR.");
246 }
247 else
248 {
249 size_t count = output.GetCount();
250 for ( size_t n = 0; n < count; n++ )
251 {
252 printf("\t%s\n", output[n].c_str());
253 }
254
255 puts("Ok.");
256 }
257 }
258
259 #endif // TEST_EXECUTE
260
261 // ----------------------------------------------------------------------------
262 // wxFileConfig
263 // ----------------------------------------------------------------------------
264
265 #ifdef TEST_FILECONF
266
267 #include <wx/confbase.h>
268 #include <wx/fileconf.h>
269
270 static const struct FileConfTestData
271 {
272 const wxChar *name; // value name
273 const wxChar *value; // the value from the file
274 } fcTestData[] =
275 {
276 { _T("value1"), _T("one") },
277 { _T("value2"), _T("two") },
278 { _T("novalue"), _T("default") },
279 };
280
281 static void TestFileConfRead()
282 {
283 puts("*** testing wxFileConfig loading/reading ***");
284
285 wxFileConfig fileconf(_T("test"), wxEmptyString,
286 _T("testdata.fc"), wxEmptyString,
287 wxCONFIG_USE_RELATIVE_PATH);
288
289 // test simple reading
290 puts("\nReading config file:");
291 wxString defValue(_T("default")), value;
292 for ( size_t n = 0; n < WXSIZEOF(fcTestData); n++ )
293 {
294 const FileConfTestData& data = fcTestData[n];
295 value = fileconf.Read(data.name, defValue);
296 printf("\t%s = %s ", data.name, value.c_str());
297 if ( value == data.value )
298 {
299 puts("(ok)");
300 }
301 else
302 {
303 printf("(ERROR: should be %s)\n", data.value);
304 }
305 }
306
307 // test enumerating the entries
308 puts("\nEnumerating all root entries:");
309 long dummy;
310 wxString name;
311 bool cont = fileconf.GetFirstEntry(name, dummy);
312 while ( cont )
313 {
314 printf("\t%s = %s\n",
315 name.c_str(),
316 fileconf.Read(name.c_str(), _T("ERROR")).c_str());
317
318 cont = fileconf.GetNextEntry(name, dummy);
319 }
320 }
321
322 #endif // TEST_FILECONF
323
324 // ----------------------------------------------------------------------------
325 // wxHashTable
326 // ----------------------------------------------------------------------------
327
328 #ifdef TEST_HASH
329
330 #include <wx/hash.h>
331
332 struct Foo
333 {
334 Foo(int n_) { n = n_; count++; }
335 ~Foo() { count--; }
336
337 int n;
338
339 static size_t count;
340 };
341
342 size_t Foo::count = 0;
343
344 WX_DECLARE_LIST(Foo, wxListFoos);
345 WX_DECLARE_HASH(Foo, wxListFoos, wxHashFoos);
346
347 #include <wx/listimpl.cpp>
348
349 WX_DEFINE_LIST(wxListFoos);
350
351 static void TestHash()
352 {
353 puts("*** Testing wxHashTable ***\n");
354
355 {
356 wxHashFoos hash;
357 hash.DeleteContents(TRUE);
358
359 printf("Hash created: %u foos in hash, %u foos totally\n",
360 hash.GetCount(), Foo::count);
361
362 static const int hashTestData[] =
363 {
364 0, 1, 17, -2, 2, 4, -4, 345, 3, 3, 2, 1,
365 };
366
367 size_t n;
368 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
369 {
370 hash.Put(hashTestData[n], n, new Foo(n));
371 }
372
373 printf("Hash filled: %u foos in hash, %u foos totally\n",
374 hash.GetCount(), Foo::count);
375
376 puts("Hash access test:");
377 for ( n = 0; n < WXSIZEOF(hashTestData); n++ )
378 {
379 printf("\tGetting element with key %d, value %d: ",
380 hashTestData[n], n);
381 Foo *foo = hash.Get(hashTestData[n], n);
382 if ( !foo )
383 {
384 printf("ERROR, not found.\n");
385 }
386 else
387 {
388 printf("%d (%s)\n", foo->n,
389 (size_t)foo->n == n ? "ok" : "ERROR");
390 }
391 }
392
393 printf("\nTrying to get an element not in hash: ");
394
395 if ( hash.Get(1234) || hash.Get(1, 0) )
396 {
397 puts("ERROR: found!");
398 }
399 else
400 {
401 puts("ok (not found)");
402 }
403 }
404
405 printf("Hash destroyed: %u foos left\n", Foo::count);
406 }
407
408 #endif // TEST_HASH
409
410 // ----------------------------------------------------------------------------
411 // MIME types
412 // ----------------------------------------------------------------------------
413
414 #ifdef TEST_MIME
415
416 #include <wx/mimetype.h>
417
418 static void TestMimeEnum()
419 {
420 wxMimeTypesManager mimeTM;
421 wxArrayString mimetypes;
422
423 size_t count = mimeTM.EnumAllFileTypes(mimetypes);
424
425 printf("*** All %u known filetypes: ***\n", count);
426
427 wxArrayString exts;
428 wxString desc;
429
430 for ( size_t n = 0; n < count; n++ )
431 {
432 wxFileType *filetype = mimeTM.GetFileTypeFromMimeType(mimetypes[n]);
433 if ( !filetype )
434 {
435 printf("nothing known about the filetype '%s'!\n",
436 mimetypes[n].c_str());
437 continue;
438 }
439
440 filetype->GetDescription(&desc);
441 filetype->GetExtensions(exts);
442
443 filetype->GetIcon(NULL);
444
445 wxString extsAll;
446 for ( size_t e = 0; e < exts.GetCount(); e++ )
447 {
448 if ( e > 0 )
449 extsAll << _T(", ");
450 extsAll += exts[e];
451 }
452
453 printf("\t%s: %s (%s)\n",
454 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
455 }
456 }
457
458 #endif // TEST_MIME
459
460 // ----------------------------------------------------------------------------
461 // misc information functions
462 // ----------------------------------------------------------------------------
463
464 #ifdef TEST_INFO_FUNCTIONS
465
466 #include <wx/utils.h>
467
468 static void TestOsInfo()
469 {
470 puts("*** Testing OS info functions ***\n");
471
472 int major, minor;
473 wxGetOsVersion(&major, &minor);
474 printf("Running under: %s, version %d.%d\n",
475 wxGetOsDescription().c_str(), major, minor);
476
477 printf("%ld free bytes of memory left.\n", wxGetFreeMemory());
478
479 printf("Host name is %s (%s).\n",
480 wxGetHostName().c_str(), wxGetFullHostName().c_str());
481
482 puts("");
483 }
484
485 static void TestUserInfo()
486 {
487 puts("*** Testing user info functions ***\n");
488
489 printf("User id is:\t%s\n", wxGetUserId().c_str());
490 printf("User name is:\t%s\n", wxGetUserName().c_str());
491 printf("Home dir is:\t%s\n", wxGetHomeDir().c_str());
492 printf("Email address:\t%s\n", wxGetEmailAddress().c_str());
493
494 puts("");
495 }
496
497 #endif // TEST_INFO_FUNCTIONS
498
499 // ----------------------------------------------------------------------------
500 // long long
501 // ----------------------------------------------------------------------------
502
503 #ifdef TEST_LONGLONG
504
505 #include <wx/longlong.h>
506 #include <wx/timer.h>
507
508 // make a 64 bit number from 4 16 bit ones
509 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
510
511 // get a random 64 bit number
512 #define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand())
513
514 #if wxUSE_LONGLONG_WX
515 inline bool operator==(const wxLongLongWx& a, const wxLongLongNative& b)
516 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
517 inline bool operator==(const wxLongLongNative& a, const wxLongLongWx& b)
518 { return a.GetHi() == b.GetHi() && a.GetLo() == b.GetLo(); }
519 #endif // wxUSE_LONGLONG_WX
520
521 static void TestSpeed()
522 {
523 static const long max = 100000000;
524 long n;
525
526 {
527 wxStopWatch sw;
528
529 long l = 0;
530 for ( n = 0; n < max; n++ )
531 {
532 l += n;
533 }
534
535 printf("Summing longs took %ld milliseconds.\n", sw.Time());
536 }
537
538 #if wxUSE_LONGLONG_NATIVE
539 {
540 wxStopWatch sw;
541
542 wxLongLong_t l = 0;
543 for ( n = 0; n < max; n++ )
544 {
545 l += n;
546 }
547
548 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
549 }
550 #endif // wxUSE_LONGLONG_NATIVE
551
552 {
553 wxStopWatch sw;
554
555 wxLongLong l;
556 for ( n = 0; n < max; n++ )
557 {
558 l += n;
559 }
560
561 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
562 }
563 }
564
565 static void TestLongLongConversion()
566 {
567 puts("*** Testing wxLongLong conversions ***\n");
568
569 wxLongLong a;
570 size_t nTested = 0;
571 for ( size_t n = 0; n < 100000; n++ )
572 {
573 a = RAND_LL();
574
575 #if wxUSE_LONGLONG_NATIVE
576 wxLongLongNative b(a.GetHi(), a.GetLo());
577
578 wxASSERT_MSG( a == b, "conversions failure" );
579 #else
580 puts("Can't do it without native long long type, test skipped.");
581
582 return;
583 #endif // wxUSE_LONGLONG_NATIVE
584
585 if ( !(nTested % 1000) )
586 {
587 putchar('.');
588 fflush(stdout);
589 }
590
591 nTested++;
592 }
593
594 puts(" done!");
595 }
596
597 static void TestMultiplication()
598 {
599 puts("*** Testing wxLongLong multiplication ***\n");
600
601 wxLongLong a, b;
602 size_t nTested = 0;
603 for ( size_t n = 0; n < 100000; n++ )
604 {
605 a = RAND_LL();
606 b = RAND_LL();
607
608 #if wxUSE_LONGLONG_NATIVE
609 wxLongLongNative aa(a.GetHi(), a.GetLo());
610 wxLongLongNative bb(b.GetHi(), b.GetLo());
611
612 wxASSERT_MSG( a*b == aa*bb, "multiplication failure" );
613 #else // !wxUSE_LONGLONG_NATIVE
614 puts("Can't do it without native long long type, test skipped.");
615
616 return;
617 #endif // wxUSE_LONGLONG_NATIVE
618
619 if ( !(nTested % 1000) )
620 {
621 putchar('.');
622 fflush(stdout);
623 }
624
625 nTested++;
626 }
627
628 puts(" done!");
629 }
630
631 static void TestDivision()
632 {
633 puts("*** Testing wxLongLong division ***\n");
634
635 wxLongLong q, r;
636 size_t nTested = 0;
637 for ( size_t n = 0; n < 100000; n++ )
638 {
639 // get a random wxLongLong (shifting by 12 the MSB ensures that the
640 // multiplication will not overflow)
641 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
642
643 // get a random long (not wxLongLong for now) to divide it with
644 long l = rand();
645 q = ll / l;
646 r = ll % l;
647
648 #if wxUSE_LONGLONG_NATIVE
649 wxLongLongNative m(ll.GetHi(), ll.GetLo());
650
651 wxLongLongNative p = m / l, s = m % l;
652 wxASSERT_MSG( q == p && r == s, "division failure" );
653 #else // !wxUSE_LONGLONG_NATIVE
654 // verify the result
655 wxASSERT_MSG( ll == q*l + r, "division failure" );
656 #endif // wxUSE_LONGLONG_NATIVE
657
658 if ( !(nTested % 1000) )
659 {
660 putchar('.');
661 fflush(stdout);
662 }
663
664 nTested++;
665 }
666
667 puts(" done!");
668 }
669
670 static void TestAddition()
671 {
672 puts("*** Testing wxLongLong addition ***\n");
673
674 wxLongLong a, b, c;
675 size_t nTested = 0;
676 for ( size_t n = 0; n < 100000; n++ )
677 {
678 a = RAND_LL();
679 b = RAND_LL();
680 c = a + b;
681
682 #if wxUSE_LONGLONG_NATIVE
683 wxASSERT_MSG( c == wxLongLongNative(a.GetHi(), a.GetLo()) +
684 wxLongLongNative(b.GetHi(), b.GetLo()),
685 "addition failure" );
686 #else // !wxUSE_LONGLONG_NATIVE
687 wxASSERT_MSG( c - b == a, "addition failure" );
688 #endif // wxUSE_LONGLONG_NATIVE
689
690 if ( !(nTested % 1000) )
691 {
692 putchar('.');
693 fflush(stdout);
694 }
695
696 nTested++;
697 }
698
699 puts(" done!");
700 }
701
702 static void TestBitOperations()
703 {
704 puts("*** Testing wxLongLong bit operation ***\n");
705
706 wxLongLong a, c;
707 size_t nTested = 0;
708 for ( size_t n = 0; n < 100000; n++ )
709 {
710 a = RAND_LL();
711
712 #if wxUSE_LONGLONG_NATIVE
713 for ( size_t n = 0; n < 33; n++ )
714 {
715 wxLongLongNative b(a.GetHi(), a.GetLo());
716
717 b >>= n;
718 c = a >> n;
719
720 wxASSERT_MSG( b == c, "bit shift failure" );
721
722 b = wxLongLongNative(a.GetHi(), a.GetLo()) << n;
723 c = a << n;
724
725 wxASSERT_MSG( b == c, "bit shift failure" );
726 }
727
728 #else // !wxUSE_LONGLONG_NATIVE
729 puts("Can't do it without native long long type, test skipped.");
730
731 return;
732 #endif // wxUSE_LONGLONG_NATIVE
733
734 if ( !(nTested % 1000) )
735 {
736 putchar('.');
737 fflush(stdout);
738 }
739
740 nTested++;
741 }
742
743 puts(" done!");
744 }
745
746 #undef MAKE_LL
747 #undef RAND_LL
748
749 #endif // TEST_LONGLONG
750
751 // ----------------------------------------------------------------------------
752 // sockets
753 // ----------------------------------------------------------------------------
754
755 #ifdef TEST_SOCKETS
756
757 #include <wx/socket.h>
758 #include <wx/protocol/protocol.h>
759 #include <wx/protocol/ftp.h>
760 #include <wx/protocol/http.h>
761
762 static void TestSocketServer()
763 {
764 puts("*** Testing wxSocketServer ***\n");
765
766 static const int PORT = 3000;
767
768 wxIPV4address addr;
769 addr.Service(PORT);
770
771 wxSocketServer *server = new wxSocketServer(addr);
772 if ( !server->Ok() )
773 {
774 puts("ERROR: failed to bind");
775
776 return;
777 }
778
779 for ( ;; )
780 {
781 printf("Server: waiting for connection on port %d...\n", PORT);
782
783 wxSocketBase *socket = server->Accept();
784 if ( !socket )
785 {
786 puts("ERROR: wxSocketServer::Accept() failed.");
787 break;
788 }
789
790 puts("Server: got a client.");
791
792 server->SetTimeout(60); // 1 min
793
794 while ( socket->IsConnected() )
795 {
796 wxString s;
797 char ch = '\0';
798 for ( ;; )
799 {
800 if ( socket->Read(&ch, sizeof(ch)).Error() )
801 {
802 // don't log error if the client just close the connection
803 if ( socket->IsConnected() )
804 {
805 puts("ERROR: in wxSocket::Read.");
806 }
807
808 break;
809 }
810
811 if ( ch == '\r' )
812 continue;
813
814 if ( ch == '\n' )
815 break;
816
817 s += ch;
818 }
819
820 if ( ch != '\n' )
821 {
822 break;
823 }
824
825 printf("Server: got '%s'.\n", s.c_str());
826 if ( s == _T("bye") )
827 {
828 delete socket;
829
830 break;
831 }
832
833 socket->Write(s.MakeUpper().c_str(), s.length());
834 socket->Write("\r\n", 2);
835 printf("Server: wrote '%s'.\n", s.c_str());
836 }
837
838 puts("Server: lost a client.");
839
840 socket->Destroy();
841 }
842
843 // same as "delete server" but is consistent with GUI programs
844 server->Destroy();
845 }
846
847 static void TestSocketClient()
848 {
849 puts("*** Testing wxSocketClient ***\n");
850
851 static const char *hostname = "www.wxwindows.org";
852
853 wxIPV4address addr;
854 addr.Hostname(hostname);
855 addr.Service(80);
856
857 printf("--- Attempting to connect to %s:80...\n", hostname);
858
859 wxSocketClient client;
860 if ( !client.Connect(addr) )
861 {
862 printf("ERROR: failed to connect to %s\n", hostname);
863 }
864 else
865 {
866 printf("--- Connected to %s:%u...\n",
867 addr.Hostname().c_str(), addr.Service());
868
869 char buf[8192];
870
871 // could use simply "GET" here I suppose
872 wxString cmdGet =
873 wxString::Format("GET http://%s/\r\n", hostname);
874 client.Write(cmdGet, cmdGet.length());
875 printf("--- Sent command '%s' to the server\n",
876 MakePrintable(cmdGet).c_str());
877 client.Read(buf, WXSIZEOF(buf));
878 printf("--- Server replied:\n%s", buf);
879 }
880 }
881
882 static void TestProtocolFtp()
883 {
884 puts("*** Testing wxFTP ***\n");
885
886 wxLog::AddTraceMask(_T("ftp"));
887
888 static const char *hostname = "ftp.wxwindows.org";
889
890 printf("--- Attempting to connect to %s:21...\n", hostname);
891
892 wxFTP ftp;
893 if ( !ftp.Connect(hostname) )
894 {
895 printf("ERROR: failed to connect to %s\n", hostname);
896 }
897 else
898 {
899 printf("--- Connected to %s, current directory is '%s'\n",
900 hostname, ftp.Pwd().c_str());
901 if ( !ftp.ChDir(_T("pub")) )
902 {
903 puts("ERROR: failed to cd to pub");
904 }
905
906 wxArrayString files;
907 if ( !ftp.GetList(files) )
908 {
909 puts("ERROR: failed to get list of files");
910 }
911 else
912 {
913 printf("List of files under '%s':\n", ftp.Pwd().c_str());
914 size_t count = files.GetCount();
915 for ( size_t n = 0; n < count; n++ )
916 {
917 printf("\t%s\n", files[n].c_str());
918 }
919 puts("End of the file list");
920 }
921
922 if ( !ftp.ChDir(_T("..")) )
923 {
924 puts("ERROR: failed to cd to ..");
925 }
926
927 static const char *filename = "welcome.msg";
928 wxInputStream *in = ftp.GetInputStream(filename);
929 if ( !in )
930 {
931 puts("ERROR: couldn't get input stream");
932 }
933 else
934 {
935 size_t size = in->StreamSize();
936 printf("Reading file %s (%u bytes)...", filename, size);
937
938 char *data = new char[size];
939 if ( !in->Read(data, size) )
940 {
941 puts("ERROR: read error");
942 }
943 else
944 {
945 printf("\nContents of %s:\n%s\n", filename, data);
946 }
947
948 delete [] data;
949 delete in;
950 }
951 }
952 }
953
954 #endif // TEST_SOCKETS
955
956 // ----------------------------------------------------------------------------
957 // timers
958 // ----------------------------------------------------------------------------
959
960 #ifdef TEST_TIMER
961
962 #include <wx/timer.h>
963 #include <wx/utils.h>
964
965 static void TestStopWatch()
966 {
967 puts("*** Testing wxStopWatch ***\n");
968
969 wxStopWatch sw;
970 printf("Sleeping 3 seconds...");
971 wxSleep(3);
972 printf("\telapsed time: %ldms\n", sw.Time());
973
974 sw.Pause();
975 printf("Sleeping 2 more seconds...");
976 wxSleep(2);
977 printf("\telapsed time: %ldms\n", sw.Time());
978
979 sw.Resume();
980 printf("And 3 more seconds...");
981 wxSleep(3);
982 printf("\telapsed time: %ldms\n", sw.Time());
983
984 wxStopWatch sw2;
985 puts("\nChecking for 'backwards clock' bug...");
986 for ( size_t n = 0; n < 70; n++ )
987 {
988 sw2.Start();
989
990 for ( size_t m = 0; m < 100000; m++ )
991 {
992 if ( sw.Time() < 0 || sw2.Time() < 0 )
993 {
994 puts("\ntime is negative - ERROR!");
995 }
996 }
997
998 putchar('.');
999 }
1000
1001 puts(", ok.");
1002 }
1003
1004 #endif // TEST_TIMER
1005
1006 // ----------------------------------------------------------------------------
1007 // date time
1008 // ----------------------------------------------------------------------------
1009
1010 #ifdef TEST_DATETIME
1011
1012 #include <wx/date.h>
1013
1014 #include <wx/datetime.h>
1015
1016 // the test data
1017 struct Date
1018 {
1019 wxDateTime::wxDateTime_t day;
1020 wxDateTime::Month month;
1021 int year;
1022 wxDateTime::wxDateTime_t hour, min, sec;
1023 double jdn;
1024 wxDateTime::WeekDay wday;
1025 time_t gmticks, ticks;
1026
1027 void Init(const wxDateTime::Tm& tm)
1028 {
1029 day = tm.mday;
1030 month = tm.mon;
1031 year = tm.year;
1032 hour = tm.hour;
1033 min = tm.min;
1034 sec = tm.sec;
1035 jdn = 0.0;
1036 gmticks = ticks = -1;
1037 }
1038
1039 wxDateTime DT() const
1040 { return wxDateTime(day, month, year, hour, min, sec); }
1041
1042 bool SameDay(const wxDateTime::Tm& tm) const
1043 {
1044 return day == tm.mday && month == tm.mon && year == tm.year;
1045 }
1046
1047 wxString Format() const
1048 {
1049 wxString s;
1050 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
1051 hour, min, sec,
1052 wxDateTime::GetMonthName(month).c_str(),
1053 day,
1054 abs(wxDateTime::ConvertYearToBC(year)),
1055 year > 0 ? "AD" : "BC");
1056 return s;
1057 }
1058
1059 wxString FormatDate() const
1060 {
1061 wxString s;
1062 s.Printf("%02d-%s-%4d%s",
1063 day,
1064 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
1065 abs(wxDateTime::ConvertYearToBC(year)),
1066 year > 0 ? "AD" : "BC");
1067 return s;
1068 }
1069 };
1070
1071 static const Date testDates[] =
1072 {
1073 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
1074 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
1075 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
1076 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
1077 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
1078 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
1079 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
1080 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
1081 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
1082 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
1083 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
1084 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
1085 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
1086 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
1087 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
1088 };
1089
1090 // this test miscellaneous static wxDateTime functions
1091 static void TestTimeStatic()
1092 {
1093 puts("\n*** wxDateTime static methods test ***");
1094
1095 // some info about the current date
1096 int year = wxDateTime::GetCurrentYear();
1097 printf("Current year %d is %sa leap one and has %d days.\n",
1098 year,
1099 wxDateTime::IsLeapYear(year) ? "" : "not ",
1100 wxDateTime::GetNumberOfDays(year));
1101
1102 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
1103 printf("Current month is '%s' ('%s') and it has %d days\n",
1104 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
1105 wxDateTime::GetMonthName(month).c_str(),
1106 wxDateTime::GetNumberOfDays(month));
1107
1108 // leap year logic
1109 static const size_t nYears = 5;
1110 static const size_t years[2][nYears] =
1111 {
1112 // first line: the years to test
1113 { 1990, 1976, 2000, 2030, 1984, },
1114
1115 // second line: TRUE if leap, FALSE otherwise
1116 { FALSE, TRUE, TRUE, FALSE, TRUE }
1117 };
1118
1119 for ( size_t n = 0; n < nYears; n++ )
1120 {
1121 int year = years[0][n];
1122 bool should = years[1][n] != 0,
1123 is = wxDateTime::IsLeapYear(year);
1124
1125 printf("Year %d is %sa leap year (%s)\n",
1126 year,
1127 is ? "" : "not ",
1128 should == is ? "ok" : "ERROR");
1129
1130 wxASSERT( should == wxDateTime::IsLeapYear(year) );
1131 }
1132 }
1133
1134 // test constructing wxDateTime objects
1135 static void TestTimeSet()
1136 {
1137 puts("\n*** wxDateTime construction test ***");
1138
1139 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1140 {
1141 const Date& d1 = testDates[n];
1142 wxDateTime dt = d1.DT();
1143
1144 Date d2;
1145 d2.Init(dt.GetTm());
1146
1147 wxString s1 = d1.Format(),
1148 s2 = d2.Format();
1149
1150 printf("Date: %s == %s (%s)\n",
1151 s1.c_str(), s2.c_str(),
1152 s1 == s2 ? "ok" : "ERROR");
1153 }
1154 }
1155
1156 // test time zones stuff
1157 static void TestTimeZones()
1158 {
1159 puts("\n*** wxDateTime timezone test ***");
1160
1161 wxDateTime now = wxDateTime::Now();
1162
1163 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
1164 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
1165 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
1166 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
1167 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
1168 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
1169
1170 wxDateTime::Tm tm = now.GetTm();
1171 if ( wxDateTime(tm) != now )
1172 {
1173 printf("ERROR: got %s instead of %s\n",
1174 wxDateTime(tm).Format().c_str(), now.Format().c_str());
1175 }
1176 }
1177
1178 // test some minimal support for the dates outside the standard range
1179 static void TestTimeRange()
1180 {
1181 puts("\n*** wxDateTime out-of-standard-range dates test ***");
1182
1183 static const char *fmt = "%d-%b-%Y %H:%M:%S";
1184
1185 printf("Unix epoch:\t%s\n",
1186 wxDateTime(2440587.5).Format(fmt).c_str());
1187 printf("Feb 29, 0: \t%s\n",
1188 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
1189 printf("JDN 0: \t%s\n",
1190 wxDateTime(0.0).Format(fmt).c_str());
1191 printf("Jan 1, 1AD:\t%s\n",
1192 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
1193 printf("May 29, 2099:\t%s\n",
1194 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
1195 }
1196
1197 static void TestTimeTicks()
1198 {
1199 puts("\n*** wxDateTime ticks test ***");
1200
1201 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1202 {
1203 const Date& d = testDates[n];
1204 if ( d.ticks == -1 )
1205 continue;
1206
1207 wxDateTime dt = d.DT();
1208 long ticks = (dt.GetValue() / 1000).ToLong();
1209 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
1210 if ( ticks == d.ticks )
1211 {
1212 puts(" (ok)");
1213 }
1214 else
1215 {
1216 printf(" (ERROR: should be %ld, delta = %ld)\n",
1217 d.ticks, ticks - d.ticks);
1218 }
1219
1220 dt = d.DT().ToTimezone(wxDateTime::GMT0);
1221 ticks = (dt.GetValue() / 1000).ToLong();
1222 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
1223 if ( ticks == d.gmticks )
1224 {
1225 puts(" (ok)");
1226 }
1227 else
1228 {
1229 printf(" (ERROR: should be %ld, delta = %ld)\n",
1230 d.gmticks, ticks - d.gmticks);
1231 }
1232 }
1233
1234 puts("");
1235 }
1236
1237 // test conversions to JDN &c
1238 static void TestTimeJDN()
1239 {
1240 puts("\n*** wxDateTime to JDN test ***");
1241
1242 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
1243 {
1244 const Date& d = testDates[n];
1245 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1246 double jdn = dt.GetJulianDayNumber();
1247
1248 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
1249 if ( jdn == d.jdn )
1250 {
1251 puts(" (ok)");
1252 }
1253 else
1254 {
1255 printf(" (ERROR: should be %f, delta = %f)\n",
1256 d.jdn, jdn - d.jdn);
1257 }
1258 }
1259 }
1260
1261 // test week days computation
1262 static void TestTimeWDays()
1263 {
1264 puts("\n*** wxDateTime weekday test ***");
1265
1266 // test GetWeekDay()
1267 size_t n;
1268 for ( n = 0; n < WXSIZEOF(testDates); n++ )
1269 {
1270 const Date& d = testDates[n];
1271 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
1272
1273 wxDateTime::WeekDay wday = dt.GetWeekDay();
1274 printf("%s is: %s",
1275 d.Format().c_str(),
1276 wxDateTime::GetWeekDayName(wday).c_str());
1277 if ( wday == d.wday )
1278 {
1279 puts(" (ok)");
1280 }
1281 else
1282 {
1283 printf(" (ERROR: should be %s)\n",
1284 wxDateTime::GetWeekDayName(d.wday).c_str());
1285 }
1286 }
1287
1288 puts("");
1289
1290 // test SetToWeekDay()
1291 struct WeekDateTestData
1292 {
1293 Date date; // the real date (precomputed)
1294 int nWeek; // its week index in the month
1295 wxDateTime::WeekDay wday; // the weekday
1296 wxDateTime::Month month; // the month
1297 int year; // and the year
1298
1299 wxString Format() const
1300 {
1301 wxString s, which;
1302 switch ( nWeek < -1 ? -nWeek : nWeek )
1303 {
1304 case 1: which = "first"; break;
1305 case 2: which = "second"; break;
1306 case 3: which = "third"; break;
1307 case 4: which = "fourth"; break;
1308 case 5: which = "fifth"; break;
1309
1310 case -1: which = "last"; break;
1311 }
1312
1313 if ( nWeek < -1 )
1314 {
1315 which += " from end";
1316 }
1317
1318 s.Printf("The %s %s of %s in %d",
1319 which.c_str(),
1320 wxDateTime::GetWeekDayName(wday).c_str(),
1321 wxDateTime::GetMonthName(month).c_str(),
1322 year);
1323
1324 return s;
1325 }
1326 };
1327
1328 // the array data was generated by the following python program
1329 /*
1330 from DateTime import *
1331 from whrandom import *
1332 from string import *
1333
1334 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
1335 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
1336
1337 week = DateTimeDelta(7)
1338
1339 for n in range(20):
1340 year = randint(1900, 2100)
1341 month = randint(1, 12)
1342 day = randint(1, 28)
1343 dt = DateTime(year, month, day)
1344 wday = dt.day_of_week
1345
1346 countFromEnd = choice([-1, 1])
1347 weekNum = 0;
1348
1349 while dt.month is month:
1350 dt = dt - countFromEnd * week
1351 weekNum = weekNum + countFromEnd
1352
1353 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
1354
1355 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
1356 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
1357 */
1358
1359 static const WeekDateTestData weekDatesTestData[] =
1360 {
1361 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
1362 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
1363 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
1364 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
1365 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
1366 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
1367 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
1368 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
1369 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
1370 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
1371 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
1372 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
1373 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
1374 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
1375 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
1376 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
1377 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
1378 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
1379 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
1380 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
1381 };
1382
1383 static const char *fmt = "%d-%b-%Y";
1384
1385 wxDateTime dt;
1386 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
1387 {
1388 const WeekDateTestData& wd = weekDatesTestData[n];
1389
1390 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
1391
1392 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
1393
1394 const Date& d = wd.date;
1395 if ( d.SameDay(dt.GetTm()) )
1396 {
1397 puts(" (ok)");
1398 }
1399 else
1400 {
1401 dt.Set(d.day, d.month, d.year);
1402
1403 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
1404 }
1405 }
1406 }
1407
1408 // test the computation of (ISO) week numbers
1409 static void TestTimeWNumber()
1410 {
1411 puts("\n*** wxDateTime week number test ***");
1412
1413 struct WeekNumberTestData
1414 {
1415 Date date; // the date
1416 wxDateTime::wxDateTime_t week; // the week number in the year
1417 wxDateTime::wxDateTime_t wmon; // the week number in the month
1418 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
1419 wxDateTime::wxDateTime_t dnum; // day number in the year
1420 };
1421
1422 // data generated with the following python script:
1423 /*
1424 from DateTime import *
1425 from whrandom import *
1426 from string import *
1427
1428 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
1429 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
1430
1431 def GetMonthWeek(dt):
1432 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
1433 if weekNumMonth < 0:
1434 weekNumMonth = weekNumMonth + 53
1435 return weekNumMonth
1436
1437 def GetLastSundayBefore(dt):
1438 if dt.iso_week[2] == 7:
1439 return dt
1440 else:
1441 return dt - DateTimeDelta(dt.iso_week[2])
1442
1443 for n in range(20):
1444 year = randint(1900, 2100)
1445 month = randint(1, 12)
1446 day = randint(1, 28)
1447 dt = DateTime(year, month, day)
1448 dayNum = dt.day_of_year
1449 weekNum = dt.iso_week[1]
1450 weekNumMonth = GetMonthWeek(dt)
1451
1452 weekNumMonth2 = 0
1453 dtSunday = GetLastSundayBefore(dt)
1454
1455 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
1456 weekNumMonth2 = weekNumMonth2 + 1
1457 dtSunday = dtSunday - DateTimeDelta(7)
1458
1459 data = { 'day': rjust(`day`, 2), \
1460 'month': monthNames[month - 1], \
1461 'year': year, \
1462 'weekNum': rjust(`weekNum`, 2), \
1463 'weekNumMonth': weekNumMonth, \
1464 'weekNumMonth2': weekNumMonth2, \
1465 'dayNum': rjust(`dayNum`, 3) }
1466
1467 print " { { %(day)s, "\
1468 "wxDateTime::%(month)s, "\
1469 "%(year)d }, "\
1470 "%(weekNum)s, "\
1471 "%(weekNumMonth)s, "\
1472 "%(weekNumMonth2)s, "\
1473 "%(dayNum)s }," % data
1474
1475 */
1476 static const WeekNumberTestData weekNumberTestDates[] =
1477 {
1478 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
1479 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
1480 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
1481 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
1482 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
1483 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
1484 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
1485 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
1486 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
1487 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
1488 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
1489 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
1490 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
1491 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
1492 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
1493 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
1494 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
1495 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
1496 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
1497 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
1498 };
1499
1500 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
1501 {
1502 const WeekNumberTestData& wn = weekNumberTestDates[n];
1503 const Date& d = wn.date;
1504
1505 wxDateTime dt = d.DT();
1506
1507 wxDateTime::wxDateTime_t
1508 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
1509 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
1510 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
1511 dnum = dt.GetDayOfYear();
1512
1513 printf("%s: the day number is %d",
1514 d.FormatDate().c_str(), dnum);
1515 if ( dnum == wn.dnum )
1516 {
1517 printf(" (ok)");
1518 }
1519 else
1520 {
1521 printf(" (ERROR: should be %d)", wn.dnum);
1522 }
1523
1524 printf(", week in month is %d", wmon);
1525 if ( wmon == wn.wmon )
1526 {
1527 printf(" (ok)");
1528 }
1529 else
1530 {
1531 printf(" (ERROR: should be %d)", wn.wmon);
1532 }
1533
1534 printf(" or %d", wmon2);
1535 if ( wmon2 == wn.wmon2 )
1536 {
1537 printf(" (ok)");
1538 }
1539 else
1540 {
1541 printf(" (ERROR: should be %d)", wn.wmon2);
1542 }
1543
1544 printf(", week in year is %d", week);
1545 if ( week == wn.week )
1546 {
1547 puts(" (ok)");
1548 }
1549 else
1550 {
1551 printf(" (ERROR: should be %d)\n", wn.week);
1552 }
1553 }
1554 }
1555
1556 // test DST calculations
1557 static void TestTimeDST()
1558 {
1559 puts("\n*** wxDateTime DST test ***");
1560
1561 printf("DST is%s in effect now.\n\n",
1562 wxDateTime::Now().IsDST() ? "" : " not");
1563
1564 // taken from http://www.energy.ca.gov/daylightsaving.html
1565 static const Date datesDST[2][2004 - 1900 + 1] =
1566 {
1567 {
1568 { 1, wxDateTime::Apr, 1990 },
1569 { 7, wxDateTime::Apr, 1991 },
1570 { 5, wxDateTime::Apr, 1992 },
1571 { 4, wxDateTime::Apr, 1993 },
1572 { 3, wxDateTime::Apr, 1994 },
1573 { 2, wxDateTime::Apr, 1995 },
1574 { 7, wxDateTime::Apr, 1996 },
1575 { 6, wxDateTime::Apr, 1997 },
1576 { 5, wxDateTime::Apr, 1998 },
1577 { 4, wxDateTime::Apr, 1999 },
1578 { 2, wxDateTime::Apr, 2000 },
1579 { 1, wxDateTime::Apr, 2001 },
1580 { 7, wxDateTime::Apr, 2002 },
1581 { 6, wxDateTime::Apr, 2003 },
1582 { 4, wxDateTime::Apr, 2004 },
1583 },
1584 {
1585 { 28, wxDateTime::Oct, 1990 },
1586 { 27, wxDateTime::Oct, 1991 },
1587 { 25, wxDateTime::Oct, 1992 },
1588 { 31, wxDateTime::Oct, 1993 },
1589 { 30, wxDateTime::Oct, 1994 },
1590 { 29, wxDateTime::Oct, 1995 },
1591 { 27, wxDateTime::Oct, 1996 },
1592 { 26, wxDateTime::Oct, 1997 },
1593 { 25, wxDateTime::Oct, 1998 },
1594 { 31, wxDateTime::Oct, 1999 },
1595 { 29, wxDateTime::Oct, 2000 },
1596 { 28, wxDateTime::Oct, 2001 },
1597 { 27, wxDateTime::Oct, 2002 },
1598 { 26, wxDateTime::Oct, 2003 },
1599 { 31, wxDateTime::Oct, 2004 },
1600 }
1601 };
1602
1603 int year;
1604 for ( year = 1990; year < 2005; year++ )
1605 {
1606 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
1607 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
1608
1609 printf("DST period in the US for year %d: from %s to %s",
1610 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
1611
1612 size_t n = year - 1990;
1613 const Date& dBegin = datesDST[0][n];
1614 const Date& dEnd = datesDST[1][n];
1615
1616 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
1617 {
1618 puts(" (ok)");
1619 }
1620 else
1621 {
1622 printf(" (ERROR: should be %s %d to %s %d)\n",
1623 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
1624 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
1625 }
1626 }
1627
1628 puts("");
1629
1630 for ( year = 1990; year < 2005; year++ )
1631 {
1632 printf("DST period in Europe for year %d: from %s to %s\n",
1633 year,
1634 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
1635 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
1636 }
1637 }
1638
1639 // test wxDateTime -> text conversion
1640 static void TestTimeFormat()
1641 {
1642 puts("\n*** wxDateTime formatting test ***");
1643
1644 // some information may be lost during conversion, so store what kind
1645 // of info should we recover after a round trip
1646 enum CompareKind
1647 {
1648 CompareNone, // don't try comparing
1649 CompareBoth, // dates and times should be identical
1650 CompareDate, // dates only
1651 CompareTime // time only
1652 };
1653
1654 static const struct
1655 {
1656 CompareKind compareKind;
1657 const char *format;
1658 } formatTestFormats[] =
1659 {
1660 { CompareBoth, "---> %c" },
1661 { CompareDate, "Date is %A, %d of %B, in year %Y" },
1662 { CompareBoth, "Date is %x, time is %X" },
1663 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
1664 { CompareNone, "The day of year: %j, the week of year: %W" },
1665 };
1666
1667 static const Date formatTestDates[] =
1668 {
1669 { 29, wxDateTime::May, 1976, 18, 30, 00 },
1670 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
1671 #if 0
1672 // this test can't work for other centuries because it uses two digit
1673 // years in formats, so don't even try it
1674 { 29, wxDateTime::May, 2076, 18, 30, 00 },
1675 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
1676 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
1677 #endif
1678 };
1679
1680 // an extra test (as it doesn't depend on date, don't do it in the loop)
1681 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
1682
1683 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
1684 {
1685 puts("");
1686
1687 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
1688 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
1689 {
1690 wxString s = dt.Format(formatTestFormats[n].format);
1691 printf("%s", s.c_str());
1692
1693 // what can we recover?
1694 int kind = formatTestFormats[n].compareKind;
1695
1696 // convert back
1697 wxDateTime dt2;
1698 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
1699 if ( !result )
1700 {
1701 // converion failed - should it have?
1702 if ( kind == CompareNone )
1703 puts(" (ok)");
1704 else
1705 puts(" (ERROR: conversion back failed)");
1706 }
1707 else if ( *result )
1708 {
1709 // should have parsed the entire string
1710 puts(" (ERROR: conversion back stopped too soon)");
1711 }
1712 else
1713 {
1714 bool equal = FALSE; // suppress compilaer warning
1715 switch ( kind )
1716 {
1717 case CompareBoth:
1718 equal = dt2 == dt;
1719 break;
1720
1721 case CompareDate:
1722 equal = dt.IsSameDate(dt2);
1723 break;
1724
1725 case CompareTime:
1726 equal = dt.IsSameTime(dt2);
1727 break;
1728 }
1729
1730 if ( !equal )
1731 {
1732 printf(" (ERROR: got back '%s' instead of '%s')\n",
1733 dt2.Format().c_str(), dt.Format().c_str());
1734 }
1735 else
1736 {
1737 puts(" (ok)");
1738 }
1739 }
1740 }
1741 }
1742 }
1743
1744 // test text -> wxDateTime conversion
1745 static void TestTimeParse()
1746 {
1747 puts("\n*** wxDateTime parse test ***");
1748
1749 struct ParseTestData
1750 {
1751 const char *format;
1752 Date date;
1753 bool good;
1754 };
1755
1756 static const ParseTestData parseTestDates[] =
1757 {
1758 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
1759 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
1760 };
1761
1762 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
1763 {
1764 const char *format = parseTestDates[n].format;
1765
1766 printf("%s => ", format);
1767
1768 wxDateTime dt;
1769 if ( dt.ParseRfc822Date(format) )
1770 {
1771 printf("%s ", dt.Format().c_str());
1772
1773 if ( parseTestDates[n].good )
1774 {
1775 wxDateTime dtReal = parseTestDates[n].date.DT();
1776 if ( dt == dtReal )
1777 {
1778 puts("(ok)");
1779 }
1780 else
1781 {
1782 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
1783 }
1784 }
1785 else
1786 {
1787 puts("(ERROR: bad format)");
1788 }
1789 }
1790 else
1791 {
1792 printf("bad format (%s)\n",
1793 parseTestDates[n].good ? "ERROR" : "ok");
1794 }
1795 }
1796 }
1797
1798 static void TestInteractive()
1799 {
1800 puts("\n*** interactive wxDateTime tests ***");
1801
1802 char buf[128];
1803
1804 for ( ;; )
1805 {
1806 printf("Enter a date: ");
1807 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
1808 break;
1809
1810 wxDateTime dt;
1811 if ( !dt.ParseDate(buf) )
1812 {
1813 puts("failed to parse the date");
1814
1815 continue;
1816 }
1817
1818 printf("%s: day %u, week of month %u/%u, week of year %u\n",
1819 dt.FormatISODate().c_str(),
1820 dt.GetDayOfYear(),
1821 dt.GetWeekOfMonth(wxDateTime::Monday_First),
1822 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
1823 dt.GetWeekOfYear(wxDateTime::Monday_First));
1824 }
1825
1826 puts("\n*** done ***");
1827 }
1828
1829 static void TestTimeArithmetics()
1830 {
1831 puts("\n*** testing arithmetic operations on wxDateTime ***");
1832
1833 static const struct
1834 {
1835 wxDateSpan span;
1836 const char *name;
1837 } testArithmData[] =
1838 {
1839 { wxDateSpan::Day(), "day" },
1840 { wxDateSpan::Week(), "week" },
1841 { wxDateSpan::Month(), "month" },
1842 { wxDateSpan::Year(), "year" },
1843 { wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days" },
1844 };
1845
1846 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
1847
1848 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
1849 {
1850 wxDateSpan span = testArithmData[n].span;
1851 dt1 = dt + span;
1852 dt2 = dt - span;
1853
1854 const char *name = testArithmData[n].name;
1855 printf("%s + %s = %s, %s - %s = %s\n",
1856 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
1857 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
1858
1859 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
1860 if ( dt1 - span == dt )
1861 {
1862 puts(" (ok)");
1863 }
1864 else
1865 {
1866 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
1867 }
1868
1869 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
1870 if ( dt2 + span == dt )
1871 {
1872 puts(" (ok)");
1873 }
1874 else
1875 {
1876 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
1877 }
1878
1879 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
1880 if ( dt2 + 2*span == dt1 )
1881 {
1882 puts(" (ok)");
1883 }
1884 else
1885 {
1886 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
1887 }
1888
1889 puts("");
1890 }
1891 }
1892
1893 static void TestTimeHolidays()
1894 {
1895 puts("\n*** testing wxDateTimeHolidayAuthority ***\n");
1896
1897 wxDateTime::Tm tm = wxDateTime(29, wxDateTime::May, 2000).GetTm();
1898 wxDateTime dtStart(1, tm.mon, tm.year),
1899 dtEnd = dtStart.GetLastMonthDay();
1900
1901 wxDateTimeArray hol;
1902 wxDateTimeHolidayAuthority::GetHolidaysInRange(dtStart, dtEnd, hol);
1903
1904 const wxChar *format = "%d-%b-%Y (%a)";
1905
1906 printf("All holidays between %s and %s:\n",
1907 dtStart.Format(format).c_str(), dtEnd.Format(format).c_str());
1908
1909 size_t count = hol.GetCount();
1910 for ( size_t n = 0; n < count; n++ )
1911 {
1912 printf("\t%s\n", hol[n].Format(format).c_str());
1913 }
1914
1915 puts("");
1916 }
1917
1918 #if 0
1919
1920 // test compatibility with the old wxDate/wxTime classes
1921 static void TestTimeCompatibility()
1922 {
1923 puts("\n*** wxDateTime compatibility test ***");
1924
1925 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
1926 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
1927
1928 double jdnNow = wxDateTime::Now().GetJDN();
1929 long jdnMidnight = (long)(jdnNow - 0.5);
1930 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
1931
1932 jdnMidnight = wxDate().Set().GetJulianDate();
1933 printf("wxDateTime for today: %s\n",
1934 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
1935
1936 int flags = wxEUROPEAN;//wxFULL;
1937 wxDate date;
1938 date.Set();
1939 printf("Today is %s\n", date.FormatDate(flags).c_str());
1940 for ( int n = 0; n < 7; n++ )
1941 {
1942 printf("Previous %s is %s\n",
1943 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
1944 date.Previous(n + 1).FormatDate(flags).c_str());
1945 }
1946 }
1947
1948 #endif // 0
1949
1950 #endif // TEST_DATETIME
1951
1952 // ----------------------------------------------------------------------------
1953 // threads
1954 // ----------------------------------------------------------------------------
1955
1956 #ifdef TEST_THREADS
1957
1958 #include <wx/thread.h>
1959
1960 static size_t gs_counter = (size_t)-1;
1961 static wxCriticalSection gs_critsect;
1962 static wxCondition gs_cond;
1963
1964 class MyJoinableThread : public wxThread
1965 {
1966 public:
1967 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
1968 { m_n = n; Create(); }
1969
1970 // thread execution starts here
1971 virtual ExitCode Entry();
1972
1973 private:
1974 size_t m_n;
1975 };
1976
1977 wxThread::ExitCode MyJoinableThread::Entry()
1978 {
1979 unsigned long res = 1;
1980 for ( size_t n = 1; n < m_n; n++ )
1981 {
1982 res *= n;
1983
1984 // it's a loooong calculation :-)
1985 Sleep(100);
1986 }
1987
1988 return (ExitCode)res;
1989 }
1990
1991 class MyDetachedThread : public wxThread
1992 {
1993 public:
1994 MyDetachedThread(size_t n, char ch)
1995 {
1996 m_n = n;
1997 m_ch = ch;
1998 m_cancelled = FALSE;
1999
2000 Create();
2001 }
2002
2003 // thread execution starts here
2004 virtual ExitCode Entry();
2005
2006 // and stops here
2007 virtual void OnExit();
2008
2009 private:
2010 size_t m_n; // number of characters to write
2011 char m_ch; // character to write
2012
2013 bool m_cancelled; // FALSE if we exit normally
2014 };
2015
2016 wxThread::ExitCode MyDetachedThread::Entry()
2017 {
2018 {
2019 wxCriticalSectionLocker lock(gs_critsect);
2020 if ( gs_counter == (size_t)-1 )
2021 gs_counter = 1;
2022 else
2023 gs_counter++;
2024 }
2025
2026 for ( size_t n = 0; n < m_n; n++ )
2027 {
2028 if ( TestDestroy() )
2029 {
2030 m_cancelled = TRUE;
2031
2032 break;
2033 }
2034
2035 putchar(m_ch);
2036 fflush(stdout);
2037
2038 wxThread::Sleep(100);
2039 }
2040
2041 return 0;
2042 }
2043
2044 void MyDetachedThread::OnExit()
2045 {
2046 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
2047
2048 wxCriticalSectionLocker lock(gs_critsect);
2049 if ( !--gs_counter && !m_cancelled )
2050 gs_cond.Signal();
2051 }
2052
2053 void TestDetachedThreads()
2054 {
2055 puts("\n*** Testing detached threads ***");
2056
2057 static const size_t nThreads = 3;
2058 MyDetachedThread *threads[nThreads];
2059 size_t n;
2060 for ( n = 0; n < nThreads; n++ )
2061 {
2062 threads[n] = new MyDetachedThread(10, 'A' + n);
2063 }
2064
2065 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
2066 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
2067
2068 for ( n = 0; n < nThreads; n++ )
2069 {
2070 threads[n]->Run();
2071 }
2072
2073 // wait until all threads terminate
2074 gs_cond.Wait();
2075
2076 puts("");
2077 }
2078
2079 void TestJoinableThreads()
2080 {
2081 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
2082
2083 // calc 10! in the background
2084 MyJoinableThread thread(10);
2085 thread.Run();
2086
2087 printf("\nThread terminated with exit code %lu.\n",
2088 (unsigned long)thread.Wait());
2089 }
2090
2091 void TestThreadSuspend()
2092 {
2093 puts("\n*** Testing thread suspend/resume functions ***");
2094
2095 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
2096
2097 thread->Run();
2098
2099 // this is for this demo only, in a real life program we'd use another
2100 // condition variable which would be signaled from wxThread::Entry() to
2101 // tell us that the thread really started running - but here just wait a
2102 // bit and hope that it will be enough (the problem is, of course, that
2103 // the thread might still not run when we call Pause() which will result
2104 // in an error)
2105 wxThread::Sleep(300);
2106
2107 for ( size_t n = 0; n < 3; n++ )
2108 {
2109 thread->Pause();
2110
2111 puts("\nThread suspended");
2112 if ( n > 0 )
2113 {
2114 // don't sleep but resume immediately the first time
2115 wxThread::Sleep(300);
2116 }
2117 puts("Going to resume the thread");
2118
2119 thread->Resume();
2120 }
2121
2122 puts("Waiting until it terminates now");
2123
2124 // wait until the thread terminates
2125 gs_cond.Wait();
2126
2127 puts("");
2128 }
2129
2130 void TestThreadDelete()
2131 {
2132 // As above, using Sleep() is only for testing here - we must use some
2133 // synchronisation object instead to ensure that the thread is still
2134 // running when we delete it - deleting a detached thread which already
2135 // terminated will lead to a crash!
2136
2137 puts("\n*** Testing thread delete function ***");
2138
2139 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
2140
2141 thread0->Delete();
2142
2143 puts("\nDeleted a thread which didn't start to run yet.");
2144
2145 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
2146
2147 thread1->Run();
2148
2149 wxThread::Sleep(300);
2150
2151 thread1->Delete();
2152
2153 puts("\nDeleted a running thread.");
2154
2155 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
2156
2157 thread2->Run();
2158
2159 wxThread::Sleep(300);
2160
2161 thread2->Pause();
2162
2163 thread2->Delete();
2164
2165 puts("\nDeleted a sleeping thread.");
2166
2167 MyJoinableThread thread3(20);
2168 thread3.Run();
2169
2170 thread3.Delete();
2171
2172 puts("\nDeleted a joinable thread.");
2173
2174 MyJoinableThread thread4(2);
2175 thread4.Run();
2176
2177 wxThread::Sleep(300);
2178
2179 thread4.Delete();
2180
2181 puts("\nDeleted a joinable thread which already terminated.");
2182
2183 puts("");
2184 }
2185
2186 #endif // TEST_THREADS
2187
2188 // ----------------------------------------------------------------------------
2189 // arrays
2190 // ----------------------------------------------------------------------------
2191
2192 #ifdef TEST_ARRAYS
2193
2194 void PrintArray(const char* name, const wxArrayString& array)
2195 {
2196 printf("Dump of the array '%s'\n", name);
2197
2198 size_t nCount = array.GetCount();
2199 for ( size_t n = 0; n < nCount; n++ )
2200 {
2201 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
2202 }
2203 }
2204
2205 #endif // TEST_ARRAYS
2206
2207 // ----------------------------------------------------------------------------
2208 // strings
2209 // ----------------------------------------------------------------------------
2210
2211 #ifdef TEST_STRINGS
2212
2213 #include "wx/timer.h"
2214 #include "wx/tokenzr.h"
2215
2216 static void TestStringConstruction()
2217 {
2218 puts("*** Testing wxString constructores ***");
2219
2220 #define TEST_CTOR(args, res) \
2221 { \
2222 wxString s args ; \
2223 printf("wxString%s = %s ", #args, s.c_str()); \
2224 if ( s == res ) \
2225 { \
2226 puts("(ok)"); \
2227 } \
2228 else \
2229 { \
2230 printf("(ERROR: should be %s)\n", res); \
2231 } \
2232 }
2233
2234 TEST_CTOR((_T('Z'), 4), _T("ZZZZ"));
2235 TEST_CTOR((_T("Hello"), 4), _T("Hell"));
2236 TEST_CTOR((_T("Hello"), 5), _T("Hello"));
2237 // TEST_CTOR((_T("Hello"), 6), _T("Hello")); -- should give assert failure
2238
2239 static const wxChar *s = _T("?really!");
2240 const wxChar *start = wxStrchr(s, _T('r'));
2241 const wxChar *end = wxStrchr(s, _T('!'));
2242 TEST_CTOR((start, end), _T("really"));
2243
2244 puts("");
2245 }
2246
2247 static void TestString()
2248 {
2249 wxStopWatch sw;
2250
2251 wxString a, b, c;
2252
2253 a.reserve (128);
2254 b.reserve (128);
2255 c.reserve (128);
2256
2257 for (int i = 0; i < 1000000; ++i)
2258 {
2259 a = "Hello";
2260 b = " world";
2261 c = "! How'ya doin'?";
2262 a += b;
2263 a += c;
2264 c = "Hello world! What's up?";
2265 if (c != a)
2266 c = "Doh!";
2267 }
2268
2269 printf ("TestString elapsed time: %ld\n", sw.Time());
2270 }
2271
2272 static void TestPChar()
2273 {
2274 wxStopWatch sw;
2275
2276 char a [128];
2277 char b [128];
2278 char c [128];
2279
2280 for (int i = 0; i < 1000000; ++i)
2281 {
2282 strcpy (a, "Hello");
2283 strcpy (b, " world");
2284 strcpy (c, "! How'ya doin'?");
2285 strcat (a, b);
2286 strcat (a, c);
2287 strcpy (c, "Hello world! What's up?");
2288 if (strcmp (c, a) == 0)
2289 strcpy (c, "Doh!");
2290 }
2291
2292 printf ("TestPChar elapsed time: %ld\n", sw.Time());
2293 }
2294
2295 static void TestStringSub()
2296 {
2297 wxString s("Hello, world!");
2298
2299 puts("*** Testing wxString substring extraction ***");
2300
2301 printf("String = '%s'\n", s.c_str());
2302 printf("Left(5) = '%s'\n", s.Left(5).c_str());
2303 printf("Right(6) = '%s'\n", s.Right(6).c_str());
2304 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
2305 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
2306 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
2307 printf("substr(3) = '%s'\n", s.substr(3).c_str());
2308
2309 puts("");
2310 }
2311
2312 static void TestStringFormat()
2313 {
2314 puts("*** Testing wxString formatting ***");
2315
2316 wxString s;
2317 s.Printf("%03d", 18);
2318
2319 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
2320 printf("Number 18: %s\n", s.c_str());
2321
2322 puts("");
2323 }
2324
2325 // returns "not found" for npos, value for all others
2326 static wxString PosToString(size_t res)
2327 {
2328 wxString s = res == wxString::npos ? wxString(_T("not found"))
2329 : wxString::Format(_T("%u"), res);
2330 return s;
2331 }
2332
2333 static void TestStringFind()
2334 {
2335 puts("*** Testing wxString find() functions ***");
2336
2337 static const wxChar *strToFind = _T("ell");
2338 static const struct StringFindTest
2339 {
2340 const wxChar *str;
2341 size_t start,
2342 result; // of searching "ell" in str
2343 } findTestData[] =
2344 {
2345 { _T("Well, hello world"), 0, 1 },
2346 { _T("Well, hello world"), 6, 7 },
2347 { _T("Well, hello world"), 9, wxString::npos },
2348 };
2349
2350 for ( size_t n = 0; n < WXSIZEOF(findTestData); n++ )
2351 {
2352 const StringFindTest& ft = findTestData[n];
2353 size_t res = wxString(ft.str).find(strToFind, ft.start);
2354
2355 printf(_T("Index of '%s' in '%s' starting from %u is %s "),
2356 strToFind, ft.str, ft.start, PosToString(res).c_str());
2357
2358 size_t resTrue = ft.result;
2359 if ( res == resTrue )
2360 {
2361 puts(_T("(ok)"));
2362 }
2363 else
2364 {
2365 printf(_T("(ERROR: should be %s)\n"),
2366 PosToString(resTrue).c_str());
2367 }
2368 }
2369
2370 puts("");
2371 }
2372
2373 static void TestStringTokenizer()
2374 {
2375 puts("*** Testing wxStringTokenizer ***");
2376
2377 static const wxChar *modeNames[] =
2378 {
2379 _T("default"),
2380 _T("return empty"),
2381 _T("return all empty"),
2382 _T("with delims"),
2383 _T("like strtok"),
2384 };
2385
2386 static const struct StringTokenizerTest
2387 {
2388 const wxChar *str; // string to tokenize
2389 const wxChar *delims; // delimiters to use
2390 size_t count; // count of token
2391 wxStringTokenizerMode mode; // how should we tokenize it
2392 } tokenizerTestData[] =
2393 {
2394 { _T(""), _T(" "), 0 },
2395 { _T("Hello, world"), _T(" "), 2 },
2396 { _T("Hello, world "), _T(" "), 2 },
2397 { _T("Hello, world"), _T(","), 2 },
2398 { _T("Hello, world!"), _T(",!"), 2 },
2399 { _T("Hello,, world!"), _T(",!"), 3 },
2400 { _T("Hello, world!"), _T(",!"), 3, wxTOKEN_RET_EMPTY_ALL },
2401 { _T("username:password:uid:gid:gecos:home:shell"), _T(":"), 7 },
2402 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 4 },
2403 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 6, wxTOKEN_RET_EMPTY },
2404 { _T("1 \t3\t4 6 "), wxDEFAULT_DELIMITERS, 9, wxTOKEN_RET_EMPTY_ALL },
2405 { _T("01/02/99"), _T("/-"), 3 },
2406 { _T("01-02/99"), _T("/-"), 3, wxTOKEN_RET_DELIMS },
2407 };
2408
2409 for ( size_t n = 0; n < WXSIZEOF(tokenizerTestData); n++ )
2410 {
2411 const StringTokenizerTest& tt = tokenizerTestData[n];
2412 wxStringTokenizer tkz(tt.str, tt.delims, tt.mode);
2413
2414 size_t count = tkz.CountTokens();
2415 printf(_T("String '%s' has %u tokens delimited by '%s' (mode = %s) "),
2416 MakePrintable(tt.str).c_str(),
2417 count,
2418 MakePrintable(tt.delims).c_str(),
2419 modeNames[tkz.GetMode()]);
2420 if ( count == tt.count )
2421 {
2422 puts(_T("(ok)"));
2423 }
2424 else
2425 {
2426 printf(_T("(ERROR: should be %u)\n"), tt.count);
2427
2428 continue;
2429 }
2430
2431 // if we emulate strtok(), check that we do it correctly
2432 wxChar *buf, *s, *last;
2433
2434 if ( tkz.GetMode() == wxTOKEN_STRTOK )
2435 {
2436 buf = new wxChar[wxStrlen(tt.str) + 1];
2437 wxStrcpy(buf, tt.str);
2438
2439 s = wxStrtok(buf, tt.delims, &last);
2440 }
2441 else
2442 {
2443 buf = NULL;
2444 }
2445
2446 // now show the tokens themselves
2447 size_t count2 = 0;
2448 while ( tkz.HasMoreTokens() )
2449 {
2450 wxString token = tkz.GetNextToken();
2451
2452 printf(_T("\ttoken %u: '%s'"),
2453 ++count2,
2454 MakePrintable(token).c_str());
2455
2456 if ( buf )
2457 {
2458 if ( token == s )
2459 {
2460 puts(" (ok)");
2461 }
2462 else
2463 {
2464 printf(" (ERROR: should be %s)\n", s);
2465 }
2466
2467 s = wxStrtok(NULL, tt.delims, &last);
2468 }
2469 else
2470 {
2471 // nothing to compare with
2472 puts("");
2473 }
2474 }
2475
2476 if ( count2 != count )
2477 {
2478 puts(_T("\tERROR: token count mismatch"));
2479 }
2480
2481 delete [] buf;
2482 }
2483
2484 puts("");
2485 }
2486
2487 #endif // TEST_STRINGS
2488
2489 // ----------------------------------------------------------------------------
2490 // entry point
2491 // ----------------------------------------------------------------------------
2492
2493 int main(int argc, char **argv)
2494 {
2495 if ( !wxInitialize() )
2496 {
2497 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
2498 }
2499
2500 #ifdef TEST_USLEEP
2501 puts("Sleeping for 3 seconds... z-z-z-z-z...");
2502 wxUsleep(3000);
2503 #endif // TEST_USLEEP
2504
2505 #ifdef TEST_CMDLINE
2506 static const wxCmdLineEntryDesc cmdLineDesc[] =
2507 {
2508 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
2509 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
2510
2511 { wxCMD_LINE_OPTION, "o", "output", "output file" },
2512 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
2513 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
2514 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_DATE },
2515
2516 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
2517 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
2518
2519 { wxCMD_LINE_NONE }
2520 };
2521
2522 wxCmdLineParser parser(cmdLineDesc, argc, argv);
2523
2524 switch ( parser.Parse() )
2525 {
2526 case -1:
2527 wxLogMessage("Help was given, terminating.");
2528 break;
2529
2530 case 0:
2531 ShowCmdLine(parser);
2532 break;
2533
2534 default:
2535 wxLogMessage("Syntax error detected, aborting.");
2536 break;
2537 }
2538 #endif // TEST_CMDLINE
2539
2540 #ifdef TEST_STRINGS
2541 if ( 0 )
2542 {
2543 TestPChar();
2544 TestString();
2545 }
2546 if ( 0 )
2547 {
2548 TestStringConstruction();
2549 TestStringSub();
2550 TestStringFormat();
2551 TestStringFind();
2552 TestStringTokenizer();
2553 }
2554 #endif // TEST_STRINGS
2555
2556 #ifdef TEST_ARRAYS
2557 wxArrayString a1;
2558 a1.Add("tiger");
2559 a1.Add("cat");
2560 a1.Add("lion");
2561 a1.Add("dog");
2562 a1.Add("human");
2563 a1.Add("ape");
2564
2565 puts("*** Initially:");
2566
2567 PrintArray("a1", a1);
2568
2569 wxArrayString a2(a1);
2570 PrintArray("a2", a2);
2571
2572 wxSortedArrayString a3(a1);
2573 PrintArray("a3", a3);
2574
2575 puts("*** After deleting a string from a1");
2576 a1.Remove(2);
2577
2578 PrintArray("a1", a1);
2579 PrintArray("a2", a2);
2580 PrintArray("a3", a3);
2581
2582 puts("*** After reassigning a1 to a2 and a3");
2583 a3 = a2 = a1;
2584 PrintArray("a2", a2);
2585 PrintArray("a3", a3);
2586 #endif // TEST_ARRAYS
2587
2588 #ifdef TEST_DIR
2589 TestDirEnum();
2590 #endif // TEST_DIR
2591
2592 #ifdef TEST_EXECUTE
2593 TestExecute();
2594 #endif // TEST_EXECUTE
2595
2596 #ifdef TEST_FILECONF
2597 TestFileConfRead();
2598 #endif // TEST_FILECONF
2599
2600 #ifdef TEST_LOG
2601 wxString s;
2602 for ( size_t n = 0; n < 8000; n++ )
2603 {
2604 s << (char)('A' + (n % 26));
2605 }
2606
2607 wxString msg;
2608 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
2609
2610 // this one shouldn't be truncated
2611 printf(msg);
2612
2613 // but this one will because log functions use fixed size buffer
2614 // (note that it doesn't need '\n' at the end neither - will be added
2615 // by wxLog anyhow)
2616 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
2617 #endif // TEST_LOG
2618
2619 #ifdef TEST_THREADS
2620 int nCPUs = wxThread::GetCPUCount();
2621 printf("This system has %d CPUs\n", nCPUs);
2622 if ( nCPUs != -1 )
2623 wxThread::SetConcurrency(nCPUs);
2624
2625 if ( argc > 1 && argv[1][0] == 't' )
2626 wxLog::AddTraceMask("thread");
2627
2628 if ( 1 )
2629 TestDetachedThreads();
2630 if ( 1 )
2631 TestJoinableThreads();
2632 if ( 1 )
2633 TestThreadSuspend();
2634 if ( 1 )
2635 TestThreadDelete();
2636
2637 #endif // TEST_THREADS
2638
2639 #ifdef TEST_LONGLONG
2640 // seed pseudo random generator
2641 srand((unsigned)time(NULL));
2642
2643 if ( 0 )
2644 {
2645 TestSpeed();
2646 }
2647 TestMultiplication();
2648 if ( 0 )
2649 {
2650 TestDivision();
2651 TestAddition();
2652 TestLongLongConversion();
2653 TestBitOperations();
2654 }
2655 #endif // TEST_LONGLONG
2656
2657 #ifdef TEST_HASH
2658 TestHash();
2659 #endif // TEST_HASH
2660
2661 #ifdef TEST_MIME
2662 TestMimeEnum();
2663 #endif // TEST_MIME
2664
2665 #ifdef TEST_INFO_FUNCTIONS
2666 TestOsInfo();
2667 TestUserInfo();
2668 #endif // TEST_INFO_FUNCTIONS
2669
2670 #ifdef TEST_SOCKETS
2671 if ( 1 )
2672 TestSocketServer();
2673 if ( 0 )
2674 {
2675 TestSocketClient();
2676 TestProtocolFtp();
2677 }
2678 #endif // TEST_SOCKETS
2679
2680 #ifdef TEST_TIMER
2681 TestStopWatch();
2682 #endif // TEST_TIMER
2683
2684 #ifdef TEST_DATETIME
2685 if ( 0 )
2686 {
2687 TestTimeSet();
2688 TestTimeStatic();
2689 TestTimeRange();
2690 TestTimeZones();
2691 TestTimeTicks();
2692 TestTimeJDN();
2693 TestTimeDST();
2694 TestTimeWDays();
2695 TestTimeWNumber();
2696 TestTimeParse();
2697 TestTimeFormat();
2698 TestTimeArithmetics();
2699 }
2700 TestTimeHolidays();
2701 if ( 0 )
2702 TestInteractive();
2703 #endif // TEST_DATETIME
2704
2705 wxUninitialize();
2706
2707 return 0;
2708 }