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

📄 setlocal.c

📁 C语言库函数的原型,有用的拿去
💻 C
📖 第 1 页 / 共 3 页
字号:
    struct _is_ctype_compatible buf1, buf2;

    if (!_expandlocale((char *)locale, lctemp, _countof(lctemp), &idtemp, &cptemp, category))
    {
        return NULL;            /* unrecognized locale */
    }
    if (!strcmp(lctemp, ploci->lc_category[category].locale))
    {
        return ploci->lc_category[category].locale;
    }

    cch = sizeof(int)+strlen(lctemp)+1;
    if (!(pch = (char *)_malloc_crt(cch)))
    {
        return NULL;  /* error if malloc fails */
    }

    oldlocale = ploci->lc_category[category].locale; /* save for possible restore*/
    oldhandle = ploci->lc_handle[category];
    memcpy((void *)&oldid, (void *)&ploci->lc_id[category], sizeof(oldid));
    oldcodepage = ploci->lc_codepage;

    /* update locale string */
    _ERRCHECK(strcpy_s(pch + sizeof(int), cch - sizeof(int), lctemp));
    ploci->lc_category[category].locale = pch + sizeof(int);
    ploci->lc_handle[category] = MAKELCID(idtemp.wLanguage, SORT_DEFAULT);
    memcpy((void *)&ploci->lc_id[category], (void *)&idtemp, sizeof(idtemp));

    /* To speedup locale based comparisions, we identify if the current
     * local has first 127 character set same as CLOCALE. If yes then
     * ploci->lc_clike = TRUE.
     */

    if (category==LC_CTYPE)
    {
        ploci->lc_codepage = cptemp;
        buf1 = _Lcid_c[_LOC_CCACHE -1];
        /* brings the recently used codepage to the top. or else shifts
         * every thing down by one so that new _Lcid_c can be placed at
         * the top.
         */
        for ( i = 0; i < _LOC_CCACHE; i++)
        {
            if (ploci->lc_codepage == _Lcid_c[i].id)
            {
                /* We don't really want to swap cache around in case what we are looking
                 *  for is the first element of the cache
                 */
                if (i!=0)
                {
                    _Lcid_c[0] = _Lcid_c[i];
                    _Lcid_c[i] = buf1;
                }
                break;
            }
            else
            {
                buf2 = _Lcid_c[i];
                _Lcid_c[i] = buf1;
                buf1 = buf2;
            }
        }
        if ( i == _LOC_CCACHE)
        {
            if ( __crtGetStringTypeA(NULL, CT_CTYPE1,
                                      _first_127char,
                                      sizeof(_first_127char),
                                      out,
                                      ploci->lc_codepage,
                                      ploci->lc_handle[LC_CTYPE],
                                      TRUE ))
            {
                int j;
                for ( j = 0; j < sizeof(_first_127char); j++)
                    out[j] = out[j]&
                            (_UPPER|_LOWER|_DIGIT|_SPACE|_PUNCT|_CONTROL|_BLANK|_HEX|_ALPHA);
                if ( !memcmp(out, _ctype_loc_style, (sizeof(_first_127char)/sizeof(char))*sizeof(short)))
                {
                    _Lcid_c[0].is_clike = TRUE;
                }
                else
                {
                    _Lcid_c[0].is_clike = FALSE;
                }
            }
            else
                _Lcid_c[0].is_clike = FALSE;
            _Lcid_c[0].id = ploci->lc_codepage;
        }
        ploci->lc_clike = _Lcid_c[0].is_clike;
    }

    if ( category == LC_COLLATE )
        ploci->lc_collate_cp = cptemp;

    if (__lc_category[category].init(ploci))
    {
        /* restore previous state! */
        ploci->lc_category[category].locale = oldlocale;
        _free_crt(pch);
        ploci->lc_handle[category] = oldhandle;
        ploci->lc_codepage = oldcodepage;

        return NULL; /* error if non-zero return */
    }

    /* locale set up successfully */
    /* Cleanup */
    if ((oldlocale != __clocalestr) &&
        (InterlockedDecrement(ploci->lc_category[category].refcount) == 0)
        )
    {
        _ASSERT(0);
        _free_crt(ploci->lc_category[category].refcount);
        _free_crt(ploci->lc_category[category].wrefcount);
        ploci->lc_category[category].wlocale = NULL;
    }
    if (pch) {
        *(int *)pch  = 1;
    }
    ploci->lc_category[category].refcount = (int *)pch;

    return ploci->lc_category[category].locale;
} /* _setlocale_set_cat */



