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

📄 setlocal.c

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

#include <locale.h>
#include <internal.h>

#if !defined (_WIN32)

static char _clocalestr[] = "C";

#else  /* !defined (_WIN32) */

#include <cruntime.h>
#include <setlocal.h>
#include <mtdll.h>
#include <malloc.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h> /* for strtol */
#include <dbgint.h>
#include <ctype.h>
#include <awint.h>
#include <mbctype.h>
#include <rterr.h>

void * __cdecl __removelocaleref( pthreadlocinfo);
void __cdecl __addlocaleref( pthreadlocinfo);
void __cdecl __freetlocinfo(pthreadlocinfo);

/* C locale */
extern char __clocalestr[];


#ifdef _DEBUG
// free as much of memory as possible in debug mode to minimise leaks.
#include <sect_attribs.h>
#include <internal.h>
void __cdecl _locterm(void);

_CRTALLOC(".CRT$XPX") static _PVFV pterm = _locterm;

#endif  /* _DEBUG */


__declspec(selectany) struct {
        const char * catname;
        char * locale;
        int (* init)(threadlocinfo *);
} const __lc_category[LC_MAX-LC_MIN+1] = {
        /* code assumes locale initialization is "__clocalestr" */
        { "LC_ALL",     NULL,           __init_dummy /* never called */ },
        { "LC_COLLATE", __clocalestr,    __init_collate  },
        { "LC_CTYPE",   __clocalestr,    __init_ctype    },
        { "LC_MONETARY",__clocalestr,    __init_monetary },
        { "LC_NUMERIC", __clocalestr,    __init_numeric  },
        { "LC_TIME",    __clocalestr,    __init_time }
};

static const char _first_127char[] = {
        1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17,
        18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
        35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
        69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
        86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,101,102,
        103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
        120,121,122,123,124,125,126,127
};

extern threadlocinfo __initiallocinfo;
extern const unsigned short _wctype[];
static const short *_ctype_loc_style = _wctype+2;
int __locale_changed=0;



/*
 * Flag indicating whether or not setlocale() is active. Its value is the
 * number of setlocale() calls currently active.
 *
 * WARNING - This flag and query function are obsolete, and are here only to
 * preserve existing exports for binary compatibility.
 */
_CRTIMP int __setlc_active;
_CRTIMP int __cdecl ___setlc_active_func(void)
{
    return __setlc_active;
}

/*
 * Flag indicating whether or not a function which references the locale
 * without having locked it is active. Its value is the number of such
 * functions.
 *
 * WARNING - This flag and query function are obsolete, and are here only to
 * preserve existing exports for binary compatibility.
 */
_CRTIMP int __unguarded_readlc_active;
_CRTIMP int * __cdecl ___unguarded_readlc_active_add_func(void)
{
    return &__unguarded_readlc_active;
}

/* helper function prototypes */
char * _expandlocale(char *, char *, size_t, LC_ID *, UINT *, int);
void _strcats(char *, size_t, int, ...);
void __lc_lctostr(char *, size_t, const LC_STRINGS *);
int __lc_strtolc(LC_STRINGS *, const char *);
static char * __cdecl _setlocale_set_cat(pthreadlocinfo, int, const char *);
static char * __cdecl _setlocale_get_all(pthreadlocinfo);
static pthreadlocinfo __cdecl _updatetlocinfo_nolock(void);
static char * __cdecl _setlocale_nolock(pthreadlocinfo, int, const char *);
int __cdecl _setmbcp_nolock(int, pthreadmbcinfo);
pthreadlocinfo __cdecl _updatetlocinfoEx_nolock(pthreadlocinfo *, pthreadlocinfo);
#endif  /* !defined (_WIN32) */



/***
*
* _copytlocinfo_nolock(pthreadlocinfo ptlocid, pthreadlocinfo ptlocis)
*
* Purpose:
*       Copy the contents of ptlocis to ptlocid and increase the refcount of all the
*       elements in ptlocid after copy.
*
******************************************************************************/
static void __cdecl _copytlocinfo_nolock(
    pthreadlocinfo ptlocid,
    pthreadlocinfo ptlocis)
{
    if (ptlocis != NULL && ptlocid != NULL && ptlocid != ptlocis) {
        *ptlocid = *ptlocis;
        ptlocid->refcount = 0;
        __addlocaleref(ptlocid);
    }
}

/***
* _configthreadlocale(int i)
*
* Purpose:
*       To set _ownlocale flag on threadinfo sturct. If this flag is set, this thread
*       is going own it's threadlocinfo struct. Setlocale call on other thread will have
*       no effect on this thread's locale. If 0 is passed then nothing is changed, but
*       current status is returned.
* Exit   :
*       Returns the current status - i.e. per thread locale is enabled or not.
*
*******************************************************************************/
int __cdecl _configthreadlocale(int i)
{
    /*
     * ownlocale flag struct:
     * bits: 000000000000000000000000000000P1
     * P is set when _ENABLE_PER_THREAD_LOCALE is called for this thread
     * or _ENABLE_PER_THREAD_LOCALE_NEW was set when this thread was created.
     *
     * __globallocalestatus structure:
     * bits: 11111111111111111111111111111N1G
     * G is set if _ENABLE_PER_THREAD_LOCALE_GLOBAL is set.
     * G is 0 if _ENABLE_PER_THREAD_LOCALE_GLOBAL is not set.
     * N is set if _ENABLE_PER_THREAD_LOCALE_NEW is set.
     * N is 0 if _ENABLE_PER_THREAD_LOCALE_NEW is not set.
     */
    _ptiddata ptd = _getptd();
    int retval = (ptd->_ownlocale & _PER_THREAD_LOCALE_BIT)==0 ? _DISABLE_PER_THREAD_LOCALE:_ENABLE_PER_THREAD_LOCALE;

    switch(i)
    {
        case _ENABLE_PER_THREAD_LOCALE :
            ptd->_ownlocale = ptd->_ownlocale | _PER_THREAD_LOCALE_BIT;
            break;

        case _DISABLE_PER_THREAD_LOCALE :
            ptd->_ownlocale = ptd->_ownlocale & ~_PER_THREAD_LOCALE_BIT;
            break;

        case 0 :
            break;

        /* used only during dll startup for linkopt */
        case -1 :
            __globallocalestatus=-1;
            break;

        default :
            _VALIDATE_RETURN(("Invalid parameter for _configthreadlocale",0),EINVAL,-1);
            break;
    }

    return retval;

}

