]> git.saurik.com Git - wxWidgets.git/blob - samples/console/console.cpp
ab1b4c9ffbb63e6e25aa96a72ef4ffdb55caa3be
[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_DIR
34 //#define TEST_LOG
35 //#define TEST_MIME
36 //#define TEST_STRINGS
37 //#define TEST_THREADS
38 #define TEST_TIME
39 //#define TEST_LONGLONG
40
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 // ----------------------------------------------------------------------------
46 // wxDir
47 // ----------------------------------------------------------------------------
48
49 #ifdef TEST_DIR
50
51 #include <wx/dir.h>
52
53 static void TestDirEnumHelper(wxDir& dir,
54 int flags = wxDIR_DEFAULT,
55 const wxString& filespec = wxEmptyString)
56 {
57 wxString filename;
58
59 if ( !dir.IsOpened() )
60 return;
61
62 bool cont = dir.GetFirst(&filename, filespec, flags);
63 while ( cont )
64 {
65 printf("\t%s\n", filename.c_str());
66
67 cont = dir.GetNext(&filename);
68 }
69
70 puts("");
71 }
72
73 static void TestDirEnum()
74 {
75 wxDir dir(wxGetCwd());
76
77 puts("Enumerating everything in current directory:");
78 TestDirEnumHelper(dir);
79
80 puts("Enumerating really everything in current directory:");
81 TestDirEnumHelper(dir, wxDIR_DEFAULT | wxDIR_DOTDOT);
82
83 puts("Enumerating object files in current directory:");
84 TestDirEnumHelper(dir, wxDIR_DEFAULT, "*.o");
85
86 puts("Enumerating directories in current directory:");
87 TestDirEnumHelper(dir, wxDIR_DIRS);
88
89 puts("Enumerating files in current directory:");
90 TestDirEnumHelper(dir, wxDIR_FILES);
91
92 puts("Enumerating files including hidden in current directory:");
93 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
94
95 #ifdef __UNIX__
96 dir.Open("/");
97 #elif defined(__WXMSW__)
98 dir.Open("c:\\");
99 #else
100 #error "don't know where the root directory is"
101 #endif
102
103 puts("Enumerating everything in root directory:");
104 TestDirEnumHelper(dir, wxDIR_DEFAULT);
105
106 puts("Enumerating directories in root directory:");
107 TestDirEnumHelper(dir, wxDIR_DIRS);
108
109 puts("Enumerating files in root directory:");
110 TestDirEnumHelper(dir, wxDIR_FILES);
111
112 puts("Enumerating files including hidden in root directory:");
113 TestDirEnumHelper(dir, wxDIR_FILES | wxDIR_HIDDEN);
114
115 puts("Enumerating files in non existing directory:");
116 wxDir dirNo("nosuchdir");
117 TestDirEnumHelper(dirNo);
118 }
119
120 #endif // TEST_DIR
121
122 // ----------------------------------------------------------------------------
123 // MIME types
124 // ----------------------------------------------------------------------------
125
126 #ifdef TEST_MIME
127
128 #include <wx/mimetype.h>
129
130 static void TestMimeEnum()
131 {
132 wxMimeTypesManager mimeTM;
133 wxArrayString mimetypes;
134
135 size_t count = mimeTM.EnumAllFileTypes(mimetypes);
136
137 printf("*** All %u known filetypes: ***\n", count);
138
139 wxArrayString exts;
140 wxString desc;
141
142 for ( size_t n = 0; n < count; n++ )
143 {
144 wxFileType *filetype = mimeTM.GetFileTypeFromMimeType(mimetypes[n]);
145 if ( !filetype )
146 {
147 printf("nothing known about the filetype '%s'!\n",
148 mimetypes[n].c_str());
149 continue;
150 }
151
152 filetype->GetDescription(&desc);
153 filetype->GetExtensions(exts);
154
155 filetype->GetIcon(NULL);
156
157 wxString extsAll;
158 for ( size_t e = 0; e < exts.GetCount(); e++ )
159 {
160 if ( e > 0 )
161 extsAll << _T(", ");
162 extsAll += exts[e];
163 }
164
165 printf("\t%s: %s (%s)\n",
166 mimetypes[n].c_str(), desc.c_str(), extsAll.c_str());
167 }
168 }
169
170 #endif // TEST_MIME
171
172 // ----------------------------------------------------------------------------
173 // long long
174 // ----------------------------------------------------------------------------
175
176 #ifdef TEST_LONGLONG
177
178 #include <wx/longlong.h>
179 #include <wx/timer.h>
180
181 static void TestSpeed()
182 {
183 static const long max = 100000000;
184 long n;
185
186 {
187 wxStopWatch sw;
188
189 long l = 0;
190 for ( n = 0; n < max; n++ )
191 {
192 l += n;
193 }
194
195 printf("Summing longs took %ld milliseconds.\n", sw.Time());
196 }
197
198 {
199 wxStopWatch sw;
200
201 __int64 l = 0;
202 for ( n = 0; n < max; n++ )
203 {
204 l += n;
205 }
206
207 printf("Summing __int64s took %ld milliseconds.\n", sw.Time());
208 }
209
210 {
211 wxStopWatch sw;
212
213 wxLongLong l;
214 for ( n = 0; n < max; n++ )
215 {
216 l += n;
217 }
218
219 printf("Summing wxLongLongs took %ld milliseconds.\n", sw.Time());
220 }
221 }
222
223 static void TestDivision()
224 {
225 #define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3)
226
227 // seed pseudo random generator
228 //srand((unsigned)time(NULL));
229
230 size_t nTested = 0;
231 for ( size_t n = 0; n < 10000; n++ )
232 {
233 // get a random wxLongLong (shifting by 12 the MSB ensures that the
234 // multiplication will not overflow)
235 wxLongLong ll = MAKE_LL((rand() >> 12), rand(), rand(), rand());
236
237 wxASSERT( (ll * 1000l)/1000l == ll );
238
239 nTested++;
240 }
241
242 printf("\n*** Tested %u divisions/multiplications: ok\n", nTested);
243
244 #undef MAKE_LL
245 }
246
247 #endif // TEST_LONGLONG
248
249 // ----------------------------------------------------------------------------
250 // date time
251 // ----------------------------------------------------------------------------
252
253 #ifdef TEST_TIME
254
255 #include <wx/datetime.h>
256
257 // the test data
258 struct Date
259 {
260 wxDateTime::wxDateTime_t day;
261 wxDateTime::Month month;
262 int year;
263 wxDateTime::wxDateTime_t hour, min, sec;
264 double jdn;
265 wxDateTime::WeekDay wday;
266 time_t gmticks, ticks;
267
268 void Init(const wxDateTime::Tm& tm)
269 {
270 day = tm.mday;
271 month = tm.mon;
272 year = tm.year;
273 hour = tm.hour;
274 min = tm.min;
275 sec = tm.sec;
276 jdn = 0.0;
277 gmticks = ticks = -1;
278 }
279
280 wxDateTime DT() const
281 { return wxDateTime(day, month, year, hour, min, sec); }
282
283 bool SameDay(const wxDateTime::Tm& tm) const
284 {
285 return day == tm.mday && month == tm.mon && year == tm.year;
286 }
287
288 wxString Format() const
289 {
290 wxString s;
291 s.Printf("%02d:%02d:%02d %10s %02d, %4d%s",
292 hour, min, sec,
293 wxDateTime::GetMonthName(month).c_str(),
294 day,
295 abs(wxDateTime::ConvertYearToBC(year)),
296 year > 0 ? "AD" : "BC");
297 return s;
298 }
299
300 wxString FormatDate() const
301 {
302 wxString s;
303 s.Printf("%02d-%s-%4d%s",
304 day,
305 wxDateTime::GetMonthName(month, TRUE).c_str(),
306 abs(wxDateTime::ConvertYearToBC(year)),
307 year > 0 ? "AD" : "BC");
308 return s;
309 }
310 };
311
312 static const Date testDates[] =
313 {
314 { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 },
315 { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 },
316 { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 },
317 { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 },
318 { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 },
319 { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 },
320 { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 },
321 { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 },
322 { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 },
323 { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 },
324 { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 },
325 { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 },
326 { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 },
327 { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 },
328 { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 },
329 };
330
331 // this test miscellaneous static wxDateTime functions
332 static void TestTimeStatic()
333 {
334 puts("\n*** wxDateTime static methods test ***");
335
336 // some info about the current date
337 int year = wxDateTime::GetCurrentYear();
338 printf("Current year %d is %sa leap one and has %d days.\n",
339 year,
340 wxDateTime::IsLeapYear(year) ? "" : "not ",
341 wxDateTime::GetNumberOfDays(year));
342
343 wxDateTime::Month month = wxDateTime::GetCurrentMonth();
344 printf("Current month is '%s' ('%s') and it has %d days\n",
345 wxDateTime::GetMonthName(month, TRUE).c_str(),
346 wxDateTime::GetMonthName(month).c_str(),
347 wxDateTime::GetNumberOfDays(month));
348
349 // leap year logic
350 static const size_t nYears = 5;
351 static const size_t years[2][nYears] =
352 {
353 // first line: the years to test
354 { 1990, 1976, 2000, 2030, 1984, },
355
356 // second line: TRUE if leap, FALSE otherwise
357 { FALSE, TRUE, TRUE, FALSE, TRUE }
358 };
359
360 for ( size_t n = 0; n < nYears; n++ )
361 {
362 int year = years[0][n];
363 bool should = years[1][n] != 0,
364 is = wxDateTime::IsLeapYear(year);
365
366 printf("Year %d is %sa leap year (%s)\n",
367 year,
368 is ? "" : "not ",
369 should == is ? "ok" : "ERROR");
370
371 wxASSERT( should == wxDateTime::IsLeapYear(year) );
372 }
373 }
374
375 // test constructing wxDateTime objects
376 static void TestTimeSet()
377 {
378 puts("\n*** wxDateTime construction test ***");
379
380 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
381 {
382 const Date& d1 = testDates[n];
383 wxDateTime dt = d1.DT();
384
385 Date d2;
386 d2.Init(dt.GetTm());
387
388 wxString s1 = d1.Format(),
389 s2 = d2.Format();
390
391 printf("Date: %s == %s (%s)\n",
392 s1.c_str(), s2.c_str(),
393 s1 == s2 ? "ok" : "ERROR");
394 }
395 }
396
397 // test time zones stuff
398 static void TestTimeZones()
399 {
400 puts("\n*** wxDateTime timezone test ***");
401
402 wxDateTime now = wxDateTime::Now();
403
404 printf("Current GMT time:\t%s\n", now.Format("%c", wxDateTime::GMT0).c_str());
405 printf("Unix epoch (GMT):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::GMT0).c_str());
406 printf("Unix epoch (EST):\t%s\n", wxDateTime((time_t)0).Format("%c", wxDateTime::EST).c_str());
407 printf("Current time in Paris:\t%s\n", now.Format("%c", wxDateTime::CET).c_str());
408 printf(" Moscow:\t%s\n", now.Format("%c", wxDateTime::MSK).c_str());
409 printf(" New York:\t%s\n", now.Format("%c", wxDateTime::EST).c_str());
410 }
411
412 // test some minimal support for the dates outside the standard range
413 static void TestTimeRange()
414 {
415 puts("\n*** wxDateTime out-of-standard-range dates test ***");
416
417 static const char *fmt = "%d-%b-%Y %H:%M:%S";
418
419 printf("Unix epoch:\t%s\n",
420 wxDateTime(2440587.5).Format(fmt).c_str());
421 printf("Feb 29, 0: \t%s\n",
422 wxDateTime(29, wxDateTime::Feb, 0).Format(fmt).c_str());
423 printf("JDN 0: \t%s\n",
424 wxDateTime(0.0).Format(fmt).c_str());
425 printf("Jan 1, 1AD:\t%s\n",
426 wxDateTime(1, wxDateTime::Jan, 1).Format(fmt).c_str());
427 printf("May 29, 2099:\t%s\n",
428 wxDateTime(29, wxDateTime::May, 2099).Format(fmt).c_str());
429 }
430
431 static void TestTimeTicks()
432 {
433 puts("\n*** wxDateTime ticks test ***");
434
435 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
436 {
437 const Date& d = testDates[n];
438 if ( d.ticks == -1 )
439 continue;
440
441 wxDateTime dt = d.DT();
442 long ticks = (dt.GetValue() / 1000).ToLong();
443 printf("Ticks of %s:\t% 10ld", d.Format().c_str(), ticks);
444 if ( ticks == d.ticks )
445 {
446 puts(" (ok)");
447 }
448 else
449 {
450 printf(" (ERROR: should be %ld, delta = %ld)\n",
451 d.ticks, ticks - d.ticks);
452 }
453
454 dt = d.DT().ToTimezone(wxDateTime::GMT0);
455 ticks = (dt.GetValue() / 1000).ToLong();
456 printf("GMtks of %s:\t% 10ld", d.Format().c_str(), ticks);
457 if ( ticks == d.gmticks )
458 {
459 puts(" (ok)");
460 }
461 else
462 {
463 printf(" (ERROR: should be %ld, delta = %ld)\n",
464 d.gmticks, ticks - d.gmticks);
465 }
466 }
467
468 puts("");
469 }
470
471 // test conversions to JDN &c
472 static void TestTimeJDN()
473 {
474 puts("\n*** wxDateTime to JDN test ***");
475
476 for ( size_t n = 0; n < WXSIZEOF(testDates); n++ )
477 {
478 const Date& d = testDates[n];
479 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
480 double jdn = dt.GetJulianDayNumber();
481
482 printf("JDN of %s is:\t% 15.6f", d.Format().c_str(), jdn);
483 if ( jdn == d.jdn )
484 {
485 puts(" (ok)");
486 }
487 else
488 {
489 printf(" (ERROR: should be %f, delta = %f)\n",
490 d.jdn, jdn - d.jdn);
491 }
492 }
493 }
494
495 // test week days computation
496 static void TestTimeWDays()
497 {
498 puts("\n*** wxDateTime weekday test ***");
499
500 // test GetWeekDay()
501 size_t n;
502 for ( n = 0; n < WXSIZEOF(testDates); n++ )
503 {
504 const Date& d = testDates[n];
505 wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec);
506
507 wxDateTime::WeekDay wday = dt.GetWeekDay();
508 printf("%s is: %s",
509 d.Format().c_str(),
510 wxDateTime::GetWeekDayName(wday).c_str());
511 if ( wday == d.wday )
512 {
513 puts(" (ok)");
514 }
515 else
516 {
517 printf(" (ERROR: should be %s)\n",
518 wxDateTime::GetWeekDayName(d.wday).c_str());
519 }
520 }
521
522 puts("");
523
524 // test SetToWeekDay()
525 struct WeekDateTestData
526 {
527 Date date; // the real date (precomputed)
528 int nWeek; // its week index in the month
529 wxDateTime::WeekDay wday; // the weekday
530 wxDateTime::Month month; // the month
531 int year; // and the year
532
533 wxString Format() const
534 {
535 wxString s, which;
536 switch ( nWeek < -1 ? -nWeek : nWeek )
537 {
538 case 1: which = "first"; break;
539 case 2: which = "second"; break;
540 case 3: which = "third"; break;
541 case 4: which = "fourth"; break;
542 case 5: which = "fifth"; break;
543
544 case -1: which = "last"; break;
545 }
546
547 if ( nWeek < -1 )
548 {
549 which += " from end";
550 }
551
552 s.Printf("The %s %s of %s in %d",
553 which.c_str(),
554 wxDateTime::GetWeekDayName(wday).c_str(),
555 wxDateTime::GetMonthName(month).c_str(),
556 year);
557
558 return s;
559 }
560 };
561
562 // the array data was generated by the following python program
563 /*
564 from DateTime import *
565 from whrandom import *
566 from string import *
567
568 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
569 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
570
571 week = DateTimeDelta(7)
572
573 for n in range(20):
574 year = randint(1900, 2100)
575 month = randint(1, 12)
576 day = randint(1, 28)
577 dt = DateTime(year, month, day)
578 wday = dt.day_of_week
579
580 countFromEnd = choice([-1, 1])
581 weekNum = 0;
582
583 while dt.month is month:
584 dt = dt - countFromEnd * week
585 weekNum = weekNum + countFromEnd
586
587 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] }
588
589 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\
590 "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data
591 */
592
593 static const WeekDateTestData weekDatesTestData[] =
594 {
595 { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 },
596 { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 },
597 { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 },
598 { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 },
599 { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 },
600 { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 },
601 { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 },
602 { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 },
603 { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 },
604 { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 },
605 { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 },
606 { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 },
607 { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 },
608 { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 },
609 { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 },
610 { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 },
611 { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 },
612 { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 },
613 { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 },
614 { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 },
615 };
616
617 static const char *fmt = "%d-%b-%Y";
618
619 wxDateTime dt;
620 for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ )
621 {
622 const WeekDateTestData& wd = weekDatesTestData[n];
623
624 dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year);
625
626 printf("%s is %s", wd.Format().c_str(), dt.Format(fmt).c_str());
627
628 const Date& d = wd.date;
629 if ( d.SameDay(dt.GetTm()) )
630 {
631 puts(" (ok)");
632 }
633 else
634 {
635 dt.Set(d.day, d.month, d.year);
636
637 printf(" (ERROR: should be %s)\n", dt.Format(fmt).c_str());
638 }
639 }
640 }
641
642 // test the computation of (ISO) week numbers
643 static void TestTimeWNumber()
644 {
645 puts("\n*** wxDateTime week number test ***");
646
647 struct WeekNumberTestData
648 {
649 Date date; // the date
650 wxDateTime::wxDateTime_t week; // the week number
651 wxDateTime::wxDateTime_t dnum; // day number in the year
652 };
653
654 // data generated with the following python script:
655 /*
656 from DateTime import *
657 from whrandom import *
658 from string import *
659
660 monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
661 wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
662
663 for n in range(20):
664 year = randint(1900, 2100)
665 month = randint(1, 12)
666 day = randint(1, 28)
667 dt = DateTime(year, month, day)
668 dayNum = dt.day_of_year
669 weekNum = dt.iso_week[1]
670
671 data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'dayNum': rjust(`dayNum`, 3) }
672
673 print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)s, "\
674 "%(dayNum)s }," % data
675 */
676 static const WeekNumberTestData weekNumberTestDates[] =
677 {
678 { { 2, wxDateTime::Jul, 2093 }, 27, 183 },
679 { { 25, wxDateTime::Jun, 1986 }, 26, 176 },
680 { { 15, wxDateTime::Jun, 2014 }, 24, 166 },
681 { { 20, wxDateTime::Jul, 2018 }, 29, 201 },
682 { { 3, wxDateTime::Aug, 2074 }, 31, 215 },
683 { { 26, wxDateTime::Jul, 2012 }, 30, 208 },
684 { { 4, wxDateTime::Nov, 1915 }, 44, 308 },
685 { { 11, wxDateTime::Feb, 2035 }, 6, 42 },
686 { { 15, wxDateTime::Feb, 1942 }, 7, 46 },
687 { { 5, wxDateTime::Jan, 2087 }, 1, 5 },
688 { { 6, wxDateTime::Nov, 2016 }, 44, 311 },
689 { { 6, wxDateTime::Jun, 2057 }, 23, 157 },
690 { { 25, wxDateTime::Feb, 1976 }, 9, 56 },
691 { { 12, wxDateTime::Jan, 2073 }, 2, 12 },
692 { { 12, wxDateTime::Sep, 2040 }, 37, 256 },
693 { { 15, wxDateTime::Jul, 1931 }, 29, 196 },
694 { { 23, wxDateTime::Mar, 2084 }, 12, 83 },
695 { { 12, wxDateTime::Dec, 1970 }, 50, 346 },
696 { { 6, wxDateTime::Sep, 1996 }, 36, 250 },
697 { { 7, wxDateTime::Jan, 2076 }, 2, 7 },
698 };
699
700 for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ )
701 {
702 const WeekNumberTestData& wn = weekNumberTestDates[n];
703 const Date& d = wn.date;
704
705 wxDateTime dt = d.DT();
706
707 wxDateTime::wxDateTime_t week = dt.GetWeekOfYear(),
708 dnum = dt.GetDayOfYear();
709
710 printf("%s: the day number is %d",
711 d.FormatDate().c_str(), dnum);
712 if ( dnum == wn.dnum )
713 {
714 printf(" (ok)");
715 }
716 else
717 {
718 printf(" (ERROR: should be %d)", wn.dnum);
719 }
720
721 printf(", week number is %d", week);
722 if ( week == wn.week )
723 {
724 puts(" (ok)");
725 }
726 else
727 {
728 printf(" (ERROR: should be %d)\n", wn.week);
729 }
730 }
731 }
732
733 // test DST calculations
734 static void TestTimeDST()
735 {
736 puts("\n*** wxDateTime DST test ***");
737
738 printf("DST is%s in effect now.\n\n",
739 wxDateTime::Now().IsDST() ? "" : " not");
740
741 // taken from http://www.energy.ca.gov/daylightsaving.html
742 static const Date datesDST[2][2004 - 1900 + 1] =
743 {
744 {
745 { 1, wxDateTime::Apr, 1990 },
746 { 7, wxDateTime::Apr, 1991 },
747 { 5, wxDateTime::Apr, 1992 },
748 { 4, wxDateTime::Apr, 1993 },
749 { 3, wxDateTime::Apr, 1994 },
750 { 2, wxDateTime::Apr, 1995 },
751 { 7, wxDateTime::Apr, 1996 },
752 { 6, wxDateTime::Apr, 1997 },
753 { 5, wxDateTime::Apr, 1998 },
754 { 4, wxDateTime::Apr, 1999 },
755 { 2, wxDateTime::Apr, 2000 },
756 { 1, wxDateTime::Apr, 2001 },
757 { 7, wxDateTime::Apr, 2002 },
758 { 6, wxDateTime::Apr, 2003 },
759 { 4, wxDateTime::Apr, 2004 },
760 },
761 {
762 { 28, wxDateTime::Oct, 1990 },
763 { 27, wxDateTime::Oct, 1991 },
764 { 25, wxDateTime::Oct, 1992 },
765 { 31, wxDateTime::Oct, 1993 },
766 { 30, wxDateTime::Oct, 1994 },
767 { 29, wxDateTime::Oct, 1995 },
768 { 27, wxDateTime::Oct, 1996 },
769 { 26, wxDateTime::Oct, 1997 },
770 { 25, wxDateTime::Oct, 1998 },
771 { 31, wxDateTime::Oct, 1999 },
772 { 29, wxDateTime::Oct, 2000 },
773 { 28, wxDateTime::Oct, 2001 },
774 { 27, wxDateTime::Oct, 2002 },
775 { 26, wxDateTime::Oct, 2003 },
776 { 31, wxDateTime::Oct, 2004 },
777 }
778 };
779
780 int year;
781 for ( year = 1990; year < 2005; year++ )
782 {
783 wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA),
784 dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA);
785
786 printf("DST period in the US for year %d: from %s to %s",
787 year, dtBegin.Format().c_str(), dtEnd.Format().c_str());
788
789 size_t n = year - 1990;
790 const Date& dBegin = datesDST[0][n];
791 const Date& dEnd = datesDST[1][n];
792
793 if ( dBegin.SameDay(dtBegin.GetTm()) && dEnd.SameDay(dtEnd.GetTm()) )
794 {
795 puts(" (ok)");
796 }
797 else
798 {
799 printf(" (ERROR: should be %s %d to %s %d)\n",
800 wxDateTime::GetMonthName(dBegin.month).c_str(), dBegin.day,
801 wxDateTime::GetMonthName(dEnd.month).c_str(), dEnd.day);
802 }
803 }
804
805 puts("");
806
807 for ( year = 1990; year < 2005; year++ )
808 {
809 printf("DST period in Europe for year %d: from %s to %s\n",
810 year,
811 wxDateTime::GetBeginDST(year, wxDateTime::Country_EEC).Format().c_str(),
812 wxDateTime::GetEndDST(year, wxDateTime::Country_EEC).Format().c_str());
813 }
814 }
815
816 #endif // TEST_TIME
817
818 // ----------------------------------------------------------------------------
819 // threads
820 // ----------------------------------------------------------------------------
821
822 #ifdef TEST_THREADS
823
824 #include <wx/thread.h>
825
826 static size_t gs_counter = (size_t)-1;
827 static wxCriticalSection gs_critsect;
828 static wxCondition gs_cond;
829
830 class MyJoinableThread : public wxThread
831 {
832 public:
833 MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
834 { m_n = n; Create(); }
835
836 // thread execution starts here
837 virtual ExitCode Entry();
838
839 private:
840 size_t m_n;
841 };
842
843 wxThread::ExitCode MyJoinableThread::Entry()
844 {
845 unsigned long res = 1;
846 for ( size_t n = 1; n < m_n; n++ )
847 {
848 res *= n;
849
850 // it's a loooong calculation :-)
851 Sleep(100);
852 }
853
854 return (ExitCode)res;
855 }
856
857 class MyDetachedThread : public wxThread
858 {
859 public:
860 MyDetachedThread(size_t n, char ch)
861 {
862 m_n = n;
863 m_ch = ch;
864 m_cancelled = FALSE;
865
866 Create();
867 }
868
869 // thread execution starts here
870 virtual ExitCode Entry();
871
872 // and stops here
873 virtual void OnExit();
874
875 private:
876 size_t m_n; // number of characters to write
877 char m_ch; // character to write
878
879 bool m_cancelled; // FALSE if we exit normally
880 };
881
882 wxThread::ExitCode MyDetachedThread::Entry()
883 {
884 {
885 wxCriticalSectionLocker lock(gs_critsect);
886 if ( gs_counter == (size_t)-1 )
887 gs_counter = 1;
888 else
889 gs_counter++;
890 }
891
892 for ( size_t n = 0; n < m_n; n++ )
893 {
894 if ( TestDestroy() )
895 {
896 m_cancelled = TRUE;
897
898 break;
899 }
900
901 putchar(m_ch);
902 fflush(stdout);
903
904 wxThread::Sleep(100);
905 }
906
907 return 0;
908 }
909
910 void MyDetachedThread::OnExit()
911 {
912 wxLogTrace("thread", "Thread %ld is in OnExit", GetId());
913
914 wxCriticalSectionLocker lock(gs_critsect);
915 if ( !--gs_counter && !m_cancelled )
916 gs_cond.Signal();
917 }
918
919 void TestDetachedThreads()
920 {
921 puts("\n*** Testing detached threads ***");
922
923 static const size_t nThreads = 3;
924 MyDetachedThread *threads[nThreads];
925 size_t n;
926 for ( n = 0; n < nThreads; n++ )
927 {
928 threads[n] = new MyDetachedThread(10, 'A' + n);
929 }
930
931 threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
932 threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
933
934 for ( n = 0; n < nThreads; n++ )
935 {
936 threads[n]->Run();
937 }
938
939 // wait until all threads terminate
940 gs_cond.Wait();
941
942 puts("");
943 }
944
945 void TestJoinableThreads()
946 {
947 puts("\n*** Testing a joinable thread (a loooong calculation...) ***");
948
949 // calc 10! in the background
950 MyJoinableThread thread(10);
951 thread.Run();
952
953 printf("\nThread terminated with exit code %lu.\n",
954 (unsigned long)thread.Wait());
955 }
956
957 void TestThreadSuspend()
958 {
959 puts("\n*** Testing thread suspend/resume functions ***");
960
961 MyDetachedThread *thread = new MyDetachedThread(15, 'X');
962
963 thread->Run();
964
965 // this is for this demo only, in a real life program we'd use another
966 // condition variable which would be signaled from wxThread::Entry() to
967 // tell us that the thread really started running - but here just wait a
968 // bit and hope that it will be enough (the problem is, of course, that
969 // the thread might still not run when we call Pause() which will result
970 // in an error)
971 wxThread::Sleep(300);
972
973 for ( size_t n = 0; n < 3; n++ )
974 {
975 thread->Pause();
976
977 puts("\nThread suspended");
978 if ( n > 0 )
979 {
980 // don't sleep but resume immediately the first time
981 wxThread::Sleep(300);
982 }
983 puts("Going to resume the thread");
984
985 thread->Resume();
986 }
987
988 puts("Waiting until it terminates now");
989
990 // wait until the thread terminates
991 gs_cond.Wait();
992
993 puts("");
994 }
995
996 void TestThreadDelete()
997 {
998 // As above, using Sleep() is only for testing here - we must use some
999 // synchronisation object instead to ensure that the thread is still
1000 // running when we delete it - deleting a detached thread which already
1001 // terminated will lead to a crash!
1002
1003 puts("\n*** Testing thread delete function ***");
1004
1005 MyDetachedThread *thread0 = new MyDetachedThread(30, 'W');
1006
1007 thread0->Delete();
1008
1009 puts("\nDeleted a thread which didn't start to run yet.");
1010
1011 MyDetachedThread *thread1 = new MyDetachedThread(30, 'Y');
1012
1013 thread1->Run();
1014
1015 wxThread::Sleep(300);
1016
1017 thread1->Delete();
1018
1019 puts("\nDeleted a running thread.");
1020
1021 MyDetachedThread *thread2 = new MyDetachedThread(30, 'Z');
1022
1023 thread2->Run();
1024
1025 wxThread::Sleep(300);
1026
1027 thread2->Pause();
1028
1029 thread2->Delete();
1030
1031 puts("\nDeleted a sleeping thread.");
1032
1033 MyJoinableThread thread3(20);
1034 thread3.Run();
1035
1036 thread3.Delete();
1037
1038 puts("\nDeleted a joinable thread.");
1039
1040 MyJoinableThread thread4(2);
1041 thread4.Run();
1042
1043 wxThread::Sleep(300);
1044
1045 thread4.Delete();
1046
1047 puts("\nDeleted a joinable thread which already terminated.");
1048
1049 puts("");
1050 }
1051
1052 #endif // TEST_THREADS
1053
1054 // ----------------------------------------------------------------------------
1055 // arrays
1056 // ----------------------------------------------------------------------------
1057
1058 #ifdef TEST_ARRAYS
1059
1060 void PrintArray(const char* name, const wxArrayString& array)
1061 {
1062 printf("Dump of the array '%s'\n", name);
1063
1064 size_t nCount = array.GetCount();
1065 for ( size_t n = 0; n < nCount; n++ )
1066 {
1067 printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
1068 }
1069 }
1070
1071 #endif // TEST_ARRAYS
1072
1073 // ----------------------------------------------------------------------------
1074 // strings
1075 // ----------------------------------------------------------------------------
1076
1077 #ifdef TEST_STRINGS
1078
1079 #include "wx/timer.h"
1080
1081 static void TestString()
1082 {
1083 wxStopWatch sw;
1084
1085 wxString a, b, c;
1086
1087 a.reserve (128);
1088 b.reserve (128);
1089 c.reserve (128);
1090
1091 for (int i = 0; i < 1000000; ++i)
1092 {
1093 a = "Hello";
1094 b = " world";
1095 c = "! How'ya doin'?";
1096 a += b;
1097 a += c;
1098 c = "Hello world! What's up?";
1099 if (c != a)
1100 c = "Doh!";
1101 }
1102
1103 printf ("TestString elapsed time: %ld\n", sw.Time());
1104 }
1105
1106 static void TestPChar()
1107 {
1108 wxStopWatch sw;
1109
1110 char a [128];
1111 char b [128];
1112 char c [128];
1113
1114 for (int i = 0; i < 1000000; ++i)
1115 {
1116 strcpy (a, "Hello");
1117 strcpy (b, " world");
1118 strcpy (c, "! How'ya doin'?");
1119 strcat (a, b);
1120 strcat (a, c);
1121 strcpy (c, "Hello world! What's up?");
1122 if (strcmp (c, a) == 0)
1123 strcpy (c, "Doh!");
1124 }
1125
1126 printf ("TestPChar elapsed time: %ld\n", sw.Time());
1127 }
1128
1129 static void TestStringSub()
1130 {
1131 wxString s("Hello, world!");
1132
1133 puts("*** Testing wxString substring extraction ***");
1134
1135 printf("String = '%s'\n", s.c_str());
1136 printf("Left(5) = '%s'\n", s.Left(5).c_str());
1137 printf("Right(6) = '%s'\n", s.Right(6).c_str());
1138 printf("Mid(3, 5) = '%s'\n", s(3, 5).c_str());
1139 printf("Mid(3) = '%s'\n", s.Mid(3).c_str());
1140 printf("substr(3, 5) = '%s'\n", s.substr(3, 5).c_str());
1141 printf("substr(3) = '%s'\n", s.substr(3).c_str());
1142
1143 puts("");
1144 }
1145
1146 #endif // TEST_STRINGS
1147
1148 // ----------------------------------------------------------------------------
1149 // entry point
1150 // ----------------------------------------------------------------------------
1151
1152 int main(int argc, char **argv)
1153 {
1154 if ( !wxInitialize() )
1155 {
1156 fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
1157 }
1158
1159 #ifdef TEST_STRINGS
1160 if ( 0 )
1161 {
1162 TestPChar();
1163 TestString();
1164 }
1165 TestStringSub();
1166 #endif // TEST_STRINGS
1167
1168 #ifdef TEST_ARRAYS
1169 wxArrayString a1;
1170 a1.Add("tiger");
1171 a1.Add("cat");
1172 a1.Add("lion");
1173 a1.Add("dog");
1174 a1.Add("human");
1175 a1.Add("ape");
1176
1177 puts("*** Initially:");
1178
1179 PrintArray("a1", a1);
1180
1181 wxArrayString a2(a1);
1182 PrintArray("a2", a2);
1183
1184 wxSortedArrayString a3(a1);
1185 PrintArray("a3", a3);
1186
1187 puts("*** After deleting a string from a1");
1188 a1.Remove(2);
1189
1190 PrintArray("a1", a1);
1191 PrintArray("a2", a2);
1192 PrintArray("a3", a3);
1193
1194 puts("*** After reassigning a1 to a2 and a3");
1195 a3 = a2 = a1;
1196 PrintArray("a2", a2);
1197 PrintArray("a3", a3);
1198 #endif // TEST_ARRAYS
1199
1200 #ifdef TEST_DIR
1201 TestDirEnum();
1202 #endif // TEST_DIR
1203
1204 #ifdef TEST_LOG
1205 wxString s;
1206 for ( size_t n = 0; n < 8000; n++ )
1207 {
1208 s << (char)('A' + (n % 26));
1209 }
1210
1211 wxString msg;
1212 msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
1213
1214 // this one shouldn't be truncated
1215 printf(msg);
1216
1217 // but this one will because log functions use fixed size buffer
1218 // (note that it doesn't need '\n' at the end neither - will be added
1219 // by wxLog anyhow)
1220 wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
1221 #endif // TEST_LOG
1222
1223 #ifdef TEST_THREADS
1224 int nCPUs = wxThread::GetCPUCount();
1225 printf("This system has %d CPUs\n", nCPUs);
1226 if ( nCPUs != -1 )
1227 wxThread::SetConcurrency(nCPUs);
1228
1229 if ( argc > 1 && argv[1][0] == 't' )
1230 wxLog::AddTraceMask("thread");
1231
1232 if ( 1 )
1233 TestDetachedThreads();
1234 if ( 1 )
1235 TestJoinableThreads();
1236 if ( 1 )
1237 TestThreadSuspend();
1238 if ( 1 )
1239 TestThreadDelete();
1240
1241 #endif // TEST_THREADS
1242
1243 #ifdef TEST_LONGLONG
1244 if ( 0 )
1245 TestSpeed();
1246 if ( 1 )
1247 TestDivision();
1248 #endif // TEST_LONGLONG
1249
1250 #ifdef TEST_MIME
1251 TestMimeEnum();
1252 #endif // TEST_MIME
1253
1254 #ifdef TEST_TIME
1255 if ( 0 )
1256 {
1257 TestTimeSet();
1258 TestTimeStatic();
1259 TestTimeZones();
1260 TestTimeRange();
1261 TestTimeTicks();
1262 TestTimeJDN();
1263 TestTimeDST();
1264 TestTimeWDays();
1265 }
1266 TestTimeWNumber();
1267 #endif // TEST_TIME
1268
1269 wxUninitialize();
1270
1271 return 0;
1272 }