⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varformat.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        *pLastHours = *pLastHours + 2;
      TRACE("A/P\n");
    }
    else if (*pFormat == 'a' &&
              !strncmpW(pFormat, szamSlashpm, sizeof(szamSlashpm)/sizeof(WCHAR)))
    {
      /* Date formats: lowercase AM or PM designation
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat += sizeof(szamSlashpm)/sizeof(WCHAR);
      *pOut++ = FMT_DATE_AMPM_LOWER;
      if (pLastHours)
        *pLastHours = *pLastHours + 2;
      TRACE("AM/PM\n");
    }
    else if (*pFormat == 'A' &&
              !strncmpW(pFormat, szAMSlashPM, sizeof(szAMSlashPM)/sizeof(WCHAR)))
    {
      /* Date formats: Uppercase AM or PM designation
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
      *pOut++ = FMT_DATE_AMPM_UPPER;
      TRACE("AM/PM\n");
    }
    else if (*pFormat == 'c' || *pFormat == 'C')
    {
      /* Date formats: General date format
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR);
      *pOut++ = FMT_DATE_GENERAL;
      TRACE("gen date\n");
    }
    else if ((*pFormat == 'd' || *pFormat == 'D') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Day specifier
       * Other formats: Literal
       * Types the format if found
       */
      int count = -1;
      header->type = FMT_TYPE_DATE;
      while ((*pFormat == 'd' || *pFormat == 'D') && count < 6)
      {
        pFormat++;
        count++;
      }
      NEED_SPACE(sizeof(BYTE));
      *pOut++ = FMT_DATE_DAY + count;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      /* When we find the days token, reset the seen hours state so that
       * 'mm' is again written as month when encountered.
       */
      fmt_state &= ~FMT_STATE_SEEN_HOURS;
      TRACE("%d d's\n", count + 1);
    }
    else if ((*pFormat == 'h' || *pFormat == 'H') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Hour specifier
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat++;
      /* Record the position of the hours specifier - if we encounter
       * an am/pm specifier we will change the hours from 24 to 12.
       */
      pLastHours = pOut;
      if (*pFormat == 'h' || *pFormat == 'H')
      {
        pFormat++;
        *pOut++ = FMT_DATE_HOUR_0;
        TRACE("hh\n");
      }
      else
      {
        *pOut++ = FMT_DATE_HOUR;
        TRACE("h\n");
      }
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      /* Note that now we have seen an hours token, the next occurrence of
       * 'mm' indicates minutes, not months.
       */
      fmt_state |= FMT_STATE_SEEN_HOURS;
    }
    else if ((*pFormat == 'm' || *pFormat == 'M') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Month specifier (or Minute specifier, after hour specifier)
       * Other formats: Literal
       * Types the format if found
       */
      int count = -1;
      header->type = FMT_TYPE_DATE;
      while ((*pFormat == 'm' || *pFormat == 'M') && count < 4)
      {
        pFormat++;
        count++;
      }
      NEED_SPACE(sizeof(BYTE));
      if (count <= 1 && fmt_state & FMT_STATE_SEEN_HOURS &&
          !(fmt_state & FMT_STATE_WROTE_MINUTES))
      {
        /* We have seen an hours specifier and not yet written a minutes
         * specifier. Write this as minutes and thereafter as months.
         */
        *pOut++ = count == 1 ? FMT_DATE_MIN_0 : FMT_DATE_MIN;
        fmt_state |= FMT_STATE_WROTE_MINUTES; /* Hereafter write months */
      }
      else
        *pOut++ = FMT_DATE_MON + count; /* Months */
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      TRACE("%d m's\n", count + 1);
    }
    else if ((*pFormat == 'n' || *pFormat == 'N') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Minute specifier
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat++;
      if (*pFormat == 'n' || *pFormat == 'N')
      {
        pFormat++;
        *pOut++ = FMT_DATE_MIN_0;
        TRACE("nn\n");
      }
      else
      {
        *pOut++ = FMT_DATE_MIN;
        TRACE("n\n");
      }
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if ((*pFormat == 'q' || *pFormat == 'q') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Quarter specifier
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      *pOut++ = FMT_DATE_QUARTER;
      pFormat++;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      TRACE("quarter\n");
    }
    else if ((*pFormat == 's' || *pFormat == 'S') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Second specifier
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      NEED_SPACE(sizeof(BYTE));
      pFormat++;
      if (*pFormat == 's' || *pFormat == 'S')
      {
        pFormat++;
        *pOut++ = FMT_DATE_SEC_0;
        TRACE("ss\n");
      }
      else
      {
        *pOut++ = FMT_DATE_SEC;
        TRACE("s\n");
      }
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if ((*pFormat == 't' || *pFormat == 'T') &&
              !strncmpiW(pFormat, szTTTTT, sizeof(szTTTTT)/sizeof(WCHAR)))
    {
      /* Date formats: System time specifier
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      pFormat += sizeof(szTTTTT)/sizeof(WCHAR);
      NEED_SPACE(sizeof(BYTE));
      *pOut++ = FMT_DATE_TIME_SYS;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if ((*pFormat == 'w' || *pFormat == 'W') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Week of the year/Day of the week
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_DATE;
      pFormat++;
      if (*pFormat == 'w' || *pFormat == 'W')
      {
        NEED_SPACE(3 * sizeof(BYTE));
        pFormat++;
        *pOut++ = FMT_DATE_WEEK_YEAR;
        *pOut++ = nFirstDay;
        *pOut++ = nFirstWeek;
        TRACE("ww\n");
      }
      else
      {
        NEED_SPACE(2 * sizeof(BYTE));
        *pOut++ = FMT_DATE_DAY_WEEK;
        *pOut++ = nFirstDay;
        TRACE("w\n");
      }

      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if ((*pFormat == 'y' || *pFormat == 'Y') && COULD_BE(FMT_TYPE_DATE))
    {
      /* Date formats: Day of year/Year specifier
       * Other formats: Literal
       * Types the format if found
       */
      int count = -1;
      header->type = FMT_TYPE_DATE;
      while ((*pFormat == 'y' || *pFormat == 'Y') && count < 4)
      {
        pFormat++;
        count++;
      }
      if (count == 2)
      {
        count--; /* 'yyy' has no meaning, despite what MSDN says */
        pFormat--;
      }
      NEED_SPACE(sizeof(BYTE));
      *pOut++ = FMT_DATE_YEAR_DOY + count;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      TRACE("%d y's\n", count + 1);
    }
    /* -------------
     * String tokens
     * -------------
     */
    else if (*pFormat == '@' && COULD_BE(FMT_TYPE_STRING))
    {
      /* String formats: Character from string or space if no char
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_STRING;
      NEED_SPACE(2 * sizeof(BYTE));
      *pOut++ = FMT_STR_COPY_SPACE;
      *pOut = 0x0;
      while (*pFormat == '@')
      {
        *pOut = *pOut + 1;
        str_header->copy_chars++;
        pFormat++;
      }
      TRACE("%d @'s\n", *pOut);
      pOut++;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if (*pFormat == '&' && COULD_BE(FMT_TYPE_STRING))
    {
      /* String formats: Character from string or skip if no char
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_STRING;
      NEED_SPACE(2 * sizeof(BYTE));
      *pOut++ = FMT_STR_COPY_SKIP;
      *pOut = 0x0;
      while (*pFormat == '&')
      {
        *pOut = *pOut + 1;
        str_header->copy_chars++;
        pFormat++;
      }
      TRACE("%d &'s\n", *pOut);
      pOut++;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if ((*pFormat == '<' || *pFormat == '>') && COULD_BE(FMT_TYPE_STRING))
    {
      /* String formats: Use upper/lower case
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_STRING;
      if (*pFormat == '<')
        str_header->flags |= FMT_FLAG_LT;
      else
        str_header->flags |= FMT_FLAG_GT;
      TRACE("to %s case\n", *pFormat == '<' ? "lower" : "upper");
      pFormat++;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
    }
    else if (*pFormat == '!' && COULD_BE(FMT_TYPE_STRING))
    {
      /* String formats: Copy right to left
       * Other formats: Literal
       * Types the format if found
       */
      header->type = FMT_TYPE_STRING;
      str_header->flags |= FMT_FLAG_RTL;
      pFormat++;
      fmt_state &= ~FMT_STATE_OPEN_COPY;
      TRACE("copy right-to-left\n");
    }
    /* --------
     * Literals
     * --------
     */
    /* FIXME: [ seems to be ignored */
    else
    {
      if (*pFormat == '%' && header->type == FMT_TYPE_NUMBER)
      {
        /* Number formats: Percentage indicator, also a literal
         * Other formats: Literal
         * Doesn't type the format
         */
        num_header->flags |= FMT_FLAG_PERCENT;
      }

      if (fmt_state & FMT_STATE_OPEN_COPY)
      {
        pOut[-1] = pOut[-1] + 1; /* Increase the length of the open copy */
        TRACE("extend copy (char '%c'), length now %d\n", *pFormat, pOut[-1]);
      }
      else
      {
        /* Create a new open copy */
        TRACE("New copy (char '%c')\n", *pFormat);
        NEED_SPACE(3 * sizeof(BYTE));
        *pOut++ = FMT_GEN_COPY;
        *pOut++ = pFormat - lpszFormat;
        *pOut++ = 0x1;
        fmt_state |= FMT_STATE_OPEN_COPY;
      }
      pFormat++;
    }
  }

  *pOut++ = FMT_GEN_END;

  header->size = pOut - rgbTok;
  if (pcbActual)
    *pcbActual = header->size;

  return S_OK;
}

