X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/78c730856d459899f1ea8134c9f5415f586503ba..0dfaac7284d7f1a54e957bba4a881d93328c1630:/ustring.c diff --git a/ustring.c b/ustring.c index 3f52972..3d18a4f 100644 --- a/ustring.c +++ b/ustring.c @@ -11,10 +11,10 @@ wchar_t *ustrdup(wchar_t const *s) { wchar_t *r; if (s) { - r = mknewa(wchar_t, 1+ustrlen(s)); + r = snewn(1+ustrlen(s), wchar_t); ustrcpy(r, s); } else { - r = mknew(wchar_t); + r = snew(wchar_t); *r = 0; } return r; @@ -100,7 +100,7 @@ char *utoa_internal_dup(wchar_t const *s, int charset, int *lenp, int careful) len = ustrlen(s); outlen = len + 10; - outbuf = mknewa(char, outlen); + outbuf = snewn(outlen, char); outpos = 0; outbuf[outpos] = '\0'; @@ -116,7 +116,7 @@ char *utoa_internal_dup(wchar_t const *s, int charset, int *lenp, int careful) } if (!ret) { outlen = outlen * 3 / 2; - outbuf = resize(outbuf, outlen); + outbuf = sresize(outbuf, outlen, char); } outpos += ret; outbuf[outpos] = '\0'; @@ -125,7 +125,7 @@ char *utoa_internal_dup(wchar_t const *s, int charset, int *lenp, int careful) * Clean up */ outlen = outpos + 32; - outbuf = resize(outbuf, outlen); + outbuf = sresize(outbuf, outlen, char); ret = charset_from_unicode(NULL, 0, outbuf + outpos, outlen - outpos + 1, charset, &state, NULL); @@ -157,12 +157,12 @@ wchar_t *ufroma_dup(char const *s, int charset) { len = strlen(s) + 1; do { - buf = resize(buf, len); + buf = sresize(buf, len, wchar_t); ustrfroma(s, buf, len, charset); len = (3 * len) / 2 + 1; /* this guarantees a strict increase */ } while (ustrlen(buf) >= len-1); - buf = resize(buf, ustrlen(buf)+1); + buf = sresize(buf, ustrlen(buf)+1, wchar_t); return buf; } @@ -172,19 +172,20 @@ 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 = mknewa(char, 1 + MB_CUR_MAX * len); + 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 = resize(ret, siz+1); + ret = sresize(ret, siz+1, char); return ret; } @@ -203,19 +204,20 @@ 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 = mknewa(wchar_t, 1 + 2*len); /* 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 = resize(ret, siz+1); + ret = sresize(ret, siz+1, wchar_t); return ret; } @@ -386,7 +388,7 @@ static void ustrftime_internal(rdstring *rs, char formatchr, size = 0; do { size += USTRFTIME_DELTA; - buf = resize(buf, size); + buf = sresize(buf, size, wchar_t); ret = (int) wcsftime(buf, size, fmt, timespec); } while (ret == 0); @@ -406,7 +408,7 @@ static void ustrftime_internal(rdstring *rs, char formatchr, size = 0; do { size += USTRFTIME_DELTA; - buf = resize(buf, size); + buf = sresize(buf, size, char); ret = (int) strftime(buf, size, fmt, timespec); } while (ret == 0); @@ -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; +}