static char * __cdecl _setlocale_get_all ( pthreadlocinfo ploci)
{
    int i;
    int same = 1;
    char *pch = NULL;
    size_t cch = 0;
    int *refcount = NULL;
    size_t refcountSize = 0;
    /* allocate memory if necessary */
    refcountSize = sizeof(int)+(MAX_LC_LEN+1) * (LC_MAX-LC_MIN+1) + CATNAMES_LEN;
    if ( (refcount = _malloc_crt(refcountSize))
           == NULL)
        return NULL;

    pch = (char *)(refcount + 1);
    cch = refcountSize - sizeof(int);
    *pch = '\0';
    *refcount = 1;
    for (i=LC_MIN+1; ; i++)
    {
        _strcats(pch, cch, 3, __lc_category[i].catname,"=",ploci->lc_category[i].locale);
        if (i<LC_MAX)
        {
            _ERRCHECK(strcat_s(pch, cch, ";"));
            if (strcmp(ploci->lc_category[i].locale, ploci->lc_category[i+1].locale))
                same=0;
        }
        else
        {
            if (!same) {
                if (ploci->lc_category[LC_ALL].refcount != NULL &&
                    InterlockedDecrement(ploci->lc_category[LC_ALL].refcount) == 0) {
                    _ASSERT(0);
                    _free_crt(ploci->lc_category[LC_ALL].refcount);
                }
                if (ploci->lc_category[LC_ALL].wrefcount != NULL &&
                    InterlockedDecrement(ploci->lc_category[LC_ALL].wrefcount) == 0) {
                    _ASSERT(0);
                    _free_crt(ploci->lc_category[LC_ALL].wrefcount);
                }
                ploci->lc_category[LC_ALL].wrefcount = NULL;
                ploci->lc_category[LC_ALL].wlocale = NULL;
                ploci->lc_category[LC_ALL].refcount = refcount;
                return ploci->lc_category[LC_ALL].locale = pch;
            } else {
                _free_crt(refcount);
                if (ploci->lc_category[LC_ALL].refcount != NULL &&
                    InterlockedDecrement(ploci->lc_category[LC_ALL].refcount) == 0) {
                    _ASSERT(0);
                    _free_crt(ploci->lc_category[LC_ALL].refcount);
                }
                if (ploci->lc_category[LC_ALL].wrefcount != NULL &&
                    InterlockedDecrement(ploci->lc_category[LC_ALL].wrefcount) == 0) {
                    _ASSERT(0);
                    _free_crt(ploci->lc_category[LC_ALL].wrefcount);
                }
                ploci->lc_category[LC_ALL].wrefcount = NULL;
                ploci->lc_category[LC_ALL].wlocale = NULL;
                ploci->lc_category[LC_ALL].refcount = NULL;
                ploci->lc_category[LC_ALL].locale = NULL;
                return ploci->lc_category[LC_CTYPE].locale;
            }
        }
    }
} /* _setlocale_get_all */