/* Number formatting state flags */
#define NUM_WROTE_DEC  0x01 /* Written the decimal separator */
#define NUM_WRITE_ON   0x02 /* Started to write the number */

/* Format a variant using a number format */
static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat,
                                    LPBYTE rgbTok, ULONG dwFlags,
                                    BSTR *pbstrOut, LCID lcid)
{
  BYTE rgbDig[256], *prgbDig;
  NUMPARSE np;
  int have_int, need_int = 0, have_frac, need_frac, exponent = 0, pad = 0;
  WCHAR buff[256], *pBuff = buff;
  VARIANT vString, vBool;
  DWORD dwState = 0;
  FMT_HEADER *header = (FMT_HEADER*)rgbTok;
  FMT_NUMBER_HEADER *numHeader;
  const BYTE* pToken = NULL;
  HRESULT hRes = S_OK;

  TRACE("(%p->(%s%s),%s,%p,0x%08x,%p,0x%08x)\n", pVarIn, debugstr_VT(pVarIn),
        debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut,
        lcid);

  V_VT(&vString) = VT_EMPTY;
  V_VT(&vBool) = VT_BOOL;

  if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL)
  {
    have_int = have_frac = 0;
    numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNull(header));
    V_BOOL(&vBool) = VARIANT_FALSE;
  }
  else
  {
    /* Get a number string from pVarIn, and parse it */
    hRes = VariantChangeTypeEx(&vString, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR);
    if (FAILED(hRes))
      return hRes;

    np.cDig = sizeof(rgbDig);
    np.dwInFlags = NUMPRS_STD;
    hRes = VarParseNumFromStr(V_BSTR(&vString), LCID_US, 0, &np, rgbDig);
    if (FAILED(hRes))
      return hRes;

    have_int = np.cDig;
    have_frac = 0;
    exponent = np.nPwr10;

    /* Figure out which format to use */
    if (np.dwOutFlags & NUMPRS_NEG)
    {
      numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNegative(header));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -