/* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, locale_t locale, const wchar_t *fmt, va_list ap) { int ret; FILE fake; struct __sfileext fakeext; unsigned char buf[BUFSIZ]; _FILEEXT_SETUP(&fake, &fakeext); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; #ifdef notyet fake._orientation = fp->_orientation; fake._mbstate = fp->_mbstate; #endif /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfwprintf(&fake, locale, fmt, ap); if (ret >= 0 && __sflush(&fake)) ret = WEOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); }
/* * Helper function for `fprintf to unbuffered unix file': creates a * temporary buffer. We only work on write-only files; this avoids * worries about ungetc buffers and so forth. */ static int __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap) { int ret; FILE fake; unsigned char buf[BUFSIZ]; /* XXX This is probably not needed. */ if (prepwrite(fp) != 0) return (EOF); /* copy the important variables */ fake._flags = fp->_flags & ~__SNBF; fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; fake._orientation = fp->_orientation; fake._mbstate = fp->_mbstate; /* set up the buffer */ fake._bf._base = fake._p = buf; fake._bf._size = fake._w = sizeof(buf); fake._lbfsize = 0; /* not actually used, but Just In Case */ /* do the work, then copy any error status */ ret = __vfwprintf(&fake, fmt, ap); if (ret >= 0 && __fflush(&fake)) ret = WEOF; if (fake._flags & __SERR) fp->_flags |= __SERR; return (ret); }
/* * MT-safe version */ int vfwprintf_l(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) { int ret; FIX_LOCALE(locale); FLOCKFILE(fp); /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && fp->_file >= 0) ret = __sbprintf(fp, locale, fmt0, ap); else ret = __vfwprintf(fp, locale, fmt0, ap); FUNLOCKFILE(fp); return (ret); }
static void convert_and_print (const char *format, __gnuc_va_list ap) { #define ALLOCA_LIMIT 2000 size_t len; wchar_t *wformat = NULL; mbstate_t st; size_t res; const char *tmp; if (format == NULL) return; len = strlen (format) + 1; do { if (len < ALLOCA_LIMIT) wformat = (wchar_t *) alloca (len * sizeof (wchar_t)); else { if (wformat != NULL && len / 2 < ALLOCA_LIMIT) wformat = NULL; wformat = (wchar_t *) realloc (wformat, len * sizeof (wchar_t)); if (wformat == NULL) { fputws_unlocked (L"out of memory\n", stderr); return; } } memset (&st, '\0', sizeof (st)); tmp =format; } while ((res = __mbsrtowcs (wformat, &tmp, len, &st)) == len); if (res == (size_t) -1) /* The string cannot be converted. */ wformat = (wchar_t *) L"???"; __vfwprintf (stderr, wformat, ap); }
/* Write formatted output to stdout according to the format string FORMAT, using the argument list in ARG. */ int __vwprintf (const wchar_t *format, __gnuc_va_list arg) { return __vfwprintf (stdout, format, arg); }