std.check.src.global.cpp: src/global.cpp
#include
#include
#include
#include "global.hpp"
#include "error.hpp"
#include "stream.hpp"
// Disable annoying warning 4996: "'function' was declared deprecated"
#if CHECK_MSC_VERSION(14, 0)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
namespace Check
{
Stream input;
Stream output;
Stream answer;
namespace Auxiliary
{
static std::string logName;
static bool isMessageEmpty(const char *format, const va_list argList)
{
char buffer[4] = "";
vsnprintf(buffer, sizeof buffer - 1, format, argList);
return buffer[0] == '\0';
}
static void exitArgs(
const Decision result, const char *format, const va_list argList)
{
if (result == SolutionAccepted && !output.seekEnd())
incite(PresentationError, "Extra information");
FILE *logFile = stdout;
if (!logName.empty())
{
logFile = fopen(logName.c_str(), "wt");
if (logFile == NULL)
{
logName.clear();
raise(
UnhandledError, "Log file \'%s\' cannot be opened", logName.c_str());
}
}
static const char *ExitCodeNames[] =
{
"OK", "Wrong Answer", "Presentation Error", "Unhandled Error"
};
fputs(ExitCodeNames[result], logFile);
if (!isMessageEmpty(format, argList))
{
fputs(": ", logFile);
vfprintf(logFile, format, argList);
}
fputc('\n', logFile);
if (!logName.empty() && fclose(logFile) != 0)
{
logName.clear();
raise(
UnhandledError, "Log file \'%s\' cannot be closed", logName.c_str());
}
input.close();
output.close();
answer.close();
std::exit(exitCode(result));
}
}
void init(int argsCount, char *args[])
{
// Substitute terminate function to correct report uncaught exceptions
std::set_terminate(terminateLibrary);
if (argsCount < 4 || 5 < argsCount)
incite(UnhandledError, "Usage: INPUT OUTPUT ANSWER [LOG]");
if (argsCount == 5)
Auxiliary::logName = args[4];
input.open(args[1], InputStream);
output.open(args[2], OutputStream);
answer.open(args[3], AnswerStream);
}
int exitCode(const Decision result)
{
#if defined(CHECK_EJUDGE)
static const int ExitCodes[] = { 0, 5, 4, 6 };
#else
static const int ExitCodes[] = { 0, 1, 2, 3 };
#endif
return ExitCodes[result];
}
void exit(const Decision result, const char *format, ...)
{
va_list argList;
va_start(argList, format);
Auxiliary::exitArgs(result, format, argList);
va_end(argList);
}
void exitUnless(const bool cond, const Decision result, const char *format, ...)
{
if (!cond)
{
va_list argList;
va_start(argList, format);
Auxiliary::exitArgs(result, format, argList);
va_end(argList);
}
}
}
#if CHECK_MSC_VERSION(14, 0)
# pragma warning(pop)
#endif