Практика по АиСД (Б8102, весна 2019) / std.check.src.formatter.cpp

ru en cn

с начала прошло: 2105 д. 07:33
страница обновлена: 22.12.2024 01:56

std.check.src.formatter.cpp: src/formatter.cpp

#include 
#include 
#include "global.hpp"
#include "error.hpp"
#include "formatter.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
{


void Formatter::allocateBuffer(const size_t newSize)
{
  char *newBuffer = static_cast(realloc(buffer, newSize));
  if (newBuffer == NULL)
  {
    deallocateBuffer();
    incite();
  }
  buffer = newBuffer;
  bufferSize = newSize;
}


Formatter &Formatter::printArgs(const char *format, const va_list argList)
{
  int length = -1;
  size_t size = bufferSize;
  while (true)
  {
    length = vsnprintf(buffer, size - 1, format, argList);
    if (errno == EILSEQ || errno == EINVAL)
      incite(UnhandledError, "Invalid format string");
    if (length < 0 || size <= static_cast(length))
    {
      size *= 3;
      size /= 2;
    }
    else
      break;
    allocateBuffer(size);
  }

  str.append(buffer, length);
  if (MaxBufferSize < size)
    allocateBuffer(DefaultBufferSize);

  return *this;
}


Formatter &Formatter::print(const char *format, ...)
{
  va_list argList;
  va_start(argList, format);
  printArgs(format, argList);
  va_end(argList);
  return *this;
}


std::string format(const char *format, ...)
{
  va_list argList;
  va_start(argList, format);
  std::string result = Formatter().printArgs(format, argList).text();
  va_end(argList);
  return result;
}


namespace Auxiliary
{


const size_t DefaultQuoteLookSize = 10;


std::string quote(
  const char *text, const size_t length,
  const size_t index, const size_t lookSize)
{
  std::string result;
  // Here 9 equals to 1 (for central symbol) + 2 * strlen("...\'")
  result.reserve(2 * lookSize + 9);

  const size_t begin = (lookSize < index ? index - lookSize : 0);
  const size_t last = index + lookSize;
  const size_t end = (last < length ? last + 1 : length);

  if (0 < begin)
    result += "...";
  result += '\'';
  result.append(text + begin, end - begin);
  result += '\'';
  if (end < length)
    result += "...";

  return result;
}


}


}


#if CHECK_MSC_VERSION(14, 0)
#  pragma warning(pop)
#endif
Дальневосточный федеральный университет