]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
wxCmdLineParser tests
[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 // ----------------------------------------------------------------------------
27 // conditional compilation
28 // ----------------------------------------------------------------------------
29
30 // what to test?
31
32 //#define TEST_ARRAYS
33 #define TEST_CMDLINE
34 //#define TEST_DIR
35 //#define TEST_LOG
36 //#define TEST_LONGLONG
37 //#define TEST_MIME
38 //#define TEST_STRINGS
39 //#define TEST_THREADS
40 //#define TEST_TIME
41
42 // ============================================================================
43 // implementation
44 // ============================================================================
45
46 #ifdef TEST_CMDLINE
47
48 // ----------------------------------------------------------------------------
49 // wxCmdLineParser
50 // ----------------------------------------------------------------------------
51
52 #include <wx/cmdline.h>
53 #include <wx/datetime.h>
54
55 static void ShowCmdLine(const wxCmdLineParser& parser)
56 {
57 wxString s = "Input files: ";
58
59 size_t count = parser.GetParamCount();
60 for ( size_t param = 0; param < count; param++ )
61 {
62 s << parser.GetParam(param) << ' ';
63 }
64
65 s << '\n'
66 << "Verbose:\t" << (parser.Found("v") ? "yes" : "no") << '\n'
67 << "Quiet:\t" << (parser.Found("q") ? "yes" : "no") << '\n';
68
69 wxString strVal;
70 long lVal;
71 wxDateTime dt;
72 if ( parser.Found("o", &strVal) )
73 s << "Output file:\t" << strVal << '\n';
74 if ( parser.Found("i", &strVal) )
75 s << "Input dir:\t" << strVal << '\n';
76 if ( parser.Found("s", &lVal) )
77 s << "Size:\t" << lVal << '\n';
78 if ( parser.Found("d", &dt) )
79 s << "Date:\t" << dt.FormatISODate() << '\n';
80
81 wxLogMessage(s);
82 }
83
84 #endif // TEST_CMDLINE
85
86 // ----------------------------------------------------------------------------
87 // wxDir
88 // ----------------------------------------------------------------------------
89
90 #ifdef TEST_DIR
91
92 #include <wx/dir.h>
93
94 static void TestDirEnumHelper(wxDir& dir,
95 int flags = wxDIR_DEFAULT,
96 const wxString& filespec = wxEmptyString)
97 {
98 wxString filename;
99
100 if ( !dir.IsOpened() )
101 return;
102
103 bool cont = dir.GetFirst(&filename, filespec, flags);
104 while ( cont )
105 {
106 printf("\t%s\n", filename.c_str());
107
108 cont = dir.GetNext(&filename);
109 }
110
111 puts("");
112 }
113
114 static void TestDirEnum()
115 {
116 wxDir dir(wxGetCwd());
117
118 puts("Enumerating everything in current directory:");
119 TestDirEnumHelper(dir);
120
121 puts("Enumerating really everything in current directory:");
122 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
123
124 puts("Enumerating object files in current directory:");
125 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
126
127 puts("Enumerating directories in current directory:");
128 TestDirEnumHelper(dir, wxDIR_DIRS);
129
130 puts("Enumerating files in current directory:");
131 TestDirEnumHelper(dir, wxDIR_FILES);
132
133 puts("Enumerating files including hidden in current directory:");
134 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
135
136 #ifdef __UNIX__
137 dir.Open("/");
138 #elif defined(__WXMSW__)
139 dir.Open("c:\\");
140 #else
141 #error "don't know where the root directory is"
142 #endif
143
144 puts("Enumerating everything in root directory:");
145 TestDirEnumHelper(dir, wxDIR_DEFAULT);
146
147 puts("Enumerating directories in root directory:");
148 TestDirEnumHelper(dir, wxDIR_DIRS);
149
150 puts("Enumerating files in root directory:");
151 TestDirEnumHelper(dir, wxDIR_FILES);
152
153 puts("Enumerating files including hidden in root directory:");
154 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
155
156 puts("Enumerating files in non existing directory:");
157 wxDir dirNo("nosuchdir");
158 TestDirEnumHelper(dirNo);
159 }
160
161 #endif // TEST_DIR
162
163 // ----------------------------------------------------------------------------
164 // MIME types
165 // ----------------------------------------------------------------------------
166
167 #ifdef TEST_MIME
168
169 #include <wx/mimetype.h>
170
171 static void TestMimeEnum()
172 {
173 wxMimeTypesManager mimeTM;
174 wxArrayString mimetypes;
175
176 size_t count = mimeTM.EnumAllFileTypes(mimetypes);
177
178 printf("*** All %u known filetypes: ***\n", count);
179
180 wxArrayString exts;
181 wxString desc;
182
183 for ( size_t n = 0; n < count; n++ )
184 {
185 wxFileType *filetype = mimeTM.GetFileTypeFromMimeType(mimetypes[n]);
186 if ( !filetype )
187 {
188 printf("nothing known about the filetype '%s'!\n",
189 mimetypes[n].c_str());
190 continue;
191 }
192
193 filetype->GetDescription(&desc);
194 filetype->GetExtensions(exts);
195
196 filetype->GetIcon(NULL);
197
198 wxString extsAll;
199 for ( size_t e = 0; e < exts.GetCount(); e++ )
200 {
201 if ( e > 0 )
202 extsAll << _T(", ");
203 extsAll += exts[e];
204 }
205
206 printf("\t%s: %s (%s)\n",
207 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
208 }
209 }
210
211 #endif // TEST_MIME
212
213 // ----------------------------------------------------------------------------
214 // long long
215 // ----------------------------------------------------------------------------
216
217 #ifdef TEST_LONGLONG
218
219 #include <wx/longlong.h>
220 #include <wx/timer.h>
221
222 static void TestSpeed()
223 {
224 static const long max = 100000000;
225 long n;
226
227 {
228 wxStopWatch sw;
229
230 long l = 0;
231 for ( n = 0; n < max; n++ )
232 {
233 l += n;
234 }
235
236 printf("Summing longs took %ld milliseconds.\n", sw.Time());
237 }
238
239 #if wxUSE_LONGLONG_NATIVE
240 {
241 wxStopWatch sw;
242
243 wxLongLong_t l = 0;
244 for ( n = 0; n < max; n++ )
245 {
246 l += n;
247 }
248
249 printf("Summing wxLongLong_t took %ld milliseconds.\n", sw.Time());
250 }
251 #endif // wxUSE_LONGLONG_NATIVE
252
253 {
254 wxStopWatch sw;
255
256 wxLongLong l;
257 for ( n = 0; n < max; n++ )
258 {
259 l += n;
260 }
261
262 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
263 }
264 }
265
266 static void TestDivision()
267 {
268 puts("*** Testing wxLongLong division ***\n");
269
270 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
271
272 // seed pseudo random generator
273 srand((unsigned)time(NULL));
274
275 wxLongLong q, r;
276 size_t nTested = 0;
277 for ( size_t n = 0; n < 100000; n++ )
278 {
279 // get a random wxLongLong (shifting by 12 the MSB ensures that the
280 // multiplication will not overflow)
281 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
282
283 // get a random long (not wxLongLong for now) to divide it with
284 long l = rand();
285 q = ll / l;
286 r = ll % l;
287
288 // verify the result
289 wxASSERT_MSG( ll == q*l + r, "division failure" );
290
291 if ( !(nTested % 1000) )
292 {
293 putchar('.');
294 fflush(stdout);
295 }
296
297 nTested++;
298 }
299
300 puts(" done!");
301
302 #undef MAKE_LL
303 }
304
305 #endif // TEST_LONGLONG
306
307 // ----------------------------------------------------------------------------
308 // date time
309 // ----------------------------------------------------------------------------
310
311 #ifdef TEST_TIME
312
313 #include <wx/date.h>
314
315 #include <wx/datetime.h>
316
317 // the test data
318 struct Date
319 {
320 wxDateTime::wxDateTime_t day;
321 wxDateTime::Month month;
322 int year;
323 wxDateTime::wxDateTime_t hour, min, sec;
324 double jdn;
325 wxDateTime::WeekDay wday;
326 time_t gmticks, ticks;
327
328 void Init(const wxDateTime::Tm& tm)
329 {
330 day = tm.mday;
331 month = tm.mon;
332 year = tm.year;
333 hour = tm.hour;
334 min = tm.min;
335 sec = tm.sec;
336 jdn = 0.0;
337 gmticks = ticks = -1;
338 }
339
340 wxDateTime DT() const
341 { return wxDateTime(day, month, year, hour, min, sec); }
342
343 bool SameDay(const wxDateTime::Tm& tm) const
344 {
345 return day == tm.mday && month == tm.mon && year == tm.year;
346 }
347
348 wxString Format() const
349 {
350 wxString s;
351 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
352 hour, min, sec,
353 wxDateTime::GetMonthName(month).c_str(),
354 day,
355 abs(wxDateTime::ConvertYearToBC(year)),
356 year > 0 ? "AD" : "BC");
357 return s;
358 }
359
360 wxString FormatDate() const
361 {
362 wxString s;
363 s.Printf("%02d-%s-%4d%s",
364 day,
365 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
366 abs(wxDateTime::ConvertYearToBC(year)),
367 year > 0 ? "AD" : "BC");
368 return s;
369 }
370 };
371
372 static const Date testDates[] =
373 {
374 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
375 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
376 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
377 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
378 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
379 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
380 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
381 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
382 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
383 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
384 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
385 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
386 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
387 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
388 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
389 };
390
391 // this test miscellaneous static wxDateTime functions
392 static void TestTimeStatic()
393 {
394 puts("\n*** wxDateTime static methods test ***");
395
396 // some info about the current date
397 int year = wxDateTime::GetCurrentYear();
398 printf("Current year %d is %sa leap one and has %d days.\n",
399 year,
400 wxDateTime::IsLeapYear(year) ? "" : "not ",
401 wxDateTime::GetNumberOfDays(year));
402
403 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
404 printf("Current month is '%s' ('%s') and it has %d days\n",
405 wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(),
406 wxDateTime::GetMonthName(month).c_str(),
407 wxDateTime::GetNumberOfDays(month));
408
409 // leap year logic
410 static const size_t nYears = 5;
411 static const size_t years[2][nYears] =
412 {
413 // first line: the years to test
414 { 1990, 1976, 2000, 2030, 1984, },
415
416 // second line: TRUE if leap, FALSE otherwise
417 { FALSE, TRUE, TRUE, FALSE, TRUE }
418 };
419
420 for ( size_t n = 0; n < nYears; n++ )
421 {
422 int year = years[0][n];
423 bool should = years[1][n] != 0,
424 is = wxDateTime::IsLeapYear(year);
425
426 printf("Year %d is %sa leap year (%s)\n",
427 year,
428 is ? "" : "not ",
429 should == is ? "ok" : "ERROR");
430
431 wxASSERT( should == wxDateTime::IsLeapYear(year) );
432 }
433 }
434
435 // test constructing wxDateTime objects
436 static void TestTimeSet()
437 {
438 puts("\n*** wxDateTime construction test ***");
439
440 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
441 {
442 const Date& d1 = testDates[n];
443 wxDateTime dt = d1.DT();
444
445 Date d2;
446 d2.Init(dt.GetTm());
447
448 wxString s1 = d1.Format(),
449 s2 = d2.Format();
450
451 printf("Date: %s == %s (%s)\n",
452 s1.c_str(), s2.c_str(),
453 s1 == s2 ? "ok" : "ERROR");
454 }
455 }
456
457 // test time zones stuff
458 static void TestTimeZones()
459 {
460 puts("\n*** wxDateTime timezone test ***");
461
462 wxDateTime now = wxDateTime::Now();
463
464 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
465 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
466 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
467 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
468 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
469 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
470
471 wxDateTime::Tm tm = now.GetTm();
472 if ( wxDateTime(tm) != now )
473 {
474 printf("ERROR: got %s instead of %s\n",
475 wxDateTime(tm).Format().c_str(), now.Format().c_str());
476 }
477 }
478
479 // test some minimal support for the dates outside the standard range
480 static void TestTimeRange()
481 {
482 puts("\n*** wxDateTime out-of-standard-range dates test ***");
483
484 static const char *fmt = "%d-%b-%Y %H:%M:%S";
485
486 printf("Unix epoch:\t%s\n",
487 wxDateTime(2440587.5).Format(fmt).c_str());
488 printf("Feb 29, 0: \t%s\n",
489 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
490 printf("JDN 0: \t%s\n",
491 wxDateTime(0.0).Format(fmt).c_str());
492 printf("Jan 1, 1AD:\t%s\n",
493 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
494 printf("May 29, 2099:\t%s\n",
495 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
496 }
497
498 static void TestTimeTicks()
499 {
500 puts("\n*** wxDateTime ticks test ***");
501
502 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
503 {
504 const Date& d = testDates[n];
505 if ( d.ticks == -1 )
506 continue;
507
508 wxDateTime dt = d.DT();
509 long ticks = (dt.GetValue() / 1000).ToLong();
510 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
511 if ( ticks == d.ticks )
512 {
513 puts(" (ok)");
514 }
515 else
516 {
517 printf(" (ERROR: should be %ld, delta = %ld)\n",
518 d.ticks, ticks - d.ticks);
519 }
520
521 dt = d.DT().ToTimezone(wxDateTime::GMT0);
522 ticks = (dt.GetValue() / 1000).ToLong();
523 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
524 if ( ticks == d.gmticks )
525 {
526 puts(" (ok)");
527 }
528 else
529 {
530 printf(" (ERROR: should be %ld, delta = %ld)\n",
531 d.gmticks, ticks - d.gmticks);
532 }
533 }
534
535 puts("");
536 }
537
538 // test conversions to JDN &c
539 static void TestTimeJDN()
540 {
541 puts("\n*** wxDateTime to JDN test ***");
542
543 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
544 {
545 const Date& d = testDates[n];
546 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
547 double jdn = dt.GetJulianDayNumber();
548
549 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
550 if ( jdn == d.jdn )
551 {
552 puts(" (ok)");
553 }
554 else
555 {
556 printf(" (ERROR: should be %f, delta = %f)\n",
557 d.jdn, jdn - d.jdn);
558 }
559 }
560 }
561
562 // test week days computation
563 static void TestTimeWDays()
564 {
565 puts("\n*** wxDateTime weekday test ***");
566
567 // test GetWeekDay()
568 size_t n;
569 for ( n = 0; n < WXSIZEOF(testDates); n++ )
570 {
571 const Date& d = testDates[n];
572 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
573
574 wxDateTime::WeekDay wday = dt.GetWeekDay();
575 printf("%s is: %s",
576 d.Format().c_str(),
577 wxDateTime::GetWeekDayName(wday).c_str());
578 if ( wday == d.wday )
579 {
580 puts(" (ok)");
581 }
582 else
583 {
584 printf(" (ERROR: should be %s)\n",
585 wxDateTime::GetWeekDayName(d.wday).c_str());
586 }
587 }
588
589 puts("");
590
591 // test SetToWeekDay()
592 struct WeekDateTestData
593 {
594 Date date; // the real date (precomputed)
595 int nWeek; // its week index in the month
596 wxDateTime::WeekDay wday; // the weekday
597 wxDateTime::Month month; // the month
598 int year; // and the year
599
600 wxString Format() const
601 {
602 wxString s, which;
603 switch ( nWeek < -1 ? -nWeek : nWeek )
604 {
605 case 1: which = "first"; break;
606 case 2: which = "second"; break;
607 case 3: which = "third"; break;
608 case 4: which = "fourth"; break;
609 case 5: which = "fifth"; break;
610
611 case -1: which = "last"; break;
612 }
613
614 if ( nWeek < -1 )
615 {
616 which += " from end";
617 }
618
619 s.Printf("The %s %s of %s in %d",
620 which.c_str(),
621 wxDateTime::GetWeekDayName(wday).c_str(),
622 wxDateTime::GetMonthName(month).c_str(),
623 year);
624
625 return s;
626 }
627 };
628
629 // the array data was generated by the following python program
630 /*
631 from DateTime import *
632 from whrandom import *
633 from string import *
634
635 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
636 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
637
638 week = DateTimeDelta(7)
639
640 for n in range(20):
641 year = randint(1900, 2100)
642 month = randint(1, 12)
643 day = randint(1, 28)
644 dt = DateTime(year, month, day)
645 wday = dt.day_of_week
646
647 countFromEnd = choice([-1, 1])
648 weekNum = 0;
649
650 while dt.month is month:
651 dt = dt - countFromEnd * week
652 weekNum = weekNum + countFromEnd
653
654 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
655
656 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
657 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
658 */
659
660 static const WeekDateTestData weekDatesTestData[] =
661 {
662 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
663 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
664 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
665 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
666 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
667 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
668 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
669 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
670 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
671 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
672 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
673 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
674 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
675 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
676 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
677 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
678 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
679 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
680 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
681 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
682 };
683
684 static const char *fmt = "%d-%b-%Y";
685
686 wxDateTime dt;
687 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
688 {
689 const WeekDateTestData& wd = weekDatesTestData[n];
690
691 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
692
693 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
694
695 const Date& d = wd.date;
696 if ( d.SameDay(dt.GetTm()) )
697 {
698 puts(" (ok)");
699 }
700 else
701 {
702 dt.Set(d.day, d.month, d.year);
703
704 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
705 }
706 }
707 }
708
709 // test the computation of (ISO) week numbers
710 static void TestTimeWNumber()
711 {
712 puts("\n*** wxDateTime week number test ***");
713
714 struct WeekNumberTestData
715 {
716 Date date; // the date
717 wxDateTime::wxDateTime_t week; // the week number in the year
718 wxDateTime::wxDateTime_t wmon; // the week number in the month
719 wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun
720 wxDateTime::wxDateTime_t dnum; // day number in the year
721 };
722
723 // data generated with the following python script:
724 /*
725 from DateTime import *
726 from whrandom import *
727 from string import *
728
729 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
730 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
731
732 def GetMonthWeek(dt):
733 weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1
734 if weekNumMonth < 0:
735 weekNumMonth = weekNumMonth + 53
736 return weekNumMonth
737
738 def GetLastSundayBefore(dt):
739 if dt.iso_week[2] == 7:
740 return dt
741 else:
742 return dt - DateTimeDelta(dt.iso_week[2])
743
744 for n in range(20):
745 year = randint(1900, 2100)
746 month = randint(1, 12)
747 day = randint(1, 28)
748 dt = DateTime(year, month, day)
749 dayNum = dt.day_of_year
750 weekNum = dt.iso_week[1]
751 weekNumMonth = GetMonthWeek(dt)
752
753 weekNumMonth2 = 0
754 dtSunday = GetLastSundayBefore(dt)
755
756 while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)):
757 weekNumMonth2 = weekNumMonth2 + 1
758 dtSunday = dtSunday - DateTimeDelta(7)
759
760 data = { 'day': rjust(`day`, 2), \
761 'month': monthNames[month - 1], \
762 'year': year, \
763 'weekNum': rjust(`weekNum`, 2), \
764 'weekNumMonth': weekNumMonth, \
765 'weekNumMonth2': weekNumMonth2, \
766 'dayNum': rjust(`dayNum`, 3) }
767
768 print " { { %(day)s, "\
769 "wxDateTime::%(month)s, "\
770 "%(year)d }, "\
771 "%(weekNum)s, "\
772 "%(weekNumMonth)s, "\
773 "%(weekNumMonth2)s, "\
774 "%(dayNum)s }," % data
775
776 */
777 static const WeekNumberTestData weekNumberTestDates[] =
778 {
779 { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 },
780 { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 },
781 { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 },
782 { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 },
783 { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 },
784 { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 },
785 { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 },
786 { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 },
787 { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 },
788 { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 },
789 { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 },
790 { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 },
791 { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 },
792 { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 },
793 { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 },
794 { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 },
795 { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 },
796 { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 },
797 { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 },
798 { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 },
799 };
800
801 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
802 {
803 const WeekNumberTestData& wn = weekNumberTestDates[n];
804 const Date& d = wn.date;
805
806 wxDateTime dt = d.DT();
807
808 wxDateTime::wxDateTime_t
809 week = dt.GetWeekOfYear(wxDateTime::Monday_First),
810 wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First),
811 wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First),
812 dnum = dt.GetDayOfYear();
813
814 printf("%s: the day number is %d",
815 d.FormatDate().c_str(), dnum);
816 if ( dnum == wn.dnum )
817 {
818 printf(" (ok)");
819 }
820 else
821 {
822 printf(" (ERROR: should be %d)", wn.dnum);
823 }
824
825 printf(", week in month is %d", wmon);
826 if ( wmon == wn.wmon )
827 {
828 printf(" (ok)");
829 }
830 else
831 {
832 printf(" (ERROR: should be %d)", wn.wmon);
833 }
834
835 printf(" or %d", wmon2);
836 if ( wmon2 == wn.wmon2 )
837 {
838 printf(" (ok)");
839 }
840 else
841 {
842 printf(" (ERROR: should be %d)", wn.wmon2);
843 }
844
845 printf(", week in year is %d", week);
846 if ( week == wn.week )
847 {
848 puts(" (ok)");
849 }
850 else
851 {
852 printf(" (ERROR: should be %d)\n", wn.week);
853 }
854 }
855 }
856
857 // test DST calculations
858 static void TestTimeDST()
859 {
860 puts("\n*** wxDateTime DST test ***");
861
862 printf("DST is%s in effect now.\n\n",
863 wxDateTime::Now().IsDST() ? "" : " not");
864
865 // taken from http://www.energy.ca.gov/daylightsaving.html
866 static const Date datesDST[2][2004 - 1900 + 1] =
867 {
868 {
869 { 1, wxDateTime::Apr, 1990 },
870 { 7, wxDateTime::Apr, 1991 },
871 { 5, wxDateTime::Apr, 1992 },
872 { 4, wxDateTime::Apr, 1993 },
873 { 3, wxDateTime::Apr, 1994 },
874 { 2, wxDateTime::Apr, 1995 },
875 { 7, wxDateTime::Apr, 1996 },
876 { 6, wxDateTime::Apr, 1997 },
877 { 5, wxDateTime::Apr, 1998 },
878 { 4, wxDateTime::Apr, 1999 },
879 { 2, wxDateTime::Apr, 2000 },
880 { 1, wxDateTime::Apr, 2001 },
881 { 7, wxDateTime::Apr, 2002 },
882 { 6, wxDateTime::Apr, 2003 },
883 { 4, wxDateTime::Apr, 2004 },
884 },
885 {
886 { 28, wxDateTime::Oct, 1990 },
887 { 27, wxDateTime::Oct, 1991 },
888 { 25, wxDateTime::Oct, 1992 },
889 { 31, wxDateTime::Oct, 1993 },
890 { 30, wxDateTime::Oct, 1994 },
891 { 29, wxDateTime::Oct, 1995 },
892 { 27, wxDateTime::Oct, 1996 },
893 { 26, wxDateTime::Oct, 1997 },
894 { 25, wxDateTime::Oct, 1998 },
895 { 31, wxDateTime::Oct, 1999 },
896 { 29, wxDateTime::Oct, 2000 },
897 { 28, wxDateTime::Oct, 2001 },
898 { 27, wxDateTime::Oct, 2002 },
899 { 26, wxDateTime::Oct, 2003 },
900 { 31, wxDateTime::Oct, 2004 },
901 }
902 };
903
904 int year;
905 for ( year = 1990; year < 2005; year++ )
906 {
907 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
908 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
909
910 printf("DST period in the US for year %d: from %s to %s",
911 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
912
913 size_t n = year - 1990;
914 const Date& dBegin = datesDST[0][n];
915 const Date& dEnd = datesDST[1][n];
916
917 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
918 {
919 puts(" (ok)");
920 }
921 else
922 {
923 printf(" (ERROR: should be %s %d to %s %d)\n",
924 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
925 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
926 }
927 }
928
929 puts("");
930
931 for ( year = 1990; year < 2005; year++ )
932 {
933 printf("DST period in Europe for year %d: from %s to %s\n",
934 year,
935 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
936 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
937 }
938 }
939
940 // test wxDateTime -> text conversion
941 static void TestTimeFormat()
942 {
943 puts("\n*** wxDateTime formatting test ***");
944
945 // some information may be lost during conversion, so store what kind
946 // of info should we recover after a round trip
947 enum CompareKind
948 {
949 CompareNone, // don't try comparing
950 CompareBoth, // dates and times should be identical
951 CompareDate, // dates only
952 CompareTime // time only
953 };
954
955 static const struct
956 {
957 CompareKind compareKind;
958 const char *format;
959 } formatTestFormats[] =
960 {
961 { CompareBoth, "---> %c" },
962 { CompareDate, "Date is %A, %d of %B, in year %Y" },
963 { CompareBoth, "Date is %x, time is %X" },
964 { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" },
965 { CompareNone, "The day of year: %j, the week of year: %W" },
966 };
967
968 static const Date formatTestDates[] =
969 {
970 { 29, wxDateTime::May, 1976, 18, 30, 00 },
971 { 31, wxDateTime::Dec, 1999, 23, 30, 00 },
972 #if 0
973 // this test can't work for other centuries because it uses two digit
974 // years in formats, so don't even try it
975 { 29, wxDateTime::May, 2076, 18, 30, 00 },
976 { 29, wxDateTime::Feb, 2400, 02, 15, 25 },
977 { 01, wxDateTime::Jan, -52, 03, 16, 47 },
978 #endif
979 };
980
981 // an extra test (as it doesn't depend on date, don't do it in the loop)
982 printf("%s\n", wxDateTime::Now().Format("Our timezone is %Z").c_str());
983
984 for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ )
985 {
986 puts("");
987
988 wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT();
989 for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ )
990 {
991 wxString s = dt.Format(formatTestFormats[n].format);
992 printf("%s", s.c_str());
993
994 // what can we recover?
995 int kind = formatTestFormats[n].compareKind;
996
997 // convert back
998 wxDateTime dt2;
999 const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format);
1000 if ( !result )
1001 {
1002 // converion failed - should it have?
1003 if ( kind == CompareNone )
1004 puts(" (ok)");
1005 else
1006 puts(" (ERROR: conversion back failed)");
1007 }
1008 else if ( *result )
1009 {
1010 // should have parsed the entire string
1011 puts(" (ERROR: conversion back stopped too soon)");
1012 }
1013 else
1014 {
1015 bool equal = FALSE; // suppress compilaer warning
1016 switch ( kind )
1017 {
1018 case CompareBoth:
1019 equal = dt2 == dt;
1020 break;
1021
1022 case CompareDate:
1023 equal = dt.IsSameDate(dt2);
1024 break;
1025
1026 case CompareTime:
1027 equal = dt.IsSameTime(dt2);
1028 break;
1029 }
1030
1031 if ( !equal )
1032 {
1033 printf(" (ERROR: got back '%s' instead of '%s')\n",
1034 dt2.Format().c_str(), dt.Format().c_str());
1035 }
1036 else
1037 {
1038 puts(" (ok)");
1039 }
1040 }
1041 }
1042 }
1043 }
1044
1045 // test text -> wxDateTime conversion
1046 static void TestTimeParse()
1047 {
1048 puts("\n*** wxDateTime parse test ***");
1049
1050 struct ParseTestData
1051 {
1052 const char *format;
1053 Date date;
1054 bool good;
1055 };
1056
1057 static const ParseTestData parseTestDates[] =
1058 {
1059 { "Sat, 18 Dec 1999 00:46:40 +0100", { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, TRUE },
1060 { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, TRUE },
1061 };
1062
1063 for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ )
1064 {
1065 const char *format = parseTestDates[n].format;
1066
1067 printf("%s => ", format);
1068
1069 wxDateTime dt;
1070 if ( dt.ParseRfc822Date(format) )
1071 {
1072 printf("%s ", dt.Format().c_str());
1073
1074 if ( parseTestDates[n].good )
1075 {
1076 wxDateTime dtReal = parseTestDates[n].date.DT();
1077 if ( dt == dtReal )
1078 {
1079 puts("(ok)");
1080 }
1081 else
1082 {
1083 printf("(ERROR: should be %s)\n", dtReal.Format().c_str());
1084 }
1085 }
1086 else
1087 {
1088 puts("(ERROR: bad format)");
1089 }
1090 }
1091 else
1092 {
1093 printf("bad format (%s)\n",
1094 parseTestDates[n].good ? "ERROR" : "ok");
1095 }
1096 }
1097 }
1098
1099 static void TestInteractive()
1100 {
1101 puts("\n*** interactive wxDateTime tests ***");
1102
1103 char buf[128];
1104
1105 for ( ;; )
1106 {
1107 printf("Enter a date: ");
1108 if ( !fgets(buf, WXSIZEOF(buf), stdin) )
1109 break;
1110
1111 wxDateTime dt;
1112 if ( !dt.ParseDate(buf) )
1113 {
1114 puts("failed to parse the date");
1115
1116 continue;
1117 }
1118
1119 printf("%s: day %u, week of month %u/%u, week of year %u\n",
1120 dt.FormatISODate().c_str(),
1121 dt.GetDayOfYear(),
1122 dt.GetWeekOfMonth(wxDateTime::Monday_First),
1123 dt.GetWeekOfMonth(wxDateTime::Sunday_First),
1124 dt.GetWeekOfYear(wxDateTime::Monday_First));
1125 }
1126
1127 puts("\n*** done ***");
1128 }
1129
1130 static void TestTimeArithmetics()
1131 {
1132 puts("\n*** testing arithmetic operations on wxDateTime ***");
1133
1134 static const struct
1135 {
1136 wxDateSpan span;
1137 const char *name;
1138 } testArithmData[] =
1139 {
1140 { wxDateSpan::Day(), "day" },
1141 { wxDateSpan::Week(), "week" },
1142 { wxDateSpan::Month(), "month" },
1143 { wxDateSpan::Year(), "year" },
1144 { wxDateSpan(1, 2, 3, 4), "year, 2 months, 3 weeks, 4 days" },
1145 };
1146
1147 wxDateTime dt(29, wxDateTime::Dec, 1999), dt1, dt2;
1148
1149 for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ )
1150 {
1151 wxDateSpan span = testArithmData[n].span;
1152 dt1 = dt + span;
1153 dt2 = dt - span;
1154
1155 const char *name = testArithmData[n].name;
1156 printf("%s + %s = %s, %s - %s = %s\n",
1157 dt.FormatISODate().c_str(), name, dt1.FormatISODate().c_str(),
1158 dt.FormatISODate().c_str(), name, dt2.FormatISODate().c_str());
1159
1160 printf("Going back: %s", (dt1 - span).FormatISODate().c_str());
1161 if ( dt1 - span == dt )
1162 {
1163 puts(" (ok)");
1164 }
1165 else
1166 {
1167 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
1168 }
1169
1170 printf("Going forward: %s", (dt2 + span).FormatISODate().c_str());
1171 if ( dt2 + span == dt )
1172 {
1173 puts(" (ok)");
1174 }
1175 else
1176 {
1177 printf(" (ERROR: should be %s)\n", dt.FormatISODate().c_str());
1178 }
1179
1180 printf("Double increment: %s", (dt2 + 2*span).FormatISODate().c_str());
1181 if ( dt2 + 2*span == dt1 )
1182 {
1183 puts(" (ok)");
1184 }
1185 else
1186 {
1187 printf(" (ERROR: should be %s)\n", dt2.FormatISODate().c_str());
1188 }
1189
1190 puts("");
1191 }
1192 }
1193
1194 #if 0
1195
1196 // test compatibility with the old wxDate/wxTime classes
1197 static void TestTimeCompatibility()
1198 {
1199 puts("\n*** wxDateTime compatibility test ***");
1200
1201 printf("wxDate for JDN 0: %s\n", wxDate(0l).FormatDate().c_str());
1202 printf("wxDate for MJD 0: %s\n", wxDate(2400000).FormatDate().c_str());
1203
1204 double jdnNow = wxDateTime::Now().GetJDN();
1205 long jdnMidnight = (long)(jdnNow - 0.5);
1206 printf("wxDate for today: %s\n", wxDate(jdnMidnight).FormatDate().c_str());
1207
1208 jdnMidnight = wxDate().Set().GetJulianDate();
1209 printf("wxDateTime for today: %s\n",
1210 wxDateTime((double)(jdnMidnight + 0.5)).Format("%c", wxDateTime::GMT0).c_str());
1211
1212 int flags = wxEUROPEAN;//wxFULL;
1213 wxDate date;
1214 date.Set();
1215 printf("Today is %s\n", date.FormatDate(flags).c_str());
1216 for ( int n = 0; n < 7; n++ )
1217 {
1218 printf("Previous %s is %s\n",
1219 wxDateTime::GetWeekDayName((wxDateTime::WeekDay)n),
1220 date.Previous(n + 1).FormatDate(flags).c_str());
1221 }
1222 }
1223
1224 #endif // 0
1225
1226 #endif // TEST_TIME
1227
1228 // ----------------------------------------------------------------------------
1229 // threads
1230 // ----------------------------------------------------------------------------
1231
1232 #ifdef TEST_THREADS
1233
1234 #include <wx/thread.h>
1235
1236 static size_t gs_counter = (size_t)-1;
1237 static wxCriticalSection gs_critsect;
1238 static wxCondition gs_cond;
1239
1240 class MyJoinableThread : public wxThread
1241 {
1242 public:
1243 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
1244 { m_n = n; Create(); }
1245
1246 // thread execution starts here
1247 virtual ExitCode Entry();
1248
1249 private:
1250 size_t m_n;
1251 };
1252
1253 wxThread::ExitCode MyJoinableThread::Entry()
1254 {
1255 unsigned long res = 1;
1256 for ( size_t n = 1; n < m_n; n++ )
1257 {
1258 res *= n;
1259
1260 // it's a loooong calculation :-)
1261 Sleep(100);
1262 }
1263
1264 return (ExitCode)res;
1265 }
1266
1267 class MyDetachedThread : public wxThread
1268 {
1269 public:
1270 MyDetachedThread(size_t n, char ch)
1271 {
1272 m_n = n;
1273 m_ch = ch;
1274 m_cancelled = FALSE;
1275
1276 Create();
1277 }
1278
1279 // thread execution starts here
1280 virtual ExitCode Entry();
1281
1282 // and stops here
1283 virtual void OnExit();
1284
1285 private:
1286 size_t m_n; // number of characters to write
1287 char m_ch; // character to write
1288
1289 bool m_cancelled; // FALSE if we exit normally
1290 };
1291
1292 wxThread::ExitCode MyDetachedThread::Entry()
1293 {
1294 {
1295 wxCriticalSectionLocker lock(gs_critsect);
1296 if ( gs_counter == (size_t)-1 )
1297 gs_counter = 1;
1298 else
1299 gs_counter++;
1300 }
1301
1302 for ( size_t n = 0; n < m_n; n++ )
1303 {
1304 if ( TestDestroy() )
1305 {
1306 m_cancelled = TRUE;
1307
1308 break;
1309 }
1310
1311 putchar(m_ch);
1312 fflush(stdout);
1313
1314 wxThread::Sleep(100);
1315 }
1316
1317 return 0;
1318 }
1319
1320 void MyDetachedThread::OnExit()
1321 {
1322 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
1323
1324 wxCriticalSectionLocker lock(gs_critsect);
1325 if ( !--gs_counter && !m_cancelled )
1326 gs_cond.Signal();
1327 }
1328
1329 void TestDetachedThreads()
1330 {
1331 puts("\n*** Testing detached threads ***");
1332
1333 static const size_t nThreads = 3;
1334 MyDetachedThread *threads[nThreads];
1335 size_t n;
1336 for ( n = 0; n < nThreads; n++ )
1337 {
1338 threads[n] = new MyDetachedThread(10, 'A' + n);
1339 }
1340
1341 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
1342 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
1343
1344 for ( n = 0; n < nThreads; n++ )
1345 {
1346 threads[n]->Run();
1347 }
1348
1349 // wait until all threads terminate
1350 gs_cond.Wait();
1351
1352 puts("");
1353 }
1354
1355 void TestJoinableThreads()
1356 {
1357 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
1358
1359 // calc 10! in the background
1360 MyJoinableThread thread(10);
1361 thread.Run();
1362
1363 printf("\nThread terminated with exit code %lu.\n",
1364 (unsigned long)thread.Wait());
1365 }
1366
1367 void TestThreadSuspend()
1368 {
1369 puts("\n*** Testing thread suspend/resume functions ***");
1370
1371 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
1372
1373 thread->Run();
1374
1375 // this is for this demo only, in a real life program we'd use another
1376 // condition variable which would be signaled from wxThread::Entry() to
1377 // tell us that the thread really started running - but here just wait a
1378 // bit and hope that it will be enough (the problem is, of course, that
1379 // the thread might still not run when we call Pause() which will result
1380 // in an error)
1381 wxThread::Sleep(300);
1382
1383 for ( size_t n = 0; n < 3; n++ )
1384 {
1385 thread->Pause();
1386
1387 puts("\nThread suspended");
1388 if ( n > 0 )
1389 {
1390 // don't sleep but resume immediately the first time
1391 wxThread::Sleep(300);
1392 }
1393 puts("Going to resume the thread");
1394
1395 thread->Resume();
1396 }
1397
1398 puts("Waiting until it terminates now");
1399
1400 // wait until the thread terminates
1401 gs_cond.Wait();
1402
1403 puts("");
1404 }
1405
1406 void TestThreadDelete()
1407 {
1408 // As above, using Sleep() is only for testing here - we must use some
1409 // synchronisation object instead to ensure that the thread is still
1410 // running when we delete it - deleting a detached thread which already
1411 // terminated will lead to a crash!
1412
1413 puts("\n*** Testing thread delete function ***");
1414
1415 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
1416
1417 thread0->Delete();
1418
1419 puts("\nDeleted a thread which didn't start to run yet.");
1420
1421 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
1422
1423 thread1->Run();
1424
1425 wxThread::Sleep(300);
1426
1427 thread1->Delete();
1428
1429 puts("\nDeleted a running thread.");
1430
1431 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
1432
1433 thread2->Run();
1434
1435 wxThread::Sleep(300);
1436
1437 thread2->Pause();
1438
1439 thread2->Delete();
1440
1441 puts("\nDeleted a sleeping thread.");
1442
1443 MyJoinableThread thread3(20);
1444 thread3.Run();
1445
1446 thread3.Delete();
1447
1448 puts("\nDeleted a joinable thread.");
1449
1450 MyJoinableThread thread4(2);
1451 thread4.Run();
1452
1453 wxThread::Sleep(300);
1454
1455 thread4.Delete();
1456
1457 puts("\nDeleted a joinable thread which already terminated.");
1458
1459 puts("");
1460 }
1461
1462 #endif // TEST_THREADS
1463
1464 // ----------------------------------------------------------------------------
1465 // arrays
1466 // ----------------------------------------------------------------------------
1467
1468 #ifdef TEST_ARRAYS
1469
1470 void PrintArray(const char* name, const wxArrayString& array)
1471 {
1472 printf("Dump of the array '%s'\n", name);
1473
1474 size_t nCount = array.GetCount();
1475 for ( size_t n = 0; n < nCount; n++ )
1476 {
1477 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
1478 }
1479 }
1480
1481 #endif // TEST_ARRAYS
1482
1483 // ----------------------------------------------------------------------------
1484 // strings
1485 // ----------------------------------------------------------------------------
1486
1487 #ifdef TEST_STRINGS
1488
1489 #include "wx/timer.h"
1490
1491 static void TestString()
1492 {
1493 wxStopWatch sw;
1494
1495 wxString a, b, c;
1496
1497 a.reserve (128);
1498 b.reserve (128);
1499 c.reserve (128);
1500
1501 for (int i = 0; i < 1000000; ++i)
1502 {
1503 a = "Hello";
1504 b = " world";
1505 c = "! How'ya doin'?";
1506 a += b;
1507 a += c;
1508 c = "Hello world! What's up?";
1509 if (c != a)
1510 c = "Doh!";
1511 }
1512
1513 printf ("TestString elapsed time: %ld\n", sw.Time());
1514 }
1515
1516 static void TestPChar()
1517 {
1518 wxStopWatch sw;
1519
1520 char a [128];
1521 char b [128];
1522 char c [128];
1523
1524 for (int i = 0; i < 1000000; ++i)
1525 {
1526 strcpy (a, "Hello");
1527 strcpy (b, " world");
1528 strcpy (c, "! How'ya doin'?");
1529 strcat (a, b);
1530 strcat (a, c);
1531 strcpy (c, "Hello world! What's up?");
1532 if (strcmp (c, a) == 0)
1533 strcpy (c, "Doh!");
1534 }
1535
1536 printf ("TestPChar elapsed time: %ld\n", sw.Time());
1537 }
1538
1539 static void TestStringSub()
1540 {
1541 wxString s("Hello, world!");
1542
1543 puts("*** Testing wxString substring extraction ***");
1544
1545 printf("String = '%s'\n", s.c_str());
1546 printf("Left(5) = '%s'\n", s.Left(5).c_str());
1547 printf("Right(6) = '%s'\n", s.Right(6).c_str());
1548 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
1549 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
1550 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
1551 printf("substr(3) = '%s'\n", s.substr(3).c_str());
1552
1553 puts("");
1554 }
1555
1556 static void TestStringFormat()
1557 {
1558 puts("*** Testing wxString formatting ***");
1559
1560 wxString s;
1561 s.Printf("%03d", 18);
1562
1563 printf("Number 18: %s\n", wxString::Format("%03d", 18).c_str());
1564 printf("Number 18: %s\n", s.c_str());
1565
1566 puts("");
1567 }
1568
1569 #endif // TEST_STRINGS
1570
1571 // ----------------------------------------------------------------------------
1572 // entry point
1573 // ----------------------------------------------------------------------------
1574
1575 int main(int argc, char **argv)
1576 {
1577 if ( !wxInitialize() )
1578 {
1579 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
1580 }
1581
1582 #ifdef TEST_CMDLINE
1583 static const wxCmdLineEntryDesc cmdLineDesc[] =
1584 {
1585 { wxCMD_LINE_SWITCH, "v", "verbose", "be verbose" },
1586 { wxCMD_LINE_SWITCH, "q", "quiet", "be quiet" },
1587
1588 { wxCMD_LINE_OPTION, "o", "output", "output file" },
1589 { wxCMD_LINE_OPTION, "i", "input", "input dir" },
1590 { wxCMD_LINE_OPTION, "s", "size", "output block size", wxCMD_LINE_VAL_NUMBER },
1591 { wxCMD_LINE_OPTION, "d", "date", "output file date", wxCMD_LINE_VAL_NUMBER },
1592
1593 { wxCMD_LINE_PARAM, NULL, NULL, "input file",
1594 wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE },
1595
1596 { wxCMD_LINE_NONE }
1597 };
1598
1599 wxCmdLineParser parser(cmdLineDesc, argc, argv);
1600
1601 switch ( parser.Parse() )
1602 {
1603 case -1:
1604 wxLogMessage("Help was given, terminating.");
1605 break;
1606
1607 case 0:
1608 ShowCmdLine(parser);
1609 break;
1610
1611 default:
1612 wxLogMessage("Syntax error detected, aborting.");
1613 break;
1614 }
1615 #endif // TEST_CMDLINE
1616
1617 #ifdef TEST_STRINGS
1618 if ( 0 )
1619 {
1620 TestPChar();
1621 TestString();
1622 }
1623 if ( 0 )
1624 {
1625 TestStringSub();
1626 }
1627 TestStringFormat();
1628 #endif // TEST_STRINGS
1629
1630 #ifdef TEST_ARRAYS
1631 wxArrayString a1;
1632 a1.Add("tiger");
1633 a1.Add("cat");
1634 a1.Add("lion");
1635 a1.Add("dog");
1636 a1.Add("human");
1637 a1.Add("ape");
1638
1639 puts("*** Initially:");
1640
1641 PrintArray("a1", a1);
1642
1643 wxArrayString a2(a1);
1644 PrintArray("a2", a2);
1645
1646 wxSortedArrayString a3(a1);
1647 PrintArray("a3", a3);
1648
1649 puts("*** After deleting a string from a1");
1650 a1.Remove(2);
1651
1652 PrintArray("a1", a1);
1653 PrintArray("a2", a2);
1654 PrintArray("a3", a3);
1655
1656 puts("*** After reassigning a1 to a2 and a3");
1657 a3 = a2 = a1;
1658 PrintArray("a2", a2);
1659 PrintArray("a3", a3);
1660 #endif // TEST_ARRAYS
1661
1662 #ifdef TEST_DIR
1663 TestDirEnum();
1664 #endif // TEST_DIR
1665
1666 #ifdef TEST_LOG
1667 wxString s;
1668 for ( size_t n = 0; n < 8000; n++ )
1669 {
1670 s << (char)('A' + (n % 26));
1671 }
1672
1673 wxString msg;
1674 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
1675
1676 // this one shouldn't be truncated
1677 printf(msg);
1678
1679 // but this one will because log functions use fixed size buffer
1680 // (note that it doesn't need '\n' at the end neither - will be added
1681 // by wxLog anyhow)
1682 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
1683 #endif // TEST_LOG
1684
1685 #ifdef TEST_THREADS
1686 int nCPUs = wxThread::GetCPUCount();
1687 printf("This system has %d CPUs\n", nCPUs);
1688 if ( nCPUs != -1 )
1689 wxThread::SetConcurrency(nCPUs);
1690
1691 if ( argc > 1 && argv[1][0] == 't' )
1692 wxLog::AddTraceMask("thread");
1693
1694 if ( 1 )
1695 TestDetachedThreads();
1696 if ( 1 )
1697 TestJoinableThreads();
1698 if ( 1 )
1699 TestThreadSuspend();
1700 if ( 1 )
1701 TestThreadDelete();
1702
1703 #endif // TEST_THREADS
1704
1705 #ifdef TEST_LONGLONG
1706 if ( 0 )
1707 TestSpeed();
1708 if ( 1 )
1709 TestDivision();
1710 #endif // TEST_LONGLONG
1711
1712 #ifdef TEST_MIME
1713 TestMimeEnum();
1714 #endif // TEST_MIME
1715
1716 #ifdef TEST_TIME
1717 if ( 0 )
1718 {
1719 TestTimeSet();
1720 TestTimeStatic();
1721 TestTimeRange();
1722 TestTimeZones();
1723 TestTimeTicks();
1724 TestTimeJDN();
1725 TestTimeDST();
1726 TestTimeWDays();
1727 TestTimeWNumber();
1728 TestTimeParse();
1729 TestTimeFormat();
1730 TestTimeArithmetics();
1731 }
1732 if ( 0 )
1733 TestInteractive();
1734 #endif // TEST_TIME
1735
1736 wxUninitialize();
1737
1738 return 0;
1739 }