char * _expandlocale (
        char *expr,
        char * output,
        size_t sizeInChars,
        LC_ID * id,
        UINT * cp,
        int category
        )
{
    _psetloc_struct _psetloc_data = &_getptd()->_setloc_data;
    UINT *pcachecp = &_psetloc_data->_cachecp;
    LC_ID *pcacheid = &_psetloc_data->_cacheid;
    char *cachein = _psetloc_data->_cachein;
    size_t cacheinSize = _countof(_psetloc_data->_cachein);
    char *cacheout = _psetloc_data->_cacheout;
    size_t cacheoutSize = _countof(_psetloc_data->_cacheout);
    size_t charactersInExpression = 0;

    if (!expr)
        return NULL; /* error if no input */

    if (output == NULL || sizeInChars == 0)
        return NULL; /* error if no output */


    if (((*expr=='C') && (!expr[1]))
        )  /* for "C" locale, just return */
    {

        _ERRCHECK(strcpy_s(output, sizeInChars, "C"));
        if (id)
        {
            id->wLanguage = 0;
            id->wCountry  = 0;
            id->wCodePage = 0;
        }
        if (cp)
        {
            *cp = CP_ACP; /* return to ANSI code page */
        }
        return output; /* "C" */
    }

    /* first, make sure we didn't just do this one */
    charactersInExpression = strlen(expr);
    if (charactersInExpression >= MAX_LC_LEN ||       /* we would never have cached this */
        (strcmp(cacheout,expr) && strcmp(cachein,expr)))
    {
        /* do some real work */
        LC_STRINGS names;
        const char *source=NULL;
        size_t charactersInSource = 0;

        if (__lc_strtolc(&names, expr))
            return NULL;  /* syntax error */

        if (!__get_qualified_locale(&names, pcacheid, &names))
            return NULL;    /* locale not recognized/supported */

        /* begin: cache atomic section */

        *pcachecp = pcacheid->wCodePage;

        __lc_lctostr(cacheout, cacheoutSize, &names);

        if (*expr && charactersInExpression < MAX_LC_LEN)
        {
            source = expr;
            charactersInSource = charactersInExpression;
        }
        else
        {
            /* Don't cache "" empty string or over-long string */
            source = "";
        }
        /* Ensure that whatever we are about to copy in will be null terminated */

        _ERRCHECK(strncpy_s(cachein, cacheinSize, source, charactersInSource + 1));

        /* end: cache atomic section */
    }
    if (id)
        memcpy((void *)id, (void *)pcacheid, sizeof(*pcacheid));   /* possibly return LC_ID */
    if (cp)
        memcpy((void *)cp, (void *)pcachecp, sizeof(*pcachecp));   /* possibly return cp */

    _ERRCHECK(strcpy_s(output, sizeInChars, cacheout));
    return cacheout; /* return fully expanded locale string */
}

/* helpers */

int __cdecl __init_dummy(pthreadlocinfo ploci)  /* default routine for locale initializer */
{
        return 0;
}

void _strcats ( char *outstr, size_t sizeInBytes, int n, ...)
{
    int i;
    va_list substr;

    va_start (substr, n);

    for (i =0; i<n; i++)
    {
        _ERRCHECK(strcat_s(outstr, sizeInBytes, va_arg(substr, char *)));
    }
    va_end(substr);
}

int __lc_strtolc ( LC_STRINGS *names, const char *locale)
{
    int i;
    size_t len;
    char ch;

    memset((void *)names, '\0', sizeof(LC_STRINGS));  /* clear out result */

    if (*locale=='\0')
        return 0; /* trivial case */

    /* only code page is given */
    if (locale[0] == '.' && locale[1] != '\0')
    {
        _ERRCHECK(strncpy_s(names->szCodePage, _countof(names->szCodePage), &locale[1], MAX_CP_LEN-1));
        /* Make sure to null terminate the string in case locale is > MAX_CP_LEN */
        names->szCodePage[ MAX_CP_LEN -1] = 0;
        return 0;
    }

    for (i=0; ; i++)
    {
        if (!(len=strcspn(locale,"_.,")))
            return -1;  /* syntax error */

        ch = locale[len];

        if ((i==0) && (len<MAX_LANG_LEN) && (ch!='.'))
            _ERRCHECK(strncpy_s(names->szLanguage, _countof(names->szLanguage), locale, len));

        else if ((i==1) && (len<MAX_CTRY_LEN) && (ch!='_'))
            _ERRCHECK(strncpy_s(names->szCountry, _countof(names->szCountry), locale, len));

        else if ((i==2) && (len<MAX_CP_LEN) && (ch=='\0' || ch==','))
            _ERRCHECK(strncpy_s(names->szCodePage, _countof(names->szCodePage), locale, len));

        else
            return -1;  /* error parsing locale string */

        if (ch==',')
        {
            /* modifier not used in current implementation, but it
               must be parsed to for POSIX/XOpen conformance */
        /*  strncpy(names->szModifier, locale, MAX_MODIFIER_LEN-1); */
            break;
        }

        if (!ch)
            break;
        locale+=(len+1);
    }
    return 0;
}

void __lc_lctostr ( char *locale, size_t sizeInBytes, const LC_STRINGS *names)
{
    _ERRCHECK(strcpy_s(locale, sizeInBytes, (char *)names->szLanguage));
    if (*(names->szCountry))
        _strcats(locale, sizeInBytes, 2, "_", names->szCountry);
    if (*(names->szCodePage))
        _strcats(locale, sizeInBytes, 2, ".", names->szCodePage);
}


#endif  /* !defined (_WIN32) */

⌨️ 快捷键说明

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