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

📄 strftime.c

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

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

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

static void __cdecl _store_str (char *in, char **out, size_t *count);

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

static void __cdecl _store_number (int num, char **out, size_t *count);

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

extern "C" size_t __cdecl _Strftime (
        char *string,
        size_t maxsize,
        const char *format,
        const struct tm *timeptr,
        void *lc_time_arg
        );

extern "C" size_t __cdecl _Strftime_l (
        char *string,
        size_t maxsize,
        const char *format,
        const struct tm *timeptr,
        void *lc_time_arg,
        _locale_t plocinfo
        );

/* Codes for __lc_time_data ww_* fields for _store_winword */

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

#define TIME_SEP        ':'

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

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

    for (n = 0; n < 7; ++n)
        len += strlen(pt->wday_abbr[n]) + strlen(pt->wday[n]) + 2;
    p = (char *)_malloc_crt(len + 1);

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

        for (n = 0; n < 7; ++n) {
            *s++ = TIME_SEP;
            _ERRCHECK(strcpy_s(s, (len + 1) - (s - p), pt->wday_abbr[n]));
            s += strlen(s);
            *s++ = TIME_SEP;
            _ERRCHECK(strcpy_s(s, (len + 1) - (s - p), pt->wday[n]));
            s += strlen(s);
        }
        *s++ = '\0';
    }

    return (p);
}
extern "C" char * __cdecl _Getdays (
        void
        )
{
    return _Getdays_l(NULL);
}

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

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

    for (n = 0; n < 12; ++n)
        len += strlen(pt->month_abbr[n]) + strlen(pt->month[n]) + 2;
    p = (char *)_malloc_crt(len + 1);

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

        for (n = 0; n < 12; ++n) {
            *s++ = TIME_SEP;
            _ERRCHECK(strcpy_s(s, (len + 1) - (s - p), pt->month_abbr[n]));
            s += strlen(s);
            *s++ = TIME_SEP;
            _ERRCHECK(strcpy_s(s, (len + 1) - (s - p), pt->month[n]));
            s += strlen(s);
        }
        *s++ = '\0';
    }

    return (p);
}
extern "C" char * __cdecl _Getmonths (
        void
        )
{
    return _Getmonths_l(NULL);
}

/*      get a copy of the current time locale information */
extern "C" void * __cdecl _Gettnames_l (
        _locale_t plocinfo
        )
{
    const struct __lc_time_data *pt;
    size_t n, len = 0;
    char *p;
    _LocaleUpdate _loc_update(plocinfo);

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

    for (n = 0; n < 7; ++n)
        len += strlen(pt->wday_abbr[n]) + strlen(pt->wday[n]) + 2;
    for (n = 0; n < 12; ++n)
        len += strlen(pt->month_abbr[n]) + strlen(pt->month[n]) + 2;
    len += strlen(pt->ampm[0]) + strlen(pt->ampm[1]) + 2;
    len += strlen(pt->ww_sdatefmt) + 1;
    len += strlen(pt->ww_ldatefmt) + 1;
    len += strlen(pt->ww_timefmt) + 1;
    len += sizeof (*pt);
    p = (char *)_malloc_crt(len);

    if (p != 0) {
        struct __lc_time_data *pn = (struct __lc_time_data *)p;
        char *s = (char *)p + sizeof (*pt);

        memcpy(p, pt, sizeof (*pt));
        for (n = 0; n < 7; ++n) {
            pn->wday_abbr[n] = s;
            _ERRCHECK(strcpy_s(s, len - (s - p), pt->wday_abbr[n]));
            s += strlen(s) + 1;
            pn->wday[n] = s;
            _ERRCHECK(strcpy_s(s, len - (s - p), pt->wday[n]));
            s += strlen(s) + 1;
        }
        for (n = 0; n < 12; ++n) {
            pn->month_abbr[n] = s;
            _ERRCHECK(strcpy_s(s, len - (s - p), pt->month_abbr[n]));
            s += strlen(s) + 1;
            pn->month[n] = s;
            _ERRCHECK(strcpy_s(s, len - (s - p), pt->month[n]));
            s += strlen(s) + 1;
        }
        pn->ampm[0] = s;
        _ERRCHECK(strcpy_s(s, len - (s - p), pt->ampm[0]));
        s += strlen(s) + 1;
        pn->ampm[1] = s;
        _ERRCHECK(strcpy_s(s, len - (s - p), pt->ampm[1]));
        s += strlen(s) + 1;
        pn->ww_sdatefmt = s;
        _ERRCHECK(strcpy_s(s, len - (s - p), pt->ww_sdatefmt));
        s += strlen(s) + 1;
        pn->ww_ldatefmt = s;
        _ERRCHECK(strcpy_s(s, len - (s - p), pt->ww_ldatefmt));
        s += strlen(s) + 1;
        pn->ww_timefmt = s;
        _ERRCHECK(strcpy_s(s, len - (s - p), pt->ww_timefmt));
    }

    return (p);
}
extern "C" void * __cdecl _Gettnames (
        void
        )
{
    return _Gettnames_l(NULL);
}


/***
*size_t strftime(string, maxsize, format, timeptr) - Format a time string
*
*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.
*       [ANSI]
*
*Entry:
*       char *string = pointer to output string
*       size_t maxsize = max length of string
*       const char *format = format control string
*       const struct tm *timeptr = pointer to tb data structure
*
*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 _strftime_l (
        char *string,
        size_t maxsize,
        const char *format,
        const struct tm *timeptr,
        _locale_t plocinfo
        )
{
        return (_Strftime_l(string, maxsize, format, timeptr, 0, plocinfo));
}
extern "C" size_t __cdecl strftime (
        char *string,
        size_t maxsize,
        const char *format,
        const struct tm *timeptr
        )
{
        return (_Strftime_l(string, maxsize, format, timeptr, 0, NULL));
}

/***
*size_t _Strftime(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:
*       char *string = pointer to output string
*       size_t maxsize = max length of string
*       const char *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 _Strftime (
        char *string,
        size_t maxsize,
        const char *format,
        const struct tm *timeptr,
        void *lc_time_arg
        )
{
    return _Strftime_l(string, maxsize, format, timeptr,
                        lc_time_arg, NULL);
}

extern "C" size_t __cdecl _Strftime_l (
        char *string,
        size_t maxsize,
        const char *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 */
        char* strstart = string;
        _LocaleUpdate _loc_update(plocinfo);

        _VALIDATE_RETURN( ( string != NULL ), EINVAL, 0)
        _VALIDATE_RETURN( ( maxsize != 0 ), EINVAL, 0)
        *string = '\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('\0'):

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

            case('%'):

                /* 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 == '#')
                {
                    alternate_form = 1;
                    format++;
                }
                if(!_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 */
                if( _isleadbyte_l((int)(*format), _loc_update.GetLocaleT()) && left > 1)
                {
                    /* catch \0 directly following leadbyte - invalid MBCS sequence, and do not copy to output */
                    if(format[1]=='\0')
                    {
                        _ASSERTE(("Invalid MBCS character sequence passed to strftime",0));
                        failed=TRUE;
                        goto done;
                    }
                    else
                    {
                        *string++ = *format++;
                        left--;
                    }
                }


                *string++ = *format++;
                left--;
                break;
            }

⌨️ 快捷键说明

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