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

📄 wcsftime.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:
/***
*wcsftime.c - String Format Time
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*
*******************************************************************************/


#include <cruntime.h>
#include <internal.h>
#include <mtdll.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <time.h>
#include <dbgint.h>
#include <malloc.h>
#include <errno.h>
#include <locale.h>
#include <setlocal.h>

/* Prototypes for local routines */
static BOOL __cdecl _W_expandtime(
        _locale_t plocinfo,
        wchar_t specifier,
        const struct tm *tmptr,
        wchar_t **out,
        size_t *count,
        struct __lc_time_data *lc_time,
        unsigned alternate_form);

static void __cdecl _W_store_str (wchar_t *in, wchar_t **out, size_t *count);

static void __cdecl _W_store_num (int num, int digits, wchar_t **out, size_t *count,
        unsigned no_lead_zeros);

static void __cdecl _W_store_number (int num, wchar_t **out, size_t *count);

static BOOL __cdecl _W_store_winword (
        _locale_t plocinfo,
        int field_code,
        const struct tm *tmptr,
        wchar_t **out,
        size_t *count,
        struct __lc_time_data *lc_time);

/* Codes for __lc_time_data ww_* fields for _W_store_winword */

#define WW_SDATEFMT     0
#define WW_LDATEFMT     1
#define WW_TIMEFMT      2

#define TIME_SEP        L':'

/*      get a copy of the current day names */
extern "C" wchar_t * __cdecl _W_Getdays_l (
        _locale_t plocinfo
        )
{
    const struct __lc_time_data *pt;
    size_t n, len = 0;
    wchar_t *p;
    _LocaleUpdate _loc_update(plocinfo);

    pt = __LC_TIME_CURR(_loc_update.GetLocaleT()->locinfo);

    for (n = 0; n < 7; ++n)
        len += wcslen(pt->_W_wday_abbr[n]) + wcslen(pt->_W_wday[n]) + 2;
    p = (wchar_t *)_malloc_crt((len + 1) * sizeof(wchar_t));

    if (p != 0) {
        wchar_t *s = p;

        for (n = 0; n < 7; ++n) {
            *s++ = TIME_SEP;
            _ERRCHECK(wcscpy_s(s, (len + 1) - (s - p), pt->_W_wday_abbr[n]));
            s += wcslen(s);
            *s++ = TIME_SEP;
            _ERRCHECK(wcscpy_s(s, (len + 1) - (s - p), pt->_W_wday[n]));
            s += wcslen(s);
        }
        *s++ = L'\0';
    }

    return (p);
}
extern "C" wchar_t * __cdecl _W_Getdays (
        void
        )
{
    return _W_Getdays_l(NULL);
}

/*      get a copy of the current month names */
extern "C" wchar_t * __cdecl _W_Getmonths_l (
        _locale_t plocinfo
        )
{
    const struct __lc_time_data *pt;
    size_t n, len = 0;
    wchar_t *p;
    _LocaleUpdate _loc_update(plocinfo);

    pt = __LC_TIME_CURR(_loc_update.GetLocaleT()->locinfo);

    for (n = 0; n < 12; ++n)
        len += wcslen(pt->_W_month_abbr[n]) + wcslen(pt->_W_month[n]) + 2;
    p = (wchar_t *)_malloc_crt((len + 1) * sizeof(wchar_t));

    if (p != 0) {
        wchar_t *s = p;

        for (n = 0; n < 12; ++n) {
            *s++ = TIME_SEP;
            _ERRCHECK(wcscpy_s(s, (len + 1) - (s - p), pt->_W_month_abbr[n]));
            s += wcslen(s);
            *s++ = TIME_SEP;
            _ERRCHECK(wcscpy_s(s, (len + 1) - (s - p), pt->_W_month[n]));
            s += wcslen(s);
        }
        *s++ = L'\0';
    }

    return (p);
}
extern "C" wchar_t * __cdecl _W_Getmonths (
        void
        )
{
    return _W_Getmonths_l(NULL);
}

