예제 #1
0
int ezStringUtils::vsnprintf(char* szOutputBuffer, unsigned int uiBufferSize, const char* szFormat, va_list args0)
{
  va_list args;
  va_copy(args, args0);

  EZ_ASSERT(ezUnicodeUtils::IsValidUtf8(szFormat), "The sprintf format string must be valid Utf8.");

  // make sure the last character is a \0
  if ((szOutputBuffer) && (uiBufferSize > 0))
    szOutputBuffer[uiBufferSize - 1] = '\0';

  unsigned int uiReadPos = 0;
  unsigned int uiWritePos = 0;
  bool bError = false;

  while (szFormat[uiReadPos] != '\0')
  {
    const char c = szFormat[uiReadPos];

    ++uiReadPos;

    // if c is not %, just print it out and be done with it
    if (c != '%')
    {
      OutputChar (szOutputBuffer, uiBufferSize, uiWritePos, c);
      continue;
    }

    // otherwise parse the formatting string to find out what has to be done
    char cNext = szFormat[uiReadPos];

    // *** parse the format string ***

    // first read the flags (as many as there are)
    unsigned int Flags = ReadFlags (szFormat, uiReadPos, cNext);
    // read the width of the field
    int iWidth = ReadWidth (szFormat, uiReadPos, cNext);
    // read the precision specifier
    int iPrecision = ReadPrecision (szFormat, uiReadPos, cNext);
    // read the input data 'length' (short / int / long it, float / double)
    const sprintfLength::Enum Length = ReadLength (szFormat, uiReadPos, cNext);
    // read the 'specifier' type
    const char cSpecifier = ReadSpecifier (szFormat, uiReadPos, cNext, bError);

    if (bError)
    {
      snprintf (szOutputBuffer, uiBufferSize, "Error in formatting string at position %u ('%c').", uiReadPos, cSpecifier);
      va_end(args);
      return -1;
    }

    // if 'width' was specified as '*', read it from an extra parameter
    if (iWidth < 0)
      iWidth = va_arg (args, int);

    // if 'precision' was specified as '*', read it from an extra parameter
    if (iPrecision == -2)
      iPrecision = va_arg (args, int);

    // % Sign
    if (cSpecifier == '%')
    {
      OutputChar (szOutputBuffer, uiBufferSize, uiWritePos, '%');
      continue;
    }

    // Nothing: Writes the current write position back to an int pointer
    if (cSpecifier == 'n')
    {
      int* p = va_arg (args, int*);
      if (p) 
        *p = (int) uiWritePos;
        
      continue;
    }

    // String
    if (cSpecifier == 's')
    {
      const char* s = va_arg (args, const char*);
      OutputString (szOutputBuffer, uiBufferSize, uiWritePos, s, Flags, iWidth, iPrecision);
      continue;
    }

    // Character
    if (cSpecifier == 'c')
    {
      char c2 = va_arg (args, int);
      char s[2] = {c2, 0};
      OutputString (szOutputBuffer, uiBufferSize, uiWritePos, s, Flags, iWidth, iPrecision);
      continue;
    }
예제 #2
0
파일: safeformat.hpp 프로젝트: semenovf/jq
 void ReadLeaders() {
     ReadFlags();
     ReadWidth();
     if (*format_ == '.') ReadPrecision();
     ReadModifiers();
 }