#ifdef _DEBUG
void __cdecl _locterm(void)
{
    if (__ptlocinfo != &__initiallocinfo) {
        _mlock(_SETLOCALE_LOCK);
        __try
        {
            __ptlocinfo = _updatetlocinfoEx_nolock(&__ptlocinfo, &__initiallocinfo);
        }
        __finally
        {
            _munlock(_SETLOCALE_LOCK);
        }
    }
}
#endif  /* _DEBUG */

/***
* void sync_legacy_variables_lk()
*
* Purpose:
*   Syncs all the legacy locale specific variables to the global locale.
*
*******************************************************************************/
static __inline void sync_legacy_variables_lk()
{
    __lconv = __ptlocinfo->lconv;
    _pctype = __ptlocinfo->pctype;
    __mb_cur_max = __ptlocinfo->mb_cur_max;
}
/***
*_free_locale() - free threadlocinfo
*
*Purpose:
*       Free up the per-thread locale info structure specified by the passed
*       pointer.
*
*Entry:
*       pthreadlocinfo ptloci
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/

void __cdecl _free_locale(
        _locale_t plocinfo
        )
{
    if (plocinfo != NULL)
    {
        _mlock(_MB_CP_LOCK);
        __try
        {
            if (plocinfo->mbcinfo != NULL &&
                    InterlockedDecrement(&(plocinfo->mbcinfo->refcount)) == 0 &&
                    plocinfo->mbcinfo != &__initialmbcinfo )
            {
                _free_crt(plocinfo->mbcinfo);
            }
        }
        __finally
        {
            _munlock(_MB_CP_LOCK);
        }

        if (plocinfo->locinfo != NULL)
        {
            /*
             * this portion has to be in locale lock as there may be case when
             * not this thread but some other thread is still holding to this
             * locale and is also trying to free this locale. In this case
             * we may end up leaking memory.
             */

            _mlock(_SETLOCALE_LOCK);
            __try
            {
                __removelocaleref(plocinfo->locinfo);
                if ( (plocinfo->locinfo != NULL) &&
                     (plocinfo->locinfo->refcount == 0) &&
                     (plocinfo->locinfo != &__initiallocinfo) )
                    __freetlocinfo(plocinfo->locinfo);
            }
            __finally
            {
                _munlock(_SETLOCALE_LOCK);
            }
        }
        /*
         * set plocinfo structure to zero. This will reduce the chance of
         * using plocinfo after it is being freed.
         */
        plocinfo->locinfo = (void *)(((char *)NULL) + 0xbaadf00d);
        plocinfo->mbcinfo = (void *)(((char *)NULL) + 0xbaadf00d);
        _free_crt(plocinfo);
    }
}

/* __free_locale will be removed in the next LKG */
void __cdecl __free_locale(
        _locale_t plocinfo
        )
{
    _free_locale(plocinfo);
}

/***
* _locale_t _create_locale(int category, char *locale) -
*    Set one or all locale categories of global locale structure
*
* Purpose:
*       The _create_locale() routine allows the user to create a _locale_t
*       object that can be used with other locale functions.
*
* Entry:
*       int category = One of the locale categories defined in locale.h
*       char *locale = String identifying a specific locale.
*
* Exit:
*       If supplied locale pointer != NULL:
*
*           If locale string is '\0', set locale to default.
*
*           If desired setting can be honored, return a pointer to the
*           locale string for the appropriate category.
*
*           If desired setting can NOT be honored, return NULL.
*
* Exceptions:
*       Compound locale strings of the form "LC_COLLATE=xxx;LC_CTYPE=xxx;..."
*       are allowed for the LC_ALL category.  This is to support the ability
*       to restore locales with the returned string, as specified by ANSI.
*       Setting the locale with a compound locale string will succeed unless
*       *all* categories failed.  The returned string will reflect the current
*       locale.  For example, if LC_CTYPE fails in the above string, setlocale
*       will return "LC_COLLATE=xxx;LC_CTYPE=yyy;..." where yyy is the
*       previous locale (or the C locale if restoring the previous locale
*       also failed).  Unrecognized LC_* categories are ignored.
*
*******************************************************************************/

_locale_t __cdecl _create_locale(
        int _category,
        const char *_locale
        )
{
    _locale_t retval = NULL;

    /* Validate input */
    if ( (_category < LC_MIN) || (_category > LC_MAX) || _locale == NULL)
        return NULL;

    if ((retval = _calloc_crt(sizeof(_locale_tstruct), 1)) == NULL)
    {
        errno = ENOMEM;
        return NULL;
    }
    if ((retval->locinfo = _calloc_crt(sizeof(threadlocinfo), 1)) == NULL)
    {
        _free_crt(retval);
        errno = ENOMEM;
        return NULL;
    }
    if ((retval->mbcinfo = _calloc_crt(sizeof(threadmbcinfo), 1)) == NULL)
    {
        _free_crt(retval->locinfo);
        _free_crt(retval);
        errno = ENOMEM;
        return NULL;

⌨️ 快捷键说明

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