AnyPS5/core/libs/tests/GuestStrftime.cpp

96 lines
3.7 KiB
C++

#include "prx/libc/include/general/VabiMacros.hpp"
#include "prx/libc/include/GuestTime.hpp"
#include <cstddef>
#include <cstdio>
#include <cstring>
extern "C" {
std::size_t APS5_VABI strftime_nid_postfix(char*, std::size_t, const char*, const GuestTm*);
char* APS5_VABI asctime_nid_postfix(const GuestTm*);
}
namespace {
GuestTm MakeTime(int year, int hour, int wday, int yday, int isdst) {
GuestTm time{};
time.tm_sec = 5;
time.tm_min = 4;
time.tm_hour = hour;
time.tm_mday = 2;
time.tm_mon = 0;
time.tm_year = year;
time.tm_wday = wday;
time.tm_yday = yday;
time.tm_isdst = isdst;
time.tm_gmtoff = 19800;
time.tm_zone = "IST";
return time;
}
}
int main() {
struct Case {
const char* name;
int year;
int hour;
int wday;
int yday;
int isdst;
const char* format;
const char* expected;
};
constexpr Case cases[] = {
{"alternative", 126, 3, 5, 1, 0, "%Ea %OX %OD %EF %EEY", "Fri 03:04:05 01/02/26 2026-01-02 EY"},
{"padding", 126, 3, 5, 1, 0, "%-d|%_d|%0e|%-k|%_+|%--d", "2| 2|02|3|Fri Jan 2 03:04:05 IST 2026|-d"},
{"zone", 126, 3, 5, 1, 0, "%z %Z %0z", "+0530 IST +0530"},
{"year 899", -1001, 3, 5, 1, 0, "%Y %C %y %G %g %F", "0899 08 99 0899 99 0899-01-02"},
{"year -1", -1901, 3, 5, 1, 0, "%Y %C %y %c", "-001 -0 01 Fri Jan 2 03:04:05 -001"},
{"year 12345", 10445, 3, 5, 1, 0, "%Y %C %y %D %v", "12345 123 45 01/02/45 2-Jan-12345"},
{"out of range", 126, 100, 8, 400, 0, "%I %l %u %W %U %j %a %p", "04 4 8 57 57 401 ? PM"},
{"unknown dst", 126, 3, 5, 1, -1, "[%z][%Z]", "[][IST]"},
{"literals", 126, 3, 5, 1, 0, "%q %% %", "q % %"},
};
bool correct = true;
for (const auto& test : cases) {
const GuestTm time = MakeTime(test.year, test.hour, test.wday, test.yday, test.isdst);
char text[128];
const std::size_t length = strftime_nid_postfix(text, sizeof(text), test.format, &time);
if (length != std::strlen(test.expected) || std::strcmp(text, test.expected) != 0) {
std::fprintf(stderr, "strftime %s (\"%s\"): expected \"%s\", received \"%s\" (%zu)\n",
test.name, test.format, test.expected, length == 0 ? "" : text, length);
correct = false;
}
}
const GuestTm now = MakeTime(126, 3, 5, 1, 0);
char text[32];
if (strftime_nid_postfix(text, 10, "%Y-%m-%d", &now) != 0 || strftime_nid_postfix(text, 11, "%Y-%m-%d", &now) != 10) {
std::fprintf(stderr, "strftime does not return 0 when the result and its terminator do not fit\n");
correct = false;
}
if (strftime_nid_postfix(text, sizeof(text), nullptr, &now) == 0 || std::strcmp(text, "Fri Jan 2 03:04:05 2026") != 0) {
std::fprintf(stderr, "strftime with a null format does not format %%c\n");
correct = false;
}
struct AsctimeCase {
int year;
const char* expected;
};
constexpr AsctimeCase asctimeCases[] = {
{126, "Fri Jan 2 03:04:05 2026\n"},
{-1001, "Fri Jan 2 03:04:05 0899\n"},
{-1901, "Fri Jan 2 03:04:05 -001\n"},
{10445, "Fri Jan 2 03:04:05 12345\n"},
{-2147483647 - 1, "Fri Jan 2 03:04:05 -2147481748\n"},
};
for (const auto& test : asctimeCases) {
const GuestTm time = MakeTime(test.year, 3, 5, 1, 0);
const char* result = asctime_nid_postfix(&time);
if (std::strcmp(result, test.expected) != 0) {
std::fprintf(stderr, "asctime of tm_year %d: expected \"%s\", received \"%s\"\n", test.year, test.expected, result);
correct = false;
}
}
return correct ? 0 : 1;
}