/*      get a copy of the current time locale information */
extern "C" void * __cdecl _W_Gettnames_l (
        _locale_t plocinfo
        )
{
    const struct __lc_time_data *pt;
    size_t n, len = 0;
    size_t footprint =
        sizeof(*pt) % sizeof(wchar_t) == 0
        ? sizeof(*pt)
        : (sizeof(*pt) / sizeof(wchar_t) + 1) * sizeof(wchar_t);
    unsigned char *p;
    _LocaleUpdate _loc_update(plocinfo);

    pt = __LC_TIME_CURR(_loc_update.GetLocaleT()->locinfo);

    for (n = 0; n < 7; ++n)
        len += wcslen(pt->_W_wday_abbr[n]) + wcslen(pt->_W_wday[n]) + 2;
    for (n = 0; n < 12; ++n)
        len += wcslen(pt->_W_month_abbr[n]) + wcslen(pt->_W_month[n]) + 2;
    len += wcslen(pt->_W_ampm[0]) + wcslen(pt->_W_ampm[1]) + 2;
    len += wcslen(pt->_W_ww_sdatefmt) + 1;
    len += wcslen(pt->_W_ww_ldatefmt) + 1;
    len += wcslen(pt->_W_ww_timefmt) + 1;

    p = (unsigned char *)_malloc_crt(len * sizeof(wchar_t) + footprint);

    if (p != 0) {
        struct __lc_time_data *pn = (struct __lc_time_data *)p;
        wchar_t *s = (wchar_t *)(p + footprint);
        const wchar_t *olds = s;

        memcpy(pn, pt, sizeof (*pt));
        for (n = 0; n < 7; ++n) {
            pn->_W_wday_abbr[n] = s;
            _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_wday_abbr[n]));
            s += wcslen(s) + 1;
            pn->_W_wday[n] = s;
            _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_wday[n]));
            s += wcslen(s) + 1;
        }
        for (n = 0; n < 12; ++n) {
            pn->_W_month_abbr[n] = s;
            _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_month_abbr[n]));
            s += wcslen(s) + 1;
            pn->_W_month[n] = s;
            _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_month[n]));
            s += wcslen(s) + 1;
        }
        pn->_W_ampm[0] = s;
        _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_ampm[0]));
        s += wcslen(s) + 1;
        pn->_W_ampm[1] = s;
        _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_ampm[1]));
        s += wcslen(s) + 1;
        pn->_W_ww_sdatefmt = s;
        _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_ww_sdatefmt));
        s += wcslen(s) + 1;
        pn->_W_ww_ldatefmt = s;
        _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_ww_ldatefmt));
        s += wcslen(s) + 1;
        pn->_W_ww_timefmt = s;
        _ERRCHECK(wcscpy_s(s, len - (s - olds), pt->_W_ww_timefmt));
    }

    return (p);
}
extern "C" void * __cdecl _W_Gettnames (
        void
        )
{
    return _W_Gettnames_l(NULL);
}

/***
*size_t _Wcsftime(string, maxsize, format,
*       timeptr, lc_time) - Format a time string for a given locale
*
*Purpose:
*       Place characters into the user's output buffer expanding time
*       format directives as described in the user's control string.
*       Use the supplied 'tm' structure for time data when expanding
*       the format directives. Use the locale information at lc_time.
*       [ANSI]
*
*Entry:
*       wchar_t *string = pointer to output string
*       size_t maxsize = max length of string
*       const wchar_t *format = format control string
*       const struct tm *timeptr = pointer to tb data structure
*       struct __lc_time_data *lc_time = pointer to locale-specific info
*           (passed as void * to avoid type mismatch with C++)
*
*Exit:
*       !0 = If the total number of resulting characters including the
*       terminating null is not more than 'maxsize', then return the
*       number of chars placed in the 'string' array (not including the
*       null terminator).
*
*       0 = Otherwise, return 0 and the contents of the string are
*       indeterminate.
*
*Exceptions:
*
*******************************************************************************/

