add xprintf()
this introduces a "commit" callback to the xprintf kernel, to avoid pointlessly assembling a temporary output string prior to printing it. one could lift the buffer limitations by introducing a "segment" callback instead, but that would slow down xvasprintf() due to the higher callback rate, for no good reason.
This commit is contained in:
parent
0079ec774a
commit
80831e50b9
|
@ -83,7 +83,7 @@ if test "x$ob_cv_strftime_z" = x"no"; then
|
|||
fi
|
||||
|
||||
AC_CHECK_HEADERS(poll.h sys/select.h)
|
||||
AC_CHECK_FUNCS(vasprintf strnlen memrchr timegm)
|
||||
AC_CHECK_FUNCS(vasprintf strnlen memrchr timegm fwrite_unlocked)
|
||||
|
||||
AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"])
|
||||
AC_CHECK_LIB(nsl, inet_ntoa, [SOCK_LIBS="$SOCK_LIBS -lnsl"])
|
||||
|
|
|
@ -166,6 +166,7 @@ void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... );
|
|||
void flushn( void );
|
||||
|
||||
char *xvasprintf( const char *fmt, va_list ap );
|
||||
void xprintf( const char *fmt, ... );
|
||||
|
||||
#if !defined(_POSIX_SYNCHRONIZED_IO) || _POSIX_SYNCHRONIZED_IO <= 0
|
||||
# define fdatasync fsync
|
||||
|
|
47
src/util.c
47
src/util.c
|
@ -198,8 +198,10 @@ sys_error( const char *msg, ... )
|
|||
#define QPRINTF_SEGS 16
|
||||
#define QPRINTF_BUFF 1000
|
||||
|
||||
char *
|
||||
xvasprintf( const char *fmt, va_list ap )
|
||||
typedef void (*printf_cb)( const char **segs, uint *segls, int nsegs, uint totlen, void *aux );
|
||||
|
||||
static void
|
||||
xvprintf_core( const char *fmt, va_list ap, printf_cb cb, void *cb_aux )
|
||||
{
|
||||
int nsegs = 0;
|
||||
uint totlen = 0;
|
||||
|
@ -320,15 +322,54 @@ xvasprintf( const char *fmt, va_list ap )
|
|||
fmt++;
|
||||
}
|
||||
}
|
||||
char *out = d = nfmalloc( totlen + 1 );
|
||||
cb( segs, segls, nsegs, totlen, cb_aux );
|
||||
}
|
||||
|
||||
static void
|
||||
xasprintf_cb( const char **segs, uint *segls, int nsegs, uint totlen, void *aux )
|
||||
{
|
||||
char *d = nfmalloc( totlen + 1 );
|
||||
*(char **)aux = d;
|
||||
for (int i = 0; i < nsegs; i++) {
|
||||
memcpy( d, segs[i], segls[i] );
|
||||
d += segls[i];
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
char *
|
||||
xvasprintf( const char *fmt, va_list ap )
|
||||
{
|
||||
char *out;
|
||||
xvprintf_core( fmt, ap, xasprintf_cb, &out );
|
||||
return out;
|
||||
}
|
||||
|
||||
#ifndef HAVE_FWRITE_UNLOCKED
|
||||
# define flockfile(f)
|
||||
# define funlockfile(f)
|
||||
# define fwrite_unlocked(b, l, n, f) fwrite(b, l, n, f)
|
||||
#endif
|
||||
|
||||
static void
|
||||
xprintf_cb( const char **segs, uint *segls, int nsegs, uint totlen ATTR_UNUSED, void *aux ATTR_UNUSED )
|
||||
{
|
||||
flockfile( stdout );
|
||||
for (int i = 0; i < nsegs; i++)
|
||||
fwrite_unlocked( segs[i], 1, segls[i], stdout );
|
||||
funlockfile( stdout );
|
||||
}
|
||||
|
||||
void
|
||||
xprintf( const char *fmt, ... )
|
||||
{
|
||||
va_list va;
|
||||
|
||||
va_start( va, fmt );
|
||||
xvprintf_core( fmt, va, xprintf_cb, NULL );
|
||||
va_end( va );
|
||||
}
|
||||
|
||||
void
|
||||
vFprintf( FILE *f, const char *msg, va_list va )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user