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

📄 setlocal.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:
    }
    _copytlocinfo_nolock(retval->locinfo, &__initiallocinfo);

    if (_setlocale_nolock(retval->locinfo, _category, _locale) == NULL)
    {
        __removelocaleref(retval->locinfo);
        __freetlocinfo(retval->locinfo);

        _free_crt(retval);
        retval = NULL;
    }
    else
    {
        if (_setmbcp_nolock(retval->locinfo->lc_codepage, retval->mbcinfo) != 0)
        {
            _free_crt(retval->mbcinfo);
            __removelocaleref(retval->locinfo);
            __freetlocinfo(retval->locinfo);
            _free_crt(retval);
            retval = NULL;
        }
        else
        {
            retval->mbcinfo->refcount = 1;
            retval->mbcinfo->refcount = 1;
        }
    }

    return retval;
}

/* __create_locale will be removed in the next LKG */
_locale_t __cdecl __create_locale(
        int _category,
        const char *_locale
        )
{
    return _create_locale(_category, _locale);
}

/***
* _locale_t _get_current_locale() -
*    Gets the current locale setting.
*
* Purpose:
*       Gets the current locale setting for this thread. Returns locale
*       in form of _locale_t, which then can be used with other locale
*       aware string funcitons.
*
* Entry:
*
* Exit:
*
* Exceptions:
*
*******************************************************************************/

_locale_t __cdecl _get_current_locale(void)
{
    _locale_t retval = NULL;
    _ptiddata ptd = _getptd();

    if ((retval = _calloc_crt(sizeof(_locale_tstruct), 1)) == NULL)
    {
        errno = ENOMEM;
        return NULL;
    }

    __updatetlocinfo();
    __updatetmbcinfo();
    /*
     * No one can free the data pointed to by ptlocinfo while we're copying
     * it, since we're copying this thread's ptlocinfo, which won't be updated
     * during the copy.  So there are no worries about it being freed from
     * under us.  We still need a lock while adding a reference for the new
     * copy, though, because of the race condition found in _wsetlocale.
     */
    retval->locinfo = ptd->ptlocinfo;
    retval->mbcinfo = ptd->ptmbcinfo;
    _mlock(_SETLOCALE_LOCK);
    __try {
        __addlocaleref(retval->locinfo);
    }
    __finally {
        _munlock(_SETLOCALE_LOCK);
    }
    _mlock(_MB_CP_LOCK);
    __try
    {
        InterlockedIncrement(&(retval->mbcinfo->refcount));
    }
    __finally
    {
        _munlock(_MB_CP_LOCK);
    }

    return retval;
}

/* __get_current_locale will be removed in the next LKG */
_locale_t __cdecl __get_current_locale(void)
{
    return _get_current_locale();
}

/***
*char * setlocale(int category, char *locale) - Set one or all locale categories
*
*Purpose:
*       The setlocale() routine allows the user to set one or more of
*       the locale categories to the specific locale selected by the
*       user.  [ANSI]
*
*       NOTE: Under !_INTL, the C libraries only support the "C" locale.
*       Attempts to change the locale will fail.
*
*Entry:
*       int category = One of the locale categories defined in locale.h
*       char *locale = String identifying a specific locale or NULL to
*                  query the current locale.
*
*Exit:
*       If supplied locale pointer == NULL:
*
*           Return pointer to current locale string and do NOT change
*           the current locale.
*
*       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.
*
*******************************************************************************/

#if !defined (_WIN32)

char * __cdecl setlocale (
        int _category,
        const char *_locale
        )
{
    if ( (_locale == NULL) ||
         (_locale[0] == '\0') ||
         ( (_locale[0]=='C') && (_locale[1]=='\0'))  )
        return(__clocalestr);
    else
        return(NULL);
}

#else  /* !defined (_WIN32) */

char * __cdecl setlocale (
        int _category,
        const char *_locale
        )
{
    char * retval=NULL;
    pthreadlocinfo ptloci = NULL;
    _ptiddata ptd;

    /* Validate category */
    _VALIDATE_RETURN(LC_MIN <= _category && _category <= LC_MAX, EINVAL, NULL);

    ptd = _getptd();

    __updatetlocinfo();
    // Note here that we increment the _ownlocale for this thread. We need this
    // to make sure that the locale is not updated to some other locale by call to
    // stricmp().
    // Don't set any flag that aligns with N, P or G
    ptd->_ownlocale |= 0x10;
    __try {
        if ((ptloci = _calloc_crt(sizeof(threadlocinfo), 1)) != NULL)
        {
            /*
             * No one can free the data pointed to by ptlocinfo while we're
             * copying it, since we're copying this thread's ptlocinfo, which
             * won't be updated during the copy.  So there are no worries
             * about it being freed from under us.  We still need a lock while
             * making the copy, though, because of the race condition found in
             * _wsetlocale.
             */
            _mlock(_SETLOCALE_LOCK);
            __try {
                _copytlocinfo_nolock(ptloci, ptd->ptlocinfo);
            }
            __finally {
                _munlock(_SETLOCALE_LOCK);
            }

            if (( ptloci != NULL) && (retval = _setlocale_nolock(ptloci, _category, _locale))) {
                /*
                * What we are trying here is that if no call has been made to
                * setlocale to change locale from "C" locale to some other locale
                * we keep __locale_changed = 0. Other funcitons depending on locale
                * use this variable to optimize performance for C locale which is
                * normally the case in 90% of the applications.
                */
                if (_locale != NULL && strcmp(_locale, __clocalestr))
                {
                    __locale_changed = 1;
                }

                _mlock(_SETLOCALE_LOCK);
                __try {
                    (void)_updatetlocinfoEx_nolock(&ptd->ptlocinfo, ptloci);
                    __removelocaleref(ptloci);
                    // Note that after incrementing _ownlocale, if this thread doesn't
                    // have it's own locale, _ownlocale variable should be 1.
                    if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT) &&
                        !(__globallocalestatus & _GLOBAL_LOCALE_BIT)) {
                        (void)_updatetlocinfoEx_nolock(&__ptlocinfo, ptd->ptlocinfo);
                        sync_legacy_variables_lk();
                    }
                } __finally {
                    _munlock(_SETLOCALE_LOCK);
                }
            } else {
                __removelocaleref(ptloci);
                __freetlocinfo(ptloci);
            }
        }
    } __finally {
        // Undo the previous action.
        ptd->_ownlocale &= ~0x10;
    }

    return retval;
}