extern "C" size_t __cdecl _Wcsftime_l (
        wchar_t *string,
        size_t maxsize,
        const wchar_t *format,
        const struct tm *timeptr,
        void *lc_time_arg,
        _locale_t plocinfo
        )
{
        unsigned alternate_form;
        struct __lc_time_data *lc_time;
        BOOL failed=FALSE;              /* true if a failure was reported to us */
        size_t left;                    /* space left in output string */
        wchar_t* strstart = string;
        _LocaleUpdate _loc_update(plocinfo);

        _VALIDATE_RETURN( ( string != NULL ), EINVAL, 0)
        _VALIDATE_RETURN( ( maxsize != 0 ), EINVAL, 0)
        *string = L'\0';

        _VALIDATE_RETURN( ( format != NULL ), EINVAL, 0)

// Validated below
//        _VALIDATE_RETURN( ( timeptr != NULL ), EINVAL, 0)


        lc_time = lc_time_arg == 0 ? _loc_update.GetLocaleT()->locinfo->lc_time_curr :
                  (struct __lc_time_data *)lc_time_arg;

        /* Copy maxsize into temp. */
        left = maxsize;

        /* Copy the input string to the output string expanding the format
        designations appropriately.  Stop copying when one of the following
        is true: (1) we hit a null char in the input stream, or (2) there's
        no room left in the output stream. */

        while (left > 0)
        {
            switch(*format)
            {

            case(L'\0'):

                /* end of format input string */
                goto done;

            case(L'%'):

                /* Format directive.  Take appropriate action based
                on format control character. */

                /* validation section */
                _VALIDATE_RETURN(timeptr != NULL, EINVAL, 0);

                format++;                       /* skip over % char */

                /* process flags */
                alternate_form = 0;
                if (*format == L'#')
                {
                    alternate_form = 1;
                    format++;
                }
                if(!_W_expandtime (_loc_update.GetLocaleT(), *format, timeptr, &string,
                             &left,lc_time, alternate_form))
                {
                    /* if we don't have any space left, do not set the failure flag:
                     * we will simply return ERANGE and do not call _invalid_parameter_handler
                     * (see below)
                     */
                    if (left > 0)
                    {
                        failed=TRUE;
                    }
                    goto done;
                }

                format++;                       /* skip format char */
                break;


            default:
                /* store character, bump pointers, dec the char count */
                *string++ = *format++;
                left--;
                break;
            }
        }


        /* All done.  See if we terminated because we hit a null char or because
        we ran out of space */

        done:

        if (!failed && left > 0) {

            /* Store a terminating null char and return the number of chars
            we stored in the output string. */

            *string = L'\0';
            return(maxsize-left);
        }
        else
        {
            /* error - return an empty string */
            *(strstart) = L'\0';

            /* now return our error/insufficient buffer indication */
            if ( !failed && left <= 0 )
            {
                /* do not report this as an error to allow the caller to resize */
                errno=ERANGE;
            }
            else
            {
                _VALIDATE_RETURN( FALSE, EINVAL, 0);
            }
            /* unused but compiler can't tell */
            return 0;
        }
}

extern "C" size_t __cdecl _Wcsftime (
        wchar_t *string,
        size_t maxsize,
        const wchar_t *format,
        const struct tm *timeptr,
        void *lc_time_arg
        )
{
    return _Wcsftime_l(string, maxsize, format, timeptr,
                        lc_time_arg, NULL);
}

/* Some comments on the valid range of tm_year.

   The check which ensures tm_year >= 0 should not be removed from:
     asctime_s
     asctime
     _wasctime_s
     _wasctime
   these function did not handle well negative years in VS 2003 either;
   17 Mar 1861 would be output as "Sun Mar 17 00:00:00 19-'".

   The check which ensures tm_year >= 69 in the mktime family is correct;
   we had the same check in VS 2003; we do not call _invalid_parameter in
   this case, we simply return (-1) to indicate that mktime could not
   transform from struct tm to time_t.

   The check which ensures tm_year >= 0 in _W_expandtime("%y")
   should not be removed (wcsftime calls _W_expandtime);
   _W_expandtime("%y") did not handle well negative years in Everett either;
   1861 would be printed out as "-'";
   with _W_expandtime("%Y"), everything works well if tm_year >= -1900 && tm_year <= 8099.

⌨️ 快捷键说明

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