Merge pull request #2348 from colinleroy/time-functions-pass-2
Convert more time functions to asm
This commit is contained in:
@@ -4,81 +4,107 @@
|
||||
|
||||
int fails = 0;
|
||||
|
||||
time_t timestamps[] = {
|
||||
0,
|
||||
0x2FFFFFFF,
|
||||
0x6FFFFFFF,
|
||||
0xF48656FF,
|
||||
0xF4865700,
|
||||
0xFC5A3EFF,
|
||||
0x6D6739FF,
|
||||
0x6D673A00,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
typedef struct _test_data {
|
||||
time_t t;
|
||||
char *gmt;
|
||||
char *local;
|
||||
} test_data;
|
||||
|
||||
/* Values checked against glibc 2.37's implementation of ctime() */
|
||||
const char *dates_gmt[] = {
|
||||
"Thu Jan 1 00:00:00 1970\n",
|
||||
"Sun Jul 9 16:12:47 1995\n",
|
||||
"Wed Jul 18 05:49:51 2029\n",
|
||||
"Thu Dec 31 23:59:59 2099\n",
|
||||
"Fri Jan 1 00:00:00 2100\n",
|
||||
"Fri Feb 29 23:59:59 2104\n",
|
||||
"Tue Feb 29 23:59:59 2028\n",
|
||||
"Wed Mar 1 00:00:00 2028\n",
|
||||
"Sun Feb 7 06:28:15 2106\n",
|
||||
NULL
|
||||
};
|
||||
/* Test data generated using glibc 2.37 */
|
||||
test_data data[] = {
|
||||
/* First year */
|
||||
{0x00000000, "Thu Jan 1 00:00:00 1970\n", "Thu Jan 1 01:00:00 1970\n"},
|
||||
{0x004e7970, "Sun Mar 1 12:34:56 1970\n", "Sun Mar 1 13:34:56 1970\n"},
|
||||
{0x01e1337f, "Thu Dec 31 23:59:59 1970\n", "Fri Jan 1 00:59:59 1971\n"},
|
||||
|
||||
const char *dates_gmt_plus_one[] = {
|
||||
"Thu Jan 1 01:00:00 1970\n",
|
||||
"Sun Jul 9 17:12:47 1995\n",
|
||||
"Wed Jul 18 06:49:51 2029\n",
|
||||
"Fri Jan 1 00:59:59 2100\n",
|
||||
"Fri Jan 1 01:00:00 2100\n",
|
||||
"Sat Mar 1 00:59:59 2104\n",
|
||||
"Wed Mar 1 00:59:59 2028\n",
|
||||
"Wed Mar 1 01:00:00 2028\n",
|
||||
"Thu Jan 1 00:59:59 1970\n",
|
||||
NULL
|
||||
/* First leap year */
|
||||
{0x03c26700, "Sat Jan 1 00:00:00 1972\n", "Sat Jan 1 01:00:00 1972\n"},
|
||||
{0x03c8fe7f, "Wed Jan 5 23:59:59 1972\n", "Thu Jan 6 00:59:59 1972\n"},
|
||||
{0x041180ff, "Tue Feb 29 23:59:59 1972\n", "Wed Mar 1 00:59:59 1972\n"},
|
||||
{0x04118100, "Wed Mar 1 00:00:00 1972\n", "Wed Mar 1 01:00:00 1972\n"},
|
||||
{0x05a4ebff, "Sun Dec 31 23:59:59 1972\n", "Mon Jan 1 00:59:59 1973\n"},
|
||||
|
||||
/* A non-leap year */
|
||||
{0x63b0cd00, "Sun Jan 1 00:00:00 2023\n", "Sun Jan 1 01:00:00 2023\n"},
|
||||
{0x63fe957f, "Tue Feb 28 23:59:59 2023\n", "Wed Mar 1 00:59:59 2023\n"},
|
||||
{0x63fe9580, "Wed Mar 1 00:00:00 2023\n", "Wed Mar 1 01:00:00 2023\n"},
|
||||
{0x656d4ec0, "Mon Dec 4 04:00:00 2023\n", "Mon Dec 4 05:00:00 2023\n"},
|
||||
{0x6592007f, "Sun Dec 31 23:59:59 2023\n", "Mon Jan 1 00:59:59 2024\n"},
|
||||
|
||||
/* Another leap year */
|
||||
{0x65920080, "Mon Jan 1 00:00:00 2024\n", "Mon Jan 1 01:00:00 2024\n"},
|
||||
{0x65e11a7f, "Thu Feb 29 23:59:59 2024\n", "Fri Mar 1 00:59:59 2024\n"},
|
||||
{0x65e11a80, "Fri Mar 1 00:00:00 2024\n", "Fri Mar 1 01:00:00 2024\n"},
|
||||
{0x6774857f, "Tue Dec 31 23:59:59 2024\n", "Wed Jan 1 00:59:59 2025\n"},
|
||||
|
||||
/* End of century */
|
||||
{0xf48656ff, "Thu Dec 31 23:59:59 2099\n", "Fri Jan 1 00:59:59 2100\n"},
|
||||
|
||||
/* A non-leap year for exceptional reasons */
|
||||
{0xf4865700, "Fri Jan 1 00:00:00 2100\n", "Fri Jan 1 01:00:00 2100\n"},
|
||||
{0xf4d41f7f, "Sun Feb 28 23:59:59 2100\n", "Mon Mar 1 00:59:59 2100\n"},
|
||||
{0xf4d41f80, "Mon Mar 1 00:00:00 2100\n", "Mon Mar 1 01:00:00 2100\n"},
|
||||
{0xf4fceff0, "Wed Mar 31 23:00:00 2100\n", "Thu Apr 1 00:00:00 2100\n"},
|
||||
{0xf6678a7f, "Fri Dec 31 23:59:59 2100\n", "Sat Jan 1 00:59:59 2101\n"},
|
||||
|
||||
/* First post-2100 leap year */
|
||||
{0xfc0b2500, "Tue Jan 1 00:00:00 2104\n", "Tue Jan 1 01:00:00 2104\n"},
|
||||
{0xfc5a3eff, "Fri Feb 29 23:59:59 2104\n", "Sat Mar 1 00:59:59 2104\n"},
|
||||
{0xfc5a3f00, "Sat Mar 1 00:00:00 2104\n", "Sat Mar 1 01:00:00 2104\n"},
|
||||
{0xfcaa9c70, "Wed Apr 30 23:00:00 2104\n", "Thu May 1 00:00:00 2104\n"},
|
||||
|
||||
/* End of epoch */
|
||||
{0xfdedaa00, "Thu Jan 1 00:00:00 2105\n", "Thu Jan 1 01:00:00 2105\n"},
|
||||
{0xffffffff, "Sun Feb 7 06:28:15 2106\n", "Thu Jan 1 00:59:59 1970\n"}
|
||||
};
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int i;
|
||||
struct tm *tm;
|
||||
char *str;
|
||||
|
||||
for (i = 0; dates_gmt[i] != NULL; i++) {
|
||||
struct tm *tm;
|
||||
char *str;
|
||||
tm = gmtime(NULL);
|
||||
if (tm != NULL) {
|
||||
printf("gmtime should return NULL with a NULL parameter\n");
|
||||
fails++;
|
||||
}
|
||||
|
||||
/* Check gmtime */
|
||||
tm = gmtime(×tamps[i]);
|
||||
tm = localtime(NULL);
|
||||
if (tm != NULL) {
|
||||
printf("localtime should return NULL with a NULL parameter\n");
|
||||
fails++;
|
||||
}
|
||||
|
||||
/* Verify conversion both ways */
|
||||
for (i = 0; ; i++) {
|
||||
time_t t = data[i].t;
|
||||
|
||||
tm = gmtime(&t);
|
||||
str = asctime(tm);
|
||||
if (strcmp(str, dates_gmt[i])) {
|
||||
if (strcmp(data[i].gmt, str)) {
|
||||
printf("0x%lx: gmtime: unexpected result: expected %s, got %s\n", t, data[i].gmt, str);
|
||||
fails++;
|
||||
printf("gmtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n",
|
||||
timestamps[i], dates_gmt[i], str);
|
||||
}
|
||||
|
||||
/* Check localtime with UTC timezone */
|
||||
|
||||
_tz.timezone = 0;
|
||||
tm = localtime(×tamps[i]);
|
||||
tm = localtime(&t);
|
||||
str = asctime(tm);
|
||||
if (strcmp(str, dates_gmt[i])) {
|
||||
if (strcmp(data[i].gmt, str)) {
|
||||
printf("0x%lx: localtime (UTC+0): unexpected result: expected %s, got %s\n", t, data[i].gmt, str);
|
||||
fails++;
|
||||
printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n",
|
||||
timestamps[i], dates_gmt[i], str);
|
||||
}
|
||||
|
||||
/* Check localtime at UTC+1 */
|
||||
_tz.timezone = 3600;
|
||||
tm = localtime(×tamps[i]);
|
||||
tm = localtime(&t);
|
||||
str = asctime(tm);
|
||||
if (strcmp(str, dates_gmt_plus_one[i])) {
|
||||
if (strcmp(data[i].local, str)) {
|
||||
printf("0x%lx: localtime (UTC+1): unexpected result: expected %s, got %s\n", t, data[i].local, str);
|
||||
fails++;
|
||||
printf("localtime: Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n",
|
||||
timestamps[i], dates_gmt_plus_one[i], str);
|
||||
}
|
||||
|
||||
if (t == 0xFFFFFFFF)
|
||||
break;
|
||||
}
|
||||
return fails;
|
||||
}
|
||||
|
||||
@@ -4,58 +4,103 @@
|
||||
|
||||
int fails = 0;
|
||||
|
||||
time_t timestamps[] = {
|
||||
0,
|
||||
0x2FFFFFFF,
|
||||
0x6FFFFFFF,
|
||||
0xF48656FF,
|
||||
0xF4865700,
|
||||
0xFC5A3EFF,
|
||||
0x6D6739FF,
|
||||
0x6D673A00,
|
||||
0xFFFFFFFF,
|
||||
typedef struct _test_data {
|
||||
time_t t;
|
||||
struct tm tm;
|
||||
char *str;
|
||||
} test_data;
|
||||
|
||||
/* Test data generated using glibc 2.37 */
|
||||
test_data data[] = {
|
||||
/* First year */
|
||||
{0x00000000, {0, 0, 0, 1, 0, 70, 0, 4}, "Thu Jan 1 00:00:00 1970\n"},
|
||||
{0x004e7970, {56, 34, 12, 1, 2, 70, 59, 0}, "Sun Mar 1 12:34:56 1970\n"},
|
||||
{0x01e1337f, {59, 59, 23, 31, 11, 70, 364, 4}, "Thu Dec 31 23:59:59 1970\n"},
|
||||
|
||||
/* First leap year */
|
||||
{0x03c26700, {0, 0, 0, 1, 0, 72, 0, 6}, "Sat Jan 1 00:00:00 1972\n"},
|
||||
{0x03c8fe7f, {59, 59, 23, 5, 0, 72, 4, 3}, "Wed Jan 5 23:59:59 1972\n"},
|
||||
{0x041180ff, {59, 59, 23, 29, 1, 72, 59, 2}, "Tue Feb 29 23:59:59 1972\n"},
|
||||
{0x04118100, {0, 0, 0, 1, 2, 72, 60, 3}, "Wed Mar 1 00:00:00 1972\n"},
|
||||
{0x05a4ebff, {59, 59, 23, 31, 11, 72, 365, 0}, "Sun Dec 31 23:59:59 1972\n"},
|
||||
|
||||
/* A non-leap year */
|
||||
{0x63b0cd00, {0, 0, 0, 1, 0, 123, 0, 0}, "Sun Jan 1 00:00:00 2023\n"},
|
||||
{0x63fe957f, {59, 59, 23, 28, 1, 123, 58, 2}, "Tue Feb 28 23:59:59 2023\n"},
|
||||
{0x63fe9580, {0, 0, 0, 1, 2, 123, 59, 3}, "Wed Mar 1 00:00:00 2023\n"},
|
||||
{0x656d4ec0, {0, 0, 4, 4, 11, 123, 337, 1}, "Mon Dec 4 04:00:00 2023\n"},
|
||||
{0x6592007f, {59, 59, 23, 31, 11, 123, 364, 0}, "Sun Dec 31 23:59:59 2023\n"},
|
||||
|
||||
/* Another leap year */
|
||||
{0x65920080, {0, 0, 0, 1, 0, 124, 0, 1}, "Mon Jan 1 00:00:00 2024\n"},
|
||||
{0x65e11a7f, {59, 59, 23, 29, 1, 124, 59, 4}, "Thu Feb 29 23:59:59 2024\n"},
|
||||
{0x65e11a80, {0, 0, 0, 1, 2, 124, 60, 5}, "Fri Mar 1 00:00:00 2024\n"},
|
||||
{0x6774857f, {59, 59, 23, 31, 11, 124, 365, 2}, "Tue Dec 31 23:59:59 2024\n"},
|
||||
|
||||
/* End of century */
|
||||
{0xf48656ff, {59, 59, 23, 31, 11, 199, 364, 4}, "Thu Dec 31 23:59:59 2099\n"},
|
||||
|
||||
/* A non-leap year for exceptional reasons */
|
||||
{0xf4865700, {0, 0, 0, 1, 0, 200, 0, 5}, "Fri Jan 1 00:00:00 2100\n"},
|
||||
{0xf4d41f7f, {59, 59, 23, 28, 1, 200, 58, 0}, "Sun Feb 28 23:59:59 2100\n"},
|
||||
{0xf4d41f80, {0, 0, 0, 1, 2, 200, 59, 1}, "Mon Mar 1 00:00:00 2100\n"},
|
||||
{0xf4fceff0, {0, 0, 23, 31, 2, 200, 89, 3}, "Wed Mar 31 23:00:00 2100\n"},
|
||||
{0xf6678a7f, {59, 59, 23, 31, 11, 200, 364, 5}, "Fri Dec 31 23:59:59 2100\n"},
|
||||
|
||||
/* First post-2100 leap year */
|
||||
{0xfc0b2500, {0, 0, 0, 1, 0, 204, 0, 2}, "Tue Jan 1 00:00:00 2104\n"},
|
||||
{0xfc5a3eff, {59, 59, 23, 29, 1, 204, 59, 5}, "Fri Feb 29 23:59:59 2104\n"},
|
||||
{0xfc5a3f00, {0, 0, 0, 1, 2, 204, 60, 6}, "Sat Mar 1 00:00:00 2104\n"},
|
||||
{0xfcaa9c70, {0, 0, 23, 30, 3, 204, 120, 3}, "Wed Apr 30 23:00:00 2104\n"},
|
||||
|
||||
/* End of epoch */
|
||||
{0xfdedaa00, {0, 0, 0, 1, 0, 205, 0, 4}, "Thu Jan 1 00:00:00 2105\n"},
|
||||
{0xffffffff, {15, 28, 6, 7, 1, 206, 37, 0}, "Sun Feb 7 06:28:15 2106\n"}
|
||||
};
|
||||
|
||||
/* Values checked against glibc 2.37's implementation of ctime() */
|
||||
const char *dates[] = {
|
||||
"Thu Jan 1 00:00:00 1970\n",
|
||||
"Sun Jul 9 16:12:47 1995\n",
|
||||
"Wed Jul 18 05:49:51 2029\n",
|
||||
"Thu Dec 31 23:59:59 2099\n",
|
||||
"Fri Jan 1 00:00:00 2100\n",
|
||||
"Fri Feb 29 23:59:59 2104\n",
|
||||
"Tue Feb 29 23:59:59 2028\n",
|
||||
"Wed Mar 1 00:00:00 2028\n",
|
||||
"Sun Feb 7 06:28:15 2106\n",
|
||||
NULL
|
||||
};
|
||||
static int compare_tm(time_t t, struct tm *tm, struct tm *ref) {
|
||||
if (memcmp(tm, ref, sizeof(tm))) {
|
||||
printf("0x%lx: unexpected tm from gmtime: "
|
||||
"expected {%u, %u, %u, %u, %u, %u, %u, %u}, "
|
||||
"got {%u, %u, %u, %u, %u, %u, %u, %u}\n",
|
||||
t,
|
||||
ref->tm_sec, ref->tm_min, ref->tm_hour, ref->tm_mday, ref->tm_mon, ref->tm_year, ref->tm_yday, ref->tm_wday,
|
||||
tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_yday, tm->tm_wday);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t t;
|
||||
int i;
|
||||
|
||||
/* Verify conversion both ways */
|
||||
for (t = 0x0FFFFFFF; ; t += 0x10000000) {
|
||||
struct tm *tm = gmtime(&t);
|
||||
time_t r = mktime(tm);
|
||||
if (t != r) {
|
||||
fails++;
|
||||
printf("Unexpected result for t %lx: %lx\n", t, r);
|
||||
}
|
||||
if (t == 0xFFFFFFFF) {
|
||||
break;
|
||||
}
|
||||
if (mktime(NULL) != (time_t)-1) {
|
||||
printf("mktime should return -1 with a NULL parameter\n");
|
||||
fails++;
|
||||
}
|
||||
|
||||
for (i = 0; dates[i] != NULL; i++) {
|
||||
char *str = ctime(×tamps[i]);
|
||||
if (strcmp(str, dates[i])) {
|
||||
/* Verify conversion both ways */
|
||||
for (i = 0; ; i++) {
|
||||
time_t t = data[i].t;
|
||||
time_t r;
|
||||
struct tm *tm = gmtime(&t);
|
||||
r = mktime(tm);
|
||||
|
||||
if (t != r) {
|
||||
printf("unexpected timestamp from mktime: expected 0x%lx, got 0x%lx\n", t, r);
|
||||
fails++;
|
||||
printf("Unexpected result for t %lx: Expected \"%s\", got \"%s\"\n",
|
||||
timestamps[i], dates[i], str);
|
||||
}
|
||||
if (compare_tm(t, tm, &data[i].tm)) {
|
||||
fails++;
|
||||
}
|
||||
if (strcmp(data[i].str, ctime(&t))) {
|
||||
printf("0x%lx: unexpected ctime result: expected %s, got %s", t, data[i].str, ctime(&t));
|
||||
fails++;
|
||||
}
|
||||
|
||||
if (t == 0xFFFFFFFF)
|
||||
break;
|
||||
}
|
||||
return fails;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user