static char * __cdecl _setlocale_nolock(
        pthreadlocinfo ploci,
        int _category,
        const char *_locale
        )
{
    char * retval;
    /* Interpret locale */

    if (_category != LC_ALL)
    {
        retval = (_locale) ? _setlocale_set_cat(ploci, _category,_locale) :
            ploci->lc_category[_category].locale;

    } else { /* LC_ALL */
        char lctemp[MAX_LC_LEN];
        int i;
        int same = 1;
        int fLocaleSet = 0; /* flag to indicate if anything successfully set */

        if (_locale != NULL)
        {
            if ( (_locale[0]=='L') && (_locale[1]=='C') && (_locale[2]=='_') )
            {
                /* parse compound locale string */
                size_t len;
                const char * p = _locale;  /* start of string to parse */
                const char * s;

                do {
                    s = strpbrk(p,"=;");

                    if ((s==(char *)NULL) || (!(len=(size_t)(s-p))) || (*s==';'))
                        return NULL;  /* syntax error */

                    /* match with known LC_ strings, if possible, else ignore */
                    for (i=LC_ALL+1; i<=LC_MAX; i++)
                    {
                        if ((!strncmp(__lc_category[i].catname,p,len))
                            && (len==strlen(__lc_category[i].catname)))
                        {
                            break;  /* matched i */
                        }
                    } /* no match if (i>LC_MAX) -- just ignore */

                    if ((!(len = strcspn(++s,";"))) && (*s!=';'))
                        return NULL;  /* syntax error */

                    if (i<=LC_MAX)
                    {
                        _ERRCHECK(strncpy_s(lctemp, _countof(lctemp), s, len));
                        lctemp[len]='\0';   /* null terminate string */

                        /* don't fail unless all categories fail */
                        if (_setlocale_set_cat(ploci, i,lctemp))
                            fLocaleSet++;       /* record a success */
                    }
                    if (*(p = s+len)!='\0')
                        p++;  /* skip ';', if present */

                } while (*p);

                retval = (fLocaleSet) ? _setlocale_get_all(ploci) : NULL;

            } else { /* simple LC_ALL locale string */

                /* confirm locale is supported, get expanded locale */
                if (retval = _expandlocale((char *)_locale, lctemp, _countof(lctemp), NULL, NULL, _category))
                {
                    for (i=LC_MIN; i<=LC_MAX; i++)
                    {
                        if (i!=LC_ALL)
                        {
                            if (strcmp(lctemp, ploci->lc_category[i].locale))
                            {
                                if (_setlocale_set_cat(ploci, i, lctemp))
                                {
                                    fLocaleSet++;   /* record a success */
                                }
                                else
                                {
                                    same = 0;       /* record a failure */
                                }
                            }
                            else
                                fLocaleSet++;   /* trivial succcess */
                        }
                    }
                    if (same) /* needn't call setlocale_get_all() if all the same */
                    {
                        retval = _setlocale_get_all(ploci);
                        /* retval set above */
                    }
                    else
                        retval = (fLocaleSet) ? _setlocale_get_all(ploci) : NULL;
                }
            }
        } else { /* LC_ALL & NULL */
            retval = _setlocale_get_all (ploci);
        }
    }

    /* common exit point */
    return retval;
} /* setlocale */


static char * __cdecl _setlocale_set_cat (
        pthreadlocinfo ploci,
        int category,
        const char * locale
        )
{
    char * oldlocale;
    LCID oldhandle;
    UINT oldcodepage;
    LC_ID oldid;

    LC_ID idtemp;
    UINT cptemp;
    char lctemp[MAX_LC_LEN];
    char * pch = NULL;
    size_t cch = 0;
    short out[sizeof(_first_127char)];
    int i;
    _ptiddata _ptd = _getptd();
    struct _is_ctype_compatible *_Lcid_c = _ptd->_setloc_data._Lcid_c; // __setloc_data._Lcid_c is array
    int _LOC_CCACHE = sizeof(_ptd->_setloc_data._Lcid_c)/sizeof(struct _is_ctype_compatible);

⌨️ 快捷键说明

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