X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/f15300499bce37cd28ea2ace0f2bd1c364fc835e..8f664e7e91c918cd13248f6b684580c4dd2cdb31:/ustring.c diff --git a/ustring.c b/ustring.c index 8cf8554..3c5698c 100644 --- a/ustring.c +++ b/ustring.c @@ -172,17 +172,18 @@ char *utoa_locale_dup(wchar_t const *s) * This variant uses the C library locale. */ char *ret; - int len; + int len, outlen; size_t siz; len = ustrlen(s); - ret = snewn(1 + MB_CUR_MAX * len, char); + outlen = 1 + MB_CUR_MAX * len; + ret = snewn(outlen+1, char); - siz = wcstombs(ret, s, len); + siz = wcstombs(ret, s, outlen); if (siz) { - assert(siz <= MB_CUR_MAX * len); + assert(siz <= (size_t)(outlen)); ret[siz] = '\0'; ret = sresize(ret, siz+1, char); return ret; @@ -203,17 +204,18 @@ wchar_t *ufroma_locale_dup(char const *s) * This variant uses the C library locale. */ wchar_t *ret; - int len; + int len, outlen; size_t siz; len = strlen(s); - ret = snewn(1 + 2*len, wchar_t); /* be conservative */ + outlen = 1 + 2*len; + ret = snewn(outlen+1, wchar_t); /* be conservative */ - siz = mbstowcs(ret, s, len); + siz = mbstowcs(ret, s, outlen); if (siz) { - assert(siz <= (size_t)(2 * len)); + assert(siz <= (size_t)(outlen)); ret[siz] = L'\0'; ret = sresize(ret, siz+1, wchar_t); return ret; @@ -338,7 +340,7 @@ int utoi(wchar_t const *s) { s++; } - return n; + return n * sign; } double utof(wchar_t const *s) @@ -459,3 +461,28 @@ int cvt_ok(int charset, const wchar_t *s) } return TRUE; } + +/* + * Wrapper around charset_from_localenc which accepts the charset + * name as a wide string (since that happens to be more useful). + * Also throws a Halibut error and falls back to CS_ASCII if the + * charset is unrecognised, meaning the rest of the program can + * rely on always getting a valid charset id back from this + * function. + */ +int charset_from_ustr(filepos *fpos, const wchar_t *name) +{ + char *csname; + int charset; + + csname = utoa_dup(name, CS_ASCII); + charset = charset_from_localenc(csname); + + if (charset == CS_NONE) { + charset = CS_ASCII; + error(err_charset, fpos, name); + } + + sfree(csname); + return charset; +}