Archive / std.check.src.global.cpp

ru en cn

с начала прошло: 9104 д. 18:55
страница обновлена: 04.12.2024 18:55

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
Дальневосточный федеральный университет