/* libiso8601/src/tests/leap.c * * (c)2007, Laurence Withers, . * Released under the GNU GPLv2. See file COPYING or * http://www.gnu.org/copyleft/gpl.html for details. */ #include "iso8601.h" #include #include int leap_diff(const char* s1, const char* s2, int* diff) { struct iso8601_date d1, d2; if(iso8601_parse(s1, &d1, 0, 0) || iso8601_parse(s2, &d2, 0, 0)) { fprintf(stderr, "Unable to parse ``%s'' or ``%s'' (%m).", s1, s2); return -1; } *diff = iso8601_leap_elapsed(&d1, &d2); return 0; } int regression1(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2005, 12, 31); oday = d.day; d.sec = 0; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, 86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != oday) | (d.sec != 86400); iso8601_add_seconds(&d, 86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday + 1)) | (d.sec != 86399); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } int regression2(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2005, 12, 31); oday = d.day; d.sec = 86399; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, 86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != (oday + 1)) | (d.sec != 86398); iso8601_add_seconds(&d, 86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday + 2)) | (d.sec != 86398); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } int regression3(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2005, 12, 31); oday = d.day; d.sec = 86400; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, 86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != (oday + 1)) | (d.sec != 86399); iso8601_add_seconds(&d, 86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday + 2)) | (d.sec != 86399); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } int regression4(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2006, 1, 1); oday = d.day; d.sec = 86399; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, -86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != (oday - 1)) | (d.sec != 86400); iso8601_add_seconds(&d, -86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday - 1)) | (d.sec != 0); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } int regression5(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2006, 1, 2); oday = d.day; d.sec = 86398; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, -86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != (oday - 1)) | (d.sec != 86398); iso8601_add_seconds(&d, -86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday - 2)) | (d.sec != 86399); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } int regression6(void) { struct iso8601_date d; char s1[30], s2[30], s3[30]; int ret = 0, oday; iso8601_from_cal(&d, 2006, 1, 2); oday = d.day; d.sec = 86399; d.nsec = 0; iso8601_print(s1, sizeof(s1), &d, 0); iso8601_add_seconds(&d, -86400); iso8601_print(s2, sizeof(s2), &d, 0); ret |= (d.day != (oday - 1)) | (d.sec != 86399); iso8601_add_seconds(&d, -86400); iso8601_print(s3, sizeof(s3), &d, 0); ret |= (d.day != (oday - 2)) | (d.sec != 86400); printf("%s -> %s -> %s\n", s1, s2, s3); return ret; } struct regression_test { const char* name; int (*func)(void); }; struct regression_test regression_tests[] = { { "Start of leap day, +86400s", regression1 }, { "Near end of leap day, +86400s", regression2 }, { "End of leap day, +86400s", regression3 }, { "Start of post-leap day, -86400s", regression4 }, { "Near end of post-leap day, -86400s", regression5 }, { "End of post-leap day, -86400s", regression6 }, { 0, 0 } }; int regression(void) { int ret = 0; struct regression_test* test; for(test = regression_tests; test->func; ++test) { if(test->func()) { fprintf(stderr, "%s failed.\n", test->name); ++ret; } } return ret; } int main(int argc, char* argv[]) { int ret = 0, diff; if(argc == 2 && !strcmp(argv[1], "--print-summary")) { fputs("Leap second regression test.\n", stdout); return 0; } switch(argc) { case 1: ret = regression(); fputs("Alternative use: pass two dates on commandline to see elapsed leap seconds.\n", stdout); break; case 3: ret = leap_diff(argv[1], argv[2], &diff); if(!ret) printf("Leap second correction: %d\n", diff); break; case 2: if(!strcmp(argv[1], "--print-summary")) { printf("Leap second regression test."); return 0; } /* fall through */ default: ret = 1; fputs("Either zero or two arguments expected.\n", stderr); break; } /* TODO */ return ret; } /* options for text editors kate: replace-trailing-space-save true; space-indent true; tab-width 4; vim: expandtab:ts=4:sw=4 */