summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bk_html.c8
-rw-r--r--bk_info.c4
-rw-r--r--bk_man.c4
-rw-r--r--bk_text.c4
-rw-r--r--error.c8
-rw-r--r--halibut.h2
-rw-r--r--input.c4
-rw-r--r--ustring.c25
8 files changed, 41 insertions, 18 deletions
diff --git a/bk_html.c b/bk_html.c
index 86abd62..7ae80b5 100644
--- a/bk_html.c
+++ b/bk_html.c
@@ -267,13 +267,9 @@ static htmlconfig html_configure(paragraph *source) {
k++; /* treat `xhtml-' and `html-' the same */
if (!ustricmp(k, L"html-restrict-charset")) {
- char *csname = utoa_dup(uadv(k), CS_ASCII);
- ret.restrict_charset = charset_from_localenc(csname);
- sfree(csname);
+ ret.restrict_charset = charset_from_ustr(&p->fpos, uadv(k));
} else if (!ustricmp(k, L"html-output-charset")) {
- char *csname = utoa_dup(uadv(k), CS_ASCII);
- ret.output_charset = charset_from_localenc(csname);
- sfree(csname);
+ ret.output_charset = charset_from_ustr(&p->fpos, uadv(k));
} else if (!ustricmp(k, L"html-version")) {
wchar_t *vername = uadv(k);
static const struct {
diff --git a/bk_info.c b/bk_info.c
index 03f8926..d4a4aca 100644
--- a/bk_info.c
+++ b/bk_info.c
@@ -134,9 +134,7 @@ static infoconfig info_configure(paragraph *source) {
sfree(ret.filename);
ret.filename = dupstr(adv(p->origkeyword));
} else if (!ustricmp(p->keyword, L"info-charset")) {
- char *csname = utoa_dup(uadv(p->keyword), CS_ASCII);
- ret.charset = charset_from_localenc(csname);
- sfree(csname);
+ ret.charset = charset_from_ustr(&p->fpos, uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"info-max-file-size")) {
ret.maxfilesize = utoi(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"info-width")) {
diff --git a/bk_man.c b/bk_man.c
index 7271428..d2607d9 100644
--- a/bk_man.c
+++ b/bk_man.c
@@ -69,9 +69,7 @@ static manconfig man_configure(paragraph *source) {
ret.th = snewn(ep - wp + 1, wchar_t);
memcpy(ret.th, wp, (ep - wp + 1) * sizeof(wchar_t));
} else if (!ustricmp(p->keyword, L"man-charset")) {
- char *csname = utoa_dup(uadv(p->keyword), CS_ASCII);
- ret.charset = charset_from_localenc(csname);
- sfree(csname);
+ ret.charset = charset_from_ustr(&p->fpos, uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"man-headnumbers")) {
ret.headnumbers = utob(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"man-mindepth")) {
diff --git a/bk_text.c b/bk_text.c
index d7c539c..6df426e 100644
--- a/bk_text.c
+++ b/bk_text.c
@@ -126,9 +126,7 @@ static textconfig text_configure(paragraph *source) {
if (!ustricmp(p->keyword, L"text-indent")) {
ret.indent = utoi(uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"text-charset")) {
- char *csname = utoa_dup(uadv(p->keyword), CS_ASCII);
- ret.charset = charset_from_localenc(csname);
- sfree(csname);
+ ret.charset = charset_from_ustr(&p->fpos, uadv(p->keyword));
} else if (!ustricmp(p->keyword, L"text-filename")) {
sfree(ret.filename);
ret.filename = dupstr(adv(p->origkeyword));
diff --git a/error.c b/error.c
index 0330e76..7b9ceaa 100644
--- a/error.c
+++ b/error.c
@@ -257,6 +257,14 @@ static void do_error(int code, va_list ap) {
sfree(sp);
flags = FILEPOS;
break;
+ case err_charset:
+ fpos = *va_arg(ap, filepos *);
+ wsp = va_arg(ap, wchar_t *);
+ sp = utoa_locale_dup(wsp);
+ sprintf(error, "character set `%.200s' not recognised", sp);
+ flags = FILEPOS;
+ sfree(sp);
+ break;
case err_whatever:
sp = va_arg(ap, char *);
vsprintf(error, sp, ap);
diff --git a/halibut.h b/halibut.h
index 88b39f2..f76d059 100644
--- a/halibut.h
+++ b/halibut.h
@@ -241,6 +241,7 @@ enum {
err_infonodechar, /* colon/comma in node name in info */
err_text_codeline, /* \c line too long in text backend */
err_htmlver, /* unrecognised HTML version keyword */
+ err_charset, /* unrecognised character set name */
err_whatever /* random error of another type */
};
@@ -299,6 +300,7 @@ int uisdigit(wchar_t);
wchar_t *ustrlow(wchar_t *s);
wchar_t *ustrftime(const wchar_t *wfmt, const struct tm *timespec);
int cvt_ok(int charset, const wchar_t *s);
+int charset_from_ustr(filepos *fpos, const wchar_t *name);
/*
* wcwidth.c
diff --git a/input.c b/input.c
index 4eb1d8c..b31d583 100644
--- a/input.c
+++ b/input.c
@@ -86,9 +86,7 @@ static void input_configure(input *in, paragraph *cfg) {
assert(cfg->type == para_Config);
if (!ustricmp(cfg->keyword, L"input-charset")) {
- char *csname = utoa_dup(uadv(cfg->keyword), CS_ASCII);
- in->charset = charset_from_localenc(csname);
- sfree(csname);
+ in->charset = charset_from_ustr(&cfg->fpos, uadv(cfg->keyword));
}
}
diff --git a/ustring.c b/ustring.c
index 8cf8554..13ee635 100644
--- a/ustring.c
+++ b/ustring.c
@@ -459,3 +459,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;
+}