// Created by Synth Magic // 2024-11-27 22:57 // TODO: Refactor the code by need // TODO: Add ExceptionHandler on windows and signal system on linux #include #include #include #include #include #include #include #include #include #include // Time Limit (normally 1s) // 题目的时限(通常为1秒) const unsigned int case_millseconds = 1000; bool exception_happens = false; unsigned int curr_testcase = 0, sum_mark = 0; size_t cur_output = 0; #define MAX_IONUM 100000 char output_buffer[MAX_IONUM]; #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN64) #include static LPTOP_LEVEL_EXCEPTION_FILTER prev = NULL; const DWORD EXCEPTIONS[20] = {EXCEPTION_ACCESS_VIOLATION, EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_DATATYPE_MISALIGNMENT, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO, EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW, EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_GUARD_PAGE, EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_INVALID_DISPOSITION, EXCEPTION_INVALID_HANDLE, EXCEPTION_IN_PAGE_ERROR, EXCEPTION_NONCONTINUABLE_EXCEPTION, EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_STACK_OVERFLOW}; // NOT WORKING LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { EXCEPTION_RECORD *const exception_record = exception_pointers->ExceptionRecord; const DWORD code = exception_record->ExceptionCode; unsigned int i; for (i = 0; i < 20; i++) { if (code == EXCEPTIONS[i]) { printf("\x1b[31mCatching Exception at %p,This testcase will be marked as " "Runtime Error\x1b[0m\n", exception_record->ExceptionAddress); exception_happens = true; return EXCEPTION_EXECUTE_HANDLER; } } return EXCEPTION_CONTINUE_SEARCH; } FILE *memopen(const char *buf, const char *mode) { char temppath[MAX_PATH - 13]; if (0 == GetTempPath(sizeof(temppath), temppath)) { printf("\x1b[31mERROR:While creating tempoary file,Can't get temp " "path\x1b[0m\n"); return NULL; } char filename[MAX_PATH + 1]; if (0 == GetTempFileName(temppath, "TMP", 0, filename)) { printf("\x1b[31mERROR:While creating tempoary file,Can't get file " "name\x1b[0m\n"); return NULL; } FILE *f; if ((f = fopen(filename, "w+")) == NULL) { printf("\x1b[31mERROR:While creating tempoary file,The file '%s' was not " "opened\x1b[0m\n", filename); return NULL; } fputs(buf, f); fclose(f); FILE *f2; if ((f2 = fopen(filename, mode)) != NULL) return f2; else return NULL; } #elif defined(__linux__) #define memopen fmemopen #endif #if defined(__APPLE__) || defined(__MACH__) || defined(BSD) #error Unsupported OS #endif char *trim(char *s) { while (isspace(*s)) s++; char *back = s + strlen(s); while (isspace(*--back)) ; *(back + 1) = '\0'; return s; } unsigned int crc32f(unsigned char *message) { int i = 0, j; unsigned int byte, crc = 0xFFFFFFFF, mask; while (message[i] != 0) { byte = message[i]; crc = crc ^ byte; for (j = 7; j >= 0; j--) { mask = -(crc & 1); crc = (crc >> 1) ^ (0xEDB88320 & mask); } i = i + 1; } return ~crc; } void tprintf(const char *format, ...) { char *buffer; va_list args; va_start(args, format); vsprintf(buffer, format, args); size_t len = strlen(buffer); memcpy(output_buffer + cur_output, buffer, sizeof(char) * len); va_end(args); cur_output += len; } #define tscanf(format, ...) fscanf(in, format, __VA_ARGS__) void solve(FILE *); unsigned int run_testcase(const char *input, unsigned int crc32, unsigned int mark) { curr_testcase++; sum_mark += mark; unsigned int ret = mark; printf("\x1b[34mJudging Testcase #%d\x1b[0m\n", curr_testcase); FILE *in_fp = memopen(input, "r+"); if (in_fp == NULL) { printf("\x1b[31mFATAL ERROR: Cannot Create stdin file,aborting\x1b[0m\n"); exit(1); } #ifdef _WIN32 prev = SetUnhandledExceptionFilter(exception_filter); #endif struct timespec then, now; clock_gettime(CLOCK_REALTIME, &then); solve(in_fp); clock_gettime(CLOCK_REALTIME, &now); #ifdef _WIN32 SetUnhandledExceptionFilter(prev); prev = NULL; #endif fclose(in_fp); if ((now.tv_sec - then.tv_sec) * 1000 + (now.tv_nsec - then.tv_nsec) / 1000000 >= case_millseconds) { printf("\x1b[34mTime Limit Excceed on Testcase #%d\x1b[0m\n", curr_testcase); ret = 0; } else if (crc32f((unsigned char *)trim(output_buffer)) != crc32) { printf("\x1b[31mWrong Answer on Testcase #%d\x1b[0m\n", curr_testcase); ret = 0; } else if (exception_happens) { printf("\x1b[95mRuntime Error on Testcase #%d\x1b[0m\n", curr_testcase); ret = 0; } else { printf("\x1b[32mAccepted on Testcase #%d\x1b[0m\n", curr_testcase); } memset((void *)output_buffer, 0, MAX_IONUM); cur_output = 0; exception_happens = false; return ret; } // 你的代码放到这里 void solve(FILE *in) { int a = 1 / 0; } int main(void) { unsigned int total_get = 0; printf("\x1b[34mStart Judging...\x1b[0m\n"); total_get += run_testcase("1 2", 1842515611, 50); total_get += run_testcase("114514 1919810", 3586865669, 50); printf("\x1b[34mTotal testcase %d\nTotal mark %d/%d\x1b[0m", curr_testcase, total_get, sum_mark); return 0; }