static void do_error(int code, va_list ap) {
char error[1024];
- char auxbuf[256];
char c;
char *sp, *sp2;
wchar_t *wsp;
break;
case err_badparatype:
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
fpos = *va_arg(ap, filepos *);
sprintf(error, "command `%.200s' unrecognised at start of"
" paragraph", sp);
flags = FILEPOS;
+ sfree(sp);
break;
case err_badmidcmd:
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
fpos = *va_arg(ap, filepos *);
sprintf(error, "command `%.200s' unexpected in mid-paragraph", sp);
flags = FILEPOS;
+ sfree(sp);
break;
case err_unexbrace:
fpos = *va_arg(ap, filepos *);
case err_nosuchkw:
fpos = *va_arg(ap, filepos *);
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
sprintf(error, "unable to resolve cross-reference to `%.200s'", sp);
flags = FILEPOS;
+ sfree(sp);
break;
case err_multiBR:
fpos = *va_arg(ap, filepos *);
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
sprintf(error, "multiple `\\BR' entries given for `%.200s'", sp);
flags = FILEPOS;
+ sfree(sp);
break;
case err_nosuchidxtag:
+ fpos = *va_arg(ap, filepos *);
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
sprintf(error, "`\\IM' on unknown index tag `%.200s'", sp);
- flags = 0;
- /* FIXME: need to get a filepos to here somehow */
+ sfree(sp);
+ flags = FILEPOS;
break;
case err_cantopenw:
sp = va_arg(ap, char *);
case err_macroexists:
fpos = *va_arg(ap, filepos *);
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
sprintf(error, "macro `%.200s' already defined", sp);
flags = FILEPOS;
+ sfree(sp);
break;
case err_sectjump:
fpos = *va_arg(ap, filepos *);
fpos = *va_arg(ap, filepos *);
fpos2 = *va_arg(ap, filepos *);
wsp = va_arg(ap, wchar_t *);
- sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf), CS_LOCAL);
+ sp = utoa_locale_dup(wsp);
sprintf(error, "paragraph keyword `%.200s' already defined at ", sp);
sprintf(error + strlen(error), "%s:%d", fpos2.filename, fpos2.line);
flags = FILEPOS;
+ sfree(sp);
break;
case err_misplacedlcont:
fpos = *va_arg(ap, filepos *);
#include "tree234.h"
/*
- * FIXME: Charset temporary workarounds
- */
-#define CS_FIXME CS_ISO8859_1
-#define CS_LOCAL CS_ISO8859_1
-
-/*
* Structure tags
*/
typedef struct input_Tag input;
char *utoa_dup_len(wchar_t const *s, int charset, int *len);
char *utoa_careful_dup(wchar_t const *s, int charset);
wchar_t *ufroma_dup(char const *s, int charset);
+char *utoa_locale_dup(wchar_t const *s);
+wchar_t *ufroma_locale_dup(char const *s);
int ustrlen(wchar_t const *s);
wchar_t *uadv(wchar_t *s);
wchar_t *ustrcpy(wchar_t *dest, wchar_t const *source);
*/
#include <wchar.h>
+#include <stdlib.h>
+#include <assert.h>
#include <time.h>
#include "halibut.h"
return buf;
}
+char *utoa_locale_dup(wchar_t const *s)
+{
+ /*
+ * This variant uses the C library locale.
+ */
+ char *ret;
+ int len;
+ size_t siz;
+
+ len = ustrlen(s);
+
+ ret = mknewa(char, 1 + MB_CUR_MAX * len);
+
+ siz = wcstombs(ret, s, len);
+
+ if (siz) {
+ assert(siz <= MB_CUR_MAX * len);
+ ret[siz] = '\0';
+ ret = resize(ret, siz+1);
+ return ret;
+ }
+
+ /*
+ * If that failed, try a different strategy (which we will also
+ * attempt in the total absence of wcstombs). Retrieve the
+ * locale's charset from nl_langinfo or equivalent, and use
+ * normal utoa_dup.
+ */
+ return utoa_dup(s, charset_from_locale());
+}
+
+wchar_t *ufroma_locale_dup(char const *s)
+{
+ /*
+ * This variant uses the C library locale.
+ */
+ wchar_t *ret;
+ int len;
+ size_t siz;
+
+ len = strlen(s);
+
+ ret = mknewa(wchar_t, 1 + 2*len); /* be conservative */
+
+ siz = mbstowcs(ret, s, len);
+
+ if (siz) {
+ assert(siz <= (size_t)(2 * len));
+ ret[siz] = L'\0';
+ ret = resize(ret, siz+1);
+ return ret;
+ }
+
+ /*
+ * If that failed, try a different strategy (which we will also
+ * attempt in the total absence of wcstombs). Retrieve the
+ * locale's charset from nl_langinfo or equivalent, and use
+ * normal ufroma_dup.
+ */
+ return ufroma_dup(s, charset_from_locale());
+}
+
int ustrlen(wchar_t const *s) {
int len = 0;
while (*s++) len++;