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