示例#1
0
文件: mbslen.c 项目: Jar-win/Waterfox
/* get number of characters in a mult-byte character string */
int
mbslen(const char *s, size_t *ncharsp)
{
#ifdef HAVE_XLOCALE
    static locale_t loc = 0;
    static int initialized = 0;
#endif /* HAVE_XLOCALE */
#ifdef WIN32
    char *my_locale=0;
    unsigned int i;
#endif  /* WIN32 */
    int _status;
    size_t nbytes;
    int nchars;
    mbstate_t mbs;

#ifdef HAVE_XLOCALE
    if (! initialized) {
        initialized = 1;
        loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
    }

    if (loc == 0) {
        /* unable to create the UTF-8 locale */
        assert(loc != 0);  /* should never happen */
#endif /* HAVE_XLOCALE */

#ifdef WIN32
    if (!setlocale(LC_CTYPE, 0))
        ABORT(R_INTERNAL);

    if (!(my_locale = r_strdup(setlocale(LC_CTYPE, 0))))
        ABORT(R_NO_MEMORY);

    for (i=0; i<strlen(my_locale); i++)
        my_locale[i] = toupper(my_locale[i]);

    if (!strstr(my_locale, "UTF-8") && !strstr(my_locale, "UTF8"))
        ABORT(R_NOT_FOUND);
#else
    /* can't count UTF-8 characters with mbrlen if the locale isn't UTF-8 */
    /* null-checking setlocale is required because Android */
    char *locale = setlocale(LC_CTYPE, 0);
    /* some systems use "utf8" instead of "UTF-8" like Fedora 17 */
    if (!locale || (!strcasestr(locale, "UTF-8") && !strcasestr(locale, "UTF8")))
        ABORT(R_NOT_FOUND);
#endif

#ifdef HAVE_XLOCALE
    }
#endif /* HAVE_XLOCALE */

    memset(&mbs, 0, sizeof(mbs));
    nchars = 0;

#ifdef HAVE_XLOCALE
    while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0)
#else
    while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0)
#endif /* HAVE_XLOCALE */
    {
        if (nbytes == (size_t)-1)   /* should never happen */ {
            ABORT(R_INTERNAL);
        }
        if (nbytes == (size_t)-2)   /* encoding error */ {
            ABORT(R_BAD_DATA);
        }

        s += nbytes;
        ++nchars;
    }

    *ncharsp = nchars;

    _status = 0;
  abort:
#ifdef WIN32
    RFREE(my_locale);
#endif
    return _status;
}
示例#2
0
/* get number of characters in a mult-byte character string */
int
mbslen(const char *s, size_t *ncharsp)
{
#ifdef DARWIN
    static locale_t loc = 0;
    static int initialized = 0;
#endif /* DARWIN */
#ifdef WIN32
    char *my_locale=0;
    unsigned int i;
#endif  /* WIN32 */
    int _status;
    size_t nbytes;
    int nchars;
    mbstate_t mbs;

#ifdef DARWIN
    if (! initialized) {
        initialized = 1;
        loc = newlocale(LC_CTYPE_MASK, "UTF-8", LC_GLOBAL_LOCALE);
    }

    if (loc == 0) {
        /* unable to create the UTF-8 locale */
        assert(loc != 0);  /* should never happen */
#endif /* DARWIN */

#ifdef WIN32
        if (!setlocale(LC_CTYPE, 0))
            ABORT(R_INTERNAL);

        if (!(my_locale = r_strdup(setlocale(LC_CTYPE, 0))))
            ABORT(R_NO_MEMORY);

        for (i=0; i<strlen(my_locale); i++)
            my_locale[i] = toupper(my_locale[i]);

        if (!strstr(my_locale, "UTF-8"))
            ABORT(R_NOT_FOUND);
#else
        /* can't count UTF-8 characters with mbrlen if the locale isn't UTF-8 */
        if (! strcasestr(setlocale(LC_CTYPE, 0), "UTF-8"))
            ABORT(R_NOT_FOUND);
#endif

#ifdef DARWIN
    }
#endif /* DARWIN */

    memset(&mbs, 0, sizeof(mbs));
    nchars = 0;

#ifdef DARWIN
    while (*s != '\0' && (nbytes = mbrlen_l(s, strlen(s), &mbs, loc)) != 0)
#else
    while (*s != '\0' && (nbytes = mbrlen(s, strlen(s), &mbs)) != 0)
#endif /* DARWIN */
    {
        if (nbytes == (size_t)-1) { /* should never happen */
            assert(0);
            ABORT(R_INTERNAL);
        }
        if (nbytes == (size_t)-2) { /* encoding error */
            assert(0);
            ABORT(R_BAD_DATA);
        }

        s += nbytes;
        ++nchars;
    }

    *ncharsp = nchars;

    _status = 0;
abort:
#ifdef WIN32
    RFREE(my_locale);
#endif
    return _status;
}