+ const tchar *p;
+ int n;
+
+ for (p = format; *p; p++)
+ if (*p == T('%') && *(p + 1) == T('W'))
+ goto special;
+ return tvfprintf(fp, format, va);
+special:
+ n = 0;
+ for (p = format; *p; p++) {
+ if (*p == T('%') && (*(p + 1) == T('W'))) {
+ int ret;
+ tchar *tstr;
+ size_t tstr_nbytes;
+ utf16lechar *ucs = va_arg(va, utf16lechar*);
+ size_t ucs_nbytes = utf16le_strlen(ucs);
+
+ ret = utf16le_to_tstr(ucs, ucs_nbytes,
+ &tstr, &tstr_nbytes);
+ if (ret) {
+ ret = tfprintf(fp, T("??????"));
+ } else {
+ ret = tfprintf(fp, T("%"TS), tstr);
+ FREE(tstr);
+ }
+ if (ret < 0)
+ return -1;
+ else
+ n += ret;
+ p++;
+ } else {
+ if (tputc(*p, fp) == EOF)
+ return -1;
+ n++;
+ }
+ }
+ return n;
+}
+
+int
+wimlib_printf(const tchar *format, ...)
+{
+ int ret;
+ va_list va;
+
+ va_start(va, format);
+ ret = wimlib_vfprintf(stdout, format, va);
+ va_end(va);
+ return ret;
+}
+
+int
+wimlib_fprintf(FILE *fp, const tchar *format, ...)
+{
+ int ret;
+ va_list va;
+
+ va_start(va, format);
+ ret = wimlib_vfprintf(fp, format, va);
+ va_end(va);
+ return ret;
+}
+#endif
+
+#if defined(ENABLE_ERROR_MESSAGES) || defined(ENABLE_DEBUG)
+static void
+wimlib_vmsg(const tchar *tag, const tchar *format,
+ va_list va, bool perror)
+{
+#ifndef